2 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali-toolkit/internal/transition/transition-base-impl.h>
22 #include <dali-toolkit/public-api/controls/control-impl.h>
25 #include <dali/devel-api/actors/actor-devel.h>
26 #include <dali/integration-api/debug.h>
27 #include <dali/public-api/animation/key-frames.h>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/object/type-registry.h>
39 static constexpr float OPACITY_TRANSPARENT = 0.0f;
41 const Dali::AlphaFunction DEFAULT_ALPHA_FUNCTION(Dali::AlphaFunction::DEFAULT);
43 const Property::Map PROPERTY_MAP_INDEPENDENT_CONTROL{
44 {Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER},
45 {Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER},
46 {Dali::Actor::Property::POSITION_USES_ANCHOR_POINT, true},
47 {Dali::Actor::Property::INHERIT_POSITION, false},
48 {Dali::Actor::Property::INHERIT_ORIENTATION, false},
49 {Dali::Actor::Property::INHERIT_SCALE, false},
50 {Dali::Actor::Property::COLOR_MODE, Dali::ColorMode::USE_OWN_COLOR},
53 Property::Map GetOriginalProperties(Dali::Toolkit::Control control)
55 Property::Map propertyMap;
56 propertyMap.Insert(Dali::Actor::Property::ANCHOR_POINT, control[Dali::Actor::Property::ANCHOR_POINT]);
57 propertyMap.Insert(Dali::Actor::Property::PARENT_ORIGIN, control[Dali::Actor::Property::PARENT_ORIGIN]);
58 propertyMap.Insert(Dali::Actor::Property::POSITION_USES_ANCHOR_POINT, control[Dali::Actor::Property::POSITION_USES_ANCHOR_POINT]);
59 propertyMap.Insert(Dali::Actor::Property::INHERIT_POSITION, control[Dali::Actor::Property::INHERIT_POSITION]);
60 propertyMap.Insert(Dali::Actor::Property::INHERIT_ORIENTATION, control[Dali::Actor::Property::INHERIT_ORIENTATION]);
61 propertyMap.Insert(Dali::Actor::Property::INHERIT_SCALE, control[Dali::Actor::Property::INHERIT_SCALE]);
62 propertyMap.Insert(Dali::Actor::Property::COLOR_MODE, control[Dali::Actor::Property::COLOR_MODE]);
63 propertyMap.Insert(Dali::Actor::Property::HEIGHT_RESIZE_POLICY, control[Dali::Actor::Property::HEIGHT_RESIZE_POLICY]);
64 propertyMap.Insert(Dali::Actor::Property::WIDTH_RESIZE_POLICY, control[Dali::Actor::Property::WIDTH_RESIZE_POLICY]);
65 propertyMap.Insert(Dali::Actor::Property::POSITION, control[Dali::Actor::Property::POSITION]);
66 propertyMap.Insert(Dali::Actor::Property::ORIENTATION, control[Dali::Actor::Property::ORIENTATION]);
67 propertyMap.Insert(Dali::Actor::Property::SCALE, control[Dali::Actor::Property::SCALE]);
68 propertyMap.Insert(Dali::Actor::Property::COLOR, control[Dali::Actor::Property::COLOR]);
73 } // anonymous namespace
75 TransitionBasePtr TransitionBase::New()
77 TransitionBasePtr transition = new TransitionBase();
79 // Second-phase construction
80 transition->Initialize();
85 TransitionBase::TransitionBase()
86 : mAlphaFunction(DEFAULT_ALPHA_FUNCTION),
87 mTimePeriod(TimePeriod(0.0f)),
88 mTransitionWithChild(false),
89 mMoveTargetChildren(false),
90 mIsAppearingTransition(true),
91 mIsPairTransition(false)
95 void TransitionBase::Initialize()
100 void TransitionBase::SetTimePeriod(const Dali::TimePeriod& timePeriod)
102 if(timePeriod.durationSeconds < 0.0f)
104 DALI_LOG_WARNING("Duration should be greater than 0.0f.\n");
108 mTimePeriod.durationSeconds = timePeriod.durationSeconds;
111 if(timePeriod.delaySeconds < 0.0f)
113 DALI_LOG_WARNING("Delay should be greater than 0.0f.\n");
118 mTimePeriod.delaySeconds = timePeriod.delaySeconds;
122 Dali::TimePeriod TransitionBase::GetTimePeriod() const
127 void TransitionBase::TransitionWithChild(bool transitionWithChild)
129 mTransitionWithChild = transitionWithChild;
132 void TransitionBase::PreProcess(Dali::Animation animation)
134 mAnimation = animation;
135 // Retrieve original property map of mTarget to backup and to reset after transition is finished.
136 mOriginalPropertyMap = GetOriginalProperties(mTarget);
137 mMoveTargetChildren = false;
138 if(!mTransitionWithChild && mTarget.GetChildCount() > 0)
140 mMoveTargetChildren = true;
143 GetImplementation(mTarget).SetTransparent(false);
146 void TransitionBase::Play()
148 if(!mTarget[Dali::Actor::Property::CONNECTED_TO_SCENE])
150 DALI_LOG_ERROR("The target is not added on the window\n");
154 // Set world transform and color to the target control to make it independent of the parent control and its transition.
155 // The properties will be returned at the TransitionFinished() method.
156 Matrix targetWorldTransform = DevelActor::GetWorldTransform(mTarget);
157 Vector3 targetPosition, targetScale;
158 Quaternion targetOrientation;
159 targetWorldTransform.GetTransformComponents(targetPosition, targetOrientation, targetScale);
160 Vector4 targetColor = DevelActor::GetWorldColor(mTarget);
162 mTarget.SetProperties(PROPERTY_MAP_INDEPENDENT_CONTROL);
163 mTarget[Dali::Actor::Property::POSITION] = targetPosition;
164 mTarget[Dali::Actor::Property::SCALE] = targetScale;
165 mTarget[Dali::Actor::Property::ORIENTATION] = targetOrientation;
166 mTarget[Dali::Actor::Property::COLOR] = targetColor;
173 void TransitionBase::SetAnimation()
177 DALI_LOG_ERROR("animation is not initialized\n");
181 for(uint32_t i = 0; i < mStartPropertyMap.Count(); ++i)
183 Property::Value* finishValue = mFinishPropertyMap.Find(mStartPropertyMap.GetKeyAt(i).indexKey);
186 // If this transition is appearing transition, this property keeps start value during delay.
187 // If multiple transitions are applied to this Control and others run before this transition,
188 // this property should keep start value until this transition starts.
189 if(!IsPairTransition() && IsAppearingTransition() && mTimePeriod.delaySeconds > Dali::Math::MACHINE_EPSILON_10)
191 mTarget.SetProperty(mStartPropertyMap.GetKeyAt(i).indexKey, mStartPropertyMap.GetValue(i));
193 AnimateBetween(mTarget, mStartPropertyMap.GetKeyAt(i).indexKey, mStartPropertyMap.GetValue(i), *finishValue);
198 void TransitionBase::AnimateBetween(Dali::Toolkit::Control target, Property::Index index, Property::Value sourceValue, Property::Value destinationValue)
202 // To make each property keep start value during delay time.
203 // When this transition is not Pair transition, it is not required.
204 // (For appearing transition, the mTarget control will not be shown during delay time,
205 // For disapplearing transition, the property of mTarget control keeps current value during delay time)
206 if(IsPairTransition() && mTimePeriod.delaySeconds > Dali::Math::MACHINE_EPSILON_10)
208 Dali::KeyFrames initialKeyframes = Dali::KeyFrames::New();
209 initialKeyframes.Add(0.0f, sourceValue);
210 initialKeyframes.Add(1.0f, sourceValue);
211 mAnimation.AnimateBetween(Property(target, index), initialKeyframes, TimePeriod(mTimePeriod.delaySeconds));
213 Dali::KeyFrames keyframes = Dali::KeyFrames::New();
214 keyframes.Add(0.0f, sourceValue);
215 keyframes.Add(1.0f, destinationValue);
216 mAnimation.AnimateBetween(Property(target, index), keyframes, mAlphaFunction, mTimePeriod);
220 void TransitionBase::CopyTarget()
222 mCopiedActor = Dali::Actor::New();
223 mTarget.GetParent().Add(mCopiedActor);
225 mCopiedActor[Dali::DevelActor::Property::SIBLING_ORDER] = static_cast<int32_t>(mTarget[Dali::DevelActor::Property::SIBLING_ORDER]) + 1;
226 while(mTarget.GetChildCount() > 0)
228 Dali::Actor child = mTarget.GetChildAt(0);
229 Dali::DevelActor::SwitchParent(child, mCopiedActor);
232 // Copy Size property to mCopiedActor because Size is not included mOriginalPropertyMap.
233 mCopiedActor[Dali::Actor::Property::SIZE] = mTarget.GetProperty<Vector3>(Dali::Actor::Property::SIZE);
234 mCopiedActor.SetProperties(mOriginalPropertyMap);
237 void TransitionBase::TransitionFinished()
241 mTarget.SetProperties(mOriginalPropertyMap);
242 if(mMoveTargetChildren)
244 while(mCopiedActor.GetChildCount() > 0)
246 Dali::Actor child = mCopiedActor.GetChildAt(0);
247 Dali::DevelActor::SwitchParent(child, mTarget);
249 mCopiedActor.Unparent();
250 mCopiedActor.Reset();
255 } // namespace Internal
257 } // namespace Toolkit