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 Property::Map GetOriginalProperties(Dali::Toolkit::Control control)
41 Property::Map propertyMap;
42 propertyMap.Insert(Dali::Actor::Property::ANCHOR_POINT, control[Dali::Actor::Property::ANCHOR_POINT]);
43 propertyMap.Insert(Dali::Actor::Property::PARENT_ORIGIN, control[Dali::Actor::Property::PARENT_ORIGIN]);
44 propertyMap.Insert(Dali::Actor::Property::POSITION_USES_ANCHOR_POINT, control[Dali::Actor::Property::POSITION_USES_ANCHOR_POINT]);
45 propertyMap.Insert(Dali::Actor::Property::INHERIT_POSITION, control[Dali::Actor::Property::INHERIT_POSITION]);
46 propertyMap.Insert(Dali::Actor::Property::INHERIT_ORIENTATION, control[Dali::Actor::Property::INHERIT_ORIENTATION]);
47 propertyMap.Insert(Dali::Actor::Property::INHERIT_SCALE, control[Dali::Actor::Property::INHERIT_SCALE]);
48 propertyMap.Insert(Dali::Actor::Property::COLOR_MODE, control[Dali::Actor::Property::COLOR_MODE]);
49 propertyMap.Insert(Dali::Actor::Property::HEIGHT_RESIZE_POLICY, control[Dali::Actor::Property::HEIGHT_RESIZE_POLICY]);
50 propertyMap.Insert(Dali::Actor::Property::WIDTH_RESIZE_POLICY, control[Dali::Actor::Property::WIDTH_RESIZE_POLICY]);
51 propertyMap.Insert(Dali::Actor::Property::POSITION, control[Dali::Actor::Property::POSITION]);
52 propertyMap.Insert(Dali::Actor::Property::ORIENTATION, control[Dali::Actor::Property::ORIENTATION]);
53 propertyMap.Insert(Dali::Actor::Property::SCALE, control[Dali::Actor::Property::SCALE]);
54 propertyMap.Insert(Dali::Actor::Property::COLOR, control[Dali::Actor::Property::COLOR]);
58 } // anonymous namespace
60 TransitionBasePtr TransitionBase::New()
62 TransitionBasePtr transition = new TransitionBase();
64 // Second-phase construction
65 transition->Initialize();
70 TransitionBase::TransitionBase()
71 : mAlphaFunction(Dali::AlphaFunction::DEFAULT),
72 mTimePeriod(TimePeriod(0.0f)),
73 mTransitionWithChild(false),
74 mMoveTargetChildren(false),
75 mIsAppearingTransition(true),
76 mIsPairTransition(false)
80 void TransitionBase::Initialize()
85 void TransitionBase::SetTimePeriod(const Dali::TimePeriod& timePeriod)
87 if(timePeriod.durationSeconds < 0.0f)
89 DALI_LOG_WARNING("Duration should be greater than 0.0f.\n");
93 mTimePeriod.durationSeconds = timePeriod.durationSeconds;
96 if(timePeriod.delaySeconds < 0.0f)
98 DALI_LOG_WARNING("Delay should be greater than 0.0f.\n");
103 mTimePeriod.delaySeconds = timePeriod.delaySeconds;
107 Dali::TimePeriod TransitionBase::GetTimePeriod() const
112 void TransitionBase::TransitionWithChild(bool transitionWithChild)
114 mTransitionWithChild = transitionWithChild;
117 void TransitionBase::PreProcess(Dali::Animation animation)
119 mAnimation = animation;
120 // Retrieve original property map of mTarget to backup and to reset after transition is finished.
121 mOriginalPropertyMap = GetOriginalProperties(mTarget);
122 mMoveTargetChildren = false;
123 if(!mTransitionWithChild && mTarget.GetChildCount() > 0)
125 mMoveTargetChildren = true;
128 GetImplementation(mTarget).SetTransparent(false);
131 void TransitionBase::Play()
133 if(!mTarget[Dali::Actor::Property::CONNECTED_TO_SCENE])
135 DALI_LOG_ERROR("The target is not added on the window\n");
139 // Set world transform and color to the target control to make it independent of the parent control and its transition.
140 // The properties will be returned at the TransitionFinished() method.
141 Matrix targetWorldTransform = DevelActor::GetWorldTransform(mTarget);
142 Vector3 targetPosition, targetScale;
143 Quaternion targetOrientation;
144 targetWorldTransform.GetTransformComponents(targetPosition, targetOrientation, targetScale);
145 Vector4 targetColor = DevelActor::GetWorldColor(mTarget);
147 mTarget[Dali::Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER;
148 mTarget[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
149 mTarget[Dali::Actor::Property::POSITION_USES_ANCHOR_POINT] = true;
150 mTarget[Dali::Actor::Property::INHERIT_POSITION] = false;
151 mTarget[Dali::Actor::Property::INHERIT_ORIENTATION] = false;
152 mTarget[Dali::Actor::Property::INHERIT_SCALE] = false;
153 mTarget[Dali::Actor::Property::COLOR_MODE] = Dali::ColorMode::USE_OWN_COLOR;
155 mTarget[Dali::Actor::Property::POSITION] = targetPosition;
156 mTarget[Dali::Actor::Property::SCALE] = targetScale;
157 mTarget[Dali::Actor::Property::ORIENTATION] = targetOrientation;
158 mTarget[Dali::Actor::Property::COLOR] = targetColor;
165 void TransitionBase::SetAnimation()
169 DALI_LOG_ERROR("animation is not initialized\n");
173 for(uint32_t i = 0; i < mStartPropertyMap.Count(); ++i)
175 Property::Value* finishValue = mFinishPropertyMap.Find(mStartPropertyMap.GetKeyAt(i).indexKey);
178 // If this transition is appearing transition, this property keeps start value during delay.
179 // If multiple transitions are applied to this Control and others run before this transition,
180 // this property should keep start value until this transition starts.
181 if(!IsPairTransition() && IsAppearingTransition() && mTimePeriod.delaySeconds > Dali::Math::MACHINE_EPSILON_10)
183 mTarget.SetProperty(mStartPropertyMap.GetKeyAt(i).indexKey, mStartPropertyMap.GetValue(i));
185 AnimateBetween(mTarget, mStartPropertyMap.GetKeyAt(i).indexKey, mStartPropertyMap.GetValue(i), *finishValue);
190 void TransitionBase::AnimateBetween(Dali::Toolkit::Control target, Property::Index index, Property::Value sourceValue, Property::Value destinationValue)
194 // To make each property keep start value during delay time.
195 // When this transition is not Pair transition, it is not required.
196 // (For appearing transition, the mTarget control will not be shown during delay time,
197 // For disapplearing transition, the property of mTarget control keeps current value during delay time)
198 if(IsPairTransition() && mTimePeriod.delaySeconds > Dali::Math::MACHINE_EPSILON_10)
200 Dali::KeyFrames initialKeyframes = Dali::KeyFrames::New();
201 initialKeyframes.Add(0.0f, sourceValue);
202 initialKeyframes.Add(1.0f, sourceValue);
203 mAnimation.AnimateBetween(Property(target, index), initialKeyframes, TimePeriod(mTimePeriod.delaySeconds));
205 Dali::KeyFrames keyframes = Dali::KeyFrames::New();
206 keyframes.Add(0.0f, sourceValue);
207 keyframes.Add(1.0f, destinationValue);
208 mAnimation.AnimateBetween(Property(target, index), keyframes, mAlphaFunction, mTimePeriod);
212 void TransitionBase::CopyTarget()
214 mCopiedActor = Dali::Actor::New();
215 mTarget.GetParent().Add(mCopiedActor);
217 mCopiedActor[Dali::DevelActor::Property::SIBLING_ORDER] = static_cast<int32_t>(mTarget[Dali::DevelActor::Property::SIBLING_ORDER]) + 1;
218 while(mTarget.GetChildCount() > 0)
220 Dali::Actor child = mTarget.GetChildAt(0);
221 Dali::DevelActor::SwitchParent(child, mCopiedActor);
224 // Copy Size property to mCopiedActor because Size is not included mOriginalPropertyMap.
225 mCopiedActor[Dali::Actor::Property::SIZE] = mTarget.GetProperty<Vector3>(Dali::Actor::Property::SIZE);
226 mCopiedActor.SetProperties(mOriginalPropertyMap);
229 void TransitionBase::TransitionFinished()
233 mTarget.SetProperties(mOriginalPropertyMap);
234 if(mMoveTargetChildren)
236 while(mCopiedActor.GetChildCount() > 0)
238 Dali::Actor child = mCopiedActor.GetChildAt(0);
239 Dali::DevelActor::SwitchParent(child, mTarget);
241 mCopiedActor.Unparent();
242 mCopiedActor.Reset();
247 } // namespace Internal
249 } // namespace Toolkit