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