696f1a92283cc404e96849c81a6c43f6199d5d9b
[platform/core/uifw/dali-demo.git] / examples / animated-gradient-card-active / animated-gradient-card-active.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 <dali/dali.h>
18 #include <dali-toolkit/dali-toolkit.h>
19 #include <iostream>
20 #include <dali-toolkit/devel-api/visuals/animated-gradient-visual-properties-devel.h>
21 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
22 #include <dali/integration-api/debug.h>
23
24 using namespace Dali;
25 using namespace Dali::Toolkit;
26
27 // This example shows how to create and display animated-gradient-effect
28 //
29 namespace
30 {
31 // The value for scale-change between wearable-mobile
32 // Can be changed on App-Create time
33 Vector2 WINDOW_SIZE = Vector2( 360.0f, 360.0f );
34 Vector2 SCALED_WINDOW_SIZE = Vector2( 1.0f, 1.0f );
35 Vector3 SCALED_WINDOW_SIZE_3 = Vector3( 1.0f, 1.0f, 0.0f );
36 float SCALED_WIDTH = 1.0f;
37 float SCALED_HEIGHT = 1.0f;
38 float FONT_SCALE = 0.25f;
39
40 // const parameters for color and animation
41 const float CHANGE_DURATION = 0.2f;
42 const float CARD_MOVE_DURATION = 1.0f;
43 const float LOADING_ONE_CYCLE_DURATION = 2.0f;
44 const int   LOADING_CYCLE_CNT = 4;
45 const int   LOADING_CYCLE_DT = 10;
46 const Vector4 DEFAULT_COLOR = Vector4( 0.5f, 0.5f, 0.5f, 1.0f );
47
48 const float PSEUDO_SCROLL_TIME = 100.0f;
49 const float PSEUDO_SCROLL_OFFSET = 0.05f;
50
51 // const static parameters for cards when resolution is 360x360
52 const int CARD_NUM = 3;
53 const Vector2 CARD_SIZE = Vector2( 210.0f, 143.0f );
54 const Vector2 CARD_OFFSET = Vector2( 0.0f, 12.5f );
55 const Vector2 CARD_DIFF = Vector2( 240.0f, 0.0f );
56 const float CARD_BOUNCE_ANIMATION_RATE = 0.3f;
57
58 const Vector2 CARD_SIZE_BIG = Vector2( 292.0f, 199.0f );
59 const Vector2 CARD_BIG_OFFSET = Vector2( 0.0f, -5.5f );
60 const float CARD_MOVE_DIST = 40.0f;
61
62 // const private parameters for each cards
63 const Vector4 CARD_COLOR_START_LIST[] =
64 {
65   Vector4( 0x24, 0x2C, 0x93, 255.f ) / 255.f,
66   Vector4( 0x7A, 0x1C, 0x9E, 255.f ) / 255.f,
67   Vector4( 0xA9, 0x0C, 0x96, 255.f ) / 255.f,
68 };
69 const Vector4 CARD_COLOR_END_LIST[] =
70 {
71   Vector4( 0x04, 0x13, 0x23, 255.f ) / 255.f,
72   Vector4( 0x28, 0x01, 0x45, 255.f ) / 255.f,
73   Vector4( 0x37, 0x0A, 0x2E, 255.f ) / 255.f,
74 };
75 const Vector4 CARD_COLOR_BACKGROUND_LIST[] =
76 {
77   Vector4( 0x28, 0x2B, 0x6E, 255.f ) / 255.f,
78   Vector4( 0x4D, 0x15, 0x61, 255.f ) / 255.f,
79   Vector4( 0x70, 0x21, 0x61, 255.f ) / 255.f,
80 };
81 const char * const CARD_IMAGE_LIST[] =
82 {
83   ( DEMO_IMAGE_DIR "Card_01.png" ),
84   ( DEMO_IMAGE_DIR "Card_02.png" ),
85   ( DEMO_IMAGE_DIR "Card_03.png" ),
86 };
87
88 // const parameters for add button position and size when resolution is 360x360x
89 const Vector2 BUTTON_ADD_SIZE = Vector2( 292.0f, 52.0f );
90 const Vector3 BUTTON_ADD_POSITION = Vector3( 0.0f, 0.0f, 0.0f );
91 const char * const BUTTON_ADD_IMAGE( DEMO_IMAGE_DIR "Card_Add_Button.png" );
92
93 // const parameters for string position and size and font-size when resolution is 360x360
94 const Vector2 LABEL_TICKET_SIZE = Vector2( 148.0f, 31.0f );
95 const Vector3 LABEL_TICKET_POSITION = Vector3( 0.0f, 72.5f, 0.0f );
96 const Vector4 LABEL_TICKET_FONT_COLOR = Vector4( 0.98f, 0.98f, 0.98f, 1.0f );
97 const float   LABEL_TICKET_FONT_SIZE = 25.0f;
98 const Vector2 LABEL_HOLD_SIZE = Vector2( 180.0f, 60.0f );
99 const Vector3 LABEL_HOLD_POSITION = Vector3( 1.0f, 103.0f, 0.0f );
100 const Vector4 LABEL_HOLD_FONT_COLOR = Vector4( 0.98f, 0.98f, 0.98f, 1.0f );
101 const float   LABEL_HOLD_FONT_SIZE = 25.0f;
102 const Vector2 LABEL_TERMINAL_SIZE = Vector2( 180.0f, 60.0f );
103 const Vector3 LABEL_TERMINAL_POSITION = Vector3( 1.0f, 133.0f, 0.0f );
104 const Vector4 LABEL_TERMINAL_FONT_COLOR = Vector4( 0.98f, 0.98f, 0.98f, 1.0f );
105 const float   LABEL_TERMINAL_FONT_SIZE = 25.0f;
106
107 // string string
108 const char * const LABEL_TICKET_STR( "Select Ticket" );
109 const char * const LABEL_HOLD_STR( "Hold near" );
110 const char * const LABEL_TERMINAL_STR( "terminal" );
111
112 class CardManager
113 {
114 public:
115   CardManager()
116     : mSize( 0.0f, 0.0f ),
117       mOffset( 0.0f, 0.0f),
118       mDiff( 0.0f, 0.0f),
119       mCurIndex( 0 ),
120       mCurState( 0 )
121   {
122   }
123   ~CardManager() {}
124
125   void Init(Window& window)
126   {
127     mSize = CARD_SIZE * SCALED_WIDTH;
128     mOffset = CARD_OFFSET * SCALED_WIDTH;
129     mDiff = CARD_DIFF * SCALED_WIDTH;
130
131     mCurIndex = 0;
132     mCurState = 0;
133
134     for( int k = 0; k < CARD_NUM; k++ )
135     {
136       mPosition[k] = mOffset + mDiff * k;
137
138       mColorStart[k] = CARD_COLOR_START_LIST[k];
139       mColorEnd[k] = CARD_COLOR_END_LIST[k];
140       mColorBackground[k] = CARD_COLOR_BACKGROUND_LIST[k];
141
142       mImageUrl[k] = CARD_IMAGE_LIST[k];
143
144       // Create an image view for this item
145       mCard[k] = ImageView::New();
146       {
147         Property::Map propertyMap;
148         propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE);
149         propertyMap.Insert(ImageVisual::Property::URL, mImageUrl[k]);
150         propertyMap.Insert(DevelVisual::Property::VISUAL_FITTING_MODE, DevelVisual::FILL);
151         mCard[k].SetProperty(Toolkit::ImageView::Property::IMAGE, propertyMap);
152       }
153
154       mCard[k].SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
155       mCard[k].SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
156       mCard[k].SetProperty( Actor::Property::SIZE, Vector2( mSize.x, mSize.y ) );
157       mCard[k].SetProperty( Actor::Property::POSITION, Vector2( mPosition[k].x, mPosition[k].y ));
158
159       window.Add( mCard[k] );
160     }
161   }
162
163   bool MoveRight(float duration)
164   {
165     Animation anim = Animation::New( duration );
166     for( int k = 0; k < CARD_NUM; k++ )
167     {
168       if( mCurIndex == 0 )
169       {
170         anim.AnimateBy( Property( mCard[k], Actor::Property::POSITION_X ), mDiff.x * CARD_BOUNCE_ANIMATION_RATE, AlphaFunction::BOUNCE );
171       }
172       else
173       {
174         anim.AnimateBy( Property( mCard[k], Actor::Property::POSITION_X ), mDiff.x, AlphaFunction::EASE_OUT );
175       }
176     }
177     bool res = false;
178     if( mCurIndex != 0 )
179     {
180       mCurIndex = (mCurIndex - 1) % CARD_NUM;
181       res = true;
182     }
183     anim.Play();
184     return res;
185   }
186
187   bool MoveLeft(float duration)
188   {
189     Animation anim = Animation::New( duration );
190     for( int k = 0; k < CARD_NUM; k++ )
191     {
192       if( mCurIndex == CARD_NUM - 1 )
193       {
194         anim.AnimateBy( Property( mCard[k], Actor::Property::POSITION_X ), -mDiff.x * CARD_BOUNCE_ANIMATION_RATE, AlphaFunction::BOUNCE );
195       }
196       else
197       {
198         anim.AnimateBy( Property( mCard[k], Actor::Property::POSITION_X ), -mDiff.x, AlphaFunction::EASE_OUT );
199       }
200     }
201     bool res = false;
202     if( mCurIndex != CARD_NUM - 1 )
203     {
204       mCurIndex = (mCurIndex + 1) % CARD_NUM;
205       res = true;
206     }
207     anim.Play();
208     return res;
209   }
210
211   Vector4 GetColorStart(int index)
212   {
213     DALI_ASSERT_ALWAYS( index >= 0 && index < CARD_NUM );
214     return mColorStart[index];
215   }
216
217   Vector4 GetColorEnd(int index)
218   {
219     DALI_ASSERT_ALWAYS( index >= 0 && index < CARD_NUM );
220     return mColorEnd[index];
221   }
222
223   Vector4 GetColorBackground(int index)
224   {
225     DALI_ASSERT_ALWAYS( index >= 0 && index < CARD_NUM );
226     return mColorBackground[index];
227   }
228
229   ImageView& operator [](int index)
230   {
231     DALI_ASSERT_ALWAYS( index >= 0 && index < CARD_NUM );
232     return mCard[index];
233   }
234
235   ImageView mCard[CARD_NUM];
236   std::string mImageUrl[CARD_NUM];
237   Vector4 mColorStart[CARD_NUM];
238   Vector4 mColorEnd[CARD_NUM];
239   Vector4 mColorBackground[CARD_NUM];
240   Vector2 mPosition[CARD_NUM];
241   Vector2 mSize;
242   Vector2 mOffset;
243   Vector2 mDiff;
244   int mCurIndex;
245   int mCurState;
246 };
247
248 } // unnamed namespace
249
250 // This example shows how to render animated gradients
251 //
252 class CardController : public ConnectionTracker
253 {
254 public:
255   CardController(Application& application)
256     : mApplication( application ),
257       mNormalColor( 0.0f, 0.0f, 0.0f, 0.0f ),
258       mNormalStartColor( 0.0f, 0.0f, 0.0f, 0.0f ),
259       mNormalEndColor( 0.0f, 0.0f, 0.0f, 0.0f),
260       mFirstTouchPos( 0.0f, 0.0f ),
261       mLastTouchPos( 0.0f, 0.0f ),
262       mCardDuration( 0.0f ),
263       mDuration( 0.0f ),
264       mLoadingTime( 0.0f ),
265       mLoadingCount( 0 ),
266       mLoadingCountScale( 0 ),
267       mTickCount( 0 ),
268       mCancelSignal( false ),
269       mIsTouchedActor( false )
270   {
271     // Connect to the Application's Init signal
272     mApplication.InitSignal().Connect( this, &CardController::Create );
273   }
274
275   ~CardController()
276   {
277     // Nothing to do here;
278   }
279
280   // The Init signal is received once (only) during the Application lifetime
281   void Create(Application& application)
282   {
283     // Get a handle to the window
284     mWindow = application.GetWindow();
285     mWindow.KeyEventSignal().Connect( this, &CardController::OnKeyEvent );
286
287     // Get current device's width and height.
288     const Window::WindowSize windowSize = mWindow.GetSize();
289     WINDOW_SIZE = Vector2(windowSize.GetWidth(), windowSize.GetHeight() );
290     SCALED_WINDOW_SIZE = WINDOW_SIZE / 360.0f;
291     SCALED_WINDOW_SIZE_3 = Vector3( SCALED_WINDOW_SIZE.x, SCALED_WINDOW_SIZE.y, 0.0f );
292     SCALED_WIDTH = SCALED_WINDOW_SIZE.x < SCALED_WINDOW_SIZE.y ? SCALED_WINDOW_SIZE.x : SCALED_WINDOW_SIZE.y;
293     SCALED_HEIGHT = SCALED_WIDTH;
294
295     // Note that this is heuristic value
296     FONT_SCALE = 0.25f * WINDOW_SIZE.y / WINDOW_SIZE.x;
297
298     mBackground = Control::New();
299     mBackground.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
300     mBackground.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
301     mBackground.SetProperty( Actor::Property::SIZE, WINDOW_SIZE );
302
303     mWindow.Add( mBackground );
304
305     BuildParameter();
306     InitMap();
307     SetupCards();
308     SetupActors();
309     SetupAnimation();
310
311     mWindow.GetRootLayer().TouchSignal().Connect( this, &CardController::OnTouchLayer );
312     Reset();
313   }
314
315   bool OnTouchCards(Actor actor, const TouchEvent &data)
316   {
317     if( data.GetPointCount() > 0 )
318     {
319       if( data.GetState( 0 ) == PointState::DOWN )
320       {
321         if( mCards.mCurState == 0 )
322         {
323           mIsTouchedActor = false;
324           if( mCards[mCards.mCurIndex] == actor )
325           {
326             mIsTouchedActor = true;
327           }
328           mCards.mCurState = 3;
329           mTempTimer = Timer::New( PSEUDO_SCROLL_TIME );
330           mTempTimer.TickSignal().Connect( this, &CardController::OnDetectMotionLayer );
331           mTempTimer.Start();
332
333           mFirstTouchPos = data.GetScreenPosition( 0 );
334           mLastTouchPos = mFirstTouchPos;
335         }
336         else if( mCards.mCurState == 1 )
337         {
338           mCancelSignal = true;
339           return false;
340         }
341       }
342       else
343       {
344         mLastTouchPos = data.GetScreenPosition( 0 );
345       }
346     }
347     return true;
348   }
349
350   bool OnTouchLayer(Actor actor, const TouchEvent &data)
351   {
352     if( data.GetPointCount() > 0 )
353     {
354       if( data.GetState( 0 ) == PointState::DOWN )
355       {
356         if( mCards.mCurState == 0 )
357         {
358           mIsTouchedActor = false;
359           mCards.mCurState = 3;
360           mTempTimer = Timer::New( PSEUDO_SCROLL_TIME );
361           mTempTimer.TickSignal().Connect( this, &CardController::OnDetectMotionLayer );
362           mTempTimer.Start();
363
364           mFirstTouchPos = data.GetScreenPosition( 0 );
365           mLastTouchPos = mFirstTouchPos;
366         }
367       }
368       else
369       {
370         mLastTouchPos = data.GetScreenPosition( 0 );
371       }
372     }
373     return true;
374   }
375
376   // Heuristic Scroll View
377   bool OnDetectMotionLayer()
378   {
379     if( mCards.mCurState == 3 )
380     {
381       Vector2 diff = (mLastTouchPos - mFirstTouchPos);
382       float offset = PSEUDO_SCROLL_OFFSET;
383       const float windowWidth = mWindow.GetSize().GetWidth();
384       // Scroll to right
385       if( diff.x > windowWidth * offset )
386       {
387         mCards.mCurState = 2;
388         MoveRight();
389         mCardChanger = Timer::New( mCardDuration * 1000.0f );
390         mCardChanger.TickSignal().Connect( this, &CardController::OnTickLayer );
391         mCardChanger.Start();
392       }
393       // Scroll to left
394       else if( diff.x < -windowWidth * offset )
395       {
396         mCards.mCurState = 2;
397         MoveLeft();
398         mCardChanger = Timer::New( mCardDuration * 1000.0f );
399         mCardChanger.TickSignal().Connect( this, &CardController::OnTickLayer );
400         mCardChanger.Start();
401       }
402       // Not a scroll input
403       else
404       {
405         // Run NFC Tag effect if we touch a card
406         if (mIsTouchedActor)
407         {
408           mCards.mCurState = 1;
409           RunAnimation( mCards.mCurIndex );
410         }
411         else
412         {
413           Reset();
414         }
415       }
416     }
417     return false;
418   }
419
420   bool OnTickLayer()
421   {
422     Reset();
423     return false;
424   }
425
426   void OnKeyEvent(const KeyEvent& event)
427   {
428     if( event.GetState() == KeyEvent::DOWN )
429     {
430       if( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) )
431       {
432         mApplication.Quit();
433       }
434     }
435   }
436
437 private:
438
439   // Utility function to make animation parameter map. return Property::Map
440   Property::Value BuildMap(const Property::Value &start, const Property::Value &target, int dir, float duration, float delay, int repeat, float repeat_delay, int motion, int easing)
441   {
442     Property::Map map;
443
444     map.Clear();
445     map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::START, start );
446     map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET, target );
447     if( dir == 0 )
448     {
449       map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD );
450     }
451     else
452     {
453       map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, DevelAnimatedGradientVisual::AnimationParameter::DirectionType::BACKWARD );
454     }
455     map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION, duration );
456     map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY, delay );
457     map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT, repeat );
458     map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY, repeat_delay );
459     if( motion == 0 )
460     {
461       map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE, DevelAnimatedGradientVisual::AnimationParameter::MotionType::LOOP );
462     }
463     else
464     {
465       map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE, DevelAnimatedGradientVisual::AnimationParameter::MotionType::MIRROR );
466     }
467     if( easing == 0 )
468     {
469       map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::LINEAR );
470     }
471     else if( easing == 1 )
472     {
473       map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN );
474     }
475     else if( easing == 2 )
476     {
477       map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::OUT );
478     }
479     else
480     {
481       map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN_OUT );
482     }
483
484     return Property::Value( map );
485   }
486
487   // Setup background visual property during nothing action
488   void InitMapNormal()
489   {
490     mBackgroundNormalMap.Clear();
491     mBackgroundNormalMap.Insert( Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT );
492
493     mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION, Vector2( -0.5, -0.5 ) );
494     mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION, Vector2( 0.5, 0.5 ) );
495     mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR, mNormalColor );
496     mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR, mNormalColor );
497     mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER, Vector2( 0.0f, 0.0f ) );
498     mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, 0.0f );
499     mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::OFFSET, 0.0f );
500   }
501
502   // Setup background visual property during NFC tagging start
503   void InitMapStart()
504   {
505     mBackgroundMapStart.Clear();
506     mBackgroundMapStart.Insert( Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT );
507
508     mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION, Vector2( -0.5, -0.5 ) );
509     mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION, Vector2( 0.5, 0.5 ) );
510     mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR, mNormalColor );
511     mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR, mNormalColor );
512     mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER, Vector2( 0.0f, 0.0f ) );
513     mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, 0.0f );
514     mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::OFFSET, BuildMap( 0.0f, 2.0f, 0, mLoadingTime, 0.0f, -1, 0.0f, 0, 0 ) );
515
516     mColorAnimationStartStart = *( BuildMap( mNormalColor, Vector4( 0, 0, 0, 0 ), 0, mDuration, 0.0f, 1, 0.0f, 0, 0 ).GetMap() );
517     mColorAnimationStartEnd = *( BuildMap( mNormalColor, Vector4( 0, 0, 0, 0 ), 0, mDuration, 0.0f, 1, 0.0f, 0, 0 ).GetMap() );
518   }
519
520   // Setup background visual property during NFC tagging end
521   void InitMapEnd()
522   {
523     mBackgroundMapEnd.Clear();
524     mBackgroundMapEnd.Insert( Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT );
525
526     mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION, Vector2( -0.5, -0.5 ) );
527     mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION, Vector2( 0.5, 0.5 ) );
528     mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR, mNormalColor );
529     mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR, mNormalColor );
530     mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER, Vector2( 0.0f, 0.0f ) );
531     mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, 0.0f );
532     mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::OFFSET, BuildMap( 0.0f, 2.0f, 0, mLoadingTime, 0.0f, -1, 0.0f, 0, 0 ) );
533
534     mColorAnimationEndStart = *( BuildMap( mNormalColor, Vector4( 0, 0, 0, 0 ), 1, mDuration, 0.0f, 1, 0.0f, 0, 0 ).GetMap() );
535     mColorAnimationEndEnd = *( BuildMap( mNormalColor, Vector4( 0, 0, 0, 0 ), 1, mDuration, 0.0f, 1, 0.0f, 0, 0 ).GetMap() );
536   }
537
538   // Setup background visual property during card change
539   void InitMapMove()
540   {
541     mBackgroundMapMove.Clear();
542     mBackgroundMapMove.Insert( Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT);
543     mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::SPREAD_TYPE, Toolkit::DevelAnimatedGradientVisual::SpreadType::CLAMP);
544
545     mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION, Vector2( -0.5, 0.0 ) );
546     mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION, Vector2( 0.5, 0.0 ) );
547     mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR, mNormalStartColor );
548     mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR, mNormalEndColor );
549     mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER, Vector2( 0.0f, 0.0f ) );
550     mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, 0.0f );
551     mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::OFFSET, BuildMap( -1.0f, 1.0f, 0, mCardDuration, 0.0f, 1, 0.0f, 0, 2 ) );
552   }
553
554   void InitMap()
555   {
556     InitMapNormal();
557     InitMapStart();
558     InitMapEnd();
559     InitMapMove();
560   }
561
562   // Setup const parameter values
563   void BuildParameter()
564   {
565     mNormalColor = DEFAULT_COLOR;
566     mCardDuration = CARD_MOVE_DURATION;
567     mDuration = CHANGE_DURATION;
568     mLoadingTime = LOADING_ONE_CYCLE_DURATION;
569     mLoadingCount = LOADING_CYCLE_CNT;
570     mLoadingCountScale = LOADING_CYCLE_DT;
571
572     mNormalStartColor = mNormalColor;
573     mNormalEndColor = mNormalColor;
574   }
575
576   void BuildAnimation()
577   {
578     InitMap();
579   }
580
581   void SetupCards()
582   {
583     mCards.Init( mWindow );
584     for( int k = 0; k < CARD_NUM; k++ )
585     {
586       mCards[k].TouchSignal().Connect( this, &CardController::OnTouchCards );
587     }
588     mNormalStartColor = mCards.GetColorBackground( mCards.mCurIndex );
589     mNormalEndColor = mCards.GetColorBackground( mCards.mCurIndex );
590   }
591
592   // Create and Add to window
593   void SetupActors()
594   {
595     mAddButton = ImageView::New();
596     mAddButton.SetImage( BUTTON_ADD_IMAGE );
597     mAddButton.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER );
598     mAddButton.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER );
599     mAddButton.SetProperty( Actor::Property::SIZE, BUTTON_ADD_SIZE * SCALED_WIDTH );
600     mAddButton.SetProperty( Actor::Property::POSITION, BUTTON_ADD_POSITION * SCALED_WIDTH );
601
602     mLabel1 = TextLabel::New( LABEL_TICKET_STR );
603     mLabel1.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER );
604     mLabel1.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER );
605     mLabel1.SetProperty( Actor::Property::SIZE, LABEL_TICKET_SIZE * SCALED_WIDTH );
606     mLabel1.SetProperty( Actor::Property::POSITION, LABEL_TICKET_POSITION * SCALED_WIDTH );
607     mLabel1.SetProperty( Actor::Property::VISIBLE, true );
608     mLabel1.SetProperty( TextLabel::Property::TEXT_COLOR, LABEL_TICKET_FONT_COLOR );
609     mLabel1.SetProperty( TextLabel::Property::POINT_SIZE, LABEL_TICKET_FONT_SIZE * FONT_SCALE );
610     mLabel1.SetProperty( TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
611     mLabel1.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
612
613     mLabel2 = TextLabel::New( LABEL_HOLD_STR );
614     mLabel2.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
615     mLabel2.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
616     mLabel2.SetProperty( Actor::Property::SIZE, LABEL_HOLD_SIZE * SCALED_WIDTH );
617     mLabel2.SetProperty( Actor::Property::POSITION, LABEL_HOLD_POSITION * SCALED_WIDTH );
618     mLabel2.SetProperty( Actor::Property::VISIBLE, false );
619     mLabel2.SetProperty( TextLabel::Property::TEXT_COLOR, LABEL_HOLD_FONT_COLOR );
620     mLabel2.SetProperty( TextLabel::Property::POINT_SIZE, LABEL_HOLD_FONT_SIZE * FONT_SCALE );
621     mLabel2.SetProperty( TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
622     mLabel2.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
623
624     mLabel3 = TextLabel::New( LABEL_TERMINAL_STR );
625     mLabel3.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
626     mLabel3.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
627     mLabel3.SetProperty( Actor::Property::SIZE, LABEL_TERMINAL_SIZE * SCALED_WIDTH );
628     mLabel3.SetProperty( Actor::Property::POSITION, LABEL_TERMINAL_POSITION * SCALED_WIDTH );
629     mLabel3.SetProperty( Actor::Property::VISIBLE, false );
630     mLabel3.SetProperty( TextLabel::Property::TEXT_COLOR, LABEL_TERMINAL_FONT_COLOR );
631     mLabel3.SetProperty( TextLabel::Property::POINT_SIZE, LABEL_TERMINAL_FONT_SIZE * FONT_SCALE );
632     mLabel3.SetProperty( TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
633     mLabel3.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
634
635     mWindow.Add( mAddButton );
636     mWindow.Add( mLabel1 );
637     mWindow.Add( mLabel2 );
638     mWindow.Add( mLabel3 );
639   }
640
641   void SetupAnimation()
642   {
643     mMoveFront = Animation::New( mDuration );
644     mMoveBack = Animation::New( mDuration );
645   }
646
647   // Run animations when 'index' card active
648   void RunAnimation(int index)
649   {
650     //set animated background color here
651     mColorAnimationStartStart[DevelAnimatedGradientVisual::AnimationParameter::Property::START] = mNormalStartColor;
652     mColorAnimationStartEnd[DevelAnimatedGradientVisual::AnimationParameter::Property::START] = mNormalStartColor;
653     mColorAnimationEndStart[DevelAnimatedGradientVisual::AnimationParameter::Property::START] = mNormalStartColor;
654     mColorAnimationEndEnd[DevelAnimatedGradientVisual::AnimationParameter::Property::START] = mNormalStartColor;
655
656     mColorAnimationStartStart[DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET] = mCards.GetColorStart( index );
657     mColorAnimationStartEnd[DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET] = mCards.GetColorEnd( index );
658     mColorAnimationEndStart[DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET] = mCards.GetColorStart( index );
659     mColorAnimationEndEnd[DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET] = mCards.GetColorEnd( index );
660
661     mBackgroundMapStart[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR] = mColorAnimationStartStart;
662     mBackgroundMapStart[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR] = mColorAnimationStartEnd;
663     mBackgroundMapEnd[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR] = mColorAnimationEndStart;
664     mBackgroundMapEnd[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR] = mColorAnimationEndEnd;
665
666     if( index == 1 )
667     {
668       // Rotate background gradient
669       mBackgroundMapStart[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT] = BuildMap( 0.0f, Math::PI * 2.0f, 0, mLoadingTime, 0.0f, -1, 0.0f, 0, 0 );
670     }
671     else if( index == 2 )
672     {
673       // Rotate background gradient more slow
674       mBackgroundMapStart[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT] = BuildMap( 0.0f, Math::PI * 2.0f, 0, mLoadingTime * 2.0, 0.0f, -1, 0.0f, 0, 0 );
675     }
676     else
677     {
678       mBackgroundMapStart[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT] = 0.0f;
679     }
680
681     mBackground.SetProperty( Control::Property::BACKGROUND, mBackgroundMapStart );
682
683     mTickCount = 0;
684     mBackgroundChanger = Timer::New( mLoadingTime * 1000.0f / mLoadingCountScale );
685     mBackgroundChanger.TickSignal().Connect( this, &CardController::OnTickBackground );
686     mBackgroundChanger.Start();
687
688     mMoveFront.AnimateTo( Property( mCards[index], Actor::Property::SIZE_WIDTH ), CARD_SIZE_BIG.x * SCALED_WIDTH );
689     mMoveFront.AnimateTo( Property( mCards[index], Actor::Property::SIZE_HEIGHT ), CARD_SIZE_BIG.y * SCALED_HEIGHT );
690     mMoveFront.AnimateTo( Property( mCards[index], Actor::Property::POSITION_Y ), CARD_BIG_OFFSET.y * SCALED_HEIGHT );
691     mMoveBack.AnimateTo( Property( mCards[index], Actor::Property::SIZE_WIDTH ), CARD_SIZE.x * SCALED_WIDTH );
692     mMoveBack.AnimateTo( Property( mCards[index], Actor::Property::SIZE_HEIGHT ), CARD_SIZE.y * SCALED_HEIGHT );
693     mMoveBack.AnimateTo( Property( mCards[index], Actor::Property::POSITION_Y ), CARD_OFFSET.y * SCALED_HEIGHT );
694     for( int i = 0; i < index; i++ )
695     {
696       mMoveFront.AnimateBy( Property( mCards[i], Actor::Property::POSITION_X ), -CARD_MOVE_DIST * SCALED_WIDTH );
697       mMoveBack.AnimateBy( Property( mCards[i], Actor::Property::POSITION_X ), CARD_MOVE_DIST * SCALED_WIDTH );
698     }
699     for( int i = index + 1; i < CARD_NUM; i++ )
700     {
701       mMoveFront.AnimateBy( Property( mCards[i], Actor::Property::POSITION_X ), CARD_MOVE_DIST * SCALED_WIDTH );
702       mMoveBack.AnimateBy( Property( mCards[i], Actor::Property::POSITION_X ), -CARD_MOVE_DIST * SCALED_WIDTH );
703     }
704     mMoveFront.AnimateTo( Property( mAddButton, Actor::Property::POSITION_Y ), BUTTON_ADD_SIZE.y * SCALED_HEIGHT );
705     mMoveBack.AnimateTo( Property( mAddButton, Actor::Property::POSITION_Y ), 0.f * SCALED_HEIGHT );
706
707     mMoveFront.AnimateTo( Property( mLabel1, Actor::Property::VISIBLE), false );
708     mMoveFront.AnimateTo( Property( mLabel2, Actor::Property::VISIBLE), true );
709     mMoveFront.AnimateTo( Property( mLabel3, Actor::Property::VISIBLE), true );
710     mMoveBack.AnimateTo( Property( mLabel1, Actor::Property::VISIBLE), true );
711     mMoveBack.AnimateTo( Property( mLabel2, Actor::Property::VISIBLE), false );
712     mMoveBack.AnimateTo( Property( mLabel3, Actor::Property::VISIBLE), false );
713
714     mMoveFront.Play();
715   }
716   bool OnTickBackground()
717   {
718     mTickCount++;
719     if( mCancelSignal || mTickCount >= mLoadingCount * mLoadingCountScale )
720     {
721       if( mCards.mCurState == 1 )
722       {
723         mCards.mCurState = 2;
724         mBackground.SetProperty( Control::Property::BACKGROUND, mBackgroundMapEnd );
725         mMoveBack.Play();
726         mBackgroundChanger.SetInterval( mDuration * 1000.0f );
727         return true;
728       }
729       else
730       {
731         Reset();
732         return false;
733       }
734     }
735     return true;
736   }
737   void MoveRight()
738   {
739     if( mCards.MoveRight( mCardDuration ) )
740     {
741       // Set smooth background color change here
742       mNormalEndColor = mCards.GetColorBackground( mCards.mCurIndex );
743       mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR] = mNormalEndColor;
744       mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR] = mNormalStartColor;
745
746       (*mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::OFFSET].GetMap())[DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION] = Property::Value( DevelAnimatedGradientVisual::AnimationParameter::DirectionType::BACKWARD );
747
748       mBackground.SetProperty( Control::Property::BACKGROUND, mBackgroundMapMove );
749     }
750   }
751   void MoveLeft()
752   {
753     if( mCards.MoveLeft( mCardDuration ) )
754     {
755       //Set smooth background color change here
756       mNormalEndColor = mCards.GetColorBackground( mCards.mCurIndex );
757       mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR] = mNormalStartColor;
758       mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR] = mNormalEndColor;
759
760       (*mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::OFFSET].GetMap())[DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION] = Property::Value( DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD );
761
762       mBackground.SetProperty( Control::Property::BACKGROUND, mBackgroundMapMove );
763     }
764   }
765
766   void Reset()
767   {
768     mCards.mCurState = 0;
769     mCancelSignal = false;
770     mMoveFront.Clear();
771     mMoveBack.Clear();
772
773     mNormalStartColor = mNormalEndColor;
774     mBackgroundNormalMap[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR] = mNormalStartColor;
775     mBackgroundNormalMap[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR] = mNormalEndColor;
776     mBackground.SetProperty(Control::Property::BACKGROUND, mBackgroundNormalMap);
777   }
778
779 private:
780   Application&  mApplication;
781   Window mWindow;
782
783   CardManager mCards;
784
785   Control mBackground;
786
787   ImageView mAddButton;
788   TextLabel mLabel1;
789   TextLabel mLabel2;
790   TextLabel mLabel3;
791
792   Timer mBackgroundChanger;
793   Timer mCardChanger;
794   Timer mTempTimer;
795
796   Animation mMoveFront;
797   Animation mMoveBack;
798
799   // Property for background animated gradient visual
800   Property::Map mBackgroundNormalMap;
801   Property::Map mBackgroundMapStart;
802   Property::Map mBackgroundMapEnd;
803   Property::Map mBackgroundMapMove;
804
805   // Property for animation of color in animated gradient visual
806   Property::Map mColorAnimationStartStart;
807   Property::Map mColorAnimationStartEnd;
808   Property::Map mColorAnimationEndStart;
809   Property::Map mColorAnimationEndEnd;
810
811   Vector4 mNormalColor;
812   Vector4 mNormalStartColor;
813   Vector4 mNormalEndColor;
814
815   Vector2 mFirstTouchPos;
816   Vector2 mLastTouchPos;
817
818   float mCardDuration;
819   float mDuration;
820   float mLoadingTime;
821   int mLoadingCount;
822   int mLoadingCountScale;
823   int mTickCount;
824
825   bool mCancelSignal;
826   bool mIsTouchedActor;
827 };
828
829 int DALI_EXPORT_API main(int argc, char **argv)
830 {
831   Application application = Application::New( &argc, &argv );
832
833   CardController test( application );
834
835   application.MainLoop();
836
837   return 0;
838 }