From b6031f4703c9c11e9567f75aa4613cf2d7e960bd Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Mon, 25 Jul 2022 18:42:18 +0200 Subject: [PATCH] some improvememts for stack box flipping --- examples/layouts/StackLayoutPage.cpp | 5 +- examples/layouts/TestRectangle.cpp | 3 + src/layouts/QskStackBoxAnimator.cpp | 105 +++++++++++++++++++-------- src/layouts/QskStackBoxAnimator.h | 15 ++++ 4 files changed, 98 insertions(+), 30 deletions(-) diff --git a/examples/layouts/StackLayoutPage.cpp b/examples/layouts/StackLayoutPage.cpp index 3f348f39..460d922a 100644 --- a/examples/layouts/StackLayoutPage.cpp +++ b/examples/layouts/StackLayoutPage.cpp @@ -68,7 +68,10 @@ namespace if ( animator == nullptr ) { animator = new QskStackBoxAnimator2( this ); - animator->setDuration( 800 ); + animator->setOrientation( Qt::Vertical ); + animator->setInverted( true ); + animator->setEasingCurve( QEasingCurve::InOutBack ); + animator->setDuration( 2000 ); } setAnimator( animator ); diff --git a/examples/layouts/TestRectangle.cpp b/examples/layouts/TestRectangle.cpp index de819622..3286dfaa 100644 --- a/examples/layouts/TestRectangle.cpp +++ b/examples/layouts/TestRectangle.cpp @@ -4,11 +4,14 @@ *****************************************************************************/ #include "TestRectangle.h" +#include TestRectangle::TestRectangle( QQuickItem* parent ) : QskTextLabel( parent ) { setAlignment( Qt::AlignCenter ); + setFontRole( QskSkin::HugeFont ); + setTextColor( Qt::white ); setPreferredSize( 10, 10 ); initSizePolicy( QskSizePolicy::Minimum, QskSizePolicy::Minimum ); diff --git a/src/layouts/QskStackBoxAnimator.cpp b/src/layouts/QskStackBoxAnimator.cpp index 61f4a13c..9baa12a2 100644 --- a/src/layouts/QskStackBoxAnimator.cpp +++ b/src/layouts/QskStackBoxAnimator.cpp @@ -62,13 +62,14 @@ static Qsk::Direction qskDirection( namespace { - class Rotation : public QQuickTransform + class RotationTransform : public QQuickTransform { Q_OBJECT - public: - Rotation( qreal angle, QQuickItem* item ) + public: + RotationTransform( Qt::Axis axis, qreal angle, QQuickItem* item ) : QQuickTransform( item ) + , m_axis( axis ) , m_angle( angle ) { prependToItem( item ); @@ -76,8 +77,11 @@ namespace void setAngle( qreal angle ) { - m_angle = angle; - update(); + if ( m_angle != angle ) + { + m_angle = angle; + update(); + } } void applyTo( QMatrix4x4* matrix) const override @@ -89,28 +93,30 @@ namespace QTransform transform; transform.translate( dx, dy ); - transform.rotate( m_angle, Qt::XAxis ); + transform.rotate( m_angle, m_axis ); 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: + private: + const Qt::Axis m_axis; qreal m_angle = 0.0; }; + + static RotationTransform* qskFindRotationTransform( const QQuickItem* item ) + { + const auto& transforms = QQuickItemPrivate::get( item )->transforms; + for ( const auto& t : transforms ) + { + if ( auto transform = qobject_cast< RotationTransform* >( t ) ) + return transform; + } + + return nullptr; + } } QskStackBoxAnimator::QskStackBoxAnimator( QskStackBox* parent ) @@ -219,9 +225,7 @@ void QskStackBoxAnimator1::setOrientation( Qt::Orientation orientation ) { if ( m_orientation != orientation ) { -#if 1 stop(); -#endif m_orientation = orientation; } } @@ -332,6 +336,8 @@ bool QskStackBoxAnimator1::eventFilter( QObject* object, QEvent* event ) QskStackBoxAnimator2::QskStackBoxAnimator2( QskStackBox* parent ) : QskStackBoxAnimator( parent ) + , m_orientation( Qt::Horizontal ) + , m_inverted( false ) { } @@ -339,23 +345,60 @@ QskStackBoxAnimator2::~QskStackBoxAnimator2() { } +void QskStackBoxAnimator2::setOrientation( Qt::Orientation orientation ) +{ + if ( m_orientation != orientation ) + { + stop(); + m_orientation = orientation; + } +} + +Qt::Orientation QskStackBoxAnimator2::orientation() const +{ + return m_orientation; +} + +void QskStackBoxAnimator2::setInverted( bool on ) +{ + if ( m_inverted != on ) + { + stop(); + m_inverted = on; + } +} + +bool QskStackBoxAnimator2::isInverted() const +{ + return m_inverted; +} + void QskStackBoxAnimator2::setup() { + const auto axis = ( m_orientation == Qt::Horizontal ) + ? Qt::YAxis : Qt::XAxis; + if ( auto item = itemAt( 0 ) ) - ( void ) new Rotation( 0.0, item ); + ( void ) new RotationTransform( axis, 0.0, item ); if ( auto item = itemAt( 1 ) ) - ( void ) new Rotation( 90.0, item ); + ( void ) new RotationTransform( axis, 90.0, item ); } void QskStackBoxAnimator2::advanceIndex( qreal value ) { - if ( value < 0.5 ) + auto degrees = value * 180.0; + + if ( degrees < 90.0 && degrees > -90.0 ) { if ( auto item = itemAt( 0 ) ) { - auto rotation = Rotation::find( item ); - rotation->setAngle( value * 180.0 ); + if ( !m_inverted ) + degrees = 360.0 - degrees; + + auto rotation = qskFindRotationTransform( item ); + rotation->setAngle( degrees ); + item->setVisible( true ); } @@ -373,8 +416,12 @@ void QskStackBoxAnimator2::advanceIndex( qreal value ) if ( auto item = itemAt( 1 ) ) { - auto rotation = Rotation::find( item ); - rotation->setAngle( ( 1.0 - value ) * -180.0 ); + degrees = degrees - 180.0; + if ( !m_inverted ) + degrees = 360.0 - degrees; + + auto rotation = qskFindRotationTransform( item ); + rotation->setAngle( degrees ); item->setVisible( true ); } @@ -387,8 +434,8 @@ void QskStackBoxAnimator2::done() { if ( auto item = itemAt( i ) ) { - delete Rotation::find( item ); - item->setVisible( i == 1 ); // not here !! + delete qskFindRotationTransform( item ); + item->setVisible( i == 1 ); } } } diff --git a/src/layouts/QskStackBoxAnimator.h b/src/layouts/QskStackBoxAnimator.h index 4e5b7d51..2861f2e2 100644 --- a/src/layouts/QskStackBoxAnimator.h +++ b/src/layouts/QskStackBoxAnimator.h @@ -48,6 +48,8 @@ class QSK_EXPORT QskStackBoxAnimator1 : public QskStackBoxAnimator { Q_OBJECT + Q_PROPERTY( Qt::Orientation orientation READ orientation WRITE setOrientation ) + public: QskStackBoxAnimator1( QskStackBox* ); ~QskStackBoxAnimator1() override; @@ -75,14 +77,27 @@ class QSK_EXPORT QskStackBoxAnimator2 : public QskStackBoxAnimator { Q_OBJECT + Q_PROPERTY( Qt::Orientation orientation READ orientation WRITE setOrientation ) + Q_PROPERTY( bool inverted READ isInverted WRITE setInverted ) + public: QskStackBoxAnimator2( QskStackBox* ); ~QskStackBoxAnimator2() override; + void setOrientation( Qt::Orientation ); + Qt::Orientation orientation() const; + + void setInverted( bool ); + bool isInverted() const; + protected: void setup() override; void advanceIndex( qreal value ) override; void done() override; + + private: + Qt::Orientation m_orientation : 2; + bool m_inverted : 1; }; class QSK_EXPORT QskStackBoxAnimator3 : public QskStackBoxAnimator