Merge remote-tracking branch 'origin/tizen' into new_text
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / buttons / push-button-impl.cpp
1 /*
2  * Copyright (c) 2014 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
18 // CLASS HEADER
19 #include "push-button-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/actors/image-actor.h>
23 #include <dali/public-api/object/type-registry.h>
24
25 // INTERNAL INCLUDES
26 #include <dali-toolkit/internal/controls/relayout-helper.h>
27
28 namespace Dali
29 {
30
31 namespace Toolkit
32 {
33
34 namespace Internal
35 {
36
37 namespace
38 {
39
40 const float TEXT_PADDING = 12.0f;
41
42 const float LABEL_DEPTH( 0.75f );
43 const float FOREGROUND_DEPTH( 0.5f );
44 const float BACKGROUND_DEPTH( 0.25f );
45
46 const float ANIMATION_TIME( 0.2f );
47
48 BaseHandle Create()
49 {
50   return Toolkit::PushButton::New();
51 }
52
53 TypeRegistration typeRegistration( typeid(Toolkit::PushButton), typeid(Toolkit::Button), Create );
54
55 } // unnamed namespace
56
57 namespace
58 {
59
60 /**
61  * Find the first image actor in the actor hierarchy
62  */
63 ImageActor FindImageActor( Actor root )
64 {
65   ImageActor imageActor = ImageActor::DownCast( root );
66   if( !imageActor && root )
67   {
68     for( unsigned int i = 0, numChildren = root.GetChildCount(); i < numChildren; ++i )
69     {
70       ImageActor childImageActor = FindImageActor( root.GetChildAt( i ) );
71       if( childImageActor )
72       {
73         return childImageActor;
74       }
75     }
76   }
77
78   return imageActor;
79 }
80
81 } // unnamed namespace
82
83 Dali::Toolkit::PushButton PushButton::New()
84 {
85   // Create the implementation, temporarily owned on stack
86   IntrusivePtr< PushButton > internalPushButton = new PushButton();
87
88   // Pass ownership to CustomActor
89   Dali::Toolkit::PushButton pushButton( *internalPushButton );
90
91   // Second-phase init of the implementation
92   // This can only be done after the CustomActor connection has been made...
93   internalPushButton->Initialize();
94
95   return pushButton;
96 }
97
98 PushButton::PushButton()
99 : Button(),
100   mSize(),
101   mPaintState( UnselectedState )
102 {
103   SetAnimationTime( ANIMATION_TIME );
104 }
105
106 PushButton::~PushButton()
107 {
108 }
109
110 void PushButton::SetButtonImage( Actor image )
111 {
112   Actor& buttonImage = GetButtonImage();
113   Actor& fadeOutButtonImage = GetFadeOutButtonImage();
114
115   switch( mPaintState )
116   {
117     case UnselectedState:
118     {
119       if( buttonImage && buttonImage.GetParent() )
120       {
121         StopFadeOutAnimation();
122         FadeOutImage( Foreground, buttonImage );
123
124         buttonImage = image;
125
126         FadeInImage( buttonImage );
127
128         StartFadeOutAnimation();
129         StartFadeInAnimation();
130       }
131       else
132       {
133         buttonImage = image;
134         Self().Add( buttonImage );
135       }
136       break;
137     }
138     case UnselectedSelectedTransition: // FALLTHROUGH
139     case UnselectedDisabledTransition:
140     {
141       float opacity = 1.f;
142       if( fadeOutButtonImage )
143       {
144         opacity = fadeOutButtonImage.GetCurrentOpacity();
145       }
146       StopFadeOutAnimation();
147
148       // Replaces the button image.
149       buttonImage = image;
150
151       Self().Add( buttonImage );
152       FadeOutImage( Foreground, buttonImage, opacity );
153
154       StartFadeOutAnimation();
155       break;
156     }
157     case SelectedUnselectedTransition: // FALLTHROUGH
158     case DisabledUnselectedTransition:
159     {
160       StopFadeInAnimation();
161       Self().Remove( buttonImage );
162
163       buttonImage = image;
164
165       FadeInImage( buttonImage );
166       StartFadeInAnimation();
167       break;
168     }
169     default:
170       buttonImage = image;
171       break;
172   }
173
174   buttonImage.SetAnchorPoint( AnchorPoint::TOP_LEFT );
175   buttonImage.SetParentOrigin( ParentOrigin::TOP_LEFT );
176   buttonImage.SetPosition( 0.f, 0.f, FOREGROUND_DEPTH );
177   buttonImage.SetSizeMode( SIZE_EQUAL_TO_PARENT );
178 }
179
180 void PushButton::SetSelectedImage( Actor image )
181 {
182   Actor& selectedImage = GetSelectedImage();
183   Actor& fadeOutButtonImage = GetFadeOutButtonImage();
184
185   switch( mPaintState )
186   {
187     case SelectedState:
188     {
189       if( selectedImage && selectedImage.GetParent() )
190       {
191         StopFadeOutAnimation();
192         FadeOutImage( Foreground, selectedImage  );
193
194         selectedImage = image;
195
196         FadeInImage( selectedImage );
197
198         StartFadeOutAnimation();
199         StartFadeInAnimation();
200       }
201       else
202       {
203         selectedImage = image;
204         Self().Add( selectedImage );
205       }
206       break;
207     }
208     case SelectedUnselectedTransition: // FALLTHROUGH
209     case SelectedDisabledTransition:
210     {
211       float opacity = 1.f;
212       if( fadeOutButtonImage )
213       {
214         opacity = fadeOutButtonImage.GetCurrentOpacity();
215       }
216       StopFadeOutAnimation();
217
218       // Replaces the button image.
219       selectedImage = image;
220
221       Self().Add( selectedImage );
222       FadeOutImage( Foreground, selectedImage, opacity );
223
224       StartFadeOutAnimation();
225       break;
226     }
227     case UnselectedSelectedTransition: // FALLTHROUGH
228     case DisabledSelectedTransition:
229     {
230       StopFadeInAnimation();
231       Self().Remove( selectedImage );
232
233       selectedImage = image;
234
235       FadeInImage( selectedImage );
236       StartFadeInAnimation();
237       break;
238     }
239     default:
240       selectedImage = image;
241       break;
242   }
243
244   selectedImage.SetAnchorPoint( AnchorPoint::TOP_LEFT );
245   selectedImage.SetParentOrigin( ParentOrigin::TOP_LEFT );
246   selectedImage.SetPosition( 0.f, 0.f, FOREGROUND_DEPTH );
247   selectedImage.SetSizeMode( SIZE_EQUAL_TO_PARENT );
248 }
249
250 void PushButton::SetBackgroundImage( Actor image )
251 {
252   Actor& backgroundImage = GetBackgroundImage();
253   Actor& fadeOutBackgroundImage = GetFadeOutBackgroundImage();
254
255   switch( mPaintState )
256   {
257     case UnselectedState:             // FALLTHROUGH
258     case SelectedState:
259     case UnselectedSelectedTransition:
260     case SelectedUnselectedTransition:
261     {
262       if( backgroundImage && backgroundImage.GetParent() )
263       {
264         StopFadeOutAnimation();
265         FadeOutImage( Background, backgroundImage  );
266
267         backgroundImage = image;
268
269         FadeInImage( backgroundImage );
270
271         StartFadeOutAnimation();
272         StartFadeInAnimation();
273       }
274       else
275       {
276         backgroundImage = image;
277         Self().Add( backgroundImage );
278       }
279       break;
280     }
281     case UnselectedDisabledTransition: // FALLTHROUGH
282     case SelectedDisabledTransition:
283     {
284       float opacity = 1.f;
285       if( fadeOutBackgroundImage )
286       {
287         opacity = fadeOutBackgroundImage.GetCurrentOpacity();
288       }
289       StopFadeOutAnimation();
290
291       // Replaces the button image.
292       backgroundImage = image;
293
294       Self().Add( backgroundImage );
295       FadeOutImage( Background, backgroundImage, opacity );
296
297       StartFadeOutAnimation();
298       break;
299     }
300     case DisabledUnselectedTransition: // FALLTHROUGH
301     case DisabledSelectedTransition:
302     {
303       StopFadeInAnimation();
304       Self().Remove( backgroundImage );
305
306       backgroundImage = image;
307
308       FadeInImage( backgroundImage );
309       StartFadeInAnimation();
310       break;
311     }
312     default:
313       backgroundImage = image;
314       break;
315     }
316
317   backgroundImage.SetAnchorPoint( AnchorPoint::TOP_LEFT );
318   backgroundImage.SetParentOrigin( ParentOrigin::TOP_LEFT );
319   backgroundImage.SetPosition( 0.f, 0.f, BACKGROUND_DEPTH );
320   backgroundImage.SetSizeMode( SIZE_EQUAL_TO_PARENT );
321 }
322
323 void PushButton::SetDisabledImage( Actor image )
324 {
325   Actor& disabledImage = GetDisabledImage();
326   Actor& fadeOutButtonImage = GetFadeOutButtonImage();
327
328   switch( mPaintState )
329   {
330     case DisabledUnselectedState: // FALLTHROUGH
331     case DisabledSelectedState:
332     {
333       if( disabledImage && disabledImage.GetParent() )
334       {
335         StopFadeOutAnimation();
336         FadeOutImage( Foreground, disabledImage  );
337
338         disabledImage = image;
339
340         FadeInImage( disabledImage );
341
342         StartFadeOutAnimation();
343         StartFadeInAnimation();
344       }
345       else
346       {
347         disabledImage = image;
348         Self().Add( disabledImage );
349       }
350       break;
351     }
352     case UnselectedDisabledTransition: // FALLTHROUGH
353     case SelectedDisabledTransition:
354     {
355       StopFadeInAnimation();
356       Self().Remove( disabledImage );
357
358       disabledImage = image;
359
360       FadeInImage( disabledImage );
361       StartFadeInAnimation();
362       break;
363     }
364     case DisabledUnselectedTransition: // FALLTHROUGH
365     case DisabledSelectedTransition:
366     {
367       float opacity = 1.f;
368       if( fadeOutButtonImage )
369       {
370         opacity = fadeOutButtonImage.GetCurrentOpacity();
371       }
372       StopFadeOutAnimation();
373
374       // Replaces the button image.
375       disabledImage = image;
376
377       Self().Add( disabledImage );
378       FadeOutImage( Foreground, disabledImage, opacity );
379
380       StartFadeOutAnimation();
381       break;
382     }
383     default:
384       disabledImage = image;
385       break;
386   }
387
388   disabledImage.SetAnchorPoint( AnchorPoint::TOP_LEFT );
389   disabledImage.SetParentOrigin( ParentOrigin::TOP_LEFT );
390   disabledImage.SetPosition( 0.f, 0.f, FOREGROUND_DEPTH );
391   disabledImage.SetSizeMode( SIZE_EQUAL_TO_PARENT );
392 }
393
394 void PushButton::SetDisabledBackgroundImage( Actor image )
395 {
396   Actor& disabledBackgroundImage = GetDisabledBackgroundImage();
397   Actor& fadeOutBackgroundImage = GetFadeOutBackgroundImage();
398
399   switch( mPaintState )
400   {
401     case DisabledUnselectedState: // FALLTHROUGH
402     case DisabledSelectedState:
403     {
404       if( disabledBackgroundImage && disabledBackgroundImage.GetParent() )
405       {
406         StopFadeOutAnimation();
407         FadeOutImage( Background, disabledBackgroundImage  );
408
409         disabledBackgroundImage = image;
410
411         FadeInImage( disabledBackgroundImage );
412
413         StartFadeOutAnimation();
414         StartFadeInAnimation();
415       }
416       else
417       {
418         disabledBackgroundImage = image;
419         Self().Add( disabledBackgroundImage );
420       }
421       break;
422     }
423     case UnselectedDisabledTransition: // FALLTHROUGH
424     case SelectedDisabledTransition:
425     {
426       StopFadeInAnimation();
427       Self().Remove( disabledBackgroundImage );
428
429       disabledBackgroundImage = image;
430
431       FadeInImage( disabledBackgroundImage );
432       StartFadeInAnimation();
433       break;
434     }
435     case DisabledUnselectedTransition: // FALLTHROUGH
436     case DisabledSelectedTransition:
437     {
438       float opacity = 1.f;
439       if( fadeOutBackgroundImage )
440       {
441         opacity = fadeOutBackgroundImage.GetCurrentOpacity();
442       }
443       StopFadeOutAnimation();
444
445       // Replaces the button image.
446       disabledBackgroundImage = image;
447
448       Self().Add( disabledBackgroundImage );
449       FadeOutImage( Background, disabledBackgroundImage, opacity );
450
451       StartFadeOutAnimation();
452       break;
453     }
454     default:
455       disabledBackgroundImage = image;
456       break;
457   }
458
459   disabledBackgroundImage.SetAnchorPoint( AnchorPoint::TOP_LEFT );
460   disabledBackgroundImage.SetParentOrigin( ParentOrigin::TOP_LEFT );
461   disabledBackgroundImage.SetPosition( 0.f, 0.f, BACKGROUND_DEPTH );
462   disabledBackgroundImage.SetSizeMode( SIZE_EQUAL_TO_PARENT );
463 }
464
465 void PushButton::OnButtonInitialize()
466 {
467   // Push button requires the Leave event.
468   Actor root = Self();
469   root.SetLeaveRequired( true );
470 }
471
472 void PushButton::OnLabelSet()
473 {
474   Actor& label = GetLabel();
475
476   if( label )
477   {
478     label.SetAnchorPoint( AnchorPoint::CENTER );
479     label.SetParentOrigin( ParentOrigin::CENTER );
480     label.SetPosition( 0.f, 0.f, LABEL_DEPTH );
481     label.SetSize( mSize );
482
483     Self().Add( label );
484   }
485 }
486
487 void PushButton::OnSelected( bool selected )
488 {
489   Actor& selectedImage = GetSelectedImage();
490   Actor& buttonImage = GetButtonImage();
491   Actor& fadeOutButtonImage = GetFadeOutButtonImage();
492
493   switch( mPaintState )
494   {
495     case UnselectedState:
496     {
497       StopFadeOutAnimation();
498       FadeOutImage( Foreground, buttonImage );
499       FadeInImage( selectedImage );
500       StartFadeOutAnimation();
501       StartFadeInAnimation();
502
503       if( buttonImage || selectedImage )
504       {
505         mPaintState = UnselectedSelectedTransition;
506       }
507       else
508       {
509         mPaintState = SelectedState;
510       }
511       break;
512     }
513     case SelectedState:
514     {
515       StopFadeOutAnimation();
516       FadeOutImage( Foreground, selectedImage );
517       FadeInImage( buttonImage );
518       StartFadeOutAnimation();
519       StartFadeInAnimation();
520
521       if( buttonImage || selectedImage )
522       {
523         mPaintState = SelectedUnselectedTransition;
524       }
525       else
526       {
527         mPaintState = UnselectedState;
528       }
529       break;
530     }
531     case UnselectedSelectedTransition:
532     {
533       float opacity = 1.f;
534       if( fadeOutButtonImage )
535       {
536         opacity = fadeOutButtonImage.GetCurrentOpacity();
537       }
538       StopFadeOutAnimation( false );
539       StopFadeInAnimation();
540
541       FadeOutImage( Foreground, selectedImage, 1.f - opacity );
542       FadeInImage( buttonImage, opacity );
543
544       StartFadeOutAnimation();
545       StartFadeInAnimation();
546
547       if( buttonImage || selectedImage )
548       {
549         mPaintState = SelectedUnselectedTransition;
550       }
551       else
552       {
553         mPaintState = UnselectedState;
554       }
555       break;
556     }
557     case SelectedUnselectedTransition:
558     {
559       float opacity = 0.f;
560       if( fadeOutButtonImage )
561       {
562         opacity = 1.f - fadeOutButtonImage.GetCurrentOpacity();
563       }
564       StopFadeOutAnimation( false );
565       StopFadeInAnimation();
566
567       FadeOutImage( Foreground, buttonImage, 1.f - opacity );
568       FadeInImage( selectedImage, opacity );
569
570       StartFadeOutAnimation();
571       StartFadeInAnimation();
572
573       if( buttonImage || selectedImage )
574       {
575         mPaintState = UnselectedSelectedTransition;
576       }
577       else
578       {
579         mPaintState = SelectedState;
580       }
581       break;
582     }
583     default:
584     {
585       break;
586     }
587   }
588 }
589
590 void PushButton::OnDisabled( bool disabled )
591 {
592   Actor& buttonImage = GetButtonImage();
593   Actor& selectedImage = GetSelectedImage();
594   Actor& backgroundImage = GetBackgroundImage();
595   Actor& disabledImage = GetDisabledImage();
596   Actor& disabledBackgroundImage = GetDisabledBackgroundImage();
597   Actor& fadeOutButtonImage = GetFadeOutButtonImage();
598
599   switch( mPaintState )
600   {
601   case UnselectedState:
602   {
603     if( disabled )
604     {
605       StopFadeOutAnimation();
606       FadeOutImage( Background, backgroundImage );
607       FadeOutImage( Foreground, buttonImage );
608       FadeInImage( disabledBackgroundImage );
609       FadeInImage( disabledImage );
610       StartFadeOutAnimation();
611       StartFadeInAnimation();
612
613       if( buttonImage || disabledImage || backgroundImage || disabledBackgroundImage )
614       {
615         mPaintState = UnselectedDisabledTransition;
616       }
617       else
618       {
619         mPaintState = DisabledUnselectedState;
620       }
621     }
622     break;
623   }
624   case SelectedState:
625   {
626     if( disabled )
627     {
628       StopFadeOutAnimation();
629       FadeOutImage( Background, backgroundImage );
630       FadeOutImage( Foreground, selectedImage );
631       FadeInImage( disabledBackgroundImage );
632       FadeInImage( disabledImage );
633       StartFadeOutAnimation();
634       StartFadeInAnimation();
635
636       if( selectedImage || disabledImage || backgroundImage || disabledBackgroundImage )
637       {
638         mPaintState = SelectedDisabledTransition;
639       }
640       else
641       {
642         mPaintState = DisabledSelectedState;
643       }
644     }
645     break;
646   }
647   case DisabledUnselectedState:
648   {
649     if( !disabled )
650     {
651       StopFadeOutAnimation();
652       FadeOutImage( Background, disabledBackgroundImage );
653       FadeOutImage( Foreground, disabledImage );
654       FadeInImage( backgroundImage );
655       FadeInImage( buttonImage );
656       StartFadeOutAnimation();
657       StartFadeInAnimation();
658
659       if( buttonImage || disabledImage || backgroundImage || disabledBackgroundImage )
660       {
661         mPaintState = DisabledUnselectedTransition;
662       }
663       else
664       {
665         mPaintState = UnselectedState;
666       }
667     }
668     break;
669   }
670   case DisabledSelectedState:
671   {
672     if( !disabled )
673     {
674       StopFadeOutAnimation();
675       FadeOutImage( Background, disabledBackgroundImage );
676       FadeOutImage( Foreground, disabledImage );
677       FadeInImage( backgroundImage );
678       FadeInImage( selectedImage );
679       StartFadeOutAnimation();
680       StartFadeInAnimation();
681
682       if( selectedImage || disabledImage || backgroundImage || disabledBackgroundImage )
683       {
684         mPaintState = DisabledSelectedTransition;
685       }
686       else
687       {
688         mPaintState = SelectedState;
689       }
690     }
691     break;
692   }
693   case UnselectedSelectedTransition:
694   {
695     if( disabled )
696     {
697       float opacity = 1.f;
698       if( fadeOutButtonImage )
699       {
700         opacity = fadeOutButtonImage.GetCurrentOpacity();
701       }
702       StopFadeOutAnimation();
703       StopFadeInAnimation();
704
705       FadeOutImage( Foreground, selectedImage, 1.f - opacity );
706       FadeOutImage( Background, backgroundImage );
707
708       FadeInImage( disabledImage );
709       FadeInImage( disabledBackgroundImage );
710
711       StartFadeOutAnimation();
712       StartFadeInAnimation();
713
714       if( selectedImage || disabledImage || backgroundImage || disabledBackgroundImage )
715       {
716         mPaintState = SelectedDisabledTransition;
717       }
718       else
719       {
720         mPaintState = DisabledSelectedState;
721       }
722     }
723     break;
724   }
725   case SelectedUnselectedTransition:
726   {
727     if( disabled )
728     {
729       float opacity = 1.f;
730       if( fadeOutButtonImage )
731       {
732         opacity = fadeOutButtonImage.GetCurrentOpacity();
733       }
734       StopFadeOutAnimation();
735       StopFadeInAnimation();
736
737       FadeOutImage( Foreground, buttonImage, 1.f - opacity );
738       FadeOutImage( Background, backgroundImage );
739
740       FadeInImage( disabledImage );
741       FadeInImage( disabledBackgroundImage );
742
743       StartFadeOutAnimation();
744       StartFadeInAnimation();
745
746       if( buttonImage || disabledImage || backgroundImage || disabledBackgroundImage )
747       {
748         mPaintState = UnselectedDisabledTransition;
749       }
750       else
751       {
752         mPaintState = DisabledUnselectedState;
753       }
754     }
755     break;
756   }
757   case UnselectedDisabledTransition:
758   {
759     if( !disabled )
760     {
761       float opacity = 1.f;
762       if( fadeOutButtonImage )
763       {
764         opacity = fadeOutButtonImage.GetCurrentOpacity();
765       }
766       StopFadeOutAnimation( false );
767       StopFadeInAnimation();
768
769       FadeOutImage( Foreground, disabledImage, 1.f - opacity );
770       FadeOutImage( Background, disabledBackgroundImage, 1.f - opacity );
771       FadeInImage( buttonImage, opacity );
772       FadeInImage( backgroundImage, opacity );
773
774       StartFadeOutAnimation();
775       StartFadeInAnimation();
776
777       if( buttonImage || disabledImage || backgroundImage || disabledBackgroundImage )
778       {
779         mPaintState = DisabledUnselectedTransition;
780       }
781       else
782       {
783         mPaintState = UnselectedState;
784       }
785     }
786     break;
787   }
788   case DisabledUnselectedTransition:
789   {
790     if( disabled )
791     {
792       float opacity = 1.f;
793       if( fadeOutButtonImage )
794       {
795         opacity = fadeOutButtonImage.GetCurrentOpacity();
796       }
797       StopFadeOutAnimation( false );
798       StopFadeInAnimation();
799
800       FadeOutImage( Foreground, buttonImage, 1.f - opacity );
801       FadeOutImage( Background, backgroundImage, 1.f - opacity );
802       FadeInImage( disabledImage, opacity );
803       FadeInImage( disabledBackgroundImage, opacity );
804
805       StartFadeOutAnimation();
806       StartFadeInAnimation();
807
808       if( buttonImage || disabledImage || backgroundImage || disabledBackgroundImage )
809       {
810         mPaintState = UnselectedDisabledTransition;
811       }
812       else
813       {
814         mPaintState = DisabledUnselectedState;
815       }
816     }
817     break;
818   }
819   case SelectedDisabledTransition:
820   {
821     if( !disabled )
822     {
823       float opacity = 1.f;
824       if( fadeOutButtonImage )
825       {
826         opacity = fadeOutButtonImage.GetCurrentOpacity();
827       }
828       StopFadeOutAnimation( false );
829       StopFadeInAnimation();
830
831       FadeOutImage( Foreground, disabledImage, 1.f - opacity );
832       FadeOutImage( Background, disabledBackgroundImage, 1.f - opacity );
833       FadeInImage( selectedImage, opacity );
834       FadeInImage( backgroundImage, opacity );
835
836       StartFadeOutAnimation();
837       StartFadeInAnimation();
838
839       if( selectedImage || disabledImage || backgroundImage || disabledBackgroundImage )
840       {
841         mPaintState = DisabledSelectedTransition;
842       }
843       else
844       {
845         mPaintState = SelectedState;
846       }
847     }
848     break;
849   }
850   case DisabledSelectedTransition:
851   {
852     if( disabled )
853     {
854       float opacity = 1.f;
855       if( fadeOutButtonImage )
856       {
857         opacity = fadeOutButtonImage.GetCurrentOpacity();
858       }
859       StopFadeOutAnimation( false );
860       StopFadeInAnimation();
861
862       FadeOutImage( Foreground, selectedImage, 1.f - opacity );
863       FadeOutImage( Background, backgroundImage, 1.f - opacity );
864       FadeInImage( disabledImage, opacity );
865       FadeInImage( disabledBackgroundImage, opacity );
866
867       StartFadeOutAnimation();
868       StartFadeInAnimation();
869
870       if( selectedImage || disabledImage || backgroundImage || disabledBackgroundImage )
871       {
872         mPaintState = SelectedDisabledTransition;
873       }
874       else
875       {
876         mPaintState = DisabledSelectedState;
877       }
878     }
879     break;
880   }
881   default:
882     break;
883   }
884 }
885
886 void PushButton::OnPressed()
887 {
888   Actor& selectedImage = GetSelectedImage();
889   Actor& buttonImage = GetButtonImage();
890   Actor& fadeOutButtonImage = GetFadeOutButtonImage();
891
892   switch( mPaintState )
893   {
894     case UnselectedState:
895     {
896       StopFadeOutAnimation();
897       FadeOutImage( Foreground, buttonImage );
898       FadeInImage( selectedImage );
899       StartFadeOutAnimation();
900       StartFadeInAnimation();
901
902       if( buttonImage || selectedImage )
903       {
904         mPaintState = UnselectedSelectedTransition;
905       }
906       else
907       {
908         mPaintState = SelectedState;
909       }
910       break;
911     }
912     case UnselectedSelectedTransition:
913     {
914       if( !IsAutoRepeating() )
915       {
916         mPaintState = SelectedUnselectedTransition;
917       }
918       break;
919     }
920     case SelectedUnselectedTransition:
921     {
922       float opacity = 1.f;
923       if( fadeOutButtonImage )
924       {
925         opacity = fadeOutButtonImage.GetCurrentOpacity();
926       }
927       StopFadeOutAnimation( false );
928       StopFadeInAnimation();
929
930       FadeOutImage( Foreground, buttonImage, 1.f - opacity );
931       FadeInImage( selectedImage, opacity );
932
933       StartFadeOutAnimation();
934       StartFadeInAnimation();
935
936       if( buttonImage || selectedImage )
937       {
938         mPaintState = UnselectedSelectedTransition;
939       }
940       else
941       {
942         mPaintState = SelectedState;
943       }
944       break;
945     }
946     default:
947       break;
948   }
949 }
950
951 void PushButton::OnReleased()
952 {
953   Actor& selectedImage = GetSelectedImage();
954   Actor& buttonImage = GetButtonImage();
955   Actor& fadeOutButtonImage = GetFadeOutButtonImage();
956
957   switch( mPaintState )
958   {
959     case SelectedState:
960     {
961       StopFadeOutAnimation();
962       FadeOutImage( Foreground, selectedImage );
963       FadeInImage( buttonImage );
964       StartFadeOutAnimation();
965       StartFadeInAnimation();
966
967       if( buttonImage || selectedImage )
968       {
969         mPaintState = SelectedUnselectedTransition;
970       }
971       else
972       {
973         mPaintState = UnselectedState;
974       }
975       break;
976     }
977     case UnselectedSelectedTransition:
978     {
979       float opacity = 1.f;
980       if( fadeOutButtonImage )
981       {
982         opacity = fadeOutButtonImage.GetCurrentOpacity();
983       }
984       StopFadeOutAnimation( false );
985       StopFadeInAnimation();
986
987       FadeOutImage( Foreground, selectedImage, 1.f - opacity );
988       FadeInImage( buttonImage, opacity );
989
990       StartFadeOutAnimation();
991       StartFadeInAnimation();
992
993       if( buttonImage || selectedImage )
994       {
995         mPaintState = SelectedUnselectedTransition;
996       }
997       else
998       {
999         mPaintState = UnselectedState;
1000       }
1001       break;
1002     }
1003     default:
1004     {
1005       break;
1006     }
1007   }
1008 }
1009
1010 void PushButton::OnClicked()
1011 {
1012   OnReleased();
1013 }
1014
1015 void PushButton::OnControlSizeSet( const Vector3& targetSize )
1016 {
1017   if( targetSize != mSize )
1018   {
1019     mSize = targetSize;
1020
1021     Actor& label = GetLabel();
1022
1023     if( label )
1024     {
1025       label.SetSize( mSize );
1026     }
1027   }
1028 }
1029
1030 Vector3 PushButton::GetNaturalSize()
1031 {
1032   Vector3 size = Control::GetNaturalSize();
1033
1034   const bool widthIsZero = EqualsZero( size.width );
1035   const bool heightIsZero = EqualsZero( size.height );
1036
1037   if( widthIsZero || heightIsZero )
1038   {
1039     // If background and background not scale9 try get size from that
1040     ImageActor imageActor = FindImageActor( GetButtonImage() );
1041     if( imageActor && imageActor.GetStyle() != ImageActor::STYLE_NINE_PATCH )
1042     {
1043       Vector3 imageSize = RelayoutHelper::GetNaturalSize( imageActor );
1044
1045       if( widthIsZero )
1046       {
1047         size.width = imageSize.width;
1048       }
1049
1050       if( heightIsZero )
1051       {
1052         size.height = imageSize.height;
1053       }
1054     }
1055
1056     ImageActor backgroundImageActor = FindImageActor( GetBackgroundImage() );
1057     if( backgroundImageActor && backgroundImageActor.GetStyle() != ImageActor::STYLE_NINE_PATCH )
1058     {
1059       Vector3 imageSize = RelayoutHelper::GetNaturalSize( backgroundImageActor );
1060
1061       if( widthIsZero )
1062       {
1063         size.width = std::max( size.width, imageSize.width );
1064       }
1065
1066       if( heightIsZero )
1067       {
1068         size.height = std::max( size.height, imageSize.height );
1069       }
1070     }
1071   }
1072
1073   return size;
1074 }
1075
1076 Actor& PushButton::GetFadeOutButtonImage()
1077 {
1078   return mFadeOutButtonContent;
1079 }
1080
1081 Actor& PushButton::GetFadeOutBackgroundImage()
1082 {
1083   return mFadeOutBackgroundContent;
1084 }
1085
1086 void PushButton::AddToFadeInAnimation( const Actor& actor )
1087 {
1088   if( !mFadeInAnimation )
1089   {
1090     mFadeInAnimation = Dali::Animation::New( GetAnimationTime() );
1091   }
1092
1093   mFadeInAnimation.OpacityTo( actor, 1.f );
1094 }
1095
1096 void PushButton::StartFadeInAnimation()
1097 {
1098   if( mFadeInAnimation )
1099   {
1100     mFadeInAnimation.FinishedSignal().Connect( this, &PushButton::FadeInAnimationFinished );
1101     mFadeInAnimation.Play();
1102   }
1103 }
1104
1105 void PushButton::StopFadeInAnimation()
1106 {
1107   if( mFadeInAnimation )
1108   {
1109     mFadeInAnimation.Clear();
1110     mFadeInAnimation.Reset();
1111   }
1112 }
1113
1114 void PushButton::AddToFadeOutAnimation( const Actor& actor )
1115 {
1116   if( !mFadeOutAnimation )
1117   {
1118     mFadeOutAnimation = Dali::Animation::New( GetAnimationTime() );
1119   }
1120
1121   mFadeOutAnimation.OpacityTo( actor, 0.f );
1122 }
1123
1124 void PushButton::StartFadeOutAnimation()
1125 {
1126   if( mFadeOutAnimation )
1127   {
1128     mFadeOutAnimation.FinishedSignal().Connect( this, &PushButton::FadeOutAnimationFinished );
1129     mFadeOutAnimation.Play();
1130   }
1131 }
1132
1133 void PushButton::StopFadeOutAnimation( bool remove )
1134 {
1135   if( mFadeOutAnimation )
1136   {
1137     mFadeOutAnimation.Clear();
1138     mFadeOutAnimation.Reset();
1139   }
1140
1141   if( remove )
1142   {
1143     Actor& fadeOutButtonImage = GetFadeOutButtonImage();
1144     Actor& fadeOutBackgroundImage = GetFadeOutBackgroundImage();
1145
1146     if( fadeOutButtonImage && fadeOutButtonImage.GetParent() )
1147     {
1148       fadeOutButtonImage.GetParent().Remove( fadeOutButtonImage );
1149     }
1150
1151     if( fadeOutBackgroundImage && fadeOutBackgroundImage.GetParent() )
1152     {
1153       fadeOutBackgroundImage.GetParent().Remove( fadeOutBackgroundImage );
1154     }
1155
1156     fadeOutButtonImage.Reset();
1157     fadeOutBackgroundImage.Reset();
1158   }
1159 }
1160
1161 void PushButton::FadeInImage( Actor& image, float opacity )
1162 {
1163   if( image )
1164   {
1165     image.SetOpacity( opacity );
1166     if( !image.GetParent() )
1167     {
1168       Self().Add( image );
1169     }
1170
1171     AddToFadeInAnimation( image );
1172   }
1173 }
1174
1175 void PushButton::FadeOutImage( ImageLayer layer, Actor& image, float opacity )
1176 {
1177   if( image )
1178   {
1179     Actor& fadeOutButtonImage = GetFadeOutButtonImage();
1180     Actor& fadeOutBackgroundImage = GetFadeOutBackgroundImage();
1181
1182     Actor& actorLayer = ( ( Background == layer ) ? fadeOutBackgroundImage : fadeOutButtonImage );
1183
1184     actorLayer = image;
1185     actorLayer.SetOpacity( opacity );
1186
1187     AddToFadeOutAnimation( actorLayer );
1188   }
1189 }
1190
1191 void PushButton::FadeOutAnimationFinished( Dali::Animation& source )
1192 {
1193   switch( mPaintState )
1194   {
1195     case UnselectedSelectedTransition:
1196     {
1197       mPaintState = SelectedState;
1198       break;
1199     }
1200     case SelectedUnselectedTransition:
1201     {
1202       mPaintState = UnselectedState;
1203       break;
1204     }
1205     case UnselectedDisabledTransition:
1206     {
1207       mPaintState = DisabledUnselectedState;
1208       break;
1209     }
1210     case DisabledUnselectedTransition:
1211     {
1212       mPaintState = UnselectedState;
1213       break;
1214     }
1215     case SelectedDisabledTransition:
1216     {
1217       mPaintState = DisabledSelectedState;
1218       break;
1219     }
1220     case DisabledSelectedTransition:
1221     {
1222       mPaintState = SelectedState;
1223       break;
1224     }
1225     default:
1226     {
1227       break;
1228     }
1229   }
1230
1231   StopFadeOutAnimation();
1232 }
1233
1234 void PushButton::FadeInAnimationFinished( Dali::Animation& source )
1235 {
1236   switch( mPaintState )
1237   {
1238     case UnselectedSelectedTransition:
1239     {
1240       mPaintState = SelectedState;
1241       break;
1242     }
1243     case SelectedUnselectedTransition:
1244     {
1245       mPaintState = UnselectedState;
1246       break;
1247     }
1248     case UnselectedDisabledTransition:
1249     {
1250       mPaintState = DisabledUnselectedState;
1251       break;
1252     }
1253     case DisabledUnselectedTransition:
1254     {
1255       mPaintState = UnselectedState;
1256       break;
1257     }
1258     case SelectedDisabledTransition:
1259     {
1260       mPaintState = DisabledSelectedState;
1261       break;
1262     }
1263     case DisabledSelectedTransition:
1264     {
1265       mPaintState = SelectedState;
1266       break;
1267     }
1268     default:
1269     {
1270       break;
1271     }
1272   }
1273
1274   StopFadeInAnimation();
1275 }
1276
1277 } // namespace Internal
1278
1279 } // namespace Toolkit
1280
1281 } // namespace Dali