From 168b8be9d05c56b12d1dde299ce7d852217322e9 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Tue, 19 Jul 2022 16:50:40 +0200 Subject: [PATCH] flipping QskStackBoxAnimator added --- examples/layouts/StackLayoutPage.cpp | 19 ++++- src/layouts/QskStackBoxAnimator.cpp | 121 +++++++++++++++++++++++++++ src/layouts/QskStackBoxAnimator.h | 14 ++++ 3 files changed, 153 insertions(+), 1 deletion(-) diff --git a/examples/layouts/StackLayoutPage.cpp b/examples/layouts/StackLayoutPage.cpp index 5d31eecf..3f348f39 100644 --- a/examples/layouts/StackLayoutPage.cpp +++ b/examples/layouts/StackLayoutPage.cpp @@ -61,6 +61,22 @@ namespace Q_EMIT transitionStarted( animator->duration() ); } + void incrementFlipping( int offset ) + { + auto animator = dynamic_cast< QskStackBoxAnimator2* >( this->animator() ); + + if ( animator == nullptr ) + { + animator = new QskStackBoxAnimator2( this ); + animator->setDuration( 800 ); + } + + setAnimator( animator ); + setCurrentIndex( incrementedIndex( offset ) ); + + Q_EMIT transitionStarted( animator->duration() ); + } + void incrementScrolling( Qt::Orientation orientation, int offset ) { auto animator = dynamic_cast< QskStackBoxAnimator1* >( this->animator() ); @@ -171,7 +187,8 @@ StackLayoutPage::StackLayoutPage( QQuickItem* parent ) buttonBox->addButton( ">>", [ box ]() { box->incrementScrolling( Qt::Horizontal, -1 ); } ); buttonBox->addButton( "^", [ box ]() { box->incrementScrolling( Qt::Vertical, -1 ); } ); buttonBox->addButton( "v", [ box ]() { box->incrementScrolling( Qt::Vertical, +1 ); } ); - buttonBox->addButton( "Fading", [ box ]() { box->incrementFading( +1 ); } ); + buttonBox->addButton( "Fade", [ box ]() { box->incrementFading( +1 ); } ); + buttonBox->addButton( "Flip", [ box ]() { box->incrementFlipping( +1 ); } ); // page indicator diff --git a/src/layouts/QskStackBoxAnimator.cpp b/src/layouts/QskStackBoxAnimator.cpp index 979b690d..61f4a13c 100644 --- a/src/layouts/QskStackBoxAnimator.cpp +++ b/src/layouts/QskStackBoxAnimator.cpp @@ -9,6 +9,10 @@ #include "QskQuick.h" #include "QskFunctions.h" +QSK_QT_PRIVATE_BEGIN +#include +QSK_QT_PRIVATE_END + static Qsk::Direction qskDirection( Qt::Orientation orientation, int from, int to, int itemCount ) { @@ -56,6 +60,59 @@ static Qsk::Direction qskDirection( return direction; } +namespace +{ + class Rotation : public QQuickTransform + { + Q_OBJECT + + public: + Rotation( qreal angle, QQuickItem* item ) + : QQuickTransform( item ) + , m_angle( angle ) + { + prependToItem( item ); + } + + void setAngle( qreal angle ) + { + m_angle = angle; + update(); + } + + void applyTo( QMatrix4x4* matrix) const override + { + if ( const auto item = qobject_cast< QQuickItem* >( parent() ) ) + { + const auto dx = 0.5 * item->width(); + const auto dy = 0.5 * item->height(); + + QTransform transform; + transform.translate( dx, dy ); + transform.rotate( m_angle, Qt::XAxis ); + transform.translate( -dx, -dy ); + + *matrix *= transform; + } + } + + static Rotation* find( const QQuickItem* item ) + { + const auto& transforms = QQuickItemPrivate::get( item )->transforms; + for ( const auto& t : transforms ) + { + if ( auto rotation = qobject_cast< Rotation* >( t ) ) + return rotation; + } + + return nullptr; + } + + private: + qreal m_angle = 0.0; + }; +} + QskStackBoxAnimator::QskStackBoxAnimator( QskStackBox* parent ) : QObject( parent ) , m_startIndex( -1 ) @@ -273,6 +330,69 @@ bool QskStackBoxAnimator1::eventFilter( QObject* object, QEvent* event ) return QObject::eventFilter( object, event ); } +QskStackBoxAnimator2::QskStackBoxAnimator2( QskStackBox* parent ) + : QskStackBoxAnimator( parent ) +{ +} + +QskStackBoxAnimator2::~QskStackBoxAnimator2() +{ +} + +void QskStackBoxAnimator2::setup() +{ + if ( auto item = itemAt( 0 ) ) + ( void ) new Rotation( 0.0, item ); + + if ( auto item = itemAt( 1 ) ) + ( void ) new Rotation( 90.0, item ); +} + +void QskStackBoxAnimator2::advanceIndex( qreal value ) +{ + if ( value < 0.5 ) + { + if ( auto item = itemAt( 0 ) ) + { + auto rotation = Rotation::find( item ); + rotation->setAngle( value * 180.0 ); + item->setVisible( true ); + } + + if ( auto item = itemAt( 1 ) ) + { + item->setVisible( false ); + } + } + else + { + if ( auto item = itemAt( 0 ) ) + { + item->setVisible( false ); + } + + if ( auto item = itemAt( 1 ) ) + { + auto rotation = Rotation::find( item ); + rotation->setAngle( ( 1.0 - value ) * -180.0 ); + + item->setVisible( true ); + } + } +} + +void QskStackBoxAnimator2::done() +{ + for ( int i = 0; i < 2; i++ ) + { + if ( auto item = itemAt( i ) ) + { + delete Rotation::find( item ); + item->setVisible( i == 1 ); // not here !! + } + } +} + QskStackBoxAnimator3::QskStackBoxAnimator3( QskStackBox* parent ) : QskStackBoxAnimator( parent ) { @@ -313,3 +433,4 @@ void QskStackBoxAnimator3::done() } #include "moc_QskStackBoxAnimator.cpp" +#include "QskStackBoxAnimator.moc" diff --git a/src/layouts/QskStackBoxAnimator.h b/src/layouts/QskStackBoxAnimator.h index 5538b55b..4e5b7d51 100644 --- a/src/layouts/QskStackBoxAnimator.h +++ b/src/layouts/QskStackBoxAnimator.h @@ -71,6 +71,20 @@ class QSK_EXPORT QskStackBoxAnimator1 : public QskStackBoxAnimator bool m_hasClip : 1; }; +class QSK_EXPORT QskStackBoxAnimator2 : public QskStackBoxAnimator +{ + Q_OBJECT + + public: + QskStackBoxAnimator2( QskStackBox* ); + ~QskStackBoxAnimator2() override; + + protected: + void setup() override; + void advanceIndex( qreal value ) override; + void done() override; +}; + class QSK_EXPORT QskStackBoxAnimator3 : public QskStackBoxAnimator { Q_OBJECT