6#include "QskSegmentedBar.h"
8#include "QskLabelData.h"
9#include "QskTextOptions.h"
11#include "QskSkinlet.h"
13#include "QskAnimationHint.h"
15#include <qguiapplication.h>
16#include <qstylehints.h>
17#include <qfontmetrics.h>
33 PrivateData( Qt::Orientation orientation )
34 : orientation( orientation )
38 QVector< QskLabelData > options;
39 QVector< bool > enabled;
41 int selectedIndex = -1;
42 int currentIndex = -1;
44 Qt::Orientation orientation;
45 bool isPressed =
false;
48QskSegmentedBar::QskSegmentedBar( QQuickItem* parent )
53QskSegmentedBar::QskSegmentedBar( Qt::Orientation orientation, QQuickItem* parent )
55 , m_data( new PrivateData( orientation ) )
57 setAcceptHoverEvents(
true );
59 if( orientation == Qt::Horizontal )
60 initSizePolicy( QskSizePolicy::MinimumExpanding, QskSizePolicy::Fixed );
62 initSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::MinimumExpanding );
64 setAcceptedMouseButtons( Qt::LeftButton );
65 setWheelEnabled(
true );
66 setFocusPolicy( Qt::StrongFocus );
68 connect(
this, &QskSegmentedBar::currentIndexChanged,
72QskSegmentedBar::~QskSegmentedBar()
76void QskSegmentedBar::setOrientation( Qt::Orientation orientation )
78 if( orientation != m_data->orientation )
81 m_data->orientation = orientation;
88Qt::Orientation QskSegmentedBar::orientation()
const
90 return m_data->orientation;
93void QskSegmentedBar::setTextOptions(
const QskTextOptions& textOptions )
95 setTextOptionsHint( Text, textOptions );
100 return textOptionsHint( Text );
103int QskSegmentedBar::addOption(
const QUrl& graphicSource,
const QString& text )
105 return addOption(
QskLabelData( text, graphicSource ) );
108int QskSegmentedBar::addOption(
const QskLabelData& option )
110 m_data->options += option;
111 m_data->enabled +=
true;
116 if ( isComponentComplete() )
117 Q_EMIT optionsChanged();
120 setSelectedIndex( 0 );
125QskLabelData QskSegmentedBar::optionAt(
int index )
const
127 return m_data->options.value( index );
130void QskSegmentedBar::setOptions(
const QStringList& options )
132 setOptions( qskCreateLabelData( options ) );
135void QskSegmentedBar::setOptions(
const QVector< QskLabelData >& options )
137 m_data->options = options;
138 m_data->enabled.fill(
true, options.count() );
144 Q_EMIT optionsChanged();
152void QskSegmentedBar::mousePressEvent( QMouseEvent* event )
156 const int index = indexAtPosition( qskMousePosition( event ) );
158 if( isSegmentEnabled( index ) )
160 m_data->isPressed =
true;
162 if( ( focusPolicy() & Qt::ClickFocus ) == Qt::ClickFocus )
164 if( !QGuiApplication::styleHints()->setFocusOnTouchRelease() )
166 if( index != m_data->currentIndex )
167 setCurrentIndex( index );
176 setSkinHint( Splash | A::Metric | A::Position, qskMousePosition( event ) );
177 startTransition( Splash | A::Metric | A::Size, hint, 0.0, 1.0 );
181void QskSegmentedBar::mouseUngrabEvent()
183 m_data->isPressed =
false;
186void QskSegmentedBar::mouseReleaseEvent( QMouseEvent* event )
190 if( m_data->isPressed )
192 m_data->isPressed =
false;
193 index = indexAtPosition( qskMousePosition( event ) );
196 if( isSegmentEnabled( index ) )
198 if( ( focusPolicy() & Qt::ClickFocus ) == Qt::ClickFocus )
200 if( QGuiApplication::styleHints()->setFocusOnTouchRelease() )
202 if( index != m_data->currentIndex )
203 setCurrentIndex( index );
208 setSelectedIndex( index );
211void QskSegmentedBar::keyPressEvent( QKeyEvent* event )
213 switch( event->key() )
222 if ( m_data->orientation == Qt::Vertical )
223 forwards = (
event->key() == Qt::Key_Down );
225 forwards = (
event->key() == Qt::Key_Right );
227 const int index = nextIndex( m_data->selectedIndex, forwards );
228 if ( index != m_data->selectedIndex )
230 if ( index >= 0 && index < count() )
231 setSelectedIndex( index );
245 const int steps = qskFocusChainIncrement( event );
249 const int index = nextIndex( m_data->currentIndex, steps > 0 );
251 if( index != m_data->currentIndex )
252 setCurrentIndex( index );
260 Inherited::keyPressEvent( event );
263void QskSegmentedBar::keyReleaseEvent( QKeyEvent* event )
265 if( event->key() == Qt::Key_Select || event->key() == Qt::Key_Space )
267 if( m_data->currentIndex >= 0 )
268 setSelectedIndex( m_data->currentIndex );
273 Inherited::keyReleaseEvent( event );
276void QskSegmentedBar::hoverEnterEvent( QHoverEvent* event )
280 setSkinHint( Segment |
Hovered | A::Metric | A::Position, qskHoverPosition( event ) );
284void QskSegmentedBar::hoverMoveEvent( QHoverEvent* event )
288 setSkinHint( Segment |
Hovered | A::Metric | A::Position, qskHoverPosition( event ) );
292void QskSegmentedBar::hoverLeaveEvent( QHoverEvent* )
300void QskSegmentedBar::focusInEvent( QFocusEvent* event )
302 int index = m_data->currentIndex;
304 switch( event->reason() )
306 case Qt::TabFocusReason:
308 index = nextIndex( -1,
true );
312 case Qt::BacktabFocusReason:
314 index = nextIndex( -1,
false );
320 if( index < 0 || index >= count() )
321 index = nextIndex( -1,
true );
325 if( index != m_data->currentIndex )
326 setCurrentIndex( index );
328 Inherited::focusInEvent( event );
331void QskSegmentedBar::focusOutEvent( QFocusEvent* event )
333 setCurrentIndex( -1 );
334 Inherited::focusOutEvent( event );
337void QskSegmentedBar::clear()
342 m_data->options.clear();
343 Q_EMIT optionsChanged();
345 if( m_data->selectedIndex >= 0 )
347 m_data->selectedIndex = -1;
348 Q_EMIT selectedIndexChanged( m_data->selectedIndex );
351 if( m_data->currentIndex >= 0 )
353 m_data->currentIndex = -1;
354 Q_EMIT currentIndexChanged( m_data->currentIndex );
360void QskSegmentedBar::setCurrentIndex(
int index )
362 if ( !isSegmentEnabled( index ) )
365 if( index != m_data->currentIndex )
367 m_data->currentIndex = index;
368 setPositionHint( Segment |
Focused, index );
370 Q_EMIT currentIndexChanged( index );
374int QskSegmentedBar::currentIndex()
const
376 return m_data->currentIndex;
379QString QskSegmentedBar::currentText()
const
381 if ( m_data->currentIndex >= 0 )
382 return optionAt( m_data->currentIndex ).text();
387void QskSegmentedBar::setSelectedIndex(
int index )
389 if ( !isSegmentEnabled( index ) )
392 if( index != m_data->selectedIndex )
394 const auto oldIndex = m_data->selectedIndex;
395 m_data->selectedIndex = index;
397 movePositionHint( Cursor, index );
400 Q_EMIT selectedIndexChanged( index );
402 const auto states = skinStates();
405 startHintTransitions( states | Selected, states, oldIndex );
408 startHintTransitions( states, states | Selected, index );
412int QskSegmentedBar::selectedIndex()
const
414 return m_data->selectedIndex;
417int QskSegmentedBar::nextIndex(
int index,
bool forwards )
const
419 const auto& options = m_data->options;
420 const int count = options.count();
424 if( index < 0 || index >= count )
427 while( ++index < count )
429 if( isSegmentEnabled( index ) )
435 if( index < 0 || index >= count )
438 while( --index >= 0 )
440 if( isSegmentEnabled( index ) )
448QVector< QskLabelData > QskSegmentedBar::options()
const
450 return m_data->options;
453int QskSegmentedBar::count()
const
455 return m_data->options.count();
458void QskSegmentedBar::setSegmentEnabled(
int index,
bool enabled )
460 auto& bitVector = m_data->enabled;
462 if( ( index < 0 ) || ( index >= bitVector.count() )
463 || ( bitVector[ index ] == enabled ) )
468 bitVector[ index ] = enabled;
472 if( m_data->currentIndex == index )
473 setCurrentIndex( -1 );
479bool QskSegmentedBar::isSegmentEnabled(
int index )
const
481 return m_data->enabled.value( index,
false );
484int QskSegmentedBar::indexAtPosition(
const QPointF& pos )
const
492 if( m_data->currentIndex >= 0 )
495 contentsRect(), QskSegmentedBar::Segment, m_data->currentIndex );
501#include "moc_QskSegmentedBar.cpp"
Lookup key for a QskSkinHintTable.
Variation
Some sort of variation.
void focusIndicatorRectChanged()
static const QskAspect::State Hovered
void setSizePolicy(QskSizePolicy)
virtual QRectF focusIndicatorRect() const
QRectF contentsRect() const
static const QskAspect::State Focused
QskAspect::Variation effectiveVariation() const override
QRectF focusIndicatorRect() const override final
bool setSkinHint(QskAspect, const QVariant &)
Insert a hint into the local hint table.
QskAnimationHint animationHint(QskAspect, QskSkinHintStatus *=nullptr) const
const QskSkinlet * effectiveSkinlet() const