2017-07-21 16:21:34 +00:00
|
|
|
/******************************************************************************
|
|
|
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
|
|
|
* This file may be used under the terms of the QSkinny License, Version 1.0
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#include "QskStackBoxAnimator.h"
|
|
|
|
#include "QskLayoutEngine.h"
|
2018-08-03 06:15:28 +00:00
|
|
|
#include "QskLayoutItem.h"
|
2017-07-21 16:21:34 +00:00
|
|
|
#include "QskStackBox.h"
|
|
|
|
|
|
|
|
static Qsk::Direction qskDirection(
|
|
|
|
Qt::Orientation orientation, int from, int to, int itemCount )
|
|
|
|
{
|
|
|
|
Qsk::Direction direction;
|
|
|
|
|
2018-08-03 06:15:28 +00:00
|
|
|
if ( orientation == Qt::Horizontal )
|
2017-07-21 16:21:34 +00:00
|
|
|
{
|
|
|
|
direction = Qsk::RightToLeft;
|
|
|
|
|
|
|
|
if ( to > from )
|
|
|
|
{
|
|
|
|
const bool isWrapping = ( from == 0 ) && ( to == itemCount - 1 );
|
|
|
|
|
|
|
|
if ( !isWrapping )
|
|
|
|
direction = Qsk::LeftToRight;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const bool isWrapping = ( to == 0 ) && ( from == itemCount - 1 );
|
|
|
|
|
|
|
|
if ( isWrapping )
|
|
|
|
direction = Qsk::LeftToRight;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
direction = Qsk::BottomToTop;
|
|
|
|
|
|
|
|
if ( to > from )
|
|
|
|
{
|
|
|
|
const bool isWrapping = ( from == 0 ) && ( to == itemCount - 1 );
|
|
|
|
|
|
|
|
if ( !isWrapping )
|
|
|
|
direction = Qsk::TopToBottom;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const bool isWrapping = ( to == 0 ) && ( from == itemCount - 1 );
|
|
|
|
|
|
|
|
if ( isWrapping )
|
|
|
|
direction = Qsk::TopToBottom;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return direction;
|
|
|
|
}
|
|
|
|
|
2018-08-03 06:15:28 +00:00
|
|
|
QskStackBoxAnimator::QskStackBoxAnimator( QskStackBox* parent )
|
|
|
|
: QObject( parent )
|
|
|
|
, m_startIndex( -1 )
|
|
|
|
, m_endIndex( -1 )
|
2017-07-21 16:21:34 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
QskStackBoxAnimator::~QskStackBoxAnimator()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskStackBoxAnimator::setStartIndex( int index )
|
|
|
|
{
|
|
|
|
m_startIndex = index;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskStackBoxAnimator::setEndIndex( int index )
|
|
|
|
{
|
|
|
|
m_endIndex = index;
|
|
|
|
}
|
|
|
|
|
|
|
|
int QskStackBoxAnimator::startIndex() const
|
|
|
|
{
|
|
|
|
return m_startIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
int QskStackBoxAnimator::endIndex() const
|
|
|
|
{
|
|
|
|
return m_endIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
QskStackBox* QskStackBoxAnimator::stackBox() const
|
|
|
|
{
|
|
|
|
return static_cast< QskStackBox* >( parent() );
|
|
|
|
}
|
|
|
|
|
|
|
|
QskLayoutItem* QskStackBoxAnimator::layoutItemAt( int index ) const
|
|
|
|
{
|
|
|
|
return stackBox()->engine().layoutItemAt(
|
|
|
|
( index == 0 ) ? m_startIndex : m_endIndex );
|
|
|
|
}
|
|
|
|
|
2018-08-03 06:15:28 +00:00
|
|
|
QskStackBoxAnimator1::QskStackBoxAnimator1( QskStackBox* parent )
|
|
|
|
: QskStackBoxAnimator( parent )
|
|
|
|
, m_orientation( Qt::Horizontal )
|
2019-05-16 06:14:32 +00:00
|
|
|
, m_hasClip( false )
|
2017-07-21 16:21:34 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
QskStackBoxAnimator1::~QskStackBoxAnimator1()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskStackBoxAnimator1::setOrientation( Qt::Orientation orientation )
|
|
|
|
{
|
|
|
|
if ( m_orientation != orientation )
|
|
|
|
{
|
|
|
|
#if 1
|
|
|
|
stop();
|
|
|
|
#endif
|
|
|
|
m_orientation = orientation;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Qt::Orientation QskStackBoxAnimator1::orientation() const
|
|
|
|
{
|
|
|
|
return m_orientation;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskStackBoxAnimator1::setup()
|
|
|
|
{
|
|
|
|
auto stackBox = this->stackBox();
|
|
|
|
|
|
|
|
m_direction = qskDirection( m_orientation,
|
|
|
|
startIndex(), endIndex(), stackBox->itemCount() );
|
|
|
|
|
|
|
|
for ( int i = 0; i < 2; i++ )
|
|
|
|
{
|
|
|
|
QskLayoutItem* layoutItem = layoutItemAt( i );
|
|
|
|
if ( layoutItem )
|
|
|
|
{
|
|
|
|
QQuickItem* item = layoutItem->item();
|
|
|
|
const Qt::Orientation orientation = this->orientation();
|
|
|
|
|
2018-08-03 06:15:28 +00:00
|
|
|
m_itemOffset[ i ] =
|
|
|
|
( orientation == Qt::Horizontal ) ? item->x() : item->y();
|
2017-07-21 16:21:34 +00:00
|
|
|
|
|
|
|
if ( i == 1 )
|
|
|
|
{
|
|
|
|
// now move the new item outside of
|
2017-07-30 12:30:50 +00:00
|
|
|
// the visible area and then "show" it
|
2017-07-21 16:21:34 +00:00
|
|
|
|
|
|
|
if ( orientation == Qt::Horizontal )
|
|
|
|
item->setX( stackBox->width() );
|
|
|
|
else
|
|
|
|
item->setY( stackBox->height() );
|
|
|
|
|
|
|
|
item->setVisible( true );
|
|
|
|
}
|
|
|
|
|
|
|
|
// we don't want the engine() to interfere, when
|
|
|
|
// controlling the item by the animation
|
|
|
|
|
|
|
|
layoutItem->setUpdateMode( QskLayoutItem::UpdateNone );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_hasClip = stackBox->clip();
|
|
|
|
if ( !m_hasClip )
|
|
|
|
stackBox->setClip( true );
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskStackBoxAnimator1::advance( qreal value )
|
|
|
|
{
|
|
|
|
auto stackBox = this->stackBox();
|
|
|
|
|
|
|
|
for ( int i = 0; i < 2; i++ )
|
|
|
|
{
|
|
|
|
QskLayoutItem* layoutItem = layoutItemAt( i );
|
|
|
|
if ( layoutItem == nullptr )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if ( layoutItem->isGeometryDirty() )
|
|
|
|
{
|
|
|
|
// the layout tried to replace the item, but we
|
|
|
|
// want to have control over the position. But we
|
|
|
|
// also lost resizing - that's why we have to do it here
|
|
|
|
// manually
|
|
|
|
|
|
|
|
stackBox->adjustItemAt( ( i == 0 ) ? startIndex() : endIndex() );
|
|
|
|
|
|
|
|
QQuickItem* item = layoutItem->item();
|
2018-08-03 06:15:28 +00:00
|
|
|
m_itemOffset[ i ] =
|
|
|
|
( m_orientation == Qt::Horizontal ) ? item->x() : item->y();
|
2017-07-21 16:21:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QQuickItem* item = layoutItem->item();
|
|
|
|
|
|
|
|
if ( m_orientation == Qt::Horizontal )
|
|
|
|
{
|
|
|
|
const qreal off = stackBox->width() * ( value - i );
|
|
|
|
|
|
|
|
if ( m_direction == Qsk::LeftToRight )
|
2018-08-03 06:15:28 +00:00
|
|
|
item->setX( m_itemOffset[ i ] - off );
|
2017-07-21 16:21:34 +00:00
|
|
|
else
|
2018-08-03 06:15:28 +00:00
|
|
|
item->setX( m_itemOffset[ i ] + off );
|
2017-07-21 16:21:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const qreal off = stackBox->height() * ( value - i );
|
|
|
|
|
|
|
|
if ( m_direction == Qsk::TopToBottom )
|
2018-08-03 06:15:28 +00:00
|
|
|
item->setY( m_itemOffset[ i ] + off );
|
2017-07-21 16:21:34 +00:00
|
|
|
else
|
2018-08-03 06:15:28 +00:00
|
|
|
item->setY( m_itemOffset[ i ] - off );
|
2017-07-21 16:21:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskStackBoxAnimator1::done()
|
|
|
|
{
|
|
|
|
for ( int i = 0; i < 2; i++ )
|
|
|
|
{
|
|
|
|
if ( QskLayoutItem* layoutItem = layoutItemAt( i ) )
|
|
|
|
{
|
|
|
|
layoutItem->setUpdateMode( QskLayoutItem::UpdateWhenVisible );
|
|
|
|
layoutItem->item()->setVisible( i == 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !m_hasClip )
|
|
|
|
stackBox()->setClip( false );
|
|
|
|
}
|
|
|
|
|
2018-08-03 06:15:28 +00:00
|
|
|
QskStackBoxAnimator3::QskStackBoxAnimator3( QskStackBox* parent )
|
|
|
|
: QskStackBoxAnimator( parent )
|
2017-07-21 16:21:34 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
QskStackBoxAnimator3::~QskStackBoxAnimator3()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskStackBoxAnimator3::setup()
|
|
|
|
{
|
|
|
|
QskLayoutItem* layoutItem = layoutItemAt( 1 );
|
|
|
|
if ( layoutItem )
|
|
|
|
{
|
|
|
|
layoutItem->item()->setOpacity( 0.0 );
|
|
|
|
layoutItem->item()->setVisible( true );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskStackBoxAnimator3::advance( qreal value )
|
|
|
|
{
|
|
|
|
QskLayoutItem* layoutItem1 = layoutItemAt( 0 );
|
|
|
|
if ( layoutItem1 )
|
|
|
|
layoutItem1->item()->setOpacity( 1.0 - value );
|
|
|
|
|
|
|
|
QskLayoutItem* layoutItem2 = layoutItemAt( 1 );
|
|
|
|
if ( layoutItem2 )
|
|
|
|
layoutItem2->item()->setOpacity( value );
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskStackBoxAnimator3::done()
|
|
|
|
{
|
|
|
|
for ( int i = 0; i < 2; i++ )
|
|
|
|
{
|
|
|
|
if ( QskLayoutItem* layoutItem = layoutItemAt( i ) )
|
|
|
|
{
|
|
|
|
layoutItem->item()->setOpacity( 1.0 );
|
|
|
|
layoutItem->item()->setVisible( i == 1 ); // not here !!
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "moc_QskStackBoxAnimator.cpp"
|