qskinny/src/controls/QskTabView.cpp

259 lines
6.0 KiB
C++
Raw Normal View History

2017-07-21 18:21:34 +02:00
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskTabView.h"
2018-08-03 08:15:28 +02:00
#include "QskAnimationHint.h"
#include "QskAspect.h"
2017-07-21 18:21:34 +02:00
#include "QskStackBox.h"
#include "QskStackBoxAnimator.h"
2018-08-03 08:15:28 +02:00
#include "QskTabBar.h"
#include "QskTabButton.h"
2017-07-21 18:21:34 +02:00
2019-02-07 13:35:57 +01:00
#include <QPointer>
2017-07-21 18:21:34 +02:00
QSK_SUBCONTROL( QskTabView, TabBar )
QSK_SUBCONTROL( QskTabView, Page )
static inline Qt::Orientation qskTransposed( Qt::Orientation orientation )
{
return ( orientation == Qt::Vertical ) ? Qt::Horizontal : Qt::Vertical;
}
class QskTabView::PrivateData
{
2018-08-03 08:15:28 +02:00
public:
QskTabBar* tabBar = nullptr;
QskStackBox* stackBox = nullptr;
2017-07-21 18:21:34 +02:00
};
2018-08-03 08:15:28 +02:00
QskTabView::QskTabView( QQuickItem* parent )
: QskTabView( Qsk::Top, parent )
2017-07-21 18:21:34 +02:00
{
}
QskTabView::QskTabView( Qsk::Position tabPosition, QQuickItem* parent )
2018-08-03 08:15:28 +02:00
: Inherited( parent )
, m_data( new PrivateData() )
2017-07-21 18:21:34 +02:00
{
setPolishOnResize( true );
m_data->tabBar = new QskTabBar( tabPosition, this );
2017-07-21 18:21:34 +02:00
m_data->tabBar->setZ( 1 );
m_data->stackBox = new QskStackBox( this );
m_data->stackBox->setObjectName( QStringLiteral( "QskTabViewStackBox" ) );
m_data->stackBox->setZ( 0 );
#if 1
2019-05-10 07:33:59 +02:00
const auto hint = animation( Page );
2017-07-21 18:21:34 +02:00
if ( hint.duration > 0 )
{
// When changing the skin, we have to update the animator. TODO ...
2017-07-21 18:21:34 +02:00
auto animator = new QskStackBoxAnimator3( m_data->stackBox );
animator->setDuration( hint.duration );
animator->setEasingCurve( hint.type );
2018-08-03 08:15:28 +02:00
2017-07-21 18:21:34 +02:00
m_data->stackBox->setAnimator( animator );
}
#endif
connect( m_data->tabBar, &QskTabBar::currentIndexChanged,
m_data->stackBox, &QskStackBox::setCurrentIndex );
connect( m_data->tabBar, &QskTabBar::currentIndexChanged,
this, &QskTabView::currentIndexChanged );
connect( m_data->tabBar, &QskTabBar::positionChanged,
this, &QskTabView::tabPositionChanged );
2017-07-21 18:21:34 +02:00
}
QskTabView::~QskTabView()
{
}
const QskTabBar* QskTabView::tabBar() const
{
return m_data->tabBar;
}
void QskTabView::setTabPosition( Qsk::Position position )
2017-07-21 18:21:34 +02:00
{
if ( position == tabPosition() )
return;
2017-07-21 18:21:34 +02:00
m_data->tabBar->setPosition( position );
2017-07-21 18:21:34 +02:00
polish();
update();
}
Qsk::Position QskTabView::tabPosition() const
{
return m_data->tabBar->position();
2017-07-21 18:21:34 +02:00
}
Qt::Orientation QskTabView::orientation() const
{
return qskTransposed( m_data->tabBar->orientation() );
}
int QskTabView::addTab( QskTabButton* button, QQuickItem* item )
{
return insertTab( -1, button, item );
}
int QskTabView::insertTab( int index, QskTabButton* button, QQuickItem* item )
{
// multiple insertion ???
2019-02-07 13:35:57 +01:00
if ( item && item->parent() == nullptr )
item->setParent( this );
2017-07-21 18:21:34 +02:00
index = m_data->tabBar->insertTab( index, button );
m_data->stackBox->insertItem( index, item, Qt::Alignment() );
return index;
}
int QskTabView::addTab( const QString& tabText, QQuickItem* item )
{
return insertTab( -1, tabText, item );
}
int QskTabView::insertTab( int index, const QString& tabText, QQuickItem* item )
{
return insertTab( index, new QskTabButton( tabText ), item );
}
void QskTabView::removeTab( int index )
{
if ( index >= 0 && index < m_data->tabBar->count() )
{
2019-02-07 13:35:57 +01:00
QPointer< QQuickItem > tabItem = m_data->stackBox->itemAtIndex( index );
2019-02-13 10:27:23 +01:00
/*
We have to remove the item from the stackBox first. Removing
the tab then will result in a currentIndexChanged, where the stack
box will be resynced.
*/
2017-07-21 18:21:34 +02:00
m_data->stackBox->removeAt( index );
2019-02-13 10:27:23 +01:00
m_data->tabBar->removeTab( index );
2019-02-07 13:35:57 +01:00
if ( tabItem )
{
if ( tabItem->parent() == this )
delete tabItem;
else
tabItem->setParentItem( nullptr );
}
2017-07-21 18:21:34 +02:00
}
}
void QskTabView::clear()
{
m_data->tabBar->clear();
m_data->stackBox->clear();
}
QskTabButton* QskTabView::buttonAt( int index ) const
{
return m_data->tabBar->buttonAt( index );
}
QQuickItem* QskTabView::itemAt( int index ) const
{
return m_data->stackBox->itemAtIndex( index );
}
2019-03-15 15:38:52 +01:00
int QskTabView::itemIndex( const QQuickItem* item )
2017-07-21 18:21:34 +02:00
{
return m_data->stackBox->indexOf( item );
}
2019-03-15 15:38:52 +01:00
int QskTabView::buttonIndex( const QskTabButton* button )
2017-07-21 18:21:34 +02:00
{
return m_data->tabBar->indexOf( button );
}
QQuickItem* QskTabView::currentItem() const
{
return itemAt( currentIndex() );
}
QskTabButton* QskTabView::currentButton() const
{
return buttonAt( currentIndex() );
}
int QskTabView::currentIndex() const
{
return m_data->tabBar->currentIndex();
}
int QskTabView::count() const
{
return m_data->tabBar->count();
}
QSizeF QskTabView::contentsSizeHint() const
{
if ( m_data->tabBar == nullptr || m_data->tabBar->count() == 0 )
return Inherited::contentsSizeHint();
const QSizeF barHint = m_data->tabBar->sizeHint();
const QSizeF boxHint = m_data->stackBox->sizeHint();
2017-07-21 18:21:34 +02:00
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() );
}
2017-07-21 18:21:34 +02:00
return QSizeF( w, h );
}
void QskTabView::setCurrentIndex( int index )
{
m_data->tabBar->setCurrentIndex( index );
}
bool QskTabView::event( QEvent* event )
{
2018-08-03 08:15:28 +02:00
switch ( event->type() )
2017-07-21 18:21:34 +02:00
{
case QEvent::LayoutRequest:
{
resetImplicitSize();
polish();
break;
}
default:
break;
}
return Inherited::event( event );
}
void QskTabView::updateLayout()
{
m_data->tabBar->setGeometry( subControlRect( TabBar ) );
2019-05-10 07:33:59 +02:00
#if 1
m_data->stackBox->setGeometry( subControlRect( Page ) );
2019-05-10 07:33:59 +02:00
#else
m_data->stackBox->setGeometry( innerBox( Page, subControlRect( Page ) ) );
#endif
2017-07-21 18:21:34 +02:00
}
#include "moc_QskTabView.cpp"