2 * Copyright (c) 2021 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]);
74 * @brief Computes and center position by using transform properties.
75 * @param[in] anchorPoint anchorPoint of an actor.
76 * @param[in] positionUsesAnchorPoint positionUsesAnchorPoint of an actor.
77 * @param[in] size size of an actor.
78 * @param[in] scale scale of an actor.
79 * @param[in] orientation orientation of an actor.
81 Vector3 CalculateCenterPosition(
82 const Vector3& anchorPoint,
83 const bool positionUsesAnchorPoint,
86 const Quaternion& orientation)
88 Vector3 centerPosition;
89 const Vector3 half(0.5f, 0.5f, 0.5f);
90 const Vector3 topLeft(0.0f, 0.0f, 0.5f);
91 // Calculate the center-point by applying the scale and rotation on the anchor point.
92 centerPosition = (half - anchorPoint) * size * scale;
93 centerPosition *= orientation;
95 // If the position is ignoring the anchor-point, then remove the anchor-point shift from the position.
96 if(!positionUsesAnchorPoint)
98 centerPosition -= (topLeft - anchorPoint) * size;
100 return centerPosition;
103 } // anonymous namespace
105 TransitionBasePtr TransitionBase::New()
107 TransitionBasePtr transition = new TransitionBase();
109 // Second-phase construction
110 transition->Initialize();
115 TransitionBase::TransitionBase()
116 : mAlphaFunction(DEFAULT_ALPHA_FUNCTION),
117 mTimePeriod(TimePeriod(0.0f)),
118 mTransitionWithChild(false),
119 mMoveTargetChildren(false),
120 mIsAppearingTransition(true),
121 mIsPairTransition(false)
125 void TransitionBase::Initialize()
130 void TransitionBase::SetTimePeriod(const Dali::TimePeriod& timePeriod)
132 if(timePeriod.durationSeconds < 0.0f)
134 DALI_LOG_WARNING("Duration should be greater than 0.0f.\n");
138 mTimePeriod.durationSeconds = timePeriod.durationSeconds;
141 if(timePeriod.delaySeconds < 0.0f)
143 DALI_LOG_WARNING("Delay should be greater than 0.0f.\n");
148 mTimePeriod.delaySeconds = timePeriod.delaySeconds;
152 Dali::TimePeriod TransitionBase::GetTimePeriod() const
157 void TransitionBase::TransitionWithChild(bool transitionWithChild)
159 mTransitionWithChild = transitionWithChild;
162 void TransitionBase::PreProcess(Dali::Animation animation)
164 mAnimation = animation;
165 // Retrieve original property map of mTarget to backup and to reset after transition is finished.
166 mOriginalPropertyMap = GetOriginalProperties(mTarget);
167 mMoveTargetChildren = false;
168 if(!mTransitionWithChild && mTarget.GetChildCount() > 0)
170 mMoveTargetChildren = true;
173 GetImplementation(mTarget).SetTransparent(false);
176 void TransitionBase::Play()
178 if(!mTarget[Dali::Actor::Property::CONNECTED_TO_SCENE])
180 DALI_LOG_ERROR("The target is not added on the window\n");
184 // Set world transform and color to the target control to make it independent of the parent control and its transition.
185 // The properties will be returned at the TransitionFinished() method.
186 Matrix targetWorldTransform = GetWorldTransform(mTarget);
187 Vector3 targetPosition, targetScale;
188 Quaternion targetOrientation;
189 targetWorldTransform.GetTransformComponents(targetPosition, targetOrientation, targetScale);
190 Vector4 targetColor = GetWorldColor(mTarget);
192 mTarget.SetProperties(PROPERTY_MAP_INDEPENDENT_CONTROL);
193 mTarget[Dali::Actor::Property::POSITION] = targetPosition;
194 mTarget[Dali::Actor::Property::SCALE] = targetScale;
195 mTarget[Dali::Actor::Property::ORIENTATION] = targetOrientation;
196 mTarget[Dali::Actor::Property::COLOR] = targetColor;
203 void TransitionBase::SetAnimation()
207 DALI_LOG_ERROR("animation is not initialized\n");
211 for(uint32_t i = 0; i < mStartPropertyMap.Count(); ++i)
213 Property::Value* finishValue = mFinishPropertyMap.Find(mStartPropertyMap.GetKeyAt(i).indexKey);
216 // If this transition is appearing transition, this property keeps start value during delay.
217 // If multiple transitions are applied to this Control and others run before this transition,
218 // this property should keep start value until this transition starts.
219 if(!IsPairTransition() && IsAppearingTransition() && mTimePeriod.delaySeconds > Dali::Math::MACHINE_EPSILON_10)
221 mTarget.SetProperty(mStartPropertyMap.GetKeyAt(i).indexKey, mStartPropertyMap.GetValue(i));
223 AnimateBetween(mTarget, mStartPropertyMap.GetKeyAt(i).indexKey, mStartPropertyMap.GetValue(i), *finishValue);
228 void TransitionBase::AnimateBetween(Dali::Toolkit::Control target, Property::Index index, Property::Value sourceValue, Property::Value destinationValue)
232 // To make each property keep start value during delay time.
233 // When this transition is not Pair transition, it is not required.
234 // (For appearing transition, the mTarget control will not be shown during delay time,
235 // For disapplearing transition, the property of mTarget control keeps current value during delay time)
236 if(IsPairTransition() && mTimePeriod.delaySeconds > Dali::Math::MACHINE_EPSILON_10)
238 Dali::KeyFrames initialKeyframes = Dali::KeyFrames::New();
239 initialKeyframes.Add(0.0f, sourceValue);
240 initialKeyframes.Add(1.0f, sourceValue);
241 mAnimation.AnimateBetween(Property(target, index), initialKeyframes, TimePeriod(mTimePeriod.delaySeconds));
243 Dali::KeyFrames keyframes = Dali::KeyFrames::New();
244 keyframes.Add(0.0f, sourceValue);
245 keyframes.Add(1.0f, destinationValue);
246 mAnimation.AnimateBetween(Property(target, index), keyframes, mAlphaFunction, mTimePeriod);
250 void TransitionBase::CopyTarget()
252 mCopiedActor = Dali::Actor::New();
253 mTarget.GetParent().Add(mCopiedActor);
255 mCopiedActor[Dali::DevelActor::Property::SIBLING_ORDER] = static_cast<int32_t>(mTarget[Dali::DevelActor::Property::SIBLING_ORDER]) + 1;
256 while(mTarget.GetChildCount() > 0)
258 Dali::Actor child = mTarget.GetChildAt(0);
259 Dali::DevelActor::SwitchParent(child, mCopiedActor);
262 // Copy Size property to mCopiedActor because Size is not included mOriginalPropertyMap.
263 mCopiedActor[Dali::Actor::Property::SIZE] = mTarget.GetProperty<Vector3>(Dali::Actor::Property::SIZE);
264 mCopiedActor.SetProperties(mOriginalPropertyMap);
267 void TransitionBase::TransitionFinished()
271 mTarget.SetProperties(mOriginalPropertyMap);
272 if(mMoveTargetChildren)
274 while(mCopiedActor.GetChildCount() > 0)
276 Dali::Actor child = mCopiedActor.GetChildAt(0);
277 Dali::DevelActor::SwitchParent(child, mTarget);
279 mCopiedActor.Unparent();
280 mCopiedActor.Reset();
285 Matrix TransitionBase::GetWorldTransform(Dali::Actor actor)
289 DONT_INHERIT_TRANSFORM = 0,
290 INHERIT_POSITION = 1,
292 INHERIT_ORIENTATION = 4,
293 INHERIT_ALL = INHERIT_POSITION | INHERIT_SCALE | INHERIT_ORIENTATION,
296 std::vector<Dali::Actor> descentList;
297 std::vector<InheritanceMode> inheritanceModeList;
298 Dali::Actor currentActor = actor;
302 inheritance = (static_cast<int>(currentActor.GetProperty<bool>(Dali::Actor::Property::INHERIT_ORIENTATION)) << 2) +
303 (static_cast<int>(currentActor.GetProperty<bool>(Dali::Actor::Property::INHERIT_SCALE)) << 1) +
304 static_cast<int>(currentActor.GetProperty<bool>(Dali::Actor::Property::INHERIT_POSITION));
305 inheritanceModeList.push_back(static_cast<InheritanceMode>(inheritance));
306 descentList.push_back(currentActor);
307 currentActor = currentActor.GetParent();
308 } while(inheritance != DONT_INHERIT_TRANSFORM && currentActor);
311 Vector3 localPosition;
312 for(unsigned int i(descentList.size() - 1); i < descentList.size(); --i)
314 Vector3 anchorPoint = descentList[i].GetProperty<Vector3>(Dali::Actor::Property::ANCHOR_POINT);
315 Vector3 parentOrigin = descentList[i].GetProperty<Vector3>(Dali::Actor::Property::PARENT_ORIGIN);
316 bool positionUsesAnchorPoint = descentList[i].GetProperty<bool>(Dali::Actor::Property::POSITION_USES_ANCHOR_POINT);
317 Vector3 size = descentList[i].GetProperty<Vector3>(Dali::Actor::Property::SIZE);
318 Vector3 actorPosition = descentList[i].GetProperty<Vector3>(Dali::Actor::Property::POSITION);
319 Quaternion localOrientation = descentList[i].GetProperty<Quaternion>(Dali::Actor::Property::ORIENTATION);
320 Vector3 localScale = descentList[i].GetProperty<Vector3>(Dali::Actor::Property::SCALE);
322 Vector3 centerPosition = CalculateCenterPosition(anchorPoint, positionUsesAnchorPoint, size, localScale, localOrientation);
323 if(inheritanceModeList[i] != DONT_INHERIT_TRANSFORM && descentList[i].GetParent())
326 Vector3 parentSize = descentList[i + 1].GetProperty<Vector3>(Dali::Actor::Property::SIZE);
327 if(inheritanceModeList[i] == INHERIT_ALL)
329 localPosition = actorPosition + centerPosition + (parentOrigin - Vector3(0.5f, 0.5f, 0.5f)) * parentSize;
330 localMatrix.SetTransformComponents(localScale, localOrientation, localPosition);
332 //Update the world matrix
334 Matrix::Multiply(tempMatrix, localMatrix, worldMatrix);
335 worldMatrix = tempMatrix;
339 Vector3 parentPosition, parentScale;
340 Quaternion parentOrientation;
341 worldMatrix.GetTransformComponents(parentPosition, parentOrientation, parentScale);
343 if((inheritanceModeList[i] & INHERIT_SCALE) == 0)
345 //Don't inherit scale
346 localScale /= parentScale;
349 if((inheritanceModeList[i] & INHERIT_ORIENTATION) == 0)
351 //Don't inherit orientation
352 parentOrientation.Invert();
353 localOrientation = parentOrientation * localOrientation;
356 if((inheritanceModeList[i] & INHERIT_POSITION) == 0)
358 localMatrix.SetTransformComponents(localScale, localOrientation, Vector3::ZERO);
360 Matrix::Multiply(tempMatrix, localMatrix, worldMatrix);
361 worldMatrix = tempMatrix;
362 worldMatrix.SetTranslation(actorPosition + centerPosition);
366 localPosition = actorPosition + centerPosition + (parentOrigin - Vector3(0.5f, 0.5f, 0.5f)) * parentSize;
367 localMatrix.SetTransformComponents(localScale, localOrientation, localPosition);
369 Matrix::Multiply(tempMatrix, localMatrix, worldMatrix);
370 worldMatrix = tempMatrix;
376 localPosition = actorPosition + centerPosition;
377 worldMatrix.SetTransformComponents(localScale, localOrientation, localPosition);
384 Vector4 TransitionBase::GetWorldColor(Dali::Actor actor)
386 std::vector<Dali::Actor> descentList;
387 std::vector<Dali::ColorMode> inheritanceModeList;
388 Dali::Actor currentActor = actor;
389 Dali::ColorMode inheritance = Dali::ColorMode::USE_OWN_MULTIPLY_PARENT_ALPHA;
392 inheritance = currentActor.GetProperty<Dali::ColorMode>(Dali::Actor::Property::COLOR_MODE);
393 inheritanceModeList.push_back(inheritance);
394 descentList.push_back(currentActor);
395 currentActor = currentActor.GetParent();
396 } while(inheritance != Dali::ColorMode::USE_OWN_COLOR && currentActor);
399 for(unsigned int i(descentList.size() - 1); i < descentList.size(); --i)
401 if(inheritanceModeList[i] == USE_OWN_COLOR || i == descentList.size() - 1)
403 worldColor = descentList[i].GetProperty<Vector4>(Dali::Actor::Property::COLOR);
405 else if(inheritanceModeList[i] == USE_OWN_MULTIPLY_PARENT_ALPHA)
407 Vector4 ownColor = descentList[i].GetProperty<Vector4>(Dali::Actor::Property::COLOR);
408 worldColor = Vector4(ownColor.r, ownColor.g, ownColor.b, ownColor.a * worldColor.a);
410 else if(inheritanceModeList[i] == USE_OWN_MULTIPLY_PARENT_COLOR)
412 Vector4 ownColor = descentList[i].GetProperty<Vector4>(Dali::Actor::Property::COLOR);
413 worldColor *= ownColor;
420 } // namespace Internal
422 } // namespace Toolkit