From: seungho Date: Fri, 29 Oct 2021 07:04:54 +0000 (+0900) Subject: Support multiple transitions for a Control. X-Git-Tag: dali_2.0.52~5^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=1fe158232ac5a8bf4ca2c769a9591e5266398bd7;hp=-c Support multiple transitions for a Control. - If a Control has multiple transitions, the Control must be hidden durring only the minimum delay of the transitions. - During delay time, the transitioned property of the Control will be set to the source value. Change-Id: If158d01511b373edaad59b5e288bc33e5adde9bb Signed-off-by: seungho --- 1fe158232ac5a8bf4ca2c769a9591e5266398bd7 diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Transition.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Transition.cpp index ef1eb2c..0ead710 100755 --- a/automated-tests/src/dali-toolkit/utc-Dali-Transition.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Transition.cpp @@ -24,6 +24,8 @@ #include #include #include +#include +#include using namespace Dali; using namespace Dali::Toolkit; @@ -1186,3 +1188,82 @@ int UtcDaliTransitionBetweenControlPairWithTreeWithoutScaleInheritance(void) END_TEST; } + + +int UtcDaliMultipleTransitionAppearing(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliMultipleTransitionAppearing"); + + Control control = Control::New(); + control.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT); + control.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + control.SetProperty(Actor::Property::POSITION, Vector3(100, 200, 0)); + control.SetProperty(Actor::Property::SIZE, Vector3(150, 150, 0)); + Property::Map controlProperty; + controlProperty.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR); + controlProperty.Insert(Toolkit::ColorVisual::Property::MIX_COLOR, Vector4(1.0f, 0.0f, 0.0f, 1.0f)); + control.SetProperty(Toolkit::Control::Property::BACKGROUND, controlProperty); + + application.GetScene().Add(control); + + application.SendNotification(); + application.Render(20); + + DALI_TEST_EQUALS(1.0f, control.GetCurrentProperty(Actor::Property::OPACITY), TEST_LOCATION); + + TransitionSet transitionSet = TransitionSet::New(); + FadeTransition fade = FadeTransition::New(control, 0.5, TimePeriod(1.0f, 1.0f)); + fade.SetAppearingTransition(true); // set fade in + transitionSet.AddTransition(fade); + SlideTransition slide = SlideTransition::New(control, Dali::Toolkit::SlideTransitionDirection::BOTTOM, TimePeriod(0.5f, 1.0f)); + slide.SetAppearingTransition(true); // set slide + transitionSet.AddTransition(slide); + transitionSet.Play(); + + bool signalReceived(false); + TransitionFinishCheck finishCheck(signalReceived); + transitionSet.FinishedSignal().Connect(&application, finishCheck); + + application.SendNotification(); + application.Render(300); + + float currentOpacity = control.GetCurrentProperty(Actor::Property::OPACITY); + DALI_TEST_CHECK(currentOpacity == 0.0f); + + application.SendNotification(); + application.Render(400); + + currentOpacity = control.GetCurrentProperty(Actor::Property::OPACITY); + DALI_TEST_CHECK(currentOpacity == 0.5f); + + application.SendNotification(); + application.Render(500); + + currentOpacity = control.GetCurrentProperty(Actor::Property::OPACITY); + DALI_TEST_CHECK(currentOpacity > 0.5f && currentOpacity < 1.0f); + + application.SendNotification(); + application.Render(500); + + currentOpacity = control.GetCurrentProperty(Actor::Property::OPACITY); + DALI_TEST_CHECK(currentOpacity > 0.5f && currentOpacity < 1.0f); + + // We didn't expect the animation to finish yet + application.SendNotification(); + finishCheck.CheckSignalNotReceived(); + + application.SendNotification(); + application.Render(500); + + // We did expect the animation to finish + application.SendNotification(); + finishCheck.CheckSignalReceived(); + + application.SendNotification(); + application.Render(20); + + DALI_TEST_EQUALS(1.0f, control.GetCurrentProperty(Actor::Property::OPACITY), TEST_LOCATION); + + END_TEST; +} diff --git a/dali-toolkit/internal/transition/transition-base-impl.cpp b/dali-toolkit/internal/transition/transition-base-impl.cpp index f8aed47..5ee926e 100644 --- a/dali-toolkit/internal/transition/transition-base-impl.cpp +++ b/dali-toolkit/internal/transition/transition-base-impl.cpp @@ -208,22 +208,18 @@ void TransitionBase::SetAnimation() return; } - // If this transition is not a transition from a Control to another Control - // and a transition effect to appear with delay, - // the mTarget should not be shown until delay seconds. - if(!IsPairTransition() && mIsAppearingTransition && mAnimation && mTimePeriod.delaySeconds > Dali::Math::MACHINE_EPSILON_10) - { - Dali::KeyFrames initialKeyframes = Dali::KeyFrames::New(); - initialKeyframes.Add(0.0f, OPACITY_TRANSPARENT); - initialKeyframes.Add(1.0f, OPACITY_TRANSPARENT); - mAnimation.AnimateBetween(Property(mTarget, Dali::Actor::Property::OPACITY), initialKeyframes, TimePeriod(mTimePeriod.delaySeconds)); - } - for(uint32_t i = 0; i < mStartPropertyMap.Count(); ++i) { Property::Value* finishValue = mFinishPropertyMap.Find(mStartPropertyMap.GetKeyAt(i).indexKey); if(finishValue) { + // If this transition is appearing transition, this property keeps start value during delay. + // If multiple transitions are applied to this Control and others run before this transition, + // this property should keep start value until this transition starts. + if(!IsPairTransition() && IsAppearingTransition() && mTimePeriod.delaySeconds > Dali::Math::MACHINE_EPSILON_10) + { + mTarget.SetProperty(mStartPropertyMap.GetKeyAt(i).indexKey, mStartPropertyMap.GetValue(i)); + } AnimateBetween(mTarget, mStartPropertyMap.GetKeyAt(i).indexKey, mStartPropertyMap.GetValue(i), *finishValue); } } diff --git a/dali-toolkit/internal/transition/transition-base-impl.h b/dali-toolkit/internal/transition/transition-base-impl.h index 409eb60..b194e52 100644 --- a/dali-toolkit/internal/transition/transition-base-impl.h +++ b/dali-toolkit/internal/transition/transition-base-impl.h @@ -101,6 +101,30 @@ public: mIsAppearingTransition = appearingTransition; } + /** + * @brief Returns whether this transition is appearing transition or not + */ + bool IsAppearingTransition() const + { + return mIsAppearingTransition; + } + + /** + * @brief Returns whether this transition is a transition from a Control to another Control or effect to appearing or disappearing. + */ + bool IsPairTransition() const + { + return mIsPairTransition; + } + + /** + * @brief Returns target which will be transition. + */ + const Dali::Toolkit::Control GetTarget() const + { + return mTarget; + } + protected: /** @@ -159,14 +183,6 @@ protected: } /** - * @brief Returns whether this transition is appearing transition or not - */ - bool IsAppearingTransition() const - { - return mIsAppearingTransition; - } - - /** * @brief Set whether this transition is a transition from a Control to another Control or effect to appearing or disappearing. * @param[in] pairTransition True if this transition is appearing transition. */ @@ -175,14 +191,6 @@ protected: mIsPairTransition = pairTransition; } - /** - * @brief Returns whether this transition is a transition from a Control to another Control or effect to appearing or disappearing. - */ - bool IsPairTransition() const - { - return mIsPairTransition; - } - protected: /** * Construct a new TransitionBase. diff --git a/dali-toolkit/internal/transition/transition-set-impl.cpp b/dali-toolkit/internal/transition/transition-set-impl.cpp index fd019b6..d1b16af 100644 --- a/dali-toolkit/internal/transition/transition-set-impl.cpp +++ b/dali-toolkit/internal/transition/transition-set-impl.cpp @@ -37,6 +37,13 @@ namespace // Signals static constexpr std::string_view SIGNAL_FINISHED = "finished"; +static constexpr float OPACITY_TRANSPARENT = 0.0f; + +float CustomAlphaFunction(float progress) +{ + return (progress >= 1.0f) ? 1.0f : 0.0f; +} + BaseHandle Create() { return Dali::Toolkit::TransitionSet::New(); @@ -117,9 +124,46 @@ void TransitionSet::TransitionPreProcess() void TransitionSet::TransitionStart() { + std::vector> minimumDelays; for(auto&& transition : mTransitions) { transition->Play(); + + // If target Control has appearing transition, the target will not be rendered during delay. + // And if the Control has multiple transitions, the target will not be rendered during minimum delay of the transitions. + // Here we can find minimum delay of each target. + if(!transition->IsPairTransition() && transition->IsAppearingTransition()) + { + bool found = false; + for(uint32_t index = 0; index < minimumDelays.size(); ++index) + { + if(minimumDelays[index].first == transition->GetTarget()) + { + minimumDelays[index].second = std::min(minimumDelays[index].second, transition->GetTimePeriod().delaySeconds); + found = true; + break; + } + } + if(!found) + { + minimumDelays.push_back(std::pair(transition->GetTarget(), transition->GetTimePeriod().delaySeconds)); + } + } + } + + // If the target has delay that is larger than 0, hide the target during minimum delay. + // The custom alpha function make the target hide just during delay. + for(auto&& delay : minimumDelays) + { + if(delay.second > Dali::Math::MACHINE_EPSILON_10) + { + Dali::KeyFrames initialKeyframes = Dali::KeyFrames::New(); + initialKeyframes.Add(0.0f, OPACITY_TRANSPARENT); + initialKeyframes.Add(1.0f, delay.first.GetProperty(Dali::Actor::Property::OPACITY)); + + AlphaFunction alpha(&CustomAlphaFunction); + mAnimation.AnimateBetween(Property(delay.first, Dali::Actor::Property::OPACITY), initialKeyframes, alpha, TimePeriod(delay.second)); + } } mAnimation.FinishedSignal().Connect(this, &TransitionSet::TransitionFinished);