Merge "Adds transition effect" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / transition / transition-impl.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/transition/transition-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali-toolkit/public-api/controls/control-impl.h>
23 #include <dali/devel-api/actors/actor-devel.h>
24 #include <dali/integration-api/debug.h>
25 #include <dali/public-api/common/dali-common.h>
26 #include <dali/public-api/object/type-registry.h>
27
28 // INTERNAL INCLUDES
29 #include <dali-toolkit/devel-api/controls/control-devel.h>
30
31 namespace Dali
32 {
33 namespace Toolkit
34 {
35 namespace Internal
36 {
37 namespace
38 {
39 const Dali::AlphaFunction DEFAULT_ALPHA_FUNCTION(Dali::AlphaFunction::DEFAULT);
40
41 } // anonymous namespace
42
43 TransitionPtr Transition::New(Dali::Toolkit::Control source, Dali::Toolkit::Control destination, TimePeriod timePeriod)
44 {
45   float delaySeconds = timePeriod.delaySeconds;
46   if(delaySeconds < 0.0f)
47   {
48     DALI_LOG_WARNING("delay should be greater than 0.0f.\n");
49     delaySeconds = 0.0f;
50   }
51
52   float durationSeconds = timePeriod.durationSeconds;
53   if(durationSeconds < 0.0f)
54   {
55     DALI_LOG_WARNING("duration should be greater than 0.0f.\n");
56     durationSeconds = 0.0f;
57   }
58
59   TransitionPtr transition = new Transition(source, destination, TimePeriod(delaySeconds, durationSeconds));
60
61   // Second-phase construction
62   transition->Initialize();
63
64   return transition;
65 }
66
67 Transition::Transition(Dali::Toolkit::Control source, Dali::Toolkit::Control destination, TimePeriod timePeriod)
68 : TransitionBase(),
69   mSourceControl(source),
70   mDestinationControl(destination)
71 {
72   SetTarget(destination);
73   SetTimePeriod(timePeriod);
74 }
75
76 Transition::~Transition()
77 {
78 }
79
80 void Transition::OnPlay()
81 {
82   if(!mSourceControl[Dali::Actor::Property::CONNECTED_TO_SCENE] ||
83      !mDestinationControl[Dali::Actor::Property::CONNECTED_TO_SCENE])
84   {
85     DALI_LOG_ERROR("The source or destination is not added on the window\n");
86     return;
87   }
88
89   //Make startPropertyMap and finishPropertyMap to use for property animation.
90   Matrix     sourceWorldTransform = mSourceControl[Dali::Actor::Property::WORLD_MATRIX];
91   Vector3    sourcePosition, sourceScale;
92   Quaternion sourceOrientation;
93   sourceWorldTransform.GetTransformComponents(sourcePosition, sourceOrientation, sourceScale);
94
95   Matrix     destinationWorldTransform = GetWorldTransform(mDestinationControl);
96   Vector3    destinationPosition, destinationScale;
97   Quaternion destinationOrientation;
98   destinationWorldTransform.GetTransformComponents(destinationPosition, destinationOrientation, destinationScale);
99
100   Vector3       targetSize  = mDestinationControl[Dali::Actor::Property::SIZE];
101   Vector4       targetColor = GetWorldColor(mDestinationControl);
102   Property::Map startPropertyMap;
103   Property::Map finishPropertyMap;
104
105   // Use world transform if this transition requires animation of transform.
106   mDestinationControl[Dali::Actor::Property::ANCHOR_POINT]               = AnchorPoint::CENTER;
107   mDestinationControl[Dali::Actor::Property::PARENT_ORIGIN]              = ParentOrigin::CENTER;
108   mDestinationControl[Dali::Actor::Property::POSITION_USES_ANCHOR_POINT] = true;
109   mDestinationControl[Dali::Actor::Property::INHERIT_POSITION]           = false;
110   mDestinationControl[Dali::Actor::Property::INHERIT_ORIENTATION]        = false;
111   mDestinationControl[Dali::Actor::Property::INHERIT_SCALE]              = false;
112   mDestinationControl[Dali::Actor::Property::COLOR_MODE]                 = Dali::ColorMode::USE_OWN_COLOR;
113
114   // Set animation of Transform
115   startPropertyMap.Insert(Dali::Actor::Property::POSITION, sourcePosition);
116   finishPropertyMap.Insert(Dali::Actor::Property::POSITION, destinationPosition);
117
118   startPropertyMap.Insert(Dali::Actor::Property::ORIENTATION, sourceOrientation);
119   finishPropertyMap.Insert(Dali::Actor::Property::ORIENTATION, destinationOrientation);
120
121   startPropertyMap.Insert(Dali::Actor::Property::SCALE, sourceScale);
122   finishPropertyMap.Insert(Dali::Actor::Property::SCALE, destinationScale);
123
124   Vector4 sourceColor = mSourceControl.GetCurrentProperty<Vector4>(Dali::Actor::Property::WORLD_COLOR);
125   startPropertyMap.Insert(Dali::Actor::Property::COLOR, sourceColor);
126   finishPropertyMap.Insert(Dali::Actor::Property::COLOR, targetColor);
127
128   // Set animation for other properties if source and destination is different.
129   Vector3 sourceSize = mSourceControl.GetCurrentProperty<Vector3>(Dali::Actor::Property::SIZE);
130   if(sourceSize != targetSize)
131   {
132     startPropertyMap.Insert(Dali::Actor::Property::SIZE, sourceSize);
133     finishPropertyMap.Insert(Dali::Actor::Property::SIZE, targetSize);
134   }
135
136   SetStartPropertyMap(startPropertyMap);
137   SetFinishPropertyMap(finishPropertyMap);
138
139   // source View becomes transparent during transition.
140   if(IsTransitionWithChild())
141   {
142     mSourceControl[Dali::Actor::Property::VISIBLE] = false;
143   }
144   else
145   {
146     GetImplementation(mSourceControl).SetTransparent(true);
147   }
148
149   Dali::Animation animation = GetAnimation();
150   if(!animation)
151   {
152     DALI_LOG_ERROR("animation is still not initialized\n");
153     return;
154   }
155   Dali::Toolkit::DevelControl::CreateTransitions(mDestinationControl, animation, mSourceControl, GetAlphaFunction(), GetTimePeriod());
156 }
157
158 void Transition::OnFinished()
159 {
160   if(IsTransitionWithChild())
161   {
162     mSourceControl[Dali::Actor::Property::VISIBLE] = true;
163   }
164   else
165   {
166     GetImplementation(mSourceControl).SetTransparent(false);
167   }
168 }
169
170 } // namespace Internal
171
172 } // namespace Toolkit
173
174 } // namespace Dali