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
27 namespace Dali
28 {
29
30 namespace Toolkit
31 {
32
33 namespace Internal
34 {
35
36 namespace
37 {
38
39 const float TEXT_PADDING = 12.0f;
40
41 const float LABEL_DEPTH( 0.75f );
42 const float FOREGROUND_DEPTH( 0.5f );
43 const float BACKGROUND_DEPTH( 0.25f );
44
45 const float ANIMATION_TIME( 0.2f );
46
47 BaseHandle Create()
48 {
49   return Toolkit::PushButton::New();
50 }
51
52 TypeRegistration typeRegistration( typeid(Toolkit::PushButton), typeid(Toolkit::Button), Create );
53
54 } // unnamed namespace
55
56 namespace
57 {
58
59 /**
60  * Find the first image actor in the actor hierarchy
61  */
62 ImageActor FindImageActor( Actor root )
63 {
64   ImageActor imageActor = ImageActor::DownCast( root );
65   if( !imageActor && root )
66   {
67     for( unsigned int i = 0, numChildren = root.GetChildCount(); i < numChildren; ++i )
68     {
69       ImageActor childImageActor = FindImageActor( root.GetChildAt( i ) );
70       if( childImageActor )
71       {
72         return childImageActor;
73       }
74     }
75   }
76
77   return imageActor;
78 }
79
80 } // unnamed namespace
81
82 Dali::Toolkit::PushButton PushButton::New()
83 {
84   // Create the implementation, temporarily owned on stack
85   IntrusivePtr< PushButton > internalPushButton = new PushButton();
86
87   // Pass ownership to CustomActor
88   Dali::Toolkit::PushButton pushButton( *internalPushButton );
89
90   // Second-phase init of the implementation
91   // This can only be done after the CustomActor connection has been made...
92   internalPushButton->Initialize();
93
94   return pushButton;
95 }
96
97 PushButton::PushButton()
98 : Button(),
99   mSize(),
100   mPaintState( UnselectedState )
101 {
102   SetAnimationTime( ANIMATION_TIME );
103 }
104
105 PushButton::~PushButton()
106 {
107 }
108
109 void PushButton::SetButtonImage( Actor image )
110 {
111   Actor& buttonImage = GetButtonImage();
112   Actor& fadeOutButtonImage = GetFadeOutButtonImage();
113
114   switch( mPaintState )
115   {
116     case UnselectedState:
117     {
118       if( buttonImage && buttonImage.GetParent() )
119       {
120         StopFadeOutAnimation();
121         FadeOutImage( Foreground, buttonImage );
122
123         buttonImage = image;
124
125         FadeInImage( buttonImage, 0.0f, 0 );
126
127         StartFadeOutAnimation();
128         StartFadeInAnimation();
129       }
130       else
131       {
132         buttonImage = image;
133         Self().Insert( 0, buttonImage );
134       }
135       break;
136     }
137     case UnselectedSelectedTransition: // FALLTHROUGH
138     case UnselectedDisabledTransition:
139     {
140       float opacity = 1.f;
141       if( fadeOutButtonImage )
142       {
143         opacity = fadeOutButtonImage.GetCurrentOpacity();
144       }
145       StopFadeOutAnimation();
146
147       // Replaces the button image.
148       buttonImage = image;
149
150       Self().Insert( 0, buttonImage );
151       FadeOutImage( Foreground, buttonImage, opacity );
152
153       StartFadeOutAnimation();
154       break;
155     }
156     case SelectedUnselectedTransition: // FALLTHROUGH
157     case DisabledUnselectedTransition:
158     {
159       StopFadeInAnimation();
160       Self().Remove( buttonImage );
161
162       buttonImage = image;
163
164       FadeInImage( buttonImage, 0.0f, 0 );
165       StartFadeInAnimation();
166       break;
167     }
168     default:
169       buttonImage = image;
170       break;
171   }
172
173   buttonImage.SetAnchorPoint( AnchorPoint::TOP_LEFT );
174   buttonImage.SetParentOrigin( ParentOrigin::TOP_LEFT );
175   buttonImage.SetPosition( 0.f, 0.f, FOREGROUND_DEPTH );
176   buttonImage.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
177   buttonImage.SetName( "BUTTON_IMAGE" );
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, 0.0f, 0 );
197
198         StartFadeOutAnimation();
199         StartFadeInAnimation();
200       }
201       else
202       {
203         selectedImage = image;
204         Self().Insert( 0, 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().Insert( 0, 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, 0.0f, 0 );
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.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
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, 0.0f, 0 );
270
271         StartFadeOutAnimation();
272         StartFadeInAnimation();
273       }
274       else
275       {
276         backgroundImage = image;
277         Self().Insert( 0, 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().Insert( 0, 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, 0.0f, 0 );
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.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
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, 0.0f, 0 );
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, 0.0f, 0 );
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.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
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, 0.0f, 0 );
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, 0.0f, 0 );
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.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
463 }
464
465 void PushButton::OnButtonInitialize()
466 {
467   // Push button requires the Leave event.
468   Actor root = Self();
469   root.SetLeaveRequired( true );
470
471   // Set resize policy to natural size so that buttons will resize to background images
472   root.SetResizePolicy( USE_NATURAL_SIZE, ALL_DIMENSIONS );
473 }
474
475 void PushButton::OnLabelSet()
476 {
477   Actor& label = GetLabel();
478
479   if( label )
480   {
481     label.SetAnchorPoint( AnchorPoint::CENTER );
482     label.SetParentOrigin( ParentOrigin::CENTER );
483     label.SetPosition( 0.f, 0.f, LABEL_DEPTH );
484     label.SetSize( mSize );
485
486     Self().Add( label );
487   }
488 }
489
490 void PushButton::OnSelected( bool selected )
491 {
492   Actor& selectedImage = GetSelectedImage();
493   Actor& buttonImage = GetButtonImage();
494   Actor& fadeOutButtonImage = GetFadeOutButtonImage();
495
496   switch( mPaintState )
497   {
498     case UnselectedState:
499     {
500       StopFadeOutAnimation();
501       FadeOutImage( Foreground, buttonImage );
502       FadeInImage( selectedImage, 0.0f, 0 );
503       StartFadeOutAnimation();
504       StartFadeInAnimation();
505
506       if( buttonImage || selectedImage )
507       {
508         mPaintState = UnselectedSelectedTransition;
509       }
510       else
511       {
512         mPaintState = SelectedState;
513       }
514       break;
515     }
516     case SelectedState:
517     {
518       StopFadeOutAnimation();
519       FadeOutImage( Foreground, selectedImage );
520       FadeInImage( buttonImage, 0.0f, 0 );
521       StartFadeOutAnimation();
522       StartFadeInAnimation();
523
524       if( buttonImage || selectedImage )
525       {
526         mPaintState = SelectedUnselectedTransition;
527       }
528       else
529       {
530         mPaintState = UnselectedState;
531       }
532       break;
533     }
534     case UnselectedSelectedTransition:
535     {
536       float opacity = 1.f;
537       if( fadeOutButtonImage )
538       {
539         opacity = fadeOutButtonImage.GetCurrentOpacity();
540       }
541       StopFadeOutAnimation( false );
542       StopFadeInAnimation();
543
544       FadeOutImage( Foreground, selectedImage, 1.f - opacity );
545       FadeInImage( buttonImage, opacity, 0 );
546
547       StartFadeOutAnimation();
548       StartFadeInAnimation();
549
550       if( buttonImage || selectedImage )
551       {
552         mPaintState = SelectedUnselectedTransition;
553       }
554       else
555       {
556         mPaintState = UnselectedState;
557       }
558       break;
559     }
560     case SelectedUnselectedTransition:
561     {
562       float opacity = 0.f;
563       if( fadeOutButtonImage )
564       {
565         opacity = 1.f - fadeOutButtonImage.GetCurrentOpacity();
566       }
567       StopFadeOutAnimation( false );
568       StopFadeInAnimation();
569
570       FadeOutImage( Foreground, buttonImage, 1.f - opacity );
571       FadeInImage( selectedImage, opacity, 0 );
572
573       StartFadeOutAnimation();
574       StartFadeInAnimation();
575
576       if( buttonImage || selectedImage )
577       {
578         mPaintState = UnselectedSelectedTransition;
579       }
580       else
581       {
582         mPaintState = SelectedState;
583       }
584       break;
585     }
586     default:
587     {
588       break;
589     }
590   }
591 }
592
593 void PushButton::OnDisabled( bool disabled )
594 {
595   Actor& buttonImage = GetButtonImage();
596   Actor& selectedImage = GetSelectedImage();
597   Actor& backgroundImage = GetBackgroundImage();
598   Actor& disabledImage = GetDisabledImage();
599   Actor& disabledBackgroundImage = GetDisabledBackgroundImage();
600   Actor& fadeOutButtonImage = GetFadeOutButtonImage();
601
602   switch( mPaintState )
603   {
604   case UnselectedState:
605   {
606     if( disabled )
607     {
608       StopFadeOutAnimation();
609       FadeOutImage( Background, backgroundImage );
610       FadeOutImage( Foreground, buttonImage );
611       FadeInImage( disabledBackgroundImage, 0.0f, 0 );
612       FadeInImage( disabledImage, 0.0f, 0 );
613       StartFadeOutAnimation();
614       StartFadeInAnimation();
615
616       if( buttonImage || disabledImage || backgroundImage || disabledBackgroundImage )
617       {
618         mPaintState = UnselectedDisabledTransition;
619       }
620       else
621       {
622         mPaintState = DisabledUnselectedState;
623       }
624     }
625     break;
626   }
627   case SelectedState:
628   {
629     if( disabled )
630     {
631       StopFadeOutAnimation();
632       FadeOutImage( Background, backgroundImage );
633       FadeOutImage( Foreground, selectedImage );
634       FadeInImage( disabledBackgroundImage, 0.0f, 0 );
635       FadeInImage( disabledImage, 0.0f, 0 );
636       StartFadeOutAnimation();
637       StartFadeInAnimation();
638
639       if( selectedImage || disabledImage || backgroundImage || disabledBackgroundImage )
640       {
641         mPaintState = SelectedDisabledTransition;
642       }
643       else
644       {
645         mPaintState = DisabledSelectedState;
646       }
647     }
648     break;
649   }
650   case DisabledUnselectedState:
651   {
652     if( !disabled )
653     {
654       StopFadeOutAnimation();
655       FadeOutImage( Background, disabledBackgroundImage );
656       FadeOutImage( Foreground, disabledImage );
657       FadeInImage( backgroundImage, 0.0f, 0 );
658       FadeInImage( buttonImage, 0.0f, 0 );
659       StartFadeOutAnimation();
660       StartFadeInAnimation();
661
662       if( buttonImage || disabledImage || backgroundImage || disabledBackgroundImage )
663       {
664         mPaintState = DisabledUnselectedTransition;
665       }
666       else
667       {
668         mPaintState = UnselectedState;
669       }
670     }
671     break;
672   }
673   case DisabledSelectedState:
674   {
675     if( !disabled )
676     {
677       StopFadeOutAnimation();
678       FadeOutImage( Background, disabledBackgroundImage );
679       FadeOutImage( Foreground, disabledImage );
680       FadeInImage( backgroundImage, 0.0f, 0 );
681       FadeInImage( selectedImage, 0.0f, 0 );
682       StartFadeOutAnimation();
683       StartFadeInAnimation();
684
685       if( selectedImage || disabledImage || backgroundImage || disabledBackgroundImage )
686       {
687         mPaintState = DisabledSelectedTransition;
688       }
689       else
690       {
691         mPaintState = SelectedState;
692       }
693     }
694     break;
695   }
696   case UnselectedSelectedTransition:
697   {
698     if( disabled )
699     {
700       float opacity = 1.f;
701       if( fadeOutButtonImage )
702       {
703         opacity = fadeOutButtonImage.GetCurrentOpacity();
704       }
705       StopFadeOutAnimation();
706       StopFadeInAnimation();
707
708       FadeOutImage( Foreground, selectedImage, 1.f - opacity );
709       FadeOutImage( Background, backgroundImage );
710
711       FadeInImage( disabledImage, 0.0f, 0 );
712       FadeInImage( disabledBackgroundImage, 0.0f, 0 );
713
714       StartFadeOutAnimation();
715       StartFadeInAnimation();
716
717       if( selectedImage || disabledImage || backgroundImage || disabledBackgroundImage )
718       {
719         mPaintState = SelectedDisabledTransition;
720       }
721       else
722       {
723         mPaintState = DisabledSelectedState;
724       }
725     }
726     break;
727   }
728   case SelectedUnselectedTransition:
729   {
730     if( disabled )
731     {
732       float opacity = 1.f;
733       if( fadeOutButtonImage )
734       {
735         opacity = fadeOutButtonImage.GetCurrentOpacity();
736       }
737       StopFadeOutAnimation();
738       StopFadeInAnimation();
739
740       FadeOutImage( Foreground, buttonImage, 1.f - opacity );
741       FadeOutImage( Background, backgroundImage );
742
743       FadeInImage( disabledImage, 0.0f, 0);
744       FadeInImage( disabledBackgroundImage, 0.0f, 0 );
745
746       StartFadeOutAnimation();
747       StartFadeInAnimation();
748
749       if( buttonImage || disabledImage || backgroundImage || disabledBackgroundImage )
750       {
751         mPaintState = UnselectedDisabledTransition;
752       }
753       else
754       {
755         mPaintState = DisabledUnselectedState;
756       }
757     }
758     break;
759   }
760   case UnselectedDisabledTransition:
761   {
762     if( !disabled )
763     {
764       float opacity = 1.f;
765       if( fadeOutButtonImage )
766       {
767         opacity = fadeOutButtonImage.GetCurrentOpacity();
768       }
769       StopFadeOutAnimation( false );
770       StopFadeInAnimation();
771
772       FadeOutImage( Foreground, disabledImage, 1.f - opacity );
773       FadeOutImage( Background, disabledBackgroundImage, 1.f - opacity );
774       FadeInImage( buttonImage, opacity, 0 );
775       FadeInImage( backgroundImage, opacity, 0 );
776
777       StartFadeOutAnimation();
778       StartFadeInAnimation();
779
780       if( buttonImage || disabledImage || backgroundImage || disabledBackgroundImage )
781       {
782         mPaintState = DisabledUnselectedTransition;
783       }
784       else
785       {
786         mPaintState = UnselectedState;
787       }
788     }
789     break;
790   }
791   case DisabledUnselectedTransition:
792   {
793     if( disabled )
794     {
795       float opacity = 1.f;
796       if( fadeOutButtonImage )
797       {
798         opacity = fadeOutButtonImage.GetCurrentOpacity();
799       }
800       StopFadeOutAnimation( false );
801       StopFadeInAnimation();
802
803       FadeOutImage( Foreground, buttonImage, 1.f - opacity );
804       FadeOutImage( Background, backgroundImage, 1.f - opacity );
805       FadeInImage( disabledImage, opacity, 0 );
806       FadeInImage( disabledBackgroundImage, opacity, 0 );
807
808       StartFadeOutAnimation();
809       StartFadeInAnimation();
810
811       if( buttonImage || disabledImage || backgroundImage || disabledBackgroundImage )
812       {
813         mPaintState = UnselectedDisabledTransition;
814       }
815       else
816       {
817         mPaintState = DisabledUnselectedState;
818       }
819     }
820     break;
821   }
822   case SelectedDisabledTransition:
823   {
824     if( !disabled )
825     {
826       float opacity = 1.f;
827       if( fadeOutButtonImage )
828       {
829         opacity = fadeOutButtonImage.GetCurrentOpacity();
830       }
831       StopFadeOutAnimation( false );
832       StopFadeInAnimation();
833
834       FadeOutImage( Foreground, disabledImage, 1.f - opacity );
835       FadeOutImage( Background, disabledBackgroundImage, 1.f - opacity );
836       FadeInImage( selectedImage, opacity, 0 );
837       FadeInImage( backgroundImage, opacity, 0 );
838
839       StartFadeOutAnimation();
840       StartFadeInAnimation();
841
842       if( selectedImage || disabledImage || backgroundImage || disabledBackgroundImage )
843       {
844         mPaintState = DisabledSelectedTransition;
845       }
846       else
847       {
848         mPaintState = SelectedState;
849       }
850     }
851     break;
852   }
853   case DisabledSelectedTransition:
854   {
855     if( disabled )
856     {
857       float opacity = 1.f;
858       if( fadeOutButtonImage )
859       {
860         opacity = fadeOutButtonImage.GetCurrentOpacity();
861       }
862       StopFadeOutAnimation( false );
863       StopFadeInAnimation();
864
865       FadeOutImage( Foreground, selectedImage, 1.f - opacity );
866       FadeOutImage( Background, backgroundImage, 1.f - opacity );
867       FadeInImage( disabledImage, opacity, 0 );
868       FadeInImage( disabledBackgroundImage, opacity, 0 );
869
870       StartFadeOutAnimation();
871       StartFadeInAnimation();
872
873       if( selectedImage || disabledImage || backgroundImage || disabledBackgroundImage )
874       {
875         mPaintState = SelectedDisabledTransition;
876       }
877       else
878       {
879         mPaintState = DisabledSelectedState;
880       }
881     }
882     break;
883   }
884   default:
885     break;
886   }
887 }
888
889 void PushButton::OnPressed()
890 {
891   Actor& selectedImage = GetSelectedImage();
892   Actor& buttonImage = GetButtonImage();
893   Actor& fadeOutButtonImage = GetFadeOutButtonImage();
894
895   switch( mPaintState )
896   {
897     case UnselectedState:
898     {
899       StopFadeOutAnimation();
900       FadeOutImage( Foreground, buttonImage );
901       FadeInImage( selectedImage, 0.0f, 0 );
902       StartFadeOutAnimation();
903       StartFadeInAnimation();
904
905       if( buttonImage || selectedImage )
906       {
907         mPaintState = UnselectedSelectedTransition;
908       }
909       else
910       {
911         mPaintState = SelectedState;
912       }
913       break;
914     }
915     case UnselectedSelectedTransition:
916     {
917       if( !IsAutoRepeating() )
918       {
919         mPaintState = SelectedUnselectedTransition;
920       }
921       break;
922     }
923     case SelectedUnselectedTransition:
924     {
925       float opacity = 1.f;
926       if( fadeOutButtonImage )
927       {
928         opacity = fadeOutButtonImage.GetCurrentOpacity();
929       }
930       StopFadeOutAnimation( false );
931       StopFadeInAnimation();
932
933       FadeOutImage( Foreground, buttonImage, 1.f - opacity );
934       FadeInImage( selectedImage, opacity, 0 );
935
936       StartFadeOutAnimation();
937       StartFadeInAnimation();
938
939       if( buttonImage || selectedImage )
940       {
941         mPaintState = UnselectedSelectedTransition;
942       }
943       else
944       {
945         mPaintState = SelectedState;
946       }
947       break;
948     }
949     default:
950       break;
951   }
952 }
953
954 void PushButton::OnReleased()
955 {
956   Actor& selectedImage = GetSelectedImage();
957   Actor& buttonImage = GetButtonImage();
958   Actor& fadeOutButtonImage = GetFadeOutButtonImage();
959
960   switch( mPaintState )
961   {
962     case SelectedState:
963     {
964       StopFadeOutAnimation();
965       FadeOutImage( Foreground, selectedImage );
966       FadeInImage( buttonImage, 0.0f, 0 );
967       StartFadeOutAnimation();
968       StartFadeInAnimation();
969
970       if( buttonImage || selectedImage )
971       {
972         mPaintState = SelectedUnselectedTransition;
973       }
974       else
975       {
976         mPaintState = UnselectedState;
977       }
978       break;
979     }
980     case UnselectedSelectedTransition:
981     {
982       float opacity = 1.f;
983       if( fadeOutButtonImage )
984       {
985         opacity = fadeOutButtonImage.GetCurrentOpacity();
986       }
987       StopFadeOutAnimation( false );
988       StopFadeInAnimation();
989
990       FadeOutImage( Foreground, selectedImage, 1.f - opacity );
991       FadeInImage( buttonImage, opacity, 0 );
992
993       StartFadeOutAnimation();
994       StartFadeInAnimation();
995
996       if( buttonImage || selectedImage )
997       {
998         mPaintState = SelectedUnselectedTransition;
999       }
1000       else
1001       {
1002         mPaintState = UnselectedState;
1003       }
1004       break;
1005     }
1006     default:
1007     {
1008       break;
1009     }
1010   }
1011 }
1012
1013 void PushButton::OnClicked()
1014 {
1015   OnReleased();
1016 }
1017
1018 void PushButton::OnControlSizeSet( const Vector3& targetSize )
1019 {
1020   if( targetSize != mSize )
1021   {
1022     mSize = targetSize;
1023
1024     Actor& label = GetLabel();
1025
1026     if( label )
1027     {
1028       label.SetSize( mSize );
1029     }
1030   }
1031 }
1032
1033 Vector3 PushButton::GetNaturalSize()
1034 {
1035   Vector3 size = Control::GetNaturalSize();
1036
1037   const bool widthIsZero = EqualsZero( size.width );
1038   const bool heightIsZero = EqualsZero( size.height );
1039
1040   if( widthIsZero || heightIsZero )
1041   {
1042     // If background and background not scale9 try get size from that
1043     ImageActor imageActor = FindImageActor( GetButtonImage() );
1044     if( imageActor && imageActor.GetStyle() != ImageActor::STYLE_NINE_PATCH )
1045     {
1046       Vector3 imageSize = imageActor.GetNaturalSize();
1047
1048       if( widthIsZero )
1049       {
1050         size.width = imageSize.width;
1051       }
1052
1053       if( heightIsZero )
1054       {
1055         size.height = imageSize.height;
1056       }
1057     }
1058
1059     ImageActor backgroundImageActor = FindImageActor( GetBackgroundImage() );
1060     if( backgroundImageActor && backgroundImageActor.GetStyle() != ImageActor::STYLE_NINE_PATCH )
1061     {
1062       Vector3 imageSize = backgroundImageActor.GetNaturalSize();
1063
1064       if( widthIsZero )
1065       {
1066         size.width = std::max( size.width, imageSize.width );
1067       }
1068
1069       if( heightIsZero )
1070       {
1071         size.height = std::max( size.height, imageSize.height );
1072       }
1073     }
1074   }
1075
1076   return size;
1077 }
1078
1079 Actor& PushButton::GetFadeOutButtonImage()
1080 {
1081   return mFadeOutButtonContent;
1082 }
1083
1084 Actor& PushButton::GetFadeOutBackgroundImage()
1085 {
1086   return mFadeOutBackgroundContent;
1087 }
1088
1089 void PushButton::AddToFadeInAnimation( const Actor& actor )
1090 {
1091   if( !mFadeInAnimation )
1092   {
1093     mFadeInAnimation = Dali::Animation::New( GetAnimationTime() );
1094   }
1095
1096   mFadeInAnimation.OpacityTo( actor, 1.f );
1097 }
1098
1099 void PushButton::StartFadeInAnimation()
1100 {
1101   if( mFadeInAnimation )
1102   {
1103     mFadeInAnimation.FinishedSignal().Connect( this, &PushButton::FadeInAnimationFinished );
1104     mFadeInAnimation.Play();
1105   }
1106 }
1107
1108 void PushButton::StopFadeInAnimation()
1109 {
1110   if( mFadeInAnimation )
1111   {
1112     mFadeInAnimation.Clear();
1113     mFadeInAnimation.Reset();
1114   }
1115 }
1116
1117 void PushButton::AddToFadeOutAnimation( const Actor& actor )
1118 {
1119   if( !mFadeOutAnimation )
1120   {
1121     mFadeOutAnimation = Dali::Animation::New( GetAnimationTime() );
1122   }
1123
1124   mFadeOutAnimation.OpacityTo( actor, 0.f );
1125 }
1126
1127 void PushButton::StartFadeOutAnimation()
1128 {
1129   if( mFadeOutAnimation )
1130   {
1131     mFadeOutAnimation.FinishedSignal().Connect( this, &PushButton::FadeOutAnimationFinished );
1132     mFadeOutAnimation.Play();
1133   }
1134 }
1135
1136 void PushButton::StopFadeOutAnimation( bool remove )
1137 {
1138   if( mFadeOutAnimation )
1139   {
1140     mFadeOutAnimation.Clear();
1141     mFadeOutAnimation.Reset();
1142   }
1143
1144   if( remove )
1145   {
1146     Actor& fadeOutButtonImage = GetFadeOutButtonImage();
1147     Actor& fadeOutBackgroundImage = GetFadeOutBackgroundImage();
1148
1149     if( fadeOutButtonImage && fadeOutButtonImage.GetParent() )
1150     {
1151       fadeOutButtonImage.GetParent().Remove( fadeOutButtonImage );
1152     }
1153
1154     if( fadeOutBackgroundImage && fadeOutBackgroundImage.GetParent() )
1155     {
1156       fadeOutBackgroundImage.GetParent().Remove( fadeOutBackgroundImage );
1157     }
1158
1159     fadeOutButtonImage.Reset();
1160     fadeOutBackgroundImage.Reset();
1161   }
1162 }
1163
1164 void PushButton::FadeInImage( Actor& image, float opacity, int priority )
1165 {
1166   if( image )
1167   {
1168     image.SetOpacity( opacity );
1169     if( !image.GetParent() )
1170     {
1171       if( priority > -1 )
1172       {
1173         Self().Insert( priority, image );
1174       }
1175       else
1176       {
1177         Self().Add( image );
1178       }
1179     }
1180
1181     AddToFadeInAnimation( image );
1182   }
1183 }
1184
1185 void PushButton::FadeOutImage( ImageLayer layer, Actor& image, float opacity )
1186 {
1187   if( image )
1188   {
1189     Actor& fadeOutButtonImage = GetFadeOutButtonImage();
1190     Actor& fadeOutBackgroundImage = GetFadeOutBackgroundImage();
1191
1192     Actor& actorLayer = ( ( Background == layer ) ? fadeOutBackgroundImage : fadeOutButtonImage );
1193
1194     actorLayer = image;
1195     actorLayer.SetOpacity( opacity );
1196
1197     AddToFadeOutAnimation( actorLayer );
1198   }
1199 }
1200
1201 void PushButton::FadeOutAnimationFinished( Dali::Animation& source )
1202 {
1203   switch( mPaintState )
1204   {
1205     case UnselectedSelectedTransition:
1206     {
1207       mPaintState = SelectedState;
1208       break;
1209     }
1210     case SelectedUnselectedTransition:
1211     {
1212       mPaintState = UnselectedState;
1213       break;
1214     }
1215     case UnselectedDisabledTransition:
1216     {
1217       mPaintState = DisabledUnselectedState;
1218       break;
1219     }
1220     case DisabledUnselectedTransition:
1221     {
1222       mPaintState = UnselectedState;
1223       break;
1224     }
1225     case SelectedDisabledTransition:
1226     {
1227       mPaintState = DisabledSelectedState;
1228       break;
1229     }
1230     case DisabledSelectedTransition:
1231     {
1232       mPaintState = SelectedState;
1233       break;
1234     }
1235     default:
1236     {
1237       break;
1238     }
1239   }
1240
1241   StopFadeOutAnimation();
1242 }
1243
1244 void PushButton::FadeInAnimationFinished( Dali::Animation& source )
1245 {
1246   switch( mPaintState )
1247   {
1248     case UnselectedSelectedTransition:
1249     {
1250       mPaintState = SelectedState;
1251       break;
1252     }
1253     case SelectedUnselectedTransition:
1254     {
1255       mPaintState = UnselectedState;
1256       break;
1257     }
1258     case UnselectedDisabledTransition:
1259     {
1260       mPaintState = DisabledUnselectedState;
1261       break;
1262     }
1263     case DisabledUnselectedTransition:
1264     {
1265       mPaintState = UnselectedState;
1266       break;
1267     }
1268     case SelectedDisabledTransition:
1269     {
1270       mPaintState = DisabledSelectedState;
1271       break;
1272     }
1273     case DisabledSelectedTransition:
1274     {
1275       mPaintState = SelectedState;
1276       break;
1277     }
1278     default:
1279     {
1280       break;
1281     }
1282   }
1283
1284   StopFadeInAnimation();
1285 }
1286
1287 } // namespace Internal
1288
1289 } // namespace Toolkit
1290
1291 } // namespace Dali