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