QskSegmentedBar ( inspired by the IOS segmented control ) added

This commit is contained in:
Uwe Rathmann 2022-04-20 14:14:37 +02:00
parent c4efdc1816
commit 50ee82fbaa
8 changed files with 997 additions and 18 deletions

View File

@ -19,6 +19,7 @@
#include <QskPushButton.h>
#include <QskProgressBar.h>
#include <QskScrollView.h>
#include <QskSegmentedBar.h>
#include <QskSeparator.h>
#include <QskSlider.h>
#include <QskSubWindow.h>
@ -127,6 +128,7 @@ namespace
void setupProgressBar();
void setupPushButton();
void setupScrollView();
void setupSegmentedBar();
void setupSeparator();
void setupSubWindow();
void setupSlider();
@ -159,6 +161,7 @@ void Editor::setup()
setupProgressBar();
setupPushButton();
setupScrollView();
setupSegmentedBar();
setupSeparator();
setupSlider();
setupSubWindow();
@ -326,6 +329,11 @@ void Editor::setupFocusIndicator()
setGradient( Q::Panel, QskGradient() );
}
void Editor::setupSegmentedBar()
{
// TODO
}
void Editor::setupSeparator()
{
using A = QskAspect;

View File

@ -147,6 +147,7 @@ namespace
void setupProgressBar();
void setupPushButton();
void setupScrollView();
void setupSegmentedBar();
void setupSeparator();
void setupSlider();
void setupSubWindow();
@ -267,6 +268,7 @@ void Editor::setup()
setupProgressBar();
setupPushButton();
setupScrollView();
setupSegmentedBar();
setupSeparator();
setupSlider();
setupSubWindow();
@ -465,6 +467,11 @@ void Editor::setupSeparator()
setSeparator( Q::Panel | A::Vertical );
}
void Editor::setupSegmentedBar()
{
// TODO
}
void Editor::setupPageIndicator()
{
using Q = QskPageIndicator;

View File

@ -0,0 +1,476 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskSegmentedBar.h"
#include "QskGraphic.h"
#include "QskGraphicProvider.h"
#include "QskTextOptions.h"
#include "QskEvent.h"
#include "QskSkinlet.h"
#include "QskAspect.h"
#include <QGuiApplication>
#include <QStyleHints>
#include <QFontMetricsF>
QSK_SUBCONTROL( QskSegmentedBar, Panel )
QSK_SUBCONTROL( QskSegmentedBar, Segment )
QSK_SUBCONTROL( QskSegmentedBar, Cursor )
QSK_SUBCONTROL( QskSegmentedBar, Text )
QSK_SUBCONTROL( QskSegmentedBar, Graphic )
QSK_SYSTEM_STATE( QskSegmentedBar, Selected, QskAspect::FirstSystemState << 2 )
namespace
{
class Option
{
public:
Option() = default;
Option( const QUrl& graphicSource, const QString& text )
: graphicSource( graphicSource )
, text( text )
{
#if 1
// lazy loading TODO ...
if ( !graphicSource.isEmpty() )
graphic = Qsk::loadGraphic( graphicSource );
#endif
}
QUrl graphicSource;
QString text;
QskGraphic graphic;
bool isEnabled = true;
};
}
class QskSegmentedBar::PrivateData
{
public:
PrivateData( Qt::Orientation orientation )
: orientation( orientation )
{
textOptions.setElideMode( Qt::ElideMiddle );
}
void addOption( QskSegmentedBar* bar, const Option& option )
{
this->options += option;
bar->resetImplicitSize();
bar->update();
Q_EMIT bar->countChanged();
if ( this->options.count() == 1 )
bar->setSelectedIndex( 0 );
}
QVector< Option > options;
QskTextOptions textOptions;
int selectedIndex = -1;
int currentIndex = -1;
Qt::Orientation orientation;
bool isPressed = false;
};
QskSegmentedBar::QskSegmentedBar( QQuickItem* parent )
: QskSegmentedBar( Qt::Horizontal, parent )
{
}
QskSegmentedBar::QskSegmentedBar( Qt::Orientation orientation, QQuickItem* parent )
: Inherited( parent )
, m_data( new PrivateData( orientation ) )
{
if( orientation == Qt::Horizontal )
initSizePolicy( QskSizePolicy::Preferred, QskSizePolicy::Fixed );
else
initSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Preferred );
setAcceptedMouseButtons( Qt::LeftButton );
setWheelEnabled( true );
setFocusPolicy( Qt::StrongFocus );
connect( this, &QskSegmentedBar::currentIndexChanged,
this, &QskControl::focusIndicatorRectChanged );
}
QskSegmentedBar::~QskSegmentedBar()
{
}
void QskSegmentedBar::setOrientation( Qt::Orientation orientation )
{
if( orientation != m_data->orientation )
{
setSizePolicy( sizePolicy( Qt::Vertical ), sizePolicy( Qt::Horizontal ) );
m_data->orientation = orientation;
resetImplicitSize();
update();
}
}
Qt::Orientation QskSegmentedBar::orientation() const
{
return m_data->orientation;
}
void QskSegmentedBar::setTextOptions( const QskTextOptions& textOptions )
{
if( textOptions != m_data->textOptions )
{
m_data->textOptions = textOptions;
update();
}
}
QskTextOptions QskSegmentedBar::textOptions() const
{
return m_data->textOptions;
}
int QskSegmentedBar::addText( const QString& text )
{
m_data->addOption( this, Option( QUrl(), text ) );
return count() - 1;
}
int QskSegmentedBar::addGraphic( const QUrl& graphicSource )
{
m_data->addOption( this, Option( graphicSource, QString() ) );
return count() - 1;
}
QVariant QskSegmentedBar::optionAt( int index ) const
{
const auto& options = m_data->options;
if( index < 0 || index >= options.count() )
return QVariantList();
const auto& option = options[ index ];
QVariant value;
if ( option.graphicSource.isValid() )
value = QVariant::fromValue( option.graphic );
else
value = QVariant::fromValue( option.text );
return value;
}
QskAspect::Placement QskSegmentedBar::effectivePlacement() const
{
return static_cast< QskAspect::Placement >( m_data->orientation );
}
void QskSegmentedBar::mousePressEvent( QMouseEvent* event )
{
const int index = indexAtPosition( event->localPos() );
if( index < 0 || index >= count() || !m_data->options[ index ].isEnabled )
return;
m_data->isPressed = true;
if( ( focusPolicy() & Qt::ClickFocus ) == Qt::ClickFocus )
{
if( !QGuiApplication::styleHints()->setFocusOnTouchRelease() )
{
if( index != m_data->currentIndex )
setCurrentIndex( index );
}
}
}
void QskSegmentedBar::mouseReleaseEvent( QMouseEvent* event )
{
int index = -1;
if( m_data->isPressed )
{
m_data->isPressed = false;
index = indexAtPosition( event->localPos() );
}
if( index < 0 || !m_data->options[ index ].isEnabled )
return;
if( ( focusPolicy() & Qt::ClickFocus ) == Qt::ClickFocus )
{
if( QGuiApplication::styleHints()->setFocusOnTouchRelease() )
{
if( index != m_data->currentIndex )
setCurrentIndex( index );
}
}
setSelectedIndex( index );
}
void QskSegmentedBar::keyPressEvent( QKeyEvent* event )
{
switch( event->key() )
{
case Qt::Key_Up:
case Qt::Key_Down:
case Qt::Key_Left:
case Qt::Key_Right:
{
bool forwards;
if ( m_data->orientation == Qt::Vertical )
forwards = ( event->key() == Qt::Key_Down );
else
forwards = ( event->key() == Qt::Key_Right );
const int index = nextIndex( m_data->selectedIndex, forwards );
if ( index != m_data->selectedIndex )
{
if ( index >= 0 && index < count() )
setSelectedIndex( index );
}
return;
}
case Qt::Key_Select:
case Qt::Key_Space:
// stop further processing
return;
default:
{
const int steps = qskFocusChainIncrement( event );
if( steps != 0 )
{
const int index = nextIndex( m_data->currentIndex, steps > 0 );
if( index != m_data->currentIndex )
setCurrentIndex( index );
if( index >= 0 )
return;
}
}
}
Inherited::keyPressEvent( event );
}
void QskSegmentedBar::keyReleaseEvent( QKeyEvent* event )
{
if( event->key() == Qt::Key_Select || event->key() == Qt::Key_Space )
{
if( m_data->currentIndex >= 0 )
setSelectedIndex( m_data->currentIndex );
return;
}
Inherited::keyReleaseEvent( event );
}
void QskSegmentedBar::focusInEvent( QFocusEvent* event )
{
int index = m_data->currentIndex;
switch( event->reason() )
{
case Qt::TabFocusReason:
{
index = nextIndex( -1, true );
break;
}
case Qt::BacktabFocusReason:
{
index = nextIndex( -1, false );
break;
}
default:
{
if( index < 0 || index >= count() )
index = nextIndex( -1, true );
}
}
if( index != m_data->currentIndex )
setCurrentIndex( index );
Inherited::focusInEvent( event );
}
void QskSegmentedBar::clear()
{
if( count() == 0 )
return;
m_data->options.clear();
Q_EMIT countChanged();
if( m_data->selectedIndex >= 0 )
{
m_data->selectedIndex = -1;
Q_EMIT selectedIndexChanged( m_data->selectedIndex );
}
if( m_data->currentIndex >= 0 )
{
m_data->currentIndex = -1;
Q_EMIT currentIndexChanged( m_data->currentIndex );
}
update();
}
void QskSegmentedBar::setCurrentIndex( int index )
{
const auto& options = m_data->options;
if( ( index < 0 ) || ( index >= options.count() )
|| !options[ index ].isEnabled )
{
index = -1;
}
if( index != m_data->currentIndex )
{
m_data->currentIndex = index;
Q_EMIT currentIndexChanged( index );
}
}
int QskSegmentedBar::currentIndex() const
{
return m_data->currentIndex;
}
void QskSegmentedBar::setSelectedIndex( int index )
{
if( index < 0 || index >= m_data->options.count() )
{
index = -1;
}
else if ( !m_data->options[ index ].isEnabled )
{
index = -1; // ???
}
if( index != m_data->selectedIndex )
{
m_data->selectedIndex = index;
movePositionHint( Cursor, index );
update();
Q_EMIT selectedIndexChanged( index );
}
}
int QskSegmentedBar::selectedIndex() const
{
return m_data->selectedIndex;
}
int QskSegmentedBar::nextIndex( int index, bool forwards ) const
{
const auto& options = m_data->options;
const int count = options.count();
if( forwards )
{
if( index < 0 || index >= count )
index = -1;
while( ++index < count )
{
if( options[ index ].isEnabled )
return index;
}
}
else
{
if( index < 0 || index >= count )
index = count;
while( --index >= 0 )
{
if( options[ index ].isEnabled )
return index;
}
}
return -1;
}
int QskSegmentedBar::count() const
{
return m_data->options.count();
}
void QskSegmentedBar::setSegmentEnabled( int index, bool enabled )
{
auto& options = m_data->options;
if( ( index < 0 ) || ( index >= options.count() )
|| ( options[ index ].isEnabled == enabled ) )
{
return;
}
options[ index ].isEnabled = enabled;
if( !enabled )
{
if( m_data->currentIndex == index )
setCurrentIndex( -1 );
}
update();
}
bool QskSegmentedBar::isSegmentEnabled( int index ) const
{
const auto& options = m_data->options;
if( index < 0 || index >= options.count() )
return false;
return options[ index ].isEnabled;
}
int QskSegmentedBar::indexAtPosition( const QPointF& pos ) const
{
return effectiveSkinlet()->sampleIndexAt( this,
contentsRect(), QskSegmentedBar::Segment, pos );
}
QRectF QskSegmentedBar::focusIndicatorRect() const
{
if( m_data->currentIndex >= 0 )
{
return effectiveSkinlet()->sampleRect( this,
contentsRect(), QskSegmentedBar::Segment, m_data->currentIndex );
}
return Inherited::focusIndicatorRect();
}
#include "moc_QskSegmentedBar.cpp"

View File

@ -0,0 +1,95 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#ifndef QSK_SEGMENTED_BAR_H
#define QSK_SEGMENTED_BAR_H
#include "QskControl.h"
#include <qurl.h>
#include <qstring.h>
class QskTextOptions;
class QskGraphic;
class QSK_EXPORT QskSegmentedBar : public QskControl
{
Q_OBJECT
Q_PROPERTY( Qt::Orientation orientation READ orientation
WRITE setOrientation NOTIFY orientationChanged )
Q_PROPERTY( int selectedIndex READ selectedIndex
WRITE setSelectedIndex NOTIFY selectedIndexChanged USER true )
Q_PROPERTY( int currentIndex READ currentIndex
WRITE setCurrentIndex NOTIFY currentIndexChanged )
Q_PROPERTY( int count READ count NOTIFY countChanged )
using Inherited = QskControl;
public:
QSK_SUBCONTROLS( Panel, Segment, Cursor, Text, Graphic )
QSK_STATES( Selected )
QskSegmentedBar( QQuickItem* parent = nullptr );
QskSegmentedBar( Qt::Orientation, QQuickItem* parent = nullptr );
~QskSegmentedBar() override;
void setOrientation( Qt::Orientation );
Qt::Orientation orientation() const;
void setTextOptions( const QskTextOptions& );
QskTextOptions textOptions() const;
int addText( const QString& );
int addGraphic( const QUrl& );
void clear();
int selectedIndex() const;
int currentIndex() const;
int count() const;
QVariant optionAt( int ) const;
void setSegmentEnabled( int, bool );
bool isSegmentEnabled( int ) const;
int indexAtPosition( const QPointF& ) const;
QRectF focusIndicatorRect() const override final;
QskAspect::Placement effectivePlacement() const override;
public Q_SLOTS:
void setSelectedIndex( int index );
void setCurrentIndex( int index );
Q_SIGNALS:
void selectedIndexChanged( int );
void currentIndexChanged( int );
void countChanged();
void orientationChanged();
protected:
void mouseReleaseEvent( QMouseEvent* ) override;
void mousePressEvent( QMouseEvent* ) override;
void keyPressEvent( QKeyEvent* ) override;
void keyReleaseEvent( QKeyEvent* ) override;
void focusInEvent( QFocusEvent* ) override;
private:
int nextIndex( int index, bool forward ) const;
class PrivateData;
std::unique_ptr< PrivateData > m_data;
};
#endif

View File

@ -0,0 +1,322 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskSegmentedBarSkinlet.h"
#include "QskSegmentedBar.h"
#include "QskGraphicNode.h"
#include "QskGraphic.h"
#include "QskColorFilter.h"
#include "QskTextNode.h"
#include "QskTextOptions.h"
#include "QskSGNode.h"
#include "QskFunctions.h"
#include <qfontmetrics.h>
#include <qmath.h>
QskSegmentedBarSkinlet::QskSegmentedBarSkinlet( QskSkin* skin )
: Inherited( skin )
{
setNodeRoles( { PanelRole, SegmentRole, CursorRole, TextRole, GraphicRole } );
}
QskSegmentedBarSkinlet::~QskSegmentedBarSkinlet() = default;
QRectF QskSegmentedBarSkinlet::subControlRect(
const QskSkinnable* skinnable, const QRectF& contentsRect,
QskAspect::Subcontrol subControl ) const
{
using Q = QskSegmentedBar;
const auto bar = static_cast< const QskSegmentedBar* >( skinnable );
if( subControl == Q::Panel )
return contentsRect;
if( subControl == Q::Cursor )
return cursorRect( bar, contentsRect );
return Inherited::subControlRect( skinnable, contentsRect, subControl );
}
QRectF QskSegmentedBarSkinlet::cursorRect(
const QskSegmentedBar* bar, const QRectF& contentsRect ) const
{
using Q = QskSegmentedBar;
if( bar->selectedIndex() < 0 || bar->count() <= 0 )
return QRectF();
auto rect = subControlRect( bar, contentsRect, Q::Panel );
rect = bar->innerBox( Q::Panel, rect );
if( rect.isEmpty() )
return QRectF();
// position is related to the index: 2.5 means
// the cursor is between segment[2] and segment[3]
const qreal position = bar->positionHint( Q::Cursor );
const int index1 = qFloor( position );
const int index2 = qCeil( position );
auto cursorRect = segmentRect( bar, contentsRect, index1 );
if ( index1 != index2 )
{
const auto targetRect = segmentRect( bar, contentsRect, index2 );
cursorRect = qskInterpolatedRect( cursorRect, targetRect, position - index1 );
}
return cursorRect;
}
QRectF QskSegmentedBarSkinlet::segmentRect(
const QskSegmentedBar* bar, const QRectF& contentsRect, int index ) const
{
using Q = QskSegmentedBar;
const auto spacing = bar->spacingHint( Q::Panel );
const auto count = bar->count();
auto rect = subControlRect( bar, contentsRect, Q::Panel );
rect = bar->innerBox( Q::Panel, rect );
if( bar->orientation() == Qt::Horizontal )
{
const qreal w = ( rect.width() - ( count - 1 ) * spacing ) / count;
rect.setLeft( index * ( w + spacing ) );
rect.setWidth( w );
}
else
{
const qreal h = ( rect.height() - ( count - 1 ) * spacing ) / count;
rect.setTop( index * ( h + spacing ) );
rect.setHeight( h );
}
return rect;
}
QSGNode* QskSegmentedBarSkinlet::updateSubNode(
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
{
using Q = QskSegmentedBar;
switch( nodeRole )
{
case PanelRole:
return updateBoxNode( skinnable, node, Q::Panel );
case CursorRole:
return updateBoxNode( skinnable, node, Q::Cursor );
case SegmentRole:
return updateSeriesNode( skinnable, Q::Segment, node );
case TextRole:
return updateSeriesNode( skinnable, Q::Text, node );
case GraphicRole:
return updateSeriesNode( skinnable, Q::Graphic, node );
}
return nullptr;
}
QSizeF QskSegmentedBarSkinlet::segmentSizeHint( const QskSegmentedBar* bar ) const
{
qreal widthMax = 0;
qreal graphicRatioMax = 0;
const QFontMetricsF fm( bar->effectiveFont( QskSegmentedBar::Text ) );
for ( int i = 0; i < bar->count(); i++ )
{
const auto value = bar->optionAt( i );
if ( value.canConvert< QskGraphic >() )
{
const auto graphic = value.value< QskGraphic >();
if ( !graphic.isNull() )
{
const auto sz = graphic.defaultSize();
if( sz.isValid() )
{
const qreal ratio = sz.width() / sz.height();
if( graphicRatioMax < ratio )
graphicRatioMax = ratio;
}
}
}
else if ( value.canConvert< QString >() )
{
const auto text = value.value< QString >();
if ( !text.isEmpty() )
{
const auto sz = fm.size( Qt::TextShowMnemonic, text );
if( sz.width() > widthMax )
widthMax = sz.width();
}
}
}
if( graphicRatioMax > 0 )
{
const qreal w = fm.height() * graphicRatioMax;
if( w > widthMax )
widthMax = w;
}
return bar->outerBoxSize( QskSegmentedBar::Segment, QSizeF( widthMax, fm.height() ) );
}
QSizeF QskSegmentedBarSkinlet::sizeHint( const QskSkinnable* skinnable,
Qt::SizeHint which, const QSizeF& ) const
{
using Q = QskSegmentedBar;
if ( which != Qt::PreferredSize )
return QSizeF();
const auto count = sampleCount( skinnable, Q::Segment );
if( count == 0 )
return QSizeF( 0, 0 );
qreal w = 0;
qreal h = 0;
if ( count > 0 )
{
const qreal spacing = skinnable->spacingHint( Q::Panel );
const auto bar = static_cast< const QskSegmentedBar* >( skinnable );
const auto segmentSize = segmentSizeHint( bar );
if( bar->orientation() == Qt::Horizontal )
{
w = count * segmentSize.width() + ( count - 1 ) * spacing;
h = segmentSize.height();
}
else
{
w = segmentSize.width();
h = count * segmentSize.height() + ( count - 1 ) * spacing;
}
}
const auto hint = skinnable->outerBoxSize( Q::Panel, QSizeF( w, h ) );
return hint.expandedTo( skinnable->strutSizeHint( Q::Panel ) );
}
int QskSegmentedBarSkinlet::sampleCount(
const QskSkinnable* skinnable, QskAspect::Subcontrol ) const
{
const auto bar = static_cast< const QskSegmentedBar* >( skinnable );
return bar->count();
}
QRectF QskSegmentedBarSkinlet::sampleRect( const QskSkinnable* skinnable,
const QRectF& contentsRect, QskAspect::Subcontrol subControl, int index ) const
{
using Q = QskSegmentedBar;
if ( subControl == Q::Segment )
{
const auto bar = static_cast< const QskSegmentedBar* >( skinnable );
return segmentRect( bar, contentsRect, index );
}
if ( subControl == Q::Text || subControl == Q::Graphic )
{
const auto rect = sampleRect( skinnable, contentsRect, Q::Segment, index );
return skinnable->innerBox( Q::Segment, rect );
}
return Inherited::sampleRect( skinnable, contentsRect, subControl, index );
}
QskAspect::States QskSegmentedBarSkinlet::sampleStates(
const QskSkinnable* skinnable, QskAspect::Subcontrol subControl, int index ) const
{
using Q = QskSegmentedBar;
auto states = Inherited::sampleStates( skinnable, subControl, index );
if ( subControl == Q::Segment || subControl == Q::Graphic || subControl == Q::Text )
{
const auto bar = static_cast< const QskSegmentedBar* >( skinnable );
if ( bar->isSegmentEnabled( index ) )
{
if ( bar->selectedIndex() == index )
states |= Q::Selected;
}
else
{
states |= Q::Disabled;
}
}
return states;
}
QSGNode* QskSegmentedBarSkinlet::updateSampleNode( const QskSkinnable* skinnable,
QskAspect::Subcontrol subControl, int index, QSGNode* node ) const
{
using Q = QskSegmentedBar;
auto bar = static_cast< const QskSegmentedBar* >( skinnable );
const auto rect = sampleRect( bar, bar->contentsRect(), subControl, index );
if ( subControl == Q::Segment )
{
return updateBoxNode( skinnable, node, rect, subControl );
}
const auto alignment = bar->alignmentHint( subControl, Qt::AlignCenter );
if ( subControl == Q::Text )
{
const auto value = bar->optionAt( index );
if ( value.canConvert< QString >() )
{
const auto text = value.value< QString >();
return QskSkinlet::updateTextNode( bar, node,
rect, alignment, text, bar->textOptions(), Q::Text );
}
return nullptr;
}
if ( subControl == Q::Graphic )
{
const auto value = bar->optionAt( index );
if ( value.canConvert< QskGraphic >() )
{
const auto graphic = value.value< QskGraphic >();
const auto filter = bar->effectiveGraphicFilter( subControl );
return QskSkinlet::updateGraphicNode(
bar, node, graphic, filter, rect, alignment );
}
return nullptr;
}
return Inherited::updateSampleNode( skinnable, subControl, index, node );
}
#include "moc_QskSegmentedBarSkinlet.cpp"

View File

@ -0,0 +1,63 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#ifndef QSK_SEGMENTED_BAR_SKINLET_H
#define QSK_SEGMENTED_BAR_SKINLET_H
#include "QskSkinlet.h"
class QskSegmentedBar;
class QSK_EXPORT QskSegmentedBarSkinlet : public QskSkinlet
{
Q_GADGET
using Inherited = QskSkinlet;
public:
enum NodeRole
{
PanelRole,
SegmentRole,
CursorRole,
TextRole,
GraphicRole,
RoleCount
};
Q_INVOKABLE QskSegmentedBarSkinlet( QskSkin* = nullptr );
~QskSegmentedBarSkinlet() override;
QRectF subControlRect( const QskSkinnable*, const QRectF&,
QskAspect::Subcontrol ) const override;
QSizeF sizeHint( const QskSkinnable*,
Qt::SizeHint, const QSizeF& ) const override;
int sampleCount( const QskSkinnable*, QskAspect::Subcontrol ) const override;
QRectF sampleRect( const QskSkinnable*,
const QRectF&, QskAspect::Subcontrol, int index ) const override;
QskAspect::States sampleStates( const QskSkinnable*,
QskAspect::Subcontrol, int index ) const override;
protected:
QSGNode* updateSubNode( const QskSkinnable*,
quint8 nodeRole, QSGNode* ) const override;
QSGNode* updateSampleNode( const QskSkinnable*,
QskAspect::Subcontrol, int index, QSGNode* ) const override;
private:
QSizeF segmentSizeHint( const QskSegmentedBar* ) const;
QRectF segmentRect( const QskSegmentedBar*, const QRectF&, int index ) const;
QRectF cursorRect( const QskSegmentedBar*, const QRectF& ) const;
};
#endif

View File

@ -44,18 +44,39 @@ QSK_QT_PRIVATE_END
#include "QskMenu.h"
#include "QskMenuSkinlet.h"
#include "QskPageIndicator.h"
#include "QskPageIndicatorSkinlet.h"
#include "QskPopup.h"
#include "QskPopupSkinlet.h"
#include "QskProgressBar.h"
#include "QskProgressBarSkinlet.h"
#include "QskPushButton.h"
#include "QskPushButtonSkinlet.h"
#include "QskScrollView.h"
#include "QskScrollViewSkinlet.h"
#include "QskSegmentedBar.h"
#include "QskSegmentedBarSkinlet.h"
#include "QskSeparator.h"
#include "QskSeparatorSkinlet.h"
#include "QskSlider.h"
#include "QskSliderSkinlet.h"
#include "QskSubWindow.h"
#include "QskSubWindowSkinlet.h"
#include "QskSubWindowArea.h"
#include "QskSubWindowAreaSkinlet.h"
#include "QskSwitchButton.h"
#include "QskSwitchButtonSkinlet.h"
#include "QskTabButton.h"
#include "QskTabButtonSkinlet.h"
@ -68,24 +89,6 @@ QSK_QT_PRIVATE_END
#include "QskTextInput.h"
#include "QskTextInputSkinlet.h"
#include "QskSeparator.h"
#include "QskSeparatorSkinlet.h"
#include "QskSubWindow.h"
#include "QskSubWindowSkinlet.h"
#include "QskSubWindowArea.h"
#include "QskSubWindowAreaSkinlet.h"
#include "QskSwitchButton.h"
#include "QskSwitchButtonSkinlet.h"
#include "QskPageIndicator.h"
#include "QskPageIndicatorSkinlet.h"
#include "QskProgressBar.h"
#include "QskProgressBarSkinlet.h"
#include "QskStatusIndicator.h"
#include "QskStatusIndicatorSkinlet.h"
@ -155,6 +158,7 @@ QskSkin::QskSkin( QObject* parent )
declareSkinlet< QskMenu, QskMenuSkinlet >();
declareSkinlet< QskPushButton, QskPushButtonSkinlet >();
declareSkinlet< QskScrollView, QskScrollViewSkinlet >();
declareSkinlet< QskSegmentedBar, QskSegmentedBarSkinlet >();
declareSkinlet< QskSeparator, QskSeparatorSkinlet >();
declareSkinlet< QskSlider, QskSliderSkinlet >();
declareSkinlet< QskStatusIndicator, QskStatusIndicatorSkinlet >();

View File

@ -179,6 +179,8 @@ HEADERS += \
controls/QskScrollBox.h \
controls/QskScrollView.h \
controls/QskScrollViewSkinlet.h \
controls/QskSegmentedBar.h \
controls/QskSegmentedBarSkinlet.h \
controls/QskSeparator.h \
controls/QskSeparatorSkinlet.h \
controls/QskSetup.h \
@ -261,6 +263,8 @@ SOURCES += \
controls/QskScrollBox.cpp \
controls/QskScrollView.cpp \
controls/QskScrollViewSkinlet.cpp \
controls/QskSegmentedBar.cpp \
controls/QskSegmentedBarSkinlet.cpp \
controls/QskSeparator.cpp \
controls/QskSeparatorSkinlet.cpp \
controls/QskSetup.cpp \