Revert "Revert "Change fitting mode to match previous behaviour.""
[platform/core/uifw/dali-demo.git] / examples / animated-gradient-card-active / animated-gradient-card-active.cpp
1 /*
2 * Copyright (c) 2018 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 STAGE_SIZE = Vector2( 360.0f, 360.0f );
34 Vector2 SCALED_STAGE_SIZE = Vector2( 1.0f, 1.0f );
35 Vector3 SCALED_STAGE_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(Stage& stage)
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].SetParentOrigin( ParentOrigin::CENTER );
155       mCard[k].SetAnchorPoint( AnchorPoint::CENTER );
156       mCard[k].SetSize( mSize.x, mSize.y );
157       mCard[k].SetPosition( mPosition[k].x, mPosition[k].y );
158
159       stage.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 stage
284     mStage = Stage::GetCurrent();
285     mStage.KeyEventSignal().Connect( this, &CardController::OnKeyEvent );
286
287     // Get current device's width and height.
288     STAGE_SIZE = mStage.GetSize();
289     SCALED_STAGE_SIZE = STAGE_SIZE / 360.0f;
290     SCALED_STAGE_SIZE_3 = Vector3( SCALED_STAGE_SIZE.x, SCALED_STAGE_SIZE.y, 0.0f );
291     SCALED_WIDTH = SCALED_STAGE_SIZE.x < SCALED_STAGE_SIZE.y ? SCALED_STAGE_SIZE.x : SCALED_STAGE_SIZE.y;
292     SCALED_HEIGHT = SCALED_WIDTH;
293
294     // Note that this is heuristic value
295     FONT_SCALE = 0.25f * STAGE_SIZE.y / STAGE_SIZE.x;
296
297     mBackground = Control::New();
298     mBackground.SetParentOrigin( ParentOrigin::CENTER );
299     mBackground.SetAnchorPoint( AnchorPoint::CENTER );
300     mBackground.SetSize( STAGE_SIZE );
301
302     mStage.Add( mBackground );
303
304     BuildParameter();
305     InitMap();
306     SetupCards();
307     SetupActors();
308     SetupAnimation();
309
310     mStage.GetRootLayer().TouchSignal().Connect( this, &CardController::OnTouchLayer );
311     Reset();
312   }
313
314   bool OnTouchCards(Actor actor, const TouchData &data)
315   {
316     if( data.GetPointCount() > 0 )
317     {
318       if( data.GetState( 0 ) == PointState::DOWN )
319       {
320         if( mCards.mCurState == 0 )
321         {
322           mIsTouchedActor = false;
323           if( mCards[mCards.mCurIndex] == actor )
324           {
325             mIsTouchedActor = true;
326           }
327           mCards.mCurState = 3;
328           mTempTimer = Timer::New( PSEUDO_SCROLL_TIME );
329           mTempTimer.TickSignal().Connect( this, &CardController::OnDetectMotionLayer );
330           mTempTimer.Start();
331
332           mFirstTouchPos = data.GetScreenPosition( 0 );
333           mLastTouchPos = mFirstTouchPos;
334         }
335         else if( mCards.mCurState == 1 )
336         {
337           mCancelSignal = true;
338           return false;
339         }
340       }
341       else
342       {
343         mLastTouchPos = data.GetScreenPosition( 0 );
344       }
345     }
346     return true;
347   }
348
349   bool OnTouchLayer(Actor actor, const TouchData &data)
350   {
351     if( data.GetPointCount() > 0 )
352     {
353       if( data.GetState( 0 ) == PointState::DOWN )
354       {
355         if( mCards.mCurState == 0 )
356         {
357           mIsTouchedActor = false;
358           mCards.mCurState = 3;
359           mTempTimer = Timer::New( PSEUDO_SCROLL_TIME );
360           mTempTimer.TickSignal().Connect( this, &CardController::OnDetectMotionLayer );
361           mTempTimer.Start();
362
363           mFirstTouchPos = data.GetScreenPosition( 0 );
364           mLastTouchPos = mFirstTouchPos;
365         }
366       }
367       else
368       {
369         mLastTouchPos = data.GetScreenPosition( 0 );
370       }
371     }
372     return true;
373   }
374
375   // Heuristic Scroll View
376   bool OnDetectMotionLayer()
377   {
378     if( mCards.mCurState == 3 )
379     {
380       Vector2 diff = (mLastTouchPos - mFirstTouchPos);
381       float offset = PSEUDO_SCROLL_OFFSET;
382       // Scroll to right
383       if( diff.x > mStage.GetSize().x * offset )
384       {
385         mCards.mCurState = 2;
386         MoveRight();
387         mCardChanger = Timer::New( mCardDuration * 1000.0f );
388         mCardChanger.TickSignal().Connect( this, &CardController::OnTickLayer );
389         mCardChanger.Start();
390       }
391       // Scroll to left
392       else if( diff.x < -mStage.GetSize().x * offset )
393       {
394         mCards.mCurState = 2;
395         MoveLeft();
396         mCardChanger = Timer::New( mCardDuration * 1000.0f );
397         mCardChanger.TickSignal().Connect( this, &CardController::OnTickLayer );
398         mCardChanger.Start();
399       }
400       // Not a scroll input
401       else
402       {
403         // Run NFC Tag effect if we touch a card
404         if (mIsTouchedActor)
405         {
406           mCards.mCurState = 1;
407           RunAnimation( mCards.mCurIndex );
408         }
409         else
410         {
411           Reset();
412         }
413       }
414     }
415     return false;
416   }
417
418   bool OnTickLayer()
419   {
420     Reset();
421     return false;
422   }
423
424   void OnKeyEvent(const KeyEvent& event)
425   {
426     if( event.state == KeyEvent::Down )
427     {
428       if( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) )
429       {
430         mApplication.Quit();
431       }
432     }
433   }
434
435 private:
436
437   // Utility function to make animation parameter map. return Property::Map
438   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)
439   {
440     Property::Map map;
441
442     map.Clear();
443     map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::START, start );
444     map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET, target );
445     if( dir == 0 )
446     {
447       map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD );
448     }
449     else
450     {
451       map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION, DevelAnimatedGradientVisual::AnimationParameter::DirectionType::BACKWARD );
452     }
453     map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::DURATION, duration );
454     map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::DELAY, delay );
455     map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT, repeat );
456     map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::REPEAT_DELAY, repeat_delay );
457     if( motion == 0 )
458     {
459       map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE, DevelAnimatedGradientVisual::AnimationParameter::MotionType::LOOP );
460     }
461     else
462     {
463       map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::MOTION_TYPE, DevelAnimatedGradientVisual::AnimationParameter::MotionType::MIRROR );
464     }
465     if( easing == 0 )
466     {
467       map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::LINEAR );
468     }
469     else if( easing == 1 )
470     {
471       map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN );
472     }
473     else if( easing == 2 )
474     {
475       map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::OUT );
476     }
477     else
478     {
479       map.Insert( DevelAnimatedGradientVisual::AnimationParameter::Property::EASING_TYPE, DevelAnimatedGradientVisual::AnimationParameter::EasingType::IN_OUT );
480     }
481
482     return Property::Value( map );
483   }
484
485   // Setup background visual property during nothing action
486   void InitMapNormal()
487   {
488     mBackgroundNormalMap.Clear();
489     mBackgroundNormalMap.Insert( Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT );
490
491     mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION, Vector2( -0.5, -0.5 ) );
492     mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION, Vector2( 0.5, 0.5 ) );
493     mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR, mNormalColor );
494     mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR, mNormalColor );
495     mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER, Vector2( 0.0f, 0.0f ) );
496     mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, 0.0f );
497     mBackgroundNormalMap.Insert( Toolkit::DevelAnimatedGradientVisual::Property::OFFSET, 0.0f );
498   }
499
500   // Setup background visual property during NFC tagging start
501   void InitMapStart()
502   {
503     mBackgroundMapStart.Clear();
504     mBackgroundMapStart.Insert( Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT );
505
506     mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION, Vector2( -0.5, -0.5 ) );
507     mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION, Vector2( 0.5, 0.5 ) );
508     mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR, mNormalColor );
509     mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR, mNormalColor );
510     mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER, Vector2( 0.0f, 0.0f ) );
511     mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, 0.0f );
512     mBackgroundMapStart.Insert( Toolkit::DevelAnimatedGradientVisual::Property::OFFSET, BuildMap( 0.0f, 2.0f, 0, mLoadingTime, 0.0f, -1, 0.0f, 0, 0 ) );
513
514     mColorAnimationStartStart = *( BuildMap( mNormalColor, Vector4( 0, 0, 0, 0 ), 0, mDuration, 0.0f, 1, 0.0f, 0, 0 ).GetMap() );
515     mColorAnimationStartEnd = *( BuildMap( mNormalColor, Vector4( 0, 0, 0, 0 ), 0, mDuration, 0.0f, 1, 0.0f, 0, 0 ).GetMap() );
516   }
517
518   // Setup background visual property during NFC tagging end
519   void InitMapEnd()
520   {
521     mBackgroundMapEnd.Clear();
522     mBackgroundMapEnd.Insert( Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT );
523
524     mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION, Vector2( -0.5, -0.5 ) );
525     mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION, Vector2( 0.5, 0.5 ) );
526     mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR, mNormalColor );
527     mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR, mNormalColor );
528     mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER, Vector2( 0.0f, 0.0f ) );
529     mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, 0.0f );
530     mBackgroundMapEnd.Insert( Toolkit::DevelAnimatedGradientVisual::Property::OFFSET, BuildMap( 0.0f, 2.0f, 0, mLoadingTime, 0.0f, -1, 0.0f, 0, 0 ) );
531
532     mColorAnimationEndStart = *( BuildMap( mNormalColor, Vector4( 0, 0, 0, 0 ), 1, mDuration, 0.0f, 1, 0.0f, 0, 0 ).GetMap() );
533     mColorAnimationEndEnd = *( BuildMap( mNormalColor, Vector4( 0, 0, 0, 0 ), 1, mDuration, 0.0f, 1, 0.0f, 0, 0 ).GetMap() );
534   }
535
536   // Setup background visual property during card change
537   void InitMapMove()
538   {
539     mBackgroundMapMove.Clear();
540     mBackgroundMapMove.Insert( Visual::Property::TYPE, DevelVisual::ANIMATED_GRADIENT);
541     mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::SPREAD_TYPE, Toolkit::DevelAnimatedGradientVisual::SpreadType::CLAMP);
542
543     mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_POSITION, Vector2( -0.5, 0.0 ) );
544     mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_POSITION, Vector2( 0.5, 0.0 ) );
545     mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR, mNormalStartColor );
546     mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR, mNormalEndColor );
547     mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_CENTER, Vector2( 0.0f, 0.0f ) );
548     mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT, 0.0f );
549     mBackgroundMapMove.Insert( Toolkit::DevelAnimatedGradientVisual::Property::OFFSET, BuildMap( -1.0f, 1.0f, 0, mCardDuration, 0.0f, 1, 0.0f, 0, 2 ) );
550   }
551
552   void InitMap()
553   {
554     InitMapNormal();
555     InitMapStart();
556     InitMapEnd();
557     InitMapMove();
558   }
559
560   // Setup const parameter values
561   void BuildParameter()
562   {
563     mNormalColor = DEFAULT_COLOR;
564     mCardDuration = CARD_MOVE_DURATION;
565     mDuration = CHANGE_DURATION;
566     mLoadingTime = LOADING_ONE_CYCLE_DURATION;
567     mLoadingCount = LOADING_CYCLE_CNT;
568     mLoadingCountScale = LOADING_CYCLE_DT;
569
570     mNormalStartColor = mNormalColor;
571     mNormalEndColor = mNormalColor;
572   }
573
574   void BuildAnimation()
575   {
576     InitMap();
577   }
578
579   void SetupCards()
580   {
581     mCards.Init( mStage );
582     for( int k = 0; k < CARD_NUM; k++ )
583     {
584       mCards[k].TouchSignal().Connect( this, &CardController::OnTouchCards );
585     }
586     mNormalStartColor = mCards.GetColorBackground( mCards.mCurIndex );
587     mNormalEndColor = mCards.GetColorBackground( mCards.mCurIndex );
588   }
589
590   // Create and Add to stage
591   void SetupActors()
592   {
593     mAddButton = ImageView::New();
594     mAddButton.SetImage( BUTTON_ADD_IMAGE );
595     mAddButton.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
596     mAddButton.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
597     mAddButton.SetSize( BUTTON_ADD_SIZE * SCALED_WIDTH );
598     mAddButton.SetPosition( BUTTON_ADD_POSITION * SCALED_WIDTH );
599
600     mLabel1 = TextLabel::New( LABEL_TICKET_STR );
601     mLabel1.SetParentOrigin( ParentOrigin::TOP_CENTER );
602     mLabel1.SetAnchorPoint( AnchorPoint::TOP_CENTER );
603     mLabel1.SetSize( LABEL_TICKET_SIZE * SCALED_WIDTH );
604     mLabel1.SetPosition( LABEL_TICKET_POSITION * SCALED_WIDTH );
605     mLabel1.SetVisible( true );
606     mLabel1.SetProperty( TextLabel::Property::TEXT_COLOR, LABEL_TICKET_FONT_COLOR );
607     mLabel1.SetProperty( TextLabel::Property::POINT_SIZE, LABEL_TICKET_FONT_SIZE * FONT_SCALE );
608     mLabel1.SetProperty( TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
609     mLabel1.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
610
611     mLabel2 = TextLabel::New( LABEL_HOLD_STR );
612     mLabel2.SetParentOrigin( ParentOrigin::CENTER );
613     mLabel2.SetAnchorPoint( AnchorPoint::CENTER );
614     mLabel2.SetSize( LABEL_HOLD_SIZE * SCALED_WIDTH );
615     mLabel2.SetPosition( LABEL_HOLD_POSITION * SCALED_WIDTH );
616     mLabel2.SetVisible( false );
617     mLabel2.SetProperty( TextLabel::Property::TEXT_COLOR, LABEL_HOLD_FONT_COLOR );
618     mLabel2.SetProperty( TextLabel::Property::POINT_SIZE, LABEL_HOLD_FONT_SIZE * FONT_SCALE );
619     mLabel2.SetProperty( TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
620     mLabel2.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
621
622     mLabel3 = TextLabel::New( LABEL_TERMINAL_STR );
623     mLabel3.SetParentOrigin( ParentOrigin::CENTER );
624     mLabel3.SetAnchorPoint( AnchorPoint::CENTER );
625     mLabel3.SetSize( LABEL_TERMINAL_SIZE * SCALED_WIDTH );
626     mLabel3.SetPosition( LABEL_TERMINAL_POSITION * SCALED_WIDTH );
627     mLabel3.SetVisible( false );
628     mLabel3.SetProperty( TextLabel::Property::TEXT_COLOR, LABEL_TERMINAL_FONT_COLOR );
629     mLabel3.SetProperty( TextLabel::Property::POINT_SIZE, LABEL_TERMINAL_FONT_SIZE * FONT_SCALE );
630     mLabel3.SetProperty( TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
631     mLabel3.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
632
633     mStage.Add( mAddButton );
634     mStage.Add( mLabel1 );
635     mStage.Add( mLabel2 );
636     mStage.Add( mLabel3 );
637   }
638
639   void SetupAnimation()
640   {
641     mMoveFront = Animation::New( mDuration );
642     mMoveBack = Animation::New( mDuration );
643   }
644
645   // Run animations when 'index' card active
646   void RunAnimation(int index)
647   {
648     //set animated background color here
649     mColorAnimationStartStart[DevelAnimatedGradientVisual::AnimationParameter::Property::START] = mNormalStartColor;
650     mColorAnimationStartEnd[DevelAnimatedGradientVisual::AnimationParameter::Property::START] = mNormalStartColor;
651     mColorAnimationEndStart[DevelAnimatedGradientVisual::AnimationParameter::Property::START] = mNormalStartColor;
652     mColorAnimationEndEnd[DevelAnimatedGradientVisual::AnimationParameter::Property::START] = mNormalStartColor;
653
654     mColorAnimationStartStart[DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET] = mCards.GetColorStart( index );
655     mColorAnimationStartEnd[DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET] = mCards.GetColorEnd( index );
656     mColorAnimationEndStart[DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET] = mCards.GetColorStart( index );
657     mColorAnimationEndEnd[DevelAnimatedGradientVisual::AnimationParameter::Property::TARGET] = mCards.GetColorEnd( index );
658
659     mBackgroundMapStart[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR] = mColorAnimationStartStart;
660     mBackgroundMapStart[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR] = mColorAnimationStartEnd;
661     mBackgroundMapEnd[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR] = mColorAnimationEndStart;
662     mBackgroundMapEnd[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR] = mColorAnimationEndEnd;
663
664     if( index == 1 )
665     {
666       // Rotate background gradient
667       mBackgroundMapStart[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT] = BuildMap( 0.0f, Math::PI * 2.0f, 0, mLoadingTime, 0.0f, -1, 0.0f, 0, 0 );
668     }
669     else if( index == 2 )
670     {
671       // Rotate background gradient more slow
672       mBackgroundMapStart[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT] = BuildMap( 0.0f, Math::PI * 2.0f, 0, mLoadingTime * 2.0, 0.0f, -1, 0.0f, 0, 0 );
673     }
674     else
675     {
676       mBackgroundMapStart[Toolkit::DevelAnimatedGradientVisual::Property::ROTATE_AMOUNT] = 0.0f;
677     }
678
679     mBackground.SetProperty( Control::Property::BACKGROUND, mBackgroundMapStart );
680
681     mTickCount = 0;
682     mBackgroundChanger = Timer::New( mLoadingTime * 1000.0f / mLoadingCountScale );
683     mBackgroundChanger.TickSignal().Connect( this, &CardController::OnTickBackground );
684     mBackgroundChanger.Start();
685
686     mMoveFront.AnimateTo( Property( mCards[index], Actor::Property::SIZE_WIDTH ), CARD_SIZE_BIG.x * SCALED_WIDTH );
687     mMoveFront.AnimateTo( Property( mCards[index], Actor::Property::SIZE_HEIGHT ), CARD_SIZE_BIG.y * SCALED_HEIGHT );
688     mMoveFront.AnimateTo( Property( mCards[index], Actor::Property::POSITION_Y ), CARD_BIG_OFFSET.y * SCALED_HEIGHT );
689     mMoveBack.AnimateTo( Property( mCards[index], Actor::Property::SIZE_WIDTH ), CARD_SIZE.x * SCALED_WIDTH );
690     mMoveBack.AnimateTo( Property( mCards[index], Actor::Property::SIZE_HEIGHT ), CARD_SIZE.y * SCALED_HEIGHT );
691     mMoveBack.AnimateTo( Property( mCards[index], Actor::Property::POSITION_Y ), CARD_OFFSET.y * SCALED_HEIGHT );
692     for( int i = 0; i < index; i++ )
693     {
694       mMoveFront.AnimateBy( Property( mCards[i], Actor::Property::POSITION_X ), -CARD_MOVE_DIST * SCALED_WIDTH );
695       mMoveBack.AnimateBy( Property( mCards[i], Actor::Property::POSITION_X ), CARD_MOVE_DIST * SCALED_WIDTH );
696     }
697     for( int i = index + 1; i < CARD_NUM; i++ )
698     {
699       mMoveFront.AnimateBy( Property( mCards[i], Actor::Property::POSITION_X ), CARD_MOVE_DIST * SCALED_WIDTH );
700       mMoveBack.AnimateBy( Property( mCards[i], Actor::Property::POSITION_X ), -CARD_MOVE_DIST * SCALED_WIDTH );
701     }
702     mMoveFront.AnimateTo( Property( mAddButton, Actor::Property::POSITION_Y ), BUTTON_ADD_SIZE.y * SCALED_HEIGHT );
703     mMoveBack.AnimateTo( Property( mAddButton, Actor::Property::POSITION_Y ), 0.f * SCALED_HEIGHT );
704
705     mMoveFront.AnimateTo( Property( mLabel1, Actor::Property::VISIBLE), false );
706     mMoveFront.AnimateTo( Property( mLabel2, Actor::Property::VISIBLE), true );
707     mMoveFront.AnimateTo( Property( mLabel3, Actor::Property::VISIBLE), true );
708     mMoveBack.AnimateTo( Property( mLabel1, Actor::Property::VISIBLE), true );
709     mMoveBack.AnimateTo( Property( mLabel2, Actor::Property::VISIBLE), false );
710     mMoveBack.AnimateTo( Property( mLabel3, Actor::Property::VISIBLE), false );
711
712     mMoveFront.Play();
713   }
714   bool OnTickBackground()
715   {
716     mTickCount++;
717     if( mCancelSignal || mTickCount >= mLoadingCount * mLoadingCountScale )
718     {
719       if( mCards.mCurState == 1 )
720       {
721         mCards.mCurState = 2;
722         mBackground.SetProperty( Control::Property::BACKGROUND, mBackgroundMapEnd );
723         mMoveBack.Play();
724         mBackgroundChanger.SetInterval( mDuration * 1000.0f );
725         return true;
726       }
727       else
728       {
729         Reset();
730         return false;
731       }
732     }
733     return true;
734   }
735   void MoveRight()
736   {
737     if( mCards.MoveRight( mCardDuration ) )
738     {
739       // Set smooth background color change here
740       mNormalEndColor = mCards.GetColorBackground( mCards.mCurIndex );
741       mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR] = mNormalEndColor;
742       mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR] = mNormalStartColor;
743
744       (*mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::OFFSET].GetMap())[DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION] = Property::Value( DevelAnimatedGradientVisual::AnimationParameter::DirectionType::BACKWARD );
745
746       mBackground.SetProperty( Control::Property::BACKGROUND, mBackgroundMapMove );
747     }
748   }
749   void MoveLeft()
750   {
751     if( mCards.MoveLeft( mCardDuration ) )
752     {
753       //Set smooth background color change here
754       mNormalEndColor = mCards.GetColorBackground( mCards.mCurIndex );
755       mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR] = mNormalStartColor;
756       mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR] = mNormalEndColor;
757
758       (*mBackgroundMapMove[Toolkit::DevelAnimatedGradientVisual::Property::OFFSET].GetMap())[DevelAnimatedGradientVisual::AnimationParameter::Property::DIRECTION] = Property::Value( DevelAnimatedGradientVisual::AnimationParameter::DirectionType::FORWARD );
759
760       mBackground.SetProperty( Control::Property::BACKGROUND, mBackgroundMapMove );
761     }
762   }
763
764   void Reset()
765   {
766     mCards.mCurState = 0;
767     mCancelSignal = false;
768     mMoveFront.Clear();
769     mMoveBack.Clear();
770
771     mNormalStartColor = mNormalEndColor;
772     mBackgroundNormalMap[Toolkit::DevelAnimatedGradientVisual::Property::START_COLOR] = mNormalStartColor;
773     mBackgroundNormalMap[Toolkit::DevelAnimatedGradientVisual::Property::END_COLOR] = mNormalEndColor;
774     mBackground.SetProperty(Control::Property::BACKGROUND, mBackgroundNormalMap);
775   }
776
777 private:
778   Application&  mApplication;
779   Stage mStage;
780
781   CardManager mCards;
782
783   Control mBackground;
784
785   ImageView mAddButton;
786   TextLabel mLabel1;
787   TextLabel mLabel2;
788   TextLabel mLabel3;
789
790   Timer mBackgroundChanger;
791   Timer mCardChanger;
792   Timer mTempTimer;
793
794   Animation mMoveFront;
795   Animation mMoveBack;
796
797   // Property for background animated gradient visual
798   Property::Map mBackgroundNormalMap;
799   Property::Map mBackgroundMapStart;
800   Property::Map mBackgroundMapEnd;
801   Property::Map mBackgroundMapMove;
802
803   // Property for animation of color in animated gradient visual
804   Property::Map mColorAnimationStartStart;
805   Property::Map mColorAnimationStartEnd;
806   Property::Map mColorAnimationEndStart;
807   Property::Map mColorAnimationEndEnd;
808
809   Vector4 mNormalColor;
810   Vector4 mNormalStartColor;
811   Vector4 mNormalEndColor;
812
813   Vector2 mFirstTouchPos;
814   Vector2 mLastTouchPos;
815
816   float mCardDuration;
817   float mDuration;
818   float mLoadingTime;
819   int mLoadingCount;
820   int mLoadingCountScale;
821   int mTickCount;
822
823   bool mCancelSignal;
824   bool mIsTouchedActor;
825 };
826
827 int main(int argc, char **argv)
828 {
829   Application application = Application::New( &argc, &argv );
830
831   CardController test( application );
832
833   application.MainLoop();
834
835   return 0;
836 }