diff --git a/examples/boxes/main.cpp b/examples/boxes/main.cpp index 51581691..1c5604fb 100644 --- a/examples/boxes/main.cpp +++ b/examples/boxes/main.cpp @@ -363,7 +363,7 @@ class TabView : public QskTabView { public: TabView( QQuickItem* parentItem = nullptr ) - : QskTabView( Qt::Vertical, parentItem ) + : QskTabView( parentItem ) { setMargins( 10 ); diff --git a/examples/layouts/main.cpp b/examples/layouts/main.cpp index 89de7662..dbcfb1f2 100644 --- a/examples/layouts/main.cpp +++ b/examples/layouts/main.cpp @@ -53,7 +53,7 @@ int main( int argc, char* argv[] ) auto tabView = new QskTabView(); tabView->setMargins( 10 ); - tabView->setOrientation( Qt::Horizontal ); + tabView->setTabPosition( Qsk::Left ); tabView->addTab( "Grid Layout", new DummyLabel( "Grid Layout - TODO ..." ) ); tabView->addTab( "Flow Layout", new FlowLayoutPage() ); tabView->addTab( "Linear Layout", new LinearLayoutPage() ); diff --git a/examples/qvgviewer/MainWindow.cpp b/examples/qvgviewer/MainWindow.cpp index c2be06f4..65164d7d 100644 --- a/examples/qvgviewer/MainWindow.cpp +++ b/examples/qvgviewer/MainWindow.cpp @@ -75,7 +75,7 @@ class GraphicLabel : public QskGraphicLabel MainWindow::MainWindow() { - m_tabView = new QskTabView( Qt::Horizontal ); + m_tabView = new QskTabView( Qsk::Left ); const QString resourceDir( ":/qvg" ); const QStringList icons = QDir( resourceDir ).entryList(); diff --git a/examples/sliders/main.cpp b/examples/sliders/main.cpp index 4de7e060..04e3d50e 100644 --- a/examples/sliders/main.cpp +++ b/examples/sliders/main.cpp @@ -27,10 +27,7 @@ class OtherSlider : public QskSlider { public: - /* - Slider overriding many hints from the skin. - "Preserved" is for horizontal, "Transposed" for vertical orientation - */ + // Slider overriding many hints from the skin. OtherSlider( QQuickItem* parentItem = nullptr ) : QskSlider( parentItem ) @@ -44,7 +41,7 @@ class OtherSlider : public QskSlider // Panel - for ( auto placement : { Preserved, Transposed } ) + for ( auto placement : { Horizontal, Vertical } ) { const Aspect aspect = Panel | placement; @@ -54,7 +51,7 @@ class OtherSlider : public QskSlider setBoxBorderColorsHint( aspect, Grey900 ); setGradientHint( aspect, Grey400 ); - if ( placement == Preserved ) + if ( placement == Horizontal ) setMarginsHint( aspect | Padding, QMarginsF( paddingW, 0, paddingW, 0 ) ); else setMarginsHint( aspect | Padding, QMarginsF( 0, paddingW, 0, paddingW ) ); @@ -62,7 +59,7 @@ class OtherSlider : public QskSlider // Groove - for ( auto placement : { Preserved, Transposed } ) + for ( auto placement : { Horizontal, Vertical } ) { const Aspect aspect = Groove | placement; @@ -74,7 +71,7 @@ class OtherSlider : public QskSlider } // no Fill - for ( auto placement : { Preserved, Transposed } ) + for ( auto placement : { Horizontal, Vertical } ) { const Aspect aspect = Fill | placement; setMetric( aspect | Size, 0 ); @@ -82,7 +79,7 @@ class OtherSlider : public QskSlider // Handle - for ( auto placement : { Preserved, Transposed } ) + for ( auto placement : { Horizontal, Vertical } ) { const Aspect aspect = Handle | placement; @@ -91,7 +88,7 @@ class OtherSlider : public QskSlider const qreal m = 0.5 * qCeil( 0.5 * ( w - h ) ) + 1; - if ( placement == Preserved ) + if ( placement == Horizontal ) setMarginsHint( aspect | Margin, QMarginsF( -m, 0, -m, 0 ) ); else setMarginsHint( aspect | Margin, QMarginsF( 0, -m, 0, -m ) ); diff --git a/examples/tabview/main.cpp b/examples/tabview/main.cpp index d9b528ea..4e16b865 100644 --- a/examples/tabview/main.cpp +++ b/examples/tabview/main.cpp @@ -53,12 +53,18 @@ class TabView : public QskTabView buttonAt( 2 )->setEnabled( false ); } - void flip() + void rotate() { - if ( orientation() == Qt::Vertical ) - setOrientation( Qt::Horizontal ); - else - setOrientation( Qt::Vertical ); + const Qsk::Position pos[] = { Qsk::Top, Qsk::Right, Qsk::Bottom, Qsk::Left }; + + for ( int i = 0; i < 4; i++ ) + { + if ( tabPosition() == pos[i] ) + { + setTabPosition( pos[ ( i + 1 ) % 4 ] ); + break; + } + } } }; @@ -75,15 +81,15 @@ int main( int argc, char* argv[] ) auto tabView = new TabView(); - auto flipButton = new QskPushButton( "Flip" ); - flipButton->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed ); - flipButton->setFocus( true ); - QObject::connect( flipButton, &QskPushButton::clicked, tabView, &TabView::flip ); + auto rotateButton = new QskPushButton( "Rotate" ); + rotateButton->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed ); + rotateButton->setFocus( true ); + QObject::connect( rotateButton, &QskPushButton::clicked, tabView, &TabView::rotate ); auto layoutBox = new QskLinearBox( Qt::Vertical ); layoutBox->setMargins( 5 ); layoutBox->setSpacing( 10 ); - layoutBox->addItem( flipButton, Qt::AlignLeft ); + layoutBox->addItem( rotateButton, Qt::AlignLeft ); layoutBox->addItem( tabView ); auto focusIndicator = new QskFocusIndicator(); diff --git a/skins/material/QskMaterialSkin.cpp b/skins/material/QskMaterialSkin.cpp index 2ac73b7f..fd6721dc 100644 --- a/skins/material/QskMaterialSkin.cpp +++ b/skins/material/QskMaterialSkin.cpp @@ -235,7 +235,7 @@ void QskMaterialSkin::initSeparatorHints() const ColorPalette& pal = m_data->palette; - for ( auto placement : { Preserved, Transposed } ) + for ( auto placement : { Horizontal, Vertical } ) { const Aspect aspect = Q::Panel | placement; @@ -419,8 +419,8 @@ void QskMaterialSkin::initSliderHints() setBoxBorderMetrics( Q::Panel, 0 ); setGradient( Q::Panel, QskGradient() ); - setMargins( Q::Panel | Preserved | Padding, QskMargins( 0.5 * dim, 0 ) ); - setMargins( Q::Panel | Transposed | Padding, QskMargins( 0, 0.5 * dim ) ); + setMargins( Q::Panel | Horizontal | Padding, QskMargins( 0.5 * dim, 0 ) ); + setMargins( Q::Panel | Vertical | Padding, QskMargins( 0, 0.5 * dim ) ); // Groove, Fill @@ -485,15 +485,37 @@ void QskMaterialSkin::initTabButtonHints() setMetric( Q::Panel | MinimumWidth, 30 ); setMetric( Q::Panel | MinimumHeight, 16 ); - for ( auto placement : { Preserved, Transposed } ) + for ( auto placement : { Left, Right, Top, Bottom } ) { const Aspect aspect = Q::Panel | placement; - const Qt::Edge edge = ( placement == Preserved ) ? Qt::BottomEdge : Qt::RightEdge; + + Qt::Edge edge; + + switch( placement ) + { + case Left: + edge = Qt::RightEdge; + break; + + case Right: + edge = Qt::LeftEdge; + break; + + case Top: + edge = Qt::BottomEdge; + break; + + case Bottom: + edge = Qt::TopEdge; + break; + + default: + break; + } setGradient( aspect, QskRgbValue::White ); - // The highlighted button has a accented bar at the bottom/right edge - + // The highlighted button has a accented bar at one edge setBoxShape( aspect, 0 ); QskBoxBorderMetrics border; @@ -501,7 +523,7 @@ void QskMaterialSkin::initTabButtonHints() setBoxBorderMetrics( aspect, border ); QskBoxBorderColors borderColors( QskRgbValue::White ); - setBoxBorderColors( placement, borderColors ); + setBoxBorderColors( aspect, borderColors ); borderColors.setColorsAt( edge, pal.accentColor ); for ( auto state : { Q::Checked, Q::Pressed, Q::Checkable | Q::Hovered } ) diff --git a/skins/squiek/QskSquiekSkin.cpp b/skins/squiek/QskSquiekSkin.cpp index 38ae90a6..03baf6db 100644 --- a/skins/squiek/QskSquiekSkin.cpp +++ b/skins/squiek/QskSquiekSkin.cpp @@ -128,14 +128,13 @@ QskSquiekSkin::~QskSquiekSkin() { } -void QskSquiekSkin::setSeparator( - QskAspect::Aspect aspect, Qt::Orientation orientation ) +void QskSquiekSkin::setSeparator( QskAspect::Aspect aspect ) { const ColorPalette& pal = m_data->palette; QskGradient gradient( QskGradient::Vertical, pal.lighter110, pal.darker125 ); - if ( orientation == Qt::Vertical ) + if ( aspect.placement() == QskAspect::Vertical ) gradient.setOrientation( QskGradient::Horizontal ); setGradient( aspect, gradient ); @@ -208,7 +207,7 @@ void QskSquiekSkin::setPanel( QskAspect::Aspect aspect, PanelStyle style ) setButton( aspect, style, 1 ); } -void QskSquiekSkin::setTab( QskAspect::Aspect aspect, Qt::Orientation orientation ) +void QskSquiekSkin::setTab( QskAspect::Aspect aspect ) { const ColorPalette& pal = m_data->palette; @@ -219,17 +218,29 @@ void QskSquiekSkin::setTab( QskAspect::Aspect aspect, Qt::Orientation orientatio QskBoxBorderMetrics border( 1 ); QskBoxShapeMetrics shape( 4 ); - if ( orientation == Qt::Horizontal ) + if ( aspect.placement() == QskAspect::Top ) + { + border.setWidthAt( Qt::BottomEdge, 0 ); + shape.setRadius( Qt::BottomLeftCorner, 0 ); + shape.setRadius( Qt::BottomRightCorner, 0 ); + } + else if ( aspect.placement() == QskAspect::Bottom ) + { + border.setWidthAt( Qt::TopEdge, 0 ); + shape.setRadius( Qt::TopLeftCorner, 0 ); + shape.setRadius( Qt::TopRightCorner, 0 ); + } + else if ( aspect.placement() == QskAspect::Left ) { border.setWidthAt( Qt::RightEdge, 0 ); shape.setRadius( Qt::TopRightCorner, 0 ); shape.setRadius( Qt::BottomRightCorner, 0 ); } - else + else if ( aspect.placement() == QskAspect::Right ) { - border.setWidthAt( Qt::BottomEdge, 0 ); + border.setWidthAt( Qt::LeftEdge, 0 ); + shape.setRadius( Qt::TopLeftCorner, 0 ); shape.setRadius( Qt::BottomLeftCorner, 0 ); - shape.setRadius( Qt::BottomRightCorner, 0 ); } setBoxBorderMetrics( aspect, border ); @@ -370,8 +381,8 @@ void QskSquiekSkin::initSeparatorHints() setMetric( Q::Panel | Size, 4 ); - setSeparator( Q::Panel, Qt::Horizontal ); - setSeparator( Q::Panel | Transposed, Qt::Vertical ); + setSeparator( Q::Panel | Horizontal ); + setSeparator( Q::Panel | Vertical ); } void QskSquiekSkin::initPageIndicatorHints() @@ -496,30 +507,44 @@ void QskSquiekSkin::initTabButtonHints() const QskMargins padding( 10, 4 ); - for ( auto placement : { Preserved, Transposed } ) + for ( auto placement : { Left, Right, Top, Bottom } ) { const Aspect aspect = Q::Panel | placement; - if ( placement == Preserved ) + QskMargins margins0, margins1, padding; + + if ( placement == Top ) { - setMargins( aspect | Margin, QskMargins( -1, 2, -1, -2 ) ); + margins0 = QskMargins( -1, 2, -1, -2 ); + margins1 = QskMargins( -1, 0, -1, -3 ); - for ( const auto state : { Q::Checked, Q::Checked | Q::Pressed } ) - setMargins( aspect | Margin | state, QskMargins( -1, 0, -1, -3 ) ); - - setMargins( aspect | Padding, padding ); - setTab( aspect, Qt::Vertical ); + padding = padding.rotated(); } - else + else if ( placement == Bottom ) { - setMargins( aspect | Margin, QskMargins( 2, -1, -2, -1 ) ); + margins0 = QskMargins( -1, -2, -1, 2 ); + margins1 = QskMargins( -1, -3, -1, 0 ); - for ( const auto state : { Q::Checked, Q::Checked | Q::Pressed } ) - setMargins( aspect | Margin | state, QskMargins( 0, -1, -3, 0 ) ); - - setMargins( aspect | Padding, padding.rotated() ); - setTab( aspect, Qt::Horizontal ); + padding = padding.rotated(); } + else if ( placement == Left ) + { + margins0 = QskMargins( 2, -1, -2, -1 ); + margins1 = QskMargins( 0, -1, -3, 0 ); + } + else if ( placement == Right ) + { + margins0 = QskMargins( -2, -1, 2, -1 ); + margins1 = QskMargins( -3, -1, 0, 0 ); + } + + setMargins( aspect | Margin, margins0 ); + + for ( const auto state : { Q::Checked, Q::Checked | Q::Pressed } ) + setMargins( aspect | Margin | state, margins1 ); + + setMargins( aspect | Padding, padding ); + setTab( aspect ); } setAnimation( Q::Panel | Color, qskDuration ); @@ -542,7 +567,7 @@ void QskSquiekSkin::initSliderHints() // Panel - for ( auto placement : { Preserved, Transposed } ) + for ( auto placement : { Horizontal, Vertical } ) { const auto aspect = Q::Panel | placement; @@ -552,12 +577,12 @@ void QskSquiekSkin::initSliderHints() setGradient( aspect, QskGradient() ); } - setMargins( Q::Panel | Preserved | Padding, QskMargins( 0.5 * dim, 0 ) ); - setMargins( Q::Panel | Transposed | Padding, QskMargins( 0, 0.5 * dim ) ); + setMargins( Q::Panel | Horizontal | Padding, QskMargins( 0.5 * dim, 0 ) ); + setMargins( Q::Panel | Vertical | Padding, QskMargins( 0, 0.5 * dim ) ); // Groove, Fill - for ( auto placement : { Preserved, Transposed } ) + for ( auto placement : { Horizontal, Vertical } ) { for ( auto subControl : { Q::Groove, Q::Fill } ) { @@ -578,7 +603,7 @@ void QskSquiekSkin::initSliderHints() // Handle - for ( auto placement : { Preserved, Transposed } ) + for ( auto placement : { Horizontal, Vertical } ) { Aspect aspect = Q::Handle | placement; diff --git a/skins/squiek/QskSquiekSkin.h b/skins/squiek/QskSquiekSkin.h index 72e870a9..483a0fd6 100644 --- a/skins/squiek/QskSquiekSkin.h +++ b/skins/squiek/QskSquiekSkin.h @@ -56,10 +56,10 @@ class QSK_SQUIEK_EXPORT QskSquiekSkin : public QskSkin Flat }; - void setSeparator( QskAspect::Aspect, Qt::Orientation ); + void setSeparator( QskAspect::Aspect ); void setButton( QskAspect::Aspect, PanelStyle, qreal border = 2.0 ); void setPanel( QskAspect::Aspect, PanelStyle ); - void setTab( QskAspect::Aspect, Qt::Orientation ); + void setTab( QskAspect::Aspect ); class PrivateData; std::unique_ptr< PrivateData > m_data; diff --git a/src/common/QskAspect.cpp b/src/common/QskAspect.cpp index 9c75ad25..202b93d8 100644 --- a/src/common/QskAspect.cpp +++ b/src/common/QskAspect.cpp @@ -305,7 +305,7 @@ void qskDebugAspect( QDebug debug, const QMetaObject* metaObject, QskAspect::Asp } } - if ( aspect.placement() != QskAspect::Preserved ) + if ( aspect.placement() != QskAspect::NoPlacement ) debug << ", " << qskEnumString( "Placement", aspect.placement() ); if ( aspect.state() ) diff --git a/src/common/QskAspect.h b/src/common/QskAspect.h index fb0bfea5..3fe7d096 100644 --- a/src/common/QskAspect.h +++ b/src/common/QskAspect.h @@ -8,8 +8,10 @@ #include "QskGlobal.h" #include "QskFlags.h" +#include "QskNamespace.h" #include +#include #include /* @@ -101,8 +103,15 @@ QSK_NAMESPACE( QskAspect ) enum Placement : quint8 { - Preserved = 0, - Transposed = 1 + NoPlacement = 0, + + Vertical = Qt::Vertical, + Horizontal = Qt::Horizontal, + + Top = 1, + Left = 2, + Right = 3, + Bottom = 4 }; QSK_ENUM( Placement ) @@ -199,8 +208,8 @@ namespace QskAspect uint isAnimator : 1; uint primitive : 7; - uint placement : 1; - uint reserved1 : 8; + uint placement : 3; + uint reserved1 : 6; uint states : 16; uint reserved2 : 16; @@ -214,17 +223,17 @@ namespace QskAspect }; inline constexpr Aspect::Aspect() - : Aspect( Control, Flag, Preserved ) + : Aspect( Control, Flag, NoPlacement ) { } inline constexpr Aspect::Aspect( Subcontrol subControl ) - : Aspect( subControl, Flag, Preserved ) + : Aspect( subControl, Flag, NoPlacement ) { } inline constexpr Aspect::Aspect( Type type ) - : Aspect( Control, type, Preserved ) + : Aspect( Control, type, NoPlacement ) { } diff --git a/src/controls/QskSeparator.cpp b/src/controls/QskSeparator.cpp index 25614f3d..8e1905f4 100644 --- a/src/controls/QskSeparator.cpp +++ b/src/controls/QskSeparator.cpp @@ -82,8 +82,7 @@ QSizeF QskSeparator::contentsSizeHint() const QskAspect::Placement QskSeparator::effectivePlacement() const { - using namespace QskAspect; - return ( m_orientation == Qt::Horizontal ) ? Preserved : Transposed; + return static_cast< QskAspect::Placement >( m_orientation ); } #include "moc_QskSeparator.cpp" diff --git a/src/controls/QskSkinHintTable.cpp b/src/controls/QskSkinHintTable.cpp index 8080e890..16384c6e 100644 --- a/src/controls/QskSkinHintTable.cpp +++ b/src/controls/QskSkinHintTable.cpp @@ -32,9 +32,9 @@ inline const QVariant* qskResolvedHint( QskAspect::Aspect aspect, if ( aspect.placement() ) { - // clear the placement bit and restart + // clear the placement bits and restart aspect = a; - aspect.setPlacement( static_cast< QskAspect::Placement >( 0 ) ); + aspect.setPlacement( QskAspect::NoPlacement ); continue; } diff --git a/src/controls/QskSkinnable.cpp b/src/controls/QskSkinnable.cpp index 8982537e..fa162579 100644 --- a/src/controls/QskSkinnable.cpp +++ b/src/controls/QskSkinnable.cpp @@ -77,15 +77,15 @@ static inline bool qskCompareResolvedStates( if ( s1 == 0 ) { - if ( aspect1.placement() == 0 ) + if ( aspect1.placement() == QskAspect::NoPlacement ) return true; - // clear the placement bit and restart with the initial state + // clear the placement bits and restart with the initial state aspect1 = a1; - aspect1.setPlacement( static_cast< QskAspect::Placement >( 0 ) ); + aspect1.setPlacement( QskAspect::NoPlacement ); aspect2 = a2; - aspect2.setPlacement( static_cast< QskAspect::Placement >( 0 ) ); + aspect2.setPlacement( QskAspect::NoPlacement ); } } else diff --git a/src/controls/QskSkinnable.h b/src/controls/QskSkinnable.h index 22db0f41..96496db3 100644 --- a/src/controls/QskSkinnable.h +++ b/src/controls/QskSkinnable.h @@ -185,7 +185,7 @@ inline T QskSkinnable::flagHint( QskAspect::Aspect aspect, T defaultValue ) cons inline QskAspect::Placement QskSkinnable::effectivePlacement() const { - return QskAspect::Preserved; + return QskAspect::NoPlacement; } #endif diff --git a/src/controls/QskSlider.cpp b/src/controls/QskSlider.cpp index 9fe8c474..7c3f79fb 100644 --- a/src/controls/QskSlider.cpp +++ b/src/controls/QskSlider.cpp @@ -91,8 +91,7 @@ Qt::Orientation QskSlider::orientation() const QskAspect::Placement QskSlider::effectivePlacement() const { - using namespace QskAspect; - return ( m_data->orientation == Qt::Horizontal ) ? Preserved : Transposed; + return static_cast< QskAspect::Placement >( m_data->orientation ); } void QskSlider::setTracking( bool on ) diff --git a/src/controls/QskTabBar.cpp b/src/controls/QskTabBar.cpp index 42a87b4f..6d30e8ea 100644 --- a/src/controls/QskTabBar.cpp +++ b/src/controls/QskTabBar.cpp @@ -11,6 +11,14 @@ QSK_SUBCONTROL( QskTabBar, Panel ) +static inline Qt::Orientation qskOrientation( int position ) +{ + if ( ( position == Qsk::Top ) || ( position == Qsk::Bottom ) ) + return Qt::Horizontal; + else + return Qt::Vertical; +} + namespace { class ButtonBox : public QskLinearBox @@ -47,9 +55,8 @@ namespace class QskTabBar::PrivateData { public: - PrivateData() - : currentIndex( -1 ) - , buttonBox( nullptr ) + PrivateData( Qsk::Position position ) + : position( position ) { } @@ -67,22 +74,26 @@ class QskTabBar::PrivateData } } - int currentIndex; + ButtonBox* buttonBox = nullptr; + int currentIndex = -1; + QskTextOptions textOptions; - ButtonBox* buttonBox; + uint position : 2; }; QskTabBar::QskTabBar( QQuickItem* parent ) - : QskTabBar( Qt::Horizontal, parent ) + : QskTabBar( Qsk::Top, parent ) { } -QskTabBar::QskTabBar( Qt::Orientation orientation, QQuickItem* parent ) +QskTabBar::QskTabBar( Qsk::Position position, QQuickItem* parent ) : Inherited( parent ) - , m_data( new PrivateData() ) + , m_data( new PrivateData( position ) ) { setAutoLayoutChildren( true ); + const auto orientation = qskOrientation( position ); + if ( orientation == Qt::Horizontal ) initSizePolicy( QskSizePolicy::Preferred, QskSizePolicy::Fixed ); else @@ -98,25 +109,36 @@ QskTabBar::~QskTabBar() { } -void QskTabBar::setOrientation( Qt::Orientation orientation ) +void QskTabBar::setPosition( Qsk::Position position ) { - if ( orientation == m_data->buttonBox->orientation() ) + if ( position == m_data->position ) return; - setSizePolicy( sizePolicy( Qt::Vertical ), sizePolicy( Qt::Horizontal ) ); - m_data->buttonBox->setOrientation( orientation ); + m_data->position = position; + + const auto orientation = qskOrientation( position ); + if ( orientation != m_data->buttonBox->orientation() ) + { + setSizePolicy( sizePolicy( Qt::Vertical ), sizePolicy( Qt::Horizontal ) ); + m_data->buttonBox->setOrientation( orientation ); + } resetImplicitSize(); for ( int i = 0; i < count(); i++ ) buttonAt( i )->update(); - Q_EMIT orientationChanged(); + Q_EMIT positionChanged( position ); +} + +Qsk::Position QskTabBar::position() const +{ + return static_cast< Qsk::Position >( m_data->position ); } Qt::Orientation QskTabBar::orientation() const { - return m_data->buttonBox->orientation(); + return qskOrientation( m_data->position ); } void QskTabBar::setTextOptions( const QskTextOptions& options ) @@ -127,7 +149,7 @@ void QskTabBar::setTextOptions( const QskTextOptions& options ) // QskControl - maybe added to the propagation system ??? m_data->textOptions = options; - Q_EMIT textOptionsChanged(); + Q_EMIT textOptionsChanged( options ); for ( int i = 0; i < count(); i++ ) buttonAt( i )->setTextOptions( options ); @@ -178,7 +200,7 @@ int QskTabBar::insertTab( int index, QskTabButton* button ) m_data->connectButton( button, this, true ); - Q_EMIT countChanged(); + Q_EMIT countChanged( count() ); return index; } @@ -193,13 +215,13 @@ void QskTabBar::removeTab( int index ) if ( index > m_data->currentIndex ) { - Q_EMIT countChanged(); + Q_EMIT countChanged( count() ); } else if ( index < m_data->currentIndex ) { m_data->currentIndex--; - Q_EMIT countChanged(); + Q_EMIT countChanged( count() ); Q_EMIT currentIndexChanged( m_data->currentIndex ); } else @@ -243,7 +265,7 @@ void QskTabBar::removeTab( int index ) m_data->currentIndex = nextIndex; - Q_EMIT countChanged(); + Q_EMIT countChanged( count() ); Q_EMIT currentIndexChanged( nextIndex ); } } @@ -256,7 +278,7 @@ void QskTabBar::clear() const int idx = currentIndex(); m_data->buttonBox->clear(); - Q_EMIT countChanged(); + Q_EMIT countChanged( count() ); if ( idx >= 0 ) Q_EMIT currentIndexChanged( -1 ); diff --git a/src/controls/QskTabBar.h b/src/controls/QskTabBar.h index a4fcccca..a690ff77 100644 --- a/src/controls/QskTabBar.h +++ b/src/controls/QskTabBar.h @@ -15,8 +15,10 @@ class QSK_EXPORT QskTabBar : public QskBox { Q_OBJECT - Q_PROPERTY( Qt::Orientation orientation READ orientation - WRITE setOrientation NOTIFY orientationChanged FINAL ) + Q_PROPERTY( Qsk::Position position READ position + WRITE setPosition NOTIFY positionChanged FINAL ) + + Q_PROPERTY( Qt::Orientation orientation READ orientation ) Q_PROPERTY( int count READ count NOTIFY countChanged FINAL ) @@ -32,11 +34,13 @@ class QSK_EXPORT QskTabBar : public QskBox QSK_SUBCONTROLS( Panel ) QskTabBar( QQuickItem* parent = nullptr ); - QskTabBar( Qt::Orientation, QQuickItem* parent = nullptr ); + QskTabBar( Qsk::Position, QQuickItem* parent = nullptr ); ~QskTabBar() override; - void setOrientation( Qt::Orientation ); + void setPosition( Qsk::Position ); + Qsk::Position position() const; + Qt::Orientation orientation() const; void setTextOptions( const QskTextOptions& ); @@ -77,9 +81,9 @@ class QSK_EXPORT QskTabBar : public QskBox Q_SIGNALS: void currentIndexChanged( int index ); - void countChanged(); - void textOptionsChanged(); - void orientationChanged(); + void countChanged( int ); + void textOptionsChanged( const QskTextOptions& ); + void positionChanged( Qsk::Position ); protected: void componentComplete() override; diff --git a/src/controls/QskTabButton.cpp b/src/controls/QskTabButton.cpp index 1b8d497d..64023ac3 100644 --- a/src/controls/QskTabButton.cpp +++ b/src/controls/QskTabButton.cpp @@ -101,15 +101,27 @@ QRectF QskTabButton::layoutRect() const QskAspect::Placement QskTabButton::effectivePlacement() const { - using namespace QskAspect; - if ( m_data->tabBar ) { - const auto o = m_data->tabBar->orientation(); - return ( o == Qt::Horizontal ) ? Preserved : Transposed; + const auto pos = m_data->tabBar->position(); + + switch ( pos ) + { + case Qsk::Left: + return QskAspect::Left; + + case Qsk::Right: + return QskAspect::Right; + + case Qsk::Top: + return QskAspect::Top; + + case Qsk::Bottom: + return QskAspect::Bottom; + } } - return Preserved; + return QskAspect::NoPlacement; } QskTabBar* QskTabButton::tabBar() const diff --git a/src/controls/QskTabView.cpp b/src/controls/QskTabView.cpp index 1106c716..9f33b901 100644 --- a/src/controls/QskTabView.cpp +++ b/src/controls/QskTabView.cpp @@ -24,28 +24,22 @@ static inline Qt::Orientation qskTransposed( Qt::Orientation orientation ) class QskTabView::PrivateData { public: - PrivateData() - : tabBar( nullptr ) - , stackBox( nullptr ) - { - } - - QskTabBar* tabBar; - QskStackBox* stackBox; + QskTabBar* tabBar = nullptr; + QskStackBox* stackBox = nullptr; }; QskTabView::QskTabView( QQuickItem* parent ) - : QskTabView( Qt::Vertical, parent ) + : QskTabView( Qsk::Top, parent ) { } -QskTabView::QskTabView( Qt::Orientation orientation, QQuickItem* parent ) +QskTabView::QskTabView( Qsk::Position tabPosition, QQuickItem* parent ) : Inherited( parent ) , m_data( new PrivateData() ) { setPolishOnResize( true ); - m_data->tabBar = new QskTabBar( qskTransposed( orientation ), this ); + m_data->tabBar = new QskTabBar( tabPosition, this ); m_data->tabBar->setZ( 1 ); m_data->stackBox = new QskStackBox( this ); @@ -71,6 +65,9 @@ QskTabView::QskTabView( Qt::Orientation orientation, QQuickItem* parent ) connect( m_data->tabBar, &QskTabBar::currentIndexChanged, this, &QskTabView::currentIndexChanged ); + + connect( m_data->tabBar, &QskTabBar::positionChanged, + this, &QskTabView::tabPositionChanged ); } QskTabView::~QskTabView() @@ -82,18 +79,20 @@ const QskTabBar* QskTabView::tabBar() const return m_data->tabBar; } -void QskTabView::setOrientation( Qt::Orientation orientation ) +void QskTabView::setTabPosition( Qsk::Position position ) { - const Qt::Orientation o = qskTransposed( orientation ); - if ( o != m_data->tabBar->orientation() ) - { - m_data->tabBar->setOrientation( o ); + if ( position == tabPosition() ) + return; - polish(); - update(); + m_data->tabBar->setPosition( position ); - Q_EMIT orientationChanged(); - } + polish(); + update(); +} + +Qsk::Position QskTabView::tabPosition() const +{ + return m_data->tabBar->position(); } Qt::Orientation QskTabView::orientation() const @@ -205,10 +204,20 @@ QSizeF QskTabView::contentsSizeHint() const return Inherited::contentsSizeHint(); const QSizeF barHint = m_data->tabBar->sizeHint(); - const QSizeF itemHint = m_data->stackBox->sizeHint(); + const QSizeF boxHint = m_data->stackBox->sizeHint(); - const qreal w = qMax( barHint.width(), itemHint.width() ); - const qreal h = barHint.height() + itemHint.height(); + qreal w, h; + + if ( orientation() == Qt::Vertical ) + { + w = qMax( barHint.width(), boxHint.width() ); + h = barHint.height() + boxHint.height(); + } + else + { + w = barHint.width() + boxHint.width(); + h = qMax( barHint.height(), boxHint.height() ); + } return QSizeF( w, h ); } diff --git a/src/controls/QskTabView.h b/src/controls/QskTabView.h index 75d42c25..9a7b0d34 100644 --- a/src/controls/QskTabView.h +++ b/src/controls/QskTabView.h @@ -7,6 +7,7 @@ #define QSK_TAB_VIEW_H #include "QskControl.h" +#include "QskNamespace.h" class QskTabBar; class QskTabButton; @@ -15,8 +16,10 @@ class QSK_EXPORT QskTabView : public QskControl { Q_OBJECT - Q_PROPERTY( Qt::Orientation orientation READ orientation - WRITE setOrientation NOTIFY orientationChanged ) + Q_PROPERTY( Qsk::Position tabPosition READ tabPosition + WRITE setTabPosition NOTIFY tabPositionChanged FINAL ) + + Q_PROPERTY( Qt::Orientation orientation READ orientation ) Q_PROPERTY( int count READ count NOTIFY countChanged FINAL ) @@ -29,13 +32,15 @@ class QSK_EXPORT QskTabView : public QskControl QSK_SUBCONTROLS( TabBar, Page ) QskTabView( QQuickItem* parent = nullptr ); - QskTabView( Qt::Orientation, QQuickItem* parent = nullptr ); + QskTabView( Qsk::Position tabPosition, QQuickItem* parent = nullptr ); ~QskTabView() override; const QskTabBar* tabBar() const; - void setOrientation( Qt::Orientation ); + void setTabPosition( Qsk::Position ); + Qsk::Position tabPosition() const; + Qt::Orientation orientation() const; int addTab( QskTabButton*, QQuickItem* ); @@ -68,8 +73,8 @@ class QSK_EXPORT QskTabView : public QskControl Q_SIGNALS: void currentIndexChanged( int index ); - void countChanged(); - void orientationChanged(); + void countChanged( int ); + void tabPositionChanged( Qsk::Position ); protected: bool event( QEvent* event ) override; diff --git a/src/controls/QskTabViewSkinlet.cpp b/src/controls/QskTabViewSkinlet.cpp index 2211179b..971ea394 100644 --- a/src/controls/QskTabViewSkinlet.cpp +++ b/src/controls/QskTabViewSkinlet.cpp @@ -52,18 +52,25 @@ QRectF QskTabViewSkinlet::pageRect( const QskTabView* tabView ) const { const QRectF barRect = subControlRect( tabView, QskTabView::TabBar ); - QRectF r = tabView->contentsRect(); + QRectF r = tabView->layoutRect(); - if ( tabView->orientation() == Qt::Vertical ) + switch( tabView->tabPosition() ) { - r.setTop( barRect.bottom() ); - } - else - { - if ( tabView->layoutMirroring() ) - r.setRight( r.right() - barRect.left() ); - else + case Qsk::Top: + r.setTop( barRect.bottom() ); + break; + + case Qsk::Bottom: + r.setBottom( barRect.top() ); + break; + + case Qsk::Left: r.setLeft( barRect.right() ); + break; + + case Qsk::Right: + r.setRight( barRect.left() ); + break; } return r; @@ -71,19 +78,27 @@ QRectF QskTabViewSkinlet::pageRect( const QskTabView* tabView ) const QRectF QskTabViewSkinlet::tabBarRect( const QskTabView* tabView ) const { - QRectF r = tabView->layoutRect(); const QSizeF hint = tabView->tabBar()->sizeHint(); - if ( tabView->orientation() == Qt::Vertical ) - { - r.setHeight( hint.height() ); - } - else - { - r.setWidth( hint.width() ); + QRectF r = tabView->layoutRect(); - if ( tabView->layoutMirroring() ) - r.moveLeft( r.right() - r.width() ); + switch( tabView->tabPosition() ) + { + case Qsk::Top: + r.setBottom( hint.height() ); + break; + + case Qsk::Bottom: + r.setTop( r.bottom() - hint.height() ); + break; + + case Qsk::Left: + r.setRight( hint.width() ); + break; + + case Qsk::Right: + r.setLeft( r.right() - hint.width() ); + break; } return r;