tabbars for all edges ( left, right, top, bottom )

This commit is contained in:
Uwe Rathmann 2019-04-17 16:33:17 +02:00
parent 53b4395db9
commit 9ba37738af
21 changed files with 286 additions and 162 deletions

View File

@ -363,7 +363,7 @@ class TabView : public QskTabView
{
public:
TabView( QQuickItem* parentItem = nullptr )
: QskTabView( Qt::Vertical, parentItem )
: QskTabView( parentItem )
{
setMargins( 10 );

View File

@ -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() );

View File

@ -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();

View File

@ -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 ) );

View File

@ -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();

View File

@ -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 } )

View File

@ -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 );
padding = padding.rotated();
}
else if ( placement == Bottom )
{
margins0 = QskMargins( -1, -2, -1, 2 );
margins1 = QskMargins( -1, -3, -1, 0 );
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, QskMargins( -1, 0, -1, -3 ) );
setMargins( aspect | Margin | state, margins1 );
setMargins( aspect | Padding, padding );
setTab( aspect, Qt::Vertical );
}
else
{
setMargins( aspect | Margin, QskMargins( 2, -1, -2, -1 ) );
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 );
}
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;

View File

@ -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;

View File

@ -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() )

View File

@ -8,8 +8,10 @@
#include "QskGlobal.h"
#include "QskFlags.h"
#include "QskNamespace.h"
#include <qmetaobject.h>
#include <qnamespace.h>
#include <functional>
/*
@ -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 )
{
}

View File

@ -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"

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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 )

View File

@ -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;
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 );

View File

@ -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;

View File

@ -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

View File

@ -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;
m_data->tabBar->setPosition( position );
polish();
update();
}
Q_EMIT orientationChanged();
}
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 );
}

View File

@ -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;

View File

@ -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() )
{
case Qsk::Top:
r.setTop( barRect.bottom() );
}
else
{
if ( tabView->layoutMirroring() )
r.setRight( r.right() - barRect.left() );
else
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;