From 8f4b94ee3d5d87bf58d3cd18386381b376c08196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Wed, 9 Jan 2019 02:13:06 -0300 Subject: [PATCH] Margin and padding CSS transitions fixes. --HG-- branch : dev --- bin/assets/layouts/test.css | 9 +- bin/assets/layouts/test.xml | 16 ++-- include/eepp/scene/actions/marginmove.hpp | 21 +++-- .../eepp/scene/actions/paddingtransition.hpp | 4 +- src/eepp/scene/actions/marginmove.cpp | 92 +++++++++++++------ src/eepp/scene/actions/paddingtransition.cpp | 38 +++++--- src/eepp/ui/uiwidget.cpp | 38 +++++--- 7 files changed, 145 insertions(+), 73 deletions(-) diff --git a/bin/assets/layouts/test.css b/bin/assets/layouts/test.css index af4d0fab4..b5089183b 100644 --- a/bin/assets/layouts/test.css +++ b/bin/assets/layouts/test.css @@ -67,7 +67,12 @@ Tooltip { textColor: black; } -#tpad { +#lvbox > * { + layout_marginTop: 8dp; +} + +#lvbox > #tpad { + layout_marginTop: 0dp; borderWidth: 2dp; borderColor: #66666666; backgroundColor: #33FF3333; @@ -75,7 +80,7 @@ Tooltip { transition: scale 0.25s, rotation 0.25s 0.25s, borderColor 0.25s, backgroundColor 0.25s, borderRadius 0.25s; } -#tpad:hover { +#lvbox > #tpad:hover { scale: 1.1; rotation: -3; backgroundColor: #FF333333; diff --git a/bin/assets/layouts/test.xml b/bin/assets/layouts/test.xml index bac231621..d0917f003 100644 --- a/bin/assets/layouts/test.xml +++ b/bin/assets/layouts/test.xml @@ -3,22 +3,22 @@ - - - - - - + + + + + + Test Test 2 Test 3 - + Test Test 2 Test 3 - + diff --git a/include/eepp/scene/actions/marginmove.hpp b/include/eepp/scene/actions/marginmove.hpp index 7d74aba1f..1cad59646 100644 --- a/include/eepp/scene/actions/marginmove.hpp +++ b/include/eepp/scene/actions/marginmove.hpp @@ -11,7 +11,15 @@ namespace EE { namespace Scene { namespace Actions { class EE_API MarginMove : public Action { public: - static MarginMove * New( const Rect& start, const Rect& end, const Time& duration, const Ease::Interpolation& type = Ease::Linear ); + enum InterpolateFlag { + Left = 1 << 0, + Top = 1 << 1, + Right = 1 << 2, + Bottom = 1 << 3, + All = Left | Top | Right | Bottom + }; + + static MarginMove * New( const Rect& start, const Rect& end, const Time& duration, const Ease::Interpolation& type = Ease::Linear, const Uint32& interpolateFlag = InterpolateFlag::All ); void start() override; @@ -27,22 +35,22 @@ class EE_API MarginMove : public Action { Interpolation1d getInterpolationLeft() const; - void setInterpolationLeft(const Interpolation1d & getInterpolationLeft); + void setInterpolationLeft(const Interpolation1d & interpolationLeft); Interpolation1d getInterpolationRight() const; - void setInterpolationRight(const Interpolation1d & getInterpolationRight); + void setInterpolationRight(const Interpolation1d & interpolationRight); Interpolation1d getInterpolationTop() const; - void setInterpolationTop(const Interpolation1d & getInterpolationTop); + void setInterpolationTop(const Interpolation1d & interpolationTop); Interpolation1d getInterpolationBottom() const; - void setInterpolationBottom(const Interpolation1d & getInterpolationBottom); + void setInterpolationBottom(const Interpolation1d & interpolationBottom); protected: - MarginMove( const Rect & start, const Rect & end, const Time & duration, const Ease::Interpolation & type ); + MarginMove( const Rect & start, const Rect & end, const Time & duration, const Ease::Interpolation & type, const Uint32& interpolateFlag ); void onStart() override; @@ -50,6 +58,7 @@ class EE_API MarginMove : public Action { MarginMove(); + Uint32 mFlags; Interpolation1d mInterpolationLeft; Interpolation1d mInterpolationRight; Interpolation1d mInterpolationTop; diff --git a/include/eepp/scene/actions/paddingtransition.hpp b/include/eepp/scene/actions/paddingtransition.hpp index 05fc46e3f..e99015c70 100644 --- a/include/eepp/scene/actions/paddingtransition.hpp +++ b/include/eepp/scene/actions/paddingtransition.hpp @@ -8,12 +8,12 @@ namespace EE { namespace Scene { namespace Actions { class EE_API PaddingTransition : public MarginMove { public: - static PaddingTransition * New( const Rectf& start, const Rectf& end, const Time& duration, const Ease::Interpolation& type = Ease::Linear ); + static PaddingTransition * New( const Rectf& start, const Rectf& end, const Time& duration, const Ease::Interpolation& type = Ease::Linear, const Uint32& interpolateFlag = InterpolateFlag::All ); Action * clone() const override; protected: - PaddingTransition( const Rectf& start, const Rectf& end, const Time & duration, const Ease::Interpolation & type ); + PaddingTransition( const Rectf& start, const Rectf& end, const Time & duration, const Ease::Interpolation & type, const Uint32& interpolateFlag ); void onUpdate( const Time& time ) override; private: diff --git a/src/eepp/scene/actions/marginmove.cpp b/src/eepp/scene/actions/marginmove.cpp index 96cfa7a40..7a273bf79 100644 --- a/src/eepp/scene/actions/marginmove.cpp +++ b/src/eepp/scene/actions/marginmove.cpp @@ -4,8 +4,8 @@ using namespace EE::UI; namespace EE { namespace Scene { namespace Actions { -MarginMove * MarginMove::New( const Rect & start, const Rect & end, const Time& duration, const Ease::Interpolation& type ) { - return eeNew( MarginMove, ( start, end, duration, type ) ); +MarginMove * MarginMove::New( const Rect & start, const Rect & end, const Time& duration, const Ease::Interpolation& type, const Uint32& interpolateFlag ) { + return eeNew( MarginMove, ( start, end, duration, type, interpolateFlag ) ); } MarginMove::MarginMove() @@ -43,18 +43,34 @@ void MarginMove::setInterpolationLeft(const Interpolation1d & interpolationLeft) mInterpolationLeft = interpolationLeft; } -MarginMove::MarginMove( const Rect& start, const Rect & end, const Time& duration, const Ease::Interpolation& type ) { - mInterpolationLeft.clear().add( start.Left, duration ).add( end.Left ).setType( type ); - mInterpolationRight.clear().add( start.Right, duration ).add( end.Right ).setType( type ); - mInterpolationTop.clear().add( start.Top, duration ).add( end.Top ).setType( type ); - mInterpolationBottom.clear().add( start.Bottom, duration ).add( end.Bottom ).setType( type ); +MarginMove::MarginMove( const Rect& start, const Rect & end, const Time& duration, const Ease::Interpolation& type, const Uint32& interpolateFlag ) : + mFlags( interpolateFlag ) +{ + if ( mFlags & InterpolateFlag::Left ) + mInterpolationLeft.clear().add( start.Left, duration ).add( end.Left ).setType( type ); + + if ( mFlags & InterpolateFlag::Right ) + mInterpolationRight.clear().add( start.Right, duration ).add( end.Right ).setType( type ); + + if ( mFlags & InterpolateFlag::Top ) + mInterpolationTop.clear().add( start.Top, duration ).add( end.Top ).setType( type ); + + if ( mFlags & InterpolateFlag::Bottom ) + mInterpolationBottom.clear().add( start.Bottom, duration ).add( end.Bottom ).setType( type ); } void MarginMove::start() { - mInterpolationLeft.start(); - mInterpolationRight.start(); - mInterpolationTop.start(); - mInterpolationBottom.start(); + if ( mFlags & InterpolateFlag::Left ) + mInterpolationLeft.start(); + + if ( mFlags & InterpolateFlag::Right ) + mInterpolationRight.start(); + + if ( mFlags & InterpolateFlag::Top ) + mInterpolationTop.start(); + + if ( mFlags & InterpolateFlag::Bottom ) + mInterpolationBottom.start(); onStart(); @@ -62,10 +78,17 @@ void MarginMove::start() { } void MarginMove::stop() { - mInterpolationLeft.stop(); - mInterpolationRight.stop(); - mInterpolationTop.stop(); - mInterpolationBottom.stop(); + if ( mFlags & InterpolateFlag::Left ) + mInterpolationLeft.stop(); + + if ( mFlags & InterpolateFlag::Right ) + mInterpolationRight.stop(); + + if ( mFlags & InterpolateFlag::Top ) + mInterpolationTop.stop(); + + if ( mFlags & InterpolateFlag::Bottom ) + mInterpolationBottom.stop(); onStop(); @@ -73,22 +96,28 @@ void MarginMove::stop() { } void MarginMove::update( const Time& time ) { - mInterpolationLeft.update( time ); - mInterpolationRight.update( time ); - mInterpolationTop.update( time ); - mInterpolationBottom.update( time ); + if ( mFlags & InterpolateFlag::Left ) + mInterpolationLeft.update( time ); + + if ( mFlags & InterpolateFlag::Right ) + mInterpolationRight.update( time ); + + if ( mFlags & InterpolateFlag::Top ) + mInterpolationTop.update( time ); + + if ( mFlags & InterpolateFlag::Bottom ) + mInterpolationBottom.update( time ); onUpdate( time ); } bool MarginMove::isDone() { - return mInterpolationLeft.ended() && - mInterpolationRight.ended() && - mInterpolationTop.ended() && - mInterpolationBottom.ended(); + return ( ( mFlags & InterpolateFlag::Left ) ? mInterpolationLeft.ended() : true ) && + ( ( mFlags & InterpolateFlag::Right ) ? mInterpolationRight.ended() : true ) && + ( ( mFlags & InterpolateFlag::Top ) ? mInterpolationTop.ended() : true ) && + ( ( mFlags & InterpolateFlag::Bottom ) ? mInterpolationBottom.ended() : true ); } - void MarginMove::onStart() { if ( NULL != mNode && mNode->isWidget() ) { onUpdate( Time::Zero ); @@ -97,17 +126,20 @@ void MarginMove::onStart() { void MarginMove::onUpdate( const Time& ) { if ( NULL != mNode && mNode->isWidget() ) { - static_cast( mNode )->setLayoutMargin( - Rect( mInterpolationLeft.getPosition(), - mInterpolationTop.getPosition(), - mInterpolationRight.getPosition(), - mInterpolationBottom.getPosition() - ) ); + UIWidget * widget = static_cast( mNode ); + + widget->setLayoutMargin( + Rect( ( mFlags & InterpolateFlag::Left ) ? mInterpolationLeft.getPosition() : widget->getLayoutMargin().Left, + ( mFlags & InterpolateFlag::Top ) ? mInterpolationTop.getPosition() : widget->getLayoutMargin().Top, + ( mFlags & InterpolateFlag::Right ) ? mInterpolationRight.getPosition() : widget->getLayoutMargin().Right, + ( mFlags & InterpolateFlag::Bottom ) ? mInterpolationBottom.getPosition() : widget->getLayoutMargin().Bottom + ) ); } } Action * MarginMove::clone() const { MarginMove * action = eeNew( MarginMove, () ); + action->mFlags = mFlags; action->setInterpolationLeft( mInterpolationLeft ); action->setInterpolationRight( mInterpolationRight ); action->setInterpolationTop( mInterpolationTop ); diff --git a/src/eepp/scene/actions/paddingtransition.cpp b/src/eepp/scene/actions/paddingtransition.cpp index 0b9bbf893..c38c0a28c 100644 --- a/src/eepp/scene/actions/paddingtransition.cpp +++ b/src/eepp/scene/actions/paddingtransition.cpp @@ -4,35 +4,47 @@ using namespace EE::UI; namespace EE { namespace Scene { namespace Actions { -PaddingTransition * PaddingTransition::New( const Rectf& start, const Rectf& end, const Time& duration, const Ease::Interpolation& type ) { - return eeNew( PaddingTransition, ( start, end, duration, type ) ); +PaddingTransition * PaddingTransition::New( const Rectf& start, const Rectf& end, const Time& duration, const Ease::Interpolation& type, const Uint32& interpolateFlag ) { + return eeNew( PaddingTransition, ( start, end, duration, type, interpolateFlag ) ); } PaddingTransition::PaddingTransition() {} -PaddingTransition::PaddingTransition( const Rectf& start, const Rectf& end, const Time& duration, const Ease::Interpolation& type ) : +PaddingTransition::PaddingTransition( const Rectf& start, const Rectf& end, const Time& duration, const Ease::Interpolation& type, const Uint32& interpolateFlag ) : MarginMove() { - mInterpolationLeft.clear().add( start.Left, duration ).add( end.Left ).setType( type ); - mInterpolationRight.clear().add( start.Right, duration ).add( end.Right ).setType( type ); - mInterpolationTop.clear().add( start.Top, duration ).add( end.Top ).setType( type ); - mInterpolationBottom.clear().add( start.Bottom, duration ).add( end.Bottom ).setType( type ); + mFlags = interpolateFlag; + + if ( mFlags & InterpolateFlag::Left ) + mInterpolationLeft.clear().add( start.Left, duration ).add( end.Left ).setType( type ); + + if ( mFlags & InterpolateFlag::Right ) + mInterpolationRight.clear().add( start.Right, duration ).add( end.Right ).setType( type ); + + if ( mFlags & InterpolateFlag::Top ) + mInterpolationTop.clear().add( start.Top, duration ).add( end.Top ).setType( type ); + + if ( mFlags & InterpolateFlag::Bottom ) + mInterpolationBottom.clear().add( start.Bottom, duration ).add( end.Bottom ).setType( type ); } void PaddingTransition::onUpdate(const Time &) { if ( NULL != mNode && mNode->isWidget() ) { - static_cast( mNode )->setPadding( - Rectf( mInterpolationLeft.getPosition(), - mInterpolationTop.getPosition(), - mInterpolationRight.getPosition(), - mInterpolationBottom.getPosition() - ) ); + UIWidget * widget = static_cast( mNode ); + + widget->setPadding( + Rectf( ( mFlags & InterpolateFlag::Left ) ? mInterpolationLeft.getPosition() : widget->getLayoutMargin().Left, + ( mFlags & InterpolateFlag::Top ) ? mInterpolationTop.getPosition() : widget->getLayoutMargin().Top, + ( mFlags & InterpolateFlag::Right ) ? mInterpolationRight.getPosition() : widget->getLayoutMargin().Right, + ( mFlags & InterpolateFlag::Bottom ) ? mInterpolationBottom.getPosition() : widget->getLayoutMargin().Bottom + ) ); } } Action * PaddingTransition::clone() const { PaddingTransition * action = eeNew( PaddingTransition, () ); + action->mFlags = mFlags; action->setInterpolationLeft( mInterpolationLeft ); action->setInterpolationRight( mInterpolationRight ); action->setInterpolationTop( mInterpolationTop ); diff --git a/src/eepp/ui/uiwidget.cpp b/src/eepp/ui/uiwidget.cpp index 2c4beafe6..6a82e86f5 100644 --- a/src/eepp/ui/uiwidget.cpp +++ b/src/eepp/ui/uiwidget.cpp @@ -861,21 +861,28 @@ bool UIWidget::setAttribute( const NodeAttribute& attribute, const Uint32& state } } else if ( String::startsWith( name, "layout_margin" ) ) { Rect margin; + Uint32 marginFlag = 0; - if ( "layout_margin" == name ) + if ( "layout_margin" == name ) { margin = attribute.asRect(); - else if ( "layout_marginleft" == name ) + marginFlag = Actions::MarginMove::All; + } else if ( "layout_marginleft" == name ) { margin = Rect( attribute.asDpDimensionI(), mLayoutMargin.Top, mLayoutMargin.Right, mLayoutMargin.Bottom ); - else if ( "layout_marginright" == name ) + marginFlag = Actions::MarginMove::Left; + } else if ( "layout_marginright" == name ) { margin = Rect( mLayoutMargin.Left, mLayoutMargin.Top, attribute.asDpDimensionI(), mLayoutMargin.Bottom ); - else if ( "layout_margintop" == name ) + marginFlag = Actions::MarginMove::Right; + } else if ( "layout_margintop" == name ) { margin = Rect( mLayoutMargin.Left, attribute.asDpDimensionI(), mLayoutMargin.Right, mLayoutMargin.Bottom ); - else if ( "layout_marginbottom" == name ) + marginFlag = Actions::MarginMove::Top; + } else if ( "layout_marginbottom" == name ) { margin = Rect( mLayoutMargin.Left, mLayoutMargin.Top, mLayoutMargin.Right, attribute.asDpDimensionI() ); + marginFlag = Actions::MarginMove::Bottom; + } if ( !isSceneNodeLoading() && NULL != mStyle && mStyle->hasTransition( state, attribute.getName() ) ) { UIStyle::TransitionInfo transitionInfo( mStyle->getTransition( state, attribute.getName() ) ); - Action * action = Actions::MarginMove::New( mLayoutMargin, margin, transitionInfo.duration, transitionInfo.timingFunction ); + Action * action = Actions::MarginMove::New( mLayoutMargin, margin, transitionInfo.duration, transitionInfo.timingFunction, marginFlag ); NodeAttribute oldAttribute = mStyle->getAttribute( UIState::StateFlagNormal, attribute.getName() ); if ( oldAttribute.isEmpty() && mStyle->getPreviousState() == UIState::StateFlagNormal ) { @@ -1025,21 +1032,28 @@ bool UIWidget::setAttribute( const NodeAttribute& attribute, const Uint32& state setBlendMode( attribute.asBlendMode() ); } else if ( String::startsWith( name, "padding" ) ) { Rectf padding; + Uint32 paddingFlag = 0; - if ( "padding" == name ) + if ( "padding" == name ) { padding = ( attribute.asRectf() ); - else if ( "paddingleft" == name ) + paddingFlag = Actions::PaddingTransition::All; + } else if ( "paddingleft" == name ) { padding = Rectf( attribute.asDpDimension(), mPadding.Top, mPadding.Right, mPadding.Bottom ); - else if ( "paddingright" == name ) + paddingFlag = Actions::PaddingTransition::Left; + } else if ( "paddingright" == name ) { padding = Rectf( mPadding.Left, mPadding.Top, attribute.asDpDimension(), mPadding.Bottom ); - else if ( "paddingtop" == name ) + paddingFlag = Actions::PaddingTransition::Right; + } else if ( "paddingtop" == name ) { padding = Rectf( mPadding.Left, attribute.asDpDimension(), mPadding.Right, mPadding.Bottom ); - else if ( "paddingbottom" == name ) + paddingFlag = Actions::PaddingTransition::Top; + } else if ( "paddingbottom" == name ) { padding = Rectf( mPadding.Left, mPadding.Top, mPadding.Right, attribute.asDpDimension() ); + paddingFlag = Actions::PaddingTransition::Bottom; + } if ( !isSceneNodeLoading() && NULL != mStyle && mStyle->hasTransition( state, attribute.getName() ) ) { UIStyle::TransitionInfo transitionInfo( mStyle->getTransition( state, attribute.getName() ) ); - Action * action = Actions::PaddingTransition::New( mPadding, padding, transitionInfo.duration, transitionInfo.timingFunction ); + Action * action = Actions::PaddingTransition::New( mPadding, padding, transitionInfo.duration, transitionInfo.timingFunction, paddingFlag ); NodeAttribute oldAttribute = mStyle->getAttribute( UIState::StateFlagNormal, attribute.getName() ); if ( oldAttribute.isEmpty() && mStyle->getPreviousState() == UIState::StateFlagNormal ) {