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