Updated demos to use DALi clang-format
[platform/core/uifw/dali-demo.git] / examples / visual-transitions / beat-control-impl.cpp
1 /*
2  * Copyright (c) 2020 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 #include "beat-control-impl.h"
18 #include <dali-toolkit/dali-toolkit.h>
19 #include <dali-toolkit/devel-api/controls/control-devel.h>
20 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
21
22 using namespace Dali; // Needed for macros
23 using namespace Dali::Toolkit;
24
25 namespace Demo
26 {
27 namespace Internal
28 {
29 namespace
30 {
31 const int BOUNCE_ANIMATION_RUNNING(0x0001);
32 const int FADE_ANIMATION_RUNNING(0x0002);
33 const int X_ANIMATION_RUNNING(0x0004);
34 const int Y_ANIMATION_RUNNING(0x0008);
35
36 Dali::BaseHandle Create()
37 {
38   return Demo::BeatControl::New();
39 }
40
41 DALI_TYPE_REGISTRATION_BEGIN(BeatControl, Dali::Toolkit::Control, Create);
42
43 DALI_PROPERTY_REGISTRATION(Demo, BeatControl, "bounceTransition", STRING, BOUNCE_TRANSITION);
44 DALI_PROPERTY_REGISTRATION(Demo, BeatControl, "leftTransition", STRING, LEFT_TRANSITION);
45 DALI_PROPERTY_REGISTRATION(Demo, BeatControl, "upTransition", STRING, UP_TRANSITION);
46 DALI_PROPERTY_REGISTRATION(Demo, BeatControl, "fadeTransition", STRING, FADE_TRANSITION);
47 DALI_PROPERTY_REGISTRATION(Demo, BeatControl, "beatVisual", MAP, BEAT_VISUAL);
48 DALI_TYPE_REGISTRATION_END();
49
50 Toolkit::TransitionData ConvertPropertyToTransition(const Property::Value& value)
51 {
52   Toolkit::TransitionData transitionData;
53
54   const Property::Array* array = value.GetArray();
55   if(array)
56   {
57     transitionData = Toolkit::TransitionData::New(*array);
58   }
59   else
60   {
61     const Property::Map* map = value.GetMap();
62     if(map)
63     {
64       transitionData = Toolkit::TransitionData::New(*map);
65     }
66   }
67   return transitionData;
68 }
69
70 } // anonymous namespace
71
72 Internal::BeatControl::BeatControl()
73 : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
74   mTransformSize(1.0f, 1.0f),
75   mTransformOrigin(Align::CENTER),
76   mTransformAnchorPoint(Align::CENTER),
77   mAnimationPlaying(0)
78 {
79 }
80
81 Internal::BeatControl::~BeatControl()
82 {
83 }
84
85 Demo::BeatControl Internal::BeatControl::New()
86 {
87   IntrusivePtr<Internal::BeatControl> impl   = new Internal::BeatControl();
88   Demo::BeatControl                   handle = Demo::BeatControl(*impl);
89   impl->Initialize();
90   return handle;
91 }
92
93 void BeatControl::StartBounceAnimation()
94 {
95   if(mAnimation)
96   {
97     mAnimation.Stop();
98     mAnimation.FinishedSignal().Disconnect(this, &BeatControl::OnBounceAnimationFinished);
99     OnBounceAnimationFinished(mAnimation);
100   }
101
102   mAnimation = DevelControl::CreateTransition(*this, mBounceTransition);
103   mAnimation.FinishedSignal().Connect(this, &BeatControl::OnBounceAnimationFinished);
104   mAnimation.Play();
105   mAnimationPlaying |= BOUNCE_ANIMATION_RUNNING;
106 }
107
108 void BeatControl::StartXAnimation()
109 {
110   if(mXAnimation)
111   {
112     mXAnimation.Stop();
113     mXAnimation.FinishedSignal().Disconnect(this, &BeatControl::OnXAnimationFinished);
114     OnXAnimationFinished(mXAnimation);
115   }
116
117   mXAnimation = DevelControl::CreateTransition(*this, mLeftTransition);
118   mXAnimation.FinishedSignal().Connect(this, &BeatControl::OnXAnimationFinished);
119   mXAnimation.Play();
120   mAnimationPlaying |= X_ANIMATION_RUNNING;
121 }
122
123 void BeatControl::StartYAnimation()
124 {
125   if(mYAnimation)
126   {
127     mYAnimation.Stop();
128     mYAnimation.FinishedSignal().Disconnect(this, &BeatControl::OnYAnimationFinished);
129     OnYAnimationFinished(mYAnimation);
130   }
131
132   mYAnimation = DevelControl::CreateTransition(*this, mUpTransition);
133   mYAnimation.FinishedSignal().Connect(this, &BeatControl::OnYAnimationFinished);
134   mYAnimation.Play();
135   mAnimationPlaying |= Y_ANIMATION_RUNNING;
136 }
137
138 void BeatControl::StartFadeAnimation()
139 {
140   if(mFadeAnimation)
141   {
142     mFadeAnimation.Stop();
143     mFadeAnimation.FinishedSignal().Disconnect(this, &BeatControl::OnFadeAnimationFinished);
144     OnFadeAnimationFinished(mFadeAnimation);
145   }
146
147   mFadeAnimation = DevelControl::CreateTransition(*this, mFadeTransition);
148   mFadeAnimation.FinishedSignal().Connect(this, &BeatControl::OnFadeAnimationFinished);
149   mFadeAnimation.Play();
150   mAnimationPlaying |= FADE_ANIMATION_RUNNING;
151 }
152
153 void BeatControl::OnBounceAnimationFinished(Animation& src)
154 {
155   mAnimationPlaying &= ~BOUNCE_ANIMATION_RUNNING;
156 }
157 void BeatControl::OnXAnimationFinished(Animation& src)
158 {
159   mAnimationPlaying &= ~X_ANIMATION_RUNNING;
160 }
161 void BeatControl::OnYAnimationFinished(Animation& src)
162 {
163   mAnimationPlaying &= ~Y_ANIMATION_RUNNING;
164 }
165 void BeatControl::OnFadeAnimationFinished(Animation& src)
166 {
167   mAnimationPlaying &= ~FADE_ANIMATION_RUNNING;
168 }
169
170 void BeatControl::OnInitialize()
171 {
172   Actor self = Self();
173 }
174
175 void BeatControl::OnSceneConnection(int depth)
176 {
177   Control::OnSceneConnection(depth);
178 }
179
180 void BeatControl::OnSceneDisconnection()
181 {
182   Control::OnSceneDisconnection();
183 }
184
185 void BeatControl::OnSizeSet(const Vector3& targetSize)
186 {
187   Control::OnSizeSet(targetSize);
188   RelayoutVisuals(Vector2(targetSize));
189 }
190
191 void BeatControl::OnRelayout(const Vector2& targetSize, RelayoutContainer& container)
192 {
193   RelayoutVisuals(targetSize);
194 }
195
196 void BeatControl::RelayoutVisuals(const Vector2& targetSize)
197 {
198   if(mVisual)
199   {
200     if((mAnimationPlaying & (X_ANIMATION_RUNNING | Y_ANIMATION_RUNNING)) == 0)
201     {
202       Vector2       size(targetSize);
203       Property::Map transformMap;
204       // Make the visual half the size of the control, but leave
205       // origin and anchor point at center, position is relative, but Zer0
206       transformMap[Visual::Transform::Property::SIZE]         = mTransformSize;
207       transformMap[Visual::Transform::Property::ORIGIN]       = mTransformOrigin;
208       transformMap[Visual::Transform::Property::ANCHOR_POINT] = mTransformAnchorPoint;
209       mVisual.SetTransformAndSize(transformMap, size);
210     }
211   }
212 }
213
214 Vector3 BeatControl::GetNaturalSize()
215 {
216   if(mVisual)
217   {
218     Vector2 naturalSize;
219     mVisual.GetNaturalSize(naturalSize);
220     return Vector3(naturalSize);
221   }
222   return Vector3::ZERO;
223 }
224
225 void BeatControl::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
226 {
227   // Chain up.
228   Control::OnStyleChange(styleManager, change);
229 }
230
231 ///////////////////////////////////////////////////////////
232 //
233 // Properties
234 //
235
236 void BeatControl::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
237 {
238   Demo::BeatControl beatControl = Demo::BeatControl::DownCast(Dali::BaseHandle(object));
239
240   if(beatControl)
241   {
242     BeatControl& impl = GetImpl(beatControl);
243     Actor        self = impl.Self();
244     switch(index)
245     {
246       case Demo::BeatControl::Property::BEAT_VISUAL:
247       {
248         bool sizeAndPositionOnly = false;
249
250         // Determine if a transform.size property exists in the map, and
251         // save it.
252         Property::Map* map = value.GetMap();
253         if(map)
254         {
255           Property::Value* value = map->Find(Visual::Property::TRANSFORM, "transform");
256           if(value)
257           {
258             Property::Map* transformMap = value->GetMap();
259             if(transformMap)
260             {
261               // We'll increment this whenever SIZE, ORIGIN or ANCHOR_POINT's are modified as we won't need to create a new visual if only these properties are used
262               // If there are more properties in the transform map, then we need to create a new visual
263               unsigned int sizeAndPositionPropertyCount = 0;
264
265               Property::Value* sizeValue = transformMap->Find(Visual::Transform::Property::SIZE, "size");
266               if(sizeValue)
267               {
268                 sizeValue->Get(impl.mTransformSize);
269                 ++sizeAndPositionPropertyCount;
270               }
271
272               Property::Value* originValue = transformMap->Find(Visual::Transform::Property::ORIGIN, "origin");
273               if(originValue)
274               {
275                 int intValue = 0;
276                 if(originValue->Get(intValue))
277                 {
278                   impl.mTransformOrigin = static_cast<Toolkit::Align::Type>(intValue);
279                   ++sizeAndPositionPropertyCount;
280                 }
281               }
282
283               Property::Value* anchorPointValue = transformMap->Find(Visual::Transform::Property::ANCHOR_POINT, "anchorPoint");
284               if(anchorPointValue)
285               {
286                 int intValue = 0;
287                 if(anchorPointValue->Get(intValue))
288                 {
289                   impl.mTransformAnchorPoint = static_cast<Toolkit::Align::Type>(intValue);
290                   ++sizeAndPositionPropertyCount;
291                 }
292               }
293
294               // If the only properties that the application is overriding are the size and the position properties, then we do not need to create another visual.
295               if(map->Count() == 1 && transformMap->Count() == sizeAndPositionPropertyCount)
296               {
297                 sizeAndPositionOnly = true;
298               }
299             }
300           }
301           if(!sizeAndPositionOnly)
302           {
303             // Only register a visual if there is more than just a size setting
304             impl.mVisual = Toolkit::VisualFactory::Get().CreateVisual(*map);
305             DevelControl::RegisterVisual(impl, Demo::BeatControl::Property::BEAT_VISUAL, impl.mVisual);
306
307             // We have registered a new visual: must trigger size negotiation
308             // in order to call SetTransformAndSize on the visual with the right size:
309             impl.RelayoutRequest();
310           }
311         }
312         break;
313       }
314       case Demo::BeatControl::Property::BOUNCE_TRANSITION:
315       {
316         impl.mBounceTransition = ConvertPropertyToTransition(value);
317         break;
318       }
319       case Demo::BeatControl::Property::LEFT_TRANSITION:
320       {
321         impl.mLeftTransition = ConvertPropertyToTransition(value);
322         break;
323       }
324       case Demo::BeatControl::Property::UP_TRANSITION:
325       {
326         impl.mUpTransition = ConvertPropertyToTransition(value);
327         break;
328       }
329       case Demo::BeatControl::Property::FADE_TRANSITION:
330       {
331         impl.mFadeTransition = ConvertPropertyToTransition(value);
332         break;
333       }
334     }
335   }
336 }
337
338 Property::Value BeatControl::GetProperty(BaseObject* object, Property::Index propertyIndex)
339 {
340   Property::Value value;
341
342   Demo::BeatControl beatControl = Demo::BeatControl::DownCast(Dali::BaseHandle(object));
343
344   if(beatControl)
345   {
346     BeatControl& impl = GetImpl(beatControl);
347     switch(propertyIndex)
348     {
349       case Demo::BeatControl::Property::BEAT_VISUAL:
350       {
351         if(impl.mVisual)
352         {
353           Property::Map map;
354           impl.mVisual.CreatePropertyMap(map);
355           value = map;
356         }
357         break;
358       }
359       case Demo::BeatControl::Property::BOUNCE_TRANSITION:
360       case Demo::BeatControl::Property::LEFT_TRANSITION:
361       case Demo::BeatControl::Property::UP_TRANSITION:
362       case Demo::BeatControl::Property::FADE_TRANSITION:
363       default:
364         break;
365     }
366   }
367
368   return value;
369 }
370
371 } // namespace Internal
372 } // namespace Demo