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:
|
2019-04-17 16:33:17 +02:00
|
|
|
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 )
|
2019-04-17 16:33:17 +02:00
|
|
|
: QskTabView( Qsk::Top, parent )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-04-17 16:33:17 +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 );
|
|
|
|
|
2019-04-17 16:33:17 +02:00
|
|
|
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 )
|
|
|
|
{
|
2017-10-17 17:34:00 +02:00
|
|
|
// 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 );
|
2018-07-26 12:23:43 +02:00
|
|
|
|
|
|
|
connect( m_data->tabBar, &QskTabBar::currentIndexChanged,
|
|
|
|
this, &QskTabView::currentIndexChanged );
|
2019-04-17 16:33:17 +02:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-04-17 16:33:17 +02:00
|
|
|
void QskTabView::setTabPosition( Qsk::Position position )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
2019-04-17 16:33:17 +02:00
|
|
|
if ( position == tabPosition() )
|
|
|
|
return;
|
2017-07-21 18:21:34 +02:00
|
|
|
|
2019-04-17 16:33:17 +02:00
|
|
|
m_data->tabBar->setPosition( position );
|
2017-07-21 18:21:34 +02:00
|
|
|
|
2019-04-17 16:33:17 +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();
|
|
|
|
|
2018-05-01 13:55:26 +02:00
|
|
|
const QSizeF barHint = m_data->tabBar->sizeHint();
|
2019-04-17 16:33:17 +02:00
|
|
|
const QSizeF boxHint = m_data->stackBox->sizeHint();
|
2017-07-21 18:21:34 +02:00
|
|
|
|
2019-04-17 16:33:17 +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()
|
|
|
|
{
|
2019-06-23 12:53:38 +02:00
|
|
|
if ( maybeUnresized() )
|
|
|
|
return;
|
|
|
|
|
2017-08-28 10:15:47 +02:00
|
|
|
m_data->tabBar->setGeometry( subControlRect( TabBar ) );
|
2019-05-10 07:33:59 +02:00
|
|
|
|
|
|
|
#if 1
|
2017-08-28 10:15:47 +02:00
|
|
|
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"
|