Button SetLabel padding fix
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / buttons / 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 "button-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <cstring> // for strcmp
23 #include <dali/public-api/events/touch-event.h>
24 #include <dali/public-api/images/resource-image.h>
25 #include <dali/public-api/object/type-registry.h>
26 #include <dali/devel-api/object/type-registry-helper.h>
27 #include <dali/public-api/actors/image-actor.h>
28 #include <dali/devel-api/scripting/scripting.h>
29
30 // INTERNAL INCLUDES
31 #include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
32 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
33
34 /**
35  * Button states and contents
36  *                                         (3) mSelectedContent
37  *  (2) mUnselectedContent                 (2) mSelectedBackgroundContent
38  *  (1) mBackgroundContent                 (1) mBackgroundContent
39  * < unselected > ----------------------- < selected >
40  *       |                OnSelect()            |
41  *       | OnDisabled()                         | OnDisabled()
42  *       |                                      |
43  * < disabled >                           < disabled-selected >
44  *  (2) mDisabledContent                   (2) mDisabledSelectedContent
45  *  (1) mDisabledBackgroundContent         (1) mDisabledBackgroundContent
46  *
47  * The drawing order of child actors is as follows.
48  *
49  *  Top      mLabel
50  *   |       mUnselectedContent / mSelectedContent / mDisabledContent / mDisabledSelectedContent
51  *   |       mSelectedBackgroundContent
52  * Bottom    mBackgroundContent / mDisabledBackgroundContent
53  *
54  * Some of contents may be missed.
55  * And 2 images - fade-in image and fade-out image - in the same layer can be shown during the transition animation. Fade-in image should be above fade-out image.
56  */
57
58 namespace Dali
59 {
60
61 namespace Toolkit
62 {
63
64 namespace Internal
65 {
66
67 namespace
68 {
69
70 BaseHandle Create()
71 {
72   // empty handle as we cannot create button (but type registered for clicked signal)
73   return BaseHandle();
74 }
75
76 // Setup properties, signals and actions using the type-registry.
77 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Button, Toolkit::Control, Create );
78
79 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabled",                     BOOLEAN, DISABLED                     )
80 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "auto-repeating",               BOOLEAN, AUTO_REPEATING               )
81 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "initial-auto-repeating-delay", FLOAT,   INITIAL_AUTO_REPEATING_DELAY )
82 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "next-auto-repeating-delay",    FLOAT,   NEXT_AUTO_REPEATING_DELAY    )
83 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "togglable",                    BOOLEAN, TOGGLABLE                    )
84 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selected",                     BOOLEAN, SELECTED                     )
85 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselected-state-image",       STRING,  UNSELECTED_STATE_IMAGE       )
86 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selected-state-image",         STRING,  SELECTED_STATE_IMAGE         )
87 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabled-state-image",         STRING,  DISABLED_STATE_IMAGE         )
88 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselected-color",             VECTOR4, UNSELECTED_COLOR             )
89 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selected-color",               VECTOR4, SELECTED_COLOR               )
90 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "label-text",                   STRING,  LABEL_TEXT                   )
91
92 DALI_SIGNAL_REGISTRATION(   Toolkit, Button, "pressed",                               SIGNAL_PRESSED               )
93 DALI_SIGNAL_REGISTRATION(   Toolkit, Button, "released",                              SIGNAL_RELEASED              )
94 DALI_SIGNAL_REGISTRATION(   Toolkit, Button, "clicked",                               SIGNAL_CLICKED               )
95 DALI_SIGNAL_REGISTRATION(   Toolkit, Button, "state-changed",                         SIGNAL_STATE_CHANGED         )
96
97 DALI_ACTION_REGISTRATION(   Toolkit, Button, "button-click",                          ACTION_BUTTON_CLICK          )
98
99 DALI_TYPE_REGISTRATION_END()
100
101 const unsigned int INITIAL_AUTOREPEATING_DELAY( 0.15f );
102 const unsigned int NEXT_AUTOREPEATING_DELAY( 0.05f );
103
104 const char* const STYLE_BUTTON_LABEL = "button.label";
105
106 } // unnamed namespace
107
108 Button::Button()
109 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS | REQUIRES_STYLE_CHANGE_SIGNALS ) ),
110   mAutoRepeatingTimer(),
111   mUnselectedColor( Color::WHITE ), // The natural colors of the specified images will be used by default.
112   mSelectedColor( Color::WHITE ),
113   mDisabled( false ),
114   mAutoRepeating( false ),
115   mTogglableButton( false ),
116   mSelected( false ),
117   mInitialAutoRepeatingDelay( INITIAL_AUTOREPEATING_DELAY ),
118   mNextAutoRepeatingDelay( NEXT_AUTOREPEATING_DELAY ),
119   mAnimationTime( 0.0f ),
120   mClickActionPerforming( false ),
121   mState( ButtonUp ),
122   mPaintState( UnselectedState )
123 {
124 }
125
126 Button::~Button()
127 {
128 }
129
130 void Button::SetDisabled( bool disabled )
131 {
132   if( disabled == mDisabled )
133   {
134     return;
135   }
136
137   StopTransitionAnimation();
138
139   mDisabled = disabled;
140
141   // Notifies the derived class the button has been disabled.
142   OnDisabled();
143
144   switch( mPaintState )
145   {
146     case UnselectedState:
147     {
148       //Layer Order
149       //(3) mDisabledContent (Inserted)
150       //(4) mUnselectedContent
151       //(2) mDisabledBackgroundContent (Inserted)
152       //(1) mBackgroundContent
153
154       AddButtonImage( mBackgroundContent );
155       TransitionButtonImage( mDisabledBackgroundContent );
156       AddButtonImage( mUnselectedContent );
157       TransitionButtonImage( mDisabledContent );
158
159       AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
160       ReAddLabel();
161
162       TransitionOut( mDecoration[ SELECTED_DECORATION ] );
163       TransitionOut( mUnselectedContent );
164       TransitionOut( mSelectedContent );
165       TransitionOut( mBackgroundContent );
166       TransitionOut( mSelectedBackgroundContent );
167       TransitionOut( mDisabledSelectedContent );
168
169       mPaintState = DisabledUnselectedState;
170       break;
171     }
172     case SelectedState:
173     {
174       //Layer Order
175       //(5) mDisabledSelectedContent (Inserted)
176       //(4) mSelectedContent
177       //(3) mDisabledBackgroundContent (Inserted)
178       //(2) mSelectedBackgroundContent
179       //(1) mBackgroundContent
180
181       AddButtonImage( mBackgroundContent );
182       AddButtonImage( mSelectedBackgroundContent );
183       TransitionButtonImage( mDisabledBackgroundContent );
184       AddButtonImage( mSelectedContent );
185       TransitionButtonImage( mDisabledSelectedContent );
186
187       AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
188       ReAddLabel();
189
190       TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
191       TransitionOut( mUnselectedContent );
192       TransitionOut( mSelectedContent );
193       TransitionOut( mBackgroundContent );
194       TransitionOut( mSelectedBackgroundContent );
195       TransitionOut( mDisabledContent );
196
197       mPaintState = DisabledSelectedState;
198       break;
199     }
200     case DisabledUnselectedState:
201     {
202       //Layer Order
203       //(3) mUnselectedContent (Inserted)
204       //(4) mDisabledContent
205       //(2) mBackgroundContent (Inserted)
206       //(1) mDisabledBackgroundContent
207
208       AddButtonImage( mDisabledBackgroundContent );
209       TransitionButtonImage( mBackgroundContent );
210       AddButtonImage( mDisabledContent );
211       TransitionButtonImage( mUnselectedContent );
212
213       AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
214       ReAddLabel();
215
216       TransitionOut( mDecoration[ SELECTED_DECORATION ] );
217       TransitionOut( mSelectedContent );
218       TransitionOut( mSelectedBackgroundContent );
219       TransitionOut( mDisabledContent );
220       TransitionOut( mDisabledSelectedContent );
221       TransitionOut( mDisabledBackgroundContent );
222
223       mPaintState = UnselectedState;
224       break;
225     }
226     case DisabledSelectedState:
227     {
228       //Layer Order
229       //(4) mSelectedContent (Inserted)
230       //(5) mDisabledSelectedContent
231       //(3) mSelectedBackgroundContent (Inserted)
232       //(2) mBackgroundContent (Inserted)
233       //(1) mDisabledBackgroundContent
234
235       AddButtonImage( mDisabledBackgroundContent );
236       TransitionButtonImage( mBackgroundContent );
237       TransitionButtonImage( mSelectedBackgroundContent );
238       AddButtonImage( mDisabledSelectedContent );
239       TransitionButtonImage( mSelectedContent );
240
241       AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
242       ReAddLabel();
243
244       TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
245       TransitionOut( mUnselectedContent );
246       TransitionOut( mDisabledContent );
247       TransitionOut( mDisabledSelectedContent );
248       TransitionOut( mDisabledBackgroundContent );
249
250       mPaintState = SelectedState;
251       break;
252     }
253   }
254
255   StartTransitionAnimation();
256 }
257
258 bool Button::IsDisabled() const
259 {
260   return mDisabled;
261 }
262
263 void Button::SetAutoRepeating( bool autoRepeating )
264 {
265   mAutoRepeating = autoRepeating;
266
267   // An autorepeating button can't be a togglable button.
268   if( autoRepeating )
269   {
270     mTogglableButton = false;
271
272     if( mSelected )
273     {
274       // Emit a signal is not wanted, only change the appearance.
275       SetSelected( false, false );
276     }
277   }
278 }
279
280 bool Button::IsAutoRepeating() const
281 {
282   return mAutoRepeating;
283 }
284
285 void Button::SetInitialAutoRepeatingDelay( float initialAutoRepeatingDelay )
286 {
287   DALI_ASSERT_ALWAYS( initialAutoRepeatingDelay > 0.f );
288   mInitialAutoRepeatingDelay = initialAutoRepeatingDelay;
289 }
290
291 float Button::GetInitialAutoRepeatingDelay() const
292 {
293   return mInitialAutoRepeatingDelay;
294 }
295
296 void Button::SetNextAutoRepeatingDelay( float nextAutoRepeatingDelay )
297 {
298   DALI_ASSERT_ALWAYS( nextAutoRepeatingDelay > 0.f );
299   mNextAutoRepeatingDelay = nextAutoRepeatingDelay;
300 }
301
302 float Button::GetNextAutoRepeatingDelay() const
303 {
304   return mNextAutoRepeatingDelay;
305 }
306
307 void Button::SetTogglableButton( bool togglable )
308 {
309   mTogglableButton = togglable;
310
311   // A togglable button can't be an autorepeating button.
312   if( togglable )
313   {
314     mAutoRepeating = false;
315   }
316 }
317
318 bool Button::IsTogglableButton() const
319 {
320   return mTogglableButton;
321 }
322
323 void Button::SetSelected( bool selected )
324 {
325   if( !mDisabled && mTogglableButton && ( selected != mSelected ) )
326   {
327     SetSelected( selected, true );
328   }
329 }
330
331 void Button::SetSelected( bool selected, bool emitSignal )
332 {
333   StopTransitionAnimation();
334
335   mSelected = selected;
336
337   // Notifies the derived class the button has been selected.
338   OnSelected();
339
340   switch( mPaintState )
341   {
342     case UnselectedState:
343     {
344       //Layer Order
345       //(3) mSelectedContent (Inserted)
346       //(4) mUnselectedContent
347       //(2) mSelectedBackgroundContent (Inserted)
348       //(1) mBackgroundContent
349
350       AddButtonImage( mBackgroundContent );
351       TransitionButtonImage( mSelectedBackgroundContent );
352       AddButtonImage( mUnselectedContent );
353       TransitionButtonImage( mSelectedContent );
354
355       AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
356       TransitionButtonImage( mDecoration[ SELECTED_DECORATION ] );
357       ReAddLabel();
358
359       TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
360       TransitionOut( mUnselectedContent );
361       TransitionOut( mDisabledContent );
362       TransitionOut( mDisabledSelectedContent );
363       TransitionOut( mDisabledBackgroundContent );
364
365       mPaintState = SelectedState;
366       break;
367     }
368     case SelectedState:
369     {
370       //Layer Order
371       //(3) mUnselectedContent (Inserted)
372       //(2) mSelectedContent
373       //(1) mBackgroundContent
374
375       AddButtonImage( mBackgroundContent );
376       AddButtonImage( mSelectedContent );
377       TransitionButtonImage( mUnselectedContent );
378
379       AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
380       TransitionButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
381       ReAddLabel();
382
383       TransitionOut( mDecoration[ SELECTED_DECORATION ] );
384       TransitionOut( mSelectedContent );
385       TransitionOut( mSelectedBackgroundContent );
386       TransitionOut( mDisabledContent );
387       TransitionOut( mDisabledSelectedContent );
388       TransitionOut( mDisabledBackgroundContent );
389
390       mPaintState = UnselectedState;
391       break;
392     }
393     case DisabledUnselectedState:
394     case DisabledSelectedState:
395     {
396       DALI_ASSERT_DEBUG( 0 && "Shouldn't be able to change paint state if the button is disabled." );
397       break;
398     }
399   }
400
401   StartTransitionAnimation();
402
403   if( emitSignal )
404   {
405     Toolkit::Button handle( GetOwner() );
406
407     // Emit signal.
408     mStateChangedSignal.Emit( handle );
409   }
410
411   RelayoutRequest();
412 }
413
414 bool Button::IsSelected() const
415 {
416   return mTogglableButton && mSelected;
417 }
418
419 void Button::SetAnimationTime( float animationTime )
420 {
421   mAnimationTime = animationTime;
422 }
423
424 float Button::GetAnimationTime() const
425 {
426   return mAnimationTime;
427 }
428
429 void Button::SetLabelText( const std::string& label )
430 {
431   if( !mLabel || ( label != GetLabelText() ) )
432   {
433     // If we have a label, unparent and update it.
434     if( mLabel )
435     {
436       mLabel.SetProperty( Toolkit::TextLabel::Property::TEXT, label );
437     }
438     else
439     {
440       // If we don't have a label, create one and set it up.
441       mLabel = Toolkit::TextLabel::New( label );
442       mLabel.SetProperty( Toolkit::Control::Property::STYLE_NAME, STYLE_BUTTON_LABEL );
443       mLabel.SetPosition( 0.f, 0.f );
444       // label should be the top of the button
445       Self().Add( mLabel );
446     }
447
448     OnLabelSet( false );
449
450     RelayoutRequest();
451   }
452 }
453
454 std::string Button::GetLabelText() const
455 {
456   Toolkit::TextLabel label = Dali::Toolkit::TextLabel::DownCast( mLabel );
457   if( label )
458   {
459     return label.GetProperty<std::string>( Dali::Toolkit::TextLabel::Property::TEXT );
460   }
461   return std::string();
462 }
463
464 Actor& Button::GetLabelActor()
465 {
466   return mLabel;
467 }
468
469 void Button::SetDecoration( DecorationState state, Actor actor )
470 {
471   if( mDecoration[ state ] && mDecoration[ state ].GetParent() )
472   {
473     mDecoration[ state ].Unparent();
474   }
475
476   mDecoration[ state ] = actor;
477   mDecoration[ state ].SetColorMode( USE_OWN_COLOR );
478
479   ResetImageLayers();
480   RelayoutRequest();
481 }
482
483 Actor& Button::GetDecoration( DecorationState state )
484 {
485   return mDecoration[ state ];
486 }
487
488 void Button::SetupContent( Actor& actorToModify, Actor newActor )
489 {
490   if( newActor )
491   {
492     StopTransitionAnimation();
493
494     if( actorToModify && actorToModify.GetParent() )
495     {
496       actorToModify.Unparent();
497     }
498
499     actorToModify = newActor;
500
501     if( actorToModify )
502     {
503       actorToModify.SetAnchorPoint( AnchorPoint::TOP_LEFT );
504       actorToModify.SetParentOrigin( ParentOrigin::TOP_LEFT );
505       actorToModify.SetPosition( 0.f, 0.f );
506     }
507
508     ResetImageLayers();
509   }
510 }
511
512 void Button::SetUnselectedColor( const Vector4& color )
513 {
514   mUnselectedColor = color;
515
516   if( mUnselectedContent && !GetUnselectedImageFilename().empty() )
517   {
518     // If there is existing unselected content, change the color on it directly.
519     mUnselectedContent.SetColor( mUnselectedColor );
520   }
521   else
522   {
523     // If there is no existing content, create a new actor to use for flat color.
524     SetupContent( mUnselectedContent, CreateSolidColorActor( mUnselectedColor ) );
525     mUnselectedContent.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
526   }
527 }
528
529 const Vector4 Button::GetUnselectedColor() const
530 {
531   return mUnselectedColor;
532 }
533
534 void Button::SetSelectedColor( const Vector4& color )
535 {
536   mSelectedColor = color;
537
538   if( mSelectedContent && !GetSelectedImageFilename().empty() )
539   {
540     // If there is existing unselected content, change the color on it directly.
541     mSelectedContent.SetColor( mSelectedColor );
542   }
543   else
544   {
545     // If there is no existing content, create a new actor to use for flat color.
546     SetupContent( mSelectedContent, CreateSolidColorActor( mSelectedColor ) );
547     mSelectedContent.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
548   }
549 }
550
551 const Vector4 Button::GetSelectedColor() const
552 {
553   return mSelectedColor;
554 }
555
556 void Button::SetUnselectedImage( const std::string& filename )
557 {
558   ImageActor newContent;
559   if( !filename.empty() )
560   {
561     Image resourceimage = Dali::ResourceImage::New( filename );
562     if( resourceimage )
563     {
564       newContent = ImageActor::New( resourceimage );
565     }
566   }
567   else
568   {
569     newContent = ImageActor::New();
570   }
571
572   if( newContent )
573   {
574     SetupContent( mUnselectedContent, newContent );
575
576     mUnselectedContent.SetColor( mUnselectedColor );
577
578     OnUnselectedImageSet();
579     RelayoutRequest();
580   }
581 }
582
583 Actor& Button::GetUnselectedImage()
584 {
585   return mUnselectedContent;
586 }
587
588 void Button::SetSelectedImage( const std::string& filename )
589 {
590   ImageActor newContent;
591   if( !filename.empty() )
592   {
593     Image resourceimage = Dali::ResourceImage::New( filename );
594     if( resourceimage )
595     {
596       newContent = ImageActor::New( resourceimage );
597     }
598   }
599   else
600   {
601     newContent = ImageActor::New();
602   }
603
604   if( newContent )
605   {
606     SetupContent( mSelectedContent, newContent );
607
608     mSelectedContent.SetColor( mSelectedColor );
609
610     OnSelectedImageSet();
611     RelayoutRequest();
612   }
613 }
614
615 Actor& Button::GetSelectedImage()
616 {
617   return mSelectedContent;
618 }
619
620 void Button::SetBackgroundImage( const std::string& filename )
621 {
622   Image resourceimage = Dali::ResourceImage::New( filename );
623   if( resourceimage )
624   {
625     SetupContent( mBackgroundContent, ImageActor::New( resourceimage ) );
626
627     OnBackgroundImageSet();
628     RelayoutRequest();
629   }
630 }
631
632 Actor& Button::GetBackgroundImage()
633 {
634   return mBackgroundContent;
635 }
636
637 void Button::SetSelectedBackgroundImage( const std::string& filename )
638 {
639   Image resourceimage = Dali::ResourceImage::New( filename );
640   if( resourceimage )
641   {
642     SetupContent( mSelectedBackgroundContent, ImageActor::New( resourceimage ) );
643
644     OnSelectedBackgroundImageSet();
645     RelayoutRequest();
646   }
647 }
648
649 Actor& Button::GetSelectedBackgroundImage()
650 {
651   return mSelectedBackgroundContent;
652 }
653
654 void Button::SetDisabledImage( const std::string& filename )
655 {
656   Image resourceimage = Dali::ResourceImage::New( filename );
657   if( resourceimage )
658   {
659     SetupContent( mDisabledContent, ImageActor::New( resourceimage ) );
660
661     OnDisabledImageSet();
662     RelayoutRequest();
663   }
664 }
665
666 Actor& Button::GetDisabledImage()
667 {
668   return mDisabledContent;
669 }
670
671 void Button::SetDisabledSelectedImage( const std::string& filename )
672 {
673   Image resourceimage = Dali::ResourceImage::New( filename );
674   if( resourceimage )
675   {
676     SetupContent( mDisabledSelectedContent, ImageActor::New( resourceimage ) );
677
678     OnDisabledSelectedImageSet();
679     RelayoutRequest();
680   }
681 }
682
683 Actor& Button::GetDisabledSelectedImage()
684 {
685   return mDisabledSelectedContent;
686 }
687
688 void Button::SetDisabledBackgroundImage( const std::string& filename )
689 {
690   Image resourceimage = Dali::ResourceImage::New( filename );
691   if( resourceimage )
692   {
693     SetupContent( mDisabledBackgroundContent, ImageActor::New( resourceimage ) );
694
695     OnDisabledBackgroundImageSet();
696     RelayoutRequest();
697   }
698 }
699
700 Actor& Button::GetDisabledBackgroundImage()
701 {
702   return mDisabledBackgroundContent;
703 }
704
705 std::string Button::GetUnselectedImageFilename() const
706 {
707   if( mUnselectedContent )
708   {
709     ResourceImage image = ResourceImage::DownCast( mUnselectedContent );
710     if( image )
711     {
712       return image.GetUrl();
713     }
714   }
715   return std::string();
716 }
717
718 std::string Button::GetSelectedImageFilename() const
719 {
720   if( mSelectedContent )
721   {
722     ResourceImage image = ResourceImage::DownCast( mSelectedContent );
723     if( image )
724     {
725       return image.GetUrl();
726     }
727   }
728   return std::string();
729 }
730
731 std::string Button::GetBackgroundImageFilename() const
732 {
733   if( mBackgroundContent )
734   {
735     ResourceImage image = ResourceImage::DownCast( mBackgroundContent );
736     if( image )
737     {
738       return image.GetUrl();
739     }
740   }
741   return std::string();
742 }
743
744 std::string Button::GetSelectedBackgroundImageFilename() const
745 {
746   if( mSelectedBackgroundContent )
747   {
748     ResourceImage image = ResourceImage::DownCast( mSelectedBackgroundContent );
749     if( image )
750     {
751       return image.GetUrl();
752     }
753   }
754   return std::string();
755 }
756
757 std::string Button::GetDisabledImageFilename() const
758 {
759   if( mDisabledContent )
760   {
761     ResourceImage image = ResourceImage::DownCast( mDisabledContent );
762     if( image )
763     {
764       return image.GetUrl();
765     }
766   }
767   return std::string();
768 }
769
770 std::string Button::GetDisabledSelectedImageFilename() const
771 {
772   if( mDisabledSelectedContent )
773   {
774     ResourceImage image = ResourceImage::DownCast( mDisabledSelectedContent );
775     if( image )
776     {
777       return image.GetUrl();
778     }
779   }
780   return std::string();
781 }
782
783 std::string Button::GetDisabledBackgroundImageFilename() const
784 {
785   if( mDisabledBackgroundContent )
786   {
787     ResourceImage image = ResourceImage::DownCast( mDisabledBackgroundContent );
788     if( image )
789     {
790       return image.GetUrl();
791     }
792   }
793   return std::string();
794 }
795
796 bool Button::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
797 {
798   bool ret = false;
799
800   Dali::BaseHandle handle( object );
801
802   Toolkit::Button button = Toolkit::Button::DownCast( handle );
803
804   DALI_ASSERT_ALWAYS( button );
805
806   if( 0 == strcmp( actionName.c_str(), ACTION_BUTTON_CLICK ) )
807   {
808     ret = GetImplementation( button ).DoClickAction( attributes );
809   }
810
811   return ret;
812 }
813
814 bool Button::DoClickAction( const Property::Map& attributes )
815 {
816   // Prevents the button signals from doing a recursive loop by sending an action
817   // and re-emitting the signals.
818   if( !mClickActionPerforming )
819   {
820     mClickActionPerforming = true;
821     OnButtonDown();
822     mState = ButtonDown;
823     OnButtonUp();
824     mClickActionPerforming = false;
825
826     return true;
827   }
828
829   return false;
830 }
831
832 void Button::OnButtonStageDisconnection()
833 {
834   if( ButtonDown == mState )
835   {
836     if( !mTogglableButton )
837     {
838       Released();
839
840       if( mAutoRepeating )
841       {
842         mAutoRepeatingTimer.Reset();
843       }
844     }
845   }
846 }
847
848 void Button::OnButtonDown()
849 {
850   if( !mTogglableButton )
851   {
852     Pressed();
853
854     if( mAutoRepeating )
855     {
856       SetUpTimer( mInitialAutoRepeatingDelay );
857     }
858   }
859
860   // The pressed signal should be emitted regardless of toggle mode.
861   Toolkit::Button handle( GetOwner() );
862   mPressedSignal.Emit( handle );
863 }
864
865 void Button::OnButtonUp()
866 {
867   if( ButtonDown == mState )
868   {
869     if( mTogglableButton )
870     {
871       SetSelected( !mSelected );
872     }
873     else
874     {
875       Released();
876
877       if( mAutoRepeating )
878       {
879         mAutoRepeatingTimer.Reset();
880       }
881     }
882
883     // The clicked and released signals should be emitted regardless of toggle mode.
884     Toolkit::Button handle( GetOwner() );
885     mReleasedSignal.Emit( handle );
886     mClickedSignal.Emit( handle );
887   }
888 }
889
890 void Button::OnTouchPointLeave()
891 {
892   if( ButtonDown == mState )
893   {
894     if( !mTogglableButton )
895     {
896       Released();
897
898       if( mAutoRepeating )
899       {
900         mAutoRepeatingTimer.Reset();
901       }
902     }
903
904     // The released signal should be emitted regardless of toggle mode.
905     Toolkit::Button handle( GetOwner() );
906     mReleasedSignal.Emit( handle );
907   }
908 }
909
910 void Button::OnTouchPointInterrupted()
911 {
912   OnTouchPointLeave();
913 }
914
915 Toolkit::Button::ButtonSignalType& Button::PressedSignal()
916 {
917   return mPressedSignal;
918 }
919
920 Toolkit::Button::ButtonSignalType& Button::ReleasedSignal()
921 {
922   return mReleasedSignal;
923 }
924
925 Toolkit::Button::ButtonSignalType& Button::ClickedSignal()
926 {
927   return mClickedSignal;
928 }
929
930 Toolkit::Button::ButtonSignalType& Button::StateChangedSignal()
931 {
932   return mStateChangedSignal;
933 }
934
935 bool Button::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
936 {
937   Dali::BaseHandle handle( object );
938
939   bool connected( true );
940   Toolkit::Button button = Toolkit::Button::DownCast( handle );
941
942   if( 0 == strcmp( signalName.c_str(), SIGNAL_PRESSED ) )
943   {
944     button.PressedSignal().Connect( tracker, functor );
945   }
946   else if( 0 == strcmp( signalName.c_str(), SIGNAL_RELEASED ) )
947   {
948     button.ReleasedSignal().Connect( tracker, functor );
949   }
950   else if( 0 == strcmp( signalName.c_str(), SIGNAL_CLICKED ) )
951   {
952     button.ClickedSignal().Connect( tracker, functor );
953   }
954   else if( 0 == strcmp( signalName.c_str(), SIGNAL_STATE_CHANGED ) )
955   {
956     button.StateChangedSignal().Connect( tracker, functor );
957   }
958   else
959   {
960     // signalName does not match any signal
961     connected = false;
962   }
963
964   return connected;
965 }
966
967 bool Button::OnTouchEvent(const TouchEvent& event)
968 {
969   // Only events are processed when the button is not disabled and the touch event has only
970   // one touch point.
971   if( ( !mDisabled ) && ( 1 == event.GetPointCount() ) )
972   {
973     switch( event.GetPoint(0).state )
974     {
975       case TouchPoint::Down:
976       {
977         OnButtonDown(); // Notification for derived classes.
978
979         // Sets the button state to ButtonDown.
980         mState = ButtonDown;
981         break;
982       }
983       case TouchPoint::Up:
984       {
985         OnButtonUp(); // Notification for derived classes.
986
987         // Sets the button state to ButtonUp.
988         mState = ButtonUp;
989         break;
990       }
991       case TouchPoint::Interrupted:
992       {
993         OnTouchPointInterrupted(); // Notification for derived classes.
994
995         // Sets the button state to the default (ButtonUp).
996         mState = ButtonUp;
997         break;
998       }
999       case TouchPoint::Leave:
1000       {
1001         OnTouchPointLeave(); // Notification for derived classes.
1002
1003         // Sets the button state to the default (ButtonUp).
1004         mState = ButtonUp;
1005         break;
1006       }
1007       case TouchPoint::Motion:
1008       case TouchPoint::Stationary: // FALLTHROUGH
1009       {
1010         // Nothing to do
1011         break;
1012       }
1013       default:
1014       {
1015         DALI_ASSERT_ALWAYS( !"Point status unhandled." );
1016         break;
1017       }
1018     }
1019   }
1020   else if( 1 < event.GetPointCount() )
1021   {
1022     OnTouchPointLeave(); // Notification for derived classes.
1023
1024     // Sets the button state to the default (ButtonUp).
1025     mState = ButtonUp;
1026   }
1027
1028   return false;
1029 }
1030
1031 void Button::OnInitialize()
1032 {
1033   Actor self = Self();
1034
1035   mTapDetector = TapGestureDetector::New();
1036   mTapDetector.Attach( self );
1037   mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
1038
1039   OnButtonInitialize();
1040
1041   self.SetKeyboardFocusable( true );
1042 }
1043
1044 bool Button::OnAccessibilityActivated()
1045 {
1046   return OnKeyboardEnter();
1047 }
1048
1049 bool Button::OnKeyboardEnter()
1050 {
1051   // When the enter key is pressed, or button is activated, the click action is performed.
1052   Property::Map attributes;
1053   bool ret = DoClickAction( attributes );
1054
1055   return ret;
1056 }
1057
1058 void Button::OnControlStageDisconnection()
1059 {
1060   OnButtonStageDisconnection(); // Notification for derived classes.
1061   mState = ButtonUp;
1062 }
1063
1064 void Button::OnTap(Actor actor, const TapGesture& tap)
1065 {
1066   // Do nothing.
1067 }
1068
1069 void Button::SetUpTimer( float delay )
1070 {
1071   mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
1072   mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot );
1073   mAutoRepeatingTimer.Start();
1074 }
1075
1076 bool Button::AutoRepeatingSlot()
1077 {
1078   bool consumed = false;
1079   if( !mDisabled )
1080   {
1081     // Restart the autorepeat timer.
1082     SetUpTimer( mNextAutoRepeatingDelay );
1083
1084     Pressed();
1085
1086     Toolkit::Button handle( GetOwner() );
1087
1088     //Emit signal.
1089     consumed = mReleasedSignal.Emit( handle );
1090     consumed |= mClickedSignal.Emit( handle );
1091     consumed |= mPressedSignal.Emit( handle );
1092  }
1093
1094   return consumed;
1095 }
1096
1097 void Button::Pressed()
1098 {
1099   if( mPaintState == UnselectedState )
1100   {
1101     StopTransitionAnimation();
1102
1103     // Notifies the derived class the button has been pressed.
1104     OnPressed();
1105
1106     //Layer Order
1107     //(4) mSelectedContent (Inserted)
1108     //(3) mUnselectedContent
1109     //(2) mSelectedBackgroundContent (Inserted)
1110     //(1) mBackgroundContent
1111
1112     AddButtonImage( mBackgroundContent );
1113     TransitionButtonImage( mSelectedBackgroundContent );
1114     AddButtonImage( mUnselectedContent );
1115     TransitionButtonImage( mSelectedContent );
1116
1117     AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1118     TransitionButtonImage( mDecoration[ SELECTED_DECORATION ] );
1119     ReAddLabel();
1120
1121     TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
1122     TransitionOut( mUnselectedContent );
1123     TransitionOut( mDisabledContent );
1124     TransitionOut( mDisabledSelectedContent );
1125     TransitionOut( mDisabledBackgroundContent );
1126
1127     mPaintState = SelectedState;
1128
1129     StartTransitionAnimation();
1130   }
1131 }
1132
1133 void Button::Released()
1134 {
1135   if( mPaintState == SelectedState )
1136   {
1137     StopTransitionAnimation();
1138
1139     // Notifies the derived class the button has been released.
1140     OnReleased();
1141
1142     //Layer Order
1143     //(3) mUnselectedContent (Inserted)
1144     //(2) mSelectedContent
1145     //(1) mBackgroundContent
1146
1147     AddButtonImage( mBackgroundContent );
1148     AddButtonImage( mSelectedContent );
1149     TransitionButtonImage( mUnselectedContent );
1150
1151     AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1152     TransitionButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1153     ReAddLabel();
1154
1155     TransitionOut( mDecoration[ SELECTED_DECORATION ] );
1156     TransitionOut( mSelectedContent );
1157     TransitionOut( mSelectedBackgroundContent );
1158     TransitionOut( mDisabledContent );
1159     TransitionOut( mDisabledSelectedContent );
1160     TransitionOut( mDisabledBackgroundContent );
1161
1162     mPaintState = UnselectedState;
1163
1164     StartTransitionAnimation();
1165   }
1166 }
1167
1168 Button::ButtonState Button::GetState()
1169 {
1170   return mState;
1171 }
1172
1173 Button::PaintState Button::GetPaintState()
1174 {
1175   return mPaintState;
1176 }
1177
1178 void Button::PrepareAddButtonImage( Actor& actor )
1179 {
1180   if( actor )
1181   {
1182     actor.Unparent();
1183     Self().Add( actor );
1184     PrepareForTranstionOut( actor );
1185   }
1186 }
1187
1188 void Button::TransitionButtonImage( Actor& actor )
1189 {
1190   if( actor )
1191   {
1192     if( !actor.GetParent() )
1193     {
1194       Self().Add( actor );
1195     }
1196
1197     OnTransitionIn( actor );
1198   }
1199 }
1200
1201 void Button::AddButtonImage( Actor& actor )
1202 {
1203   if( actor )
1204   {
1205     actor.Unparent();
1206     Self().Add( actor );
1207   }
1208 }
1209
1210 void Button::ReAddLabel()
1211 {
1212   if( mLabel )
1213   {
1214     mLabel.Unparent();
1215     Self().Add( mLabel );
1216   }
1217 }
1218
1219 void Button::RemoveButtonImage( Actor& actor )
1220 {
1221   if( actor )
1222   {
1223     if( actor.GetParent() )
1224     {
1225       Self().Remove( actor );
1226     }
1227     PrepareForTranstionIn( actor );
1228   }
1229 }
1230
1231 unsigned int Button::FindChildIndex( Actor& actor )
1232 {
1233   Actor self = Self();
1234   unsigned int childrenNum = self.GetChildCount();
1235
1236   for( unsigned int i = 0; i < childrenNum; i++ )
1237   {
1238     Actor child = self.GetChildAt( i );
1239     if( child == actor )
1240     {
1241       return i;
1242     }
1243   }
1244
1245   return childrenNum;
1246 }
1247
1248 void Button::TransitionOut( Actor actor )
1249 {
1250   OnTransitionOut( actor );
1251 }
1252
1253 void Button::ResetImageLayers()
1254 {
1255   // Ensure that all layers are in the correct order and state according to the paint state
1256
1257   switch( mPaintState )
1258   {
1259     case UnselectedState:
1260     {
1261       //Layer Order
1262       //(2) mUnselectedContent
1263       //(1) mBackgroundContent
1264
1265       RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1266       RemoveButtonImage( mSelectedContent );
1267       RemoveButtonImage( mSelectedBackgroundContent );
1268       RemoveButtonImage( mDisabledContent );
1269       RemoveButtonImage( mDisabledSelectedContent );
1270       RemoveButtonImage( mDisabledBackgroundContent );
1271
1272       PrepareAddButtonImage( mBackgroundContent );
1273       PrepareAddButtonImage( mUnselectedContent );
1274
1275       PrepareAddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1276       ReAddLabel();
1277       break;
1278     }
1279     case SelectedState:
1280     {
1281       //Layer Order
1282       //(3) mSelectedContent
1283       //(2) mSelectedBackgroundContent
1284       //(1) mBackgroundContent
1285
1286       RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1287       RemoveButtonImage( mUnselectedContent );
1288       RemoveButtonImage( mDisabledContent );
1289       RemoveButtonImage( mDisabledSelectedContent );
1290       RemoveButtonImage( mDisabledBackgroundContent );
1291
1292       PrepareAddButtonImage( mBackgroundContent );
1293       PrepareAddButtonImage( mSelectedBackgroundContent );
1294       PrepareAddButtonImage( mSelectedContent );
1295
1296       PrepareAddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1297       ReAddLabel();
1298       break;
1299     }
1300     case DisabledUnselectedState:
1301     {
1302       //Layer Order
1303       //(2) mDisabledContent
1304       //(1) mDisabledBackgroundContent
1305
1306       RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1307       RemoveButtonImage( mUnselectedContent );
1308       RemoveButtonImage( mBackgroundContent );
1309       RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1310       RemoveButtonImage( mSelectedContent );
1311       RemoveButtonImage( mDisabledSelectedContent );
1312       RemoveButtonImage( mSelectedBackgroundContent );
1313
1314       PrepareAddButtonImage( mDisabledBackgroundContent ? mDisabledBackgroundContent : mBackgroundContent );
1315       PrepareAddButtonImage( mDisabledContent ? mDisabledContent : mUnselectedContent );
1316
1317       PrepareAddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1318       ReAddLabel();
1319       break;
1320     }
1321     case DisabledSelectedState:
1322     {
1323       //Layer Order
1324       // (2) mDisabledSelectedContent
1325       // (1) mDisabledBackgroundContent
1326
1327       RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1328       RemoveButtonImage( mUnselectedContent );
1329       RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1330       RemoveButtonImage( mSelectedContent );
1331       RemoveButtonImage( mBackgroundContent );
1332       RemoveButtonImage( mSelectedBackgroundContent );
1333       RemoveButtonImage( mDisabledContent );
1334
1335       if( mDisabledBackgroundContent )
1336       {
1337         PrepareAddButtonImage( mDisabledBackgroundContent );
1338       }
1339       else
1340       {
1341         PrepareAddButtonImage( mBackgroundContent );
1342         PrepareAddButtonImage( mSelectedBackgroundContent );
1343       }
1344
1345       PrepareAddButtonImage( mDisabledSelectedContent ? mDisabledSelectedContent : mSelectedContent );
1346
1347       PrepareAddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1348       ReAddLabel();
1349       break;
1350     }
1351   }
1352 }
1353
1354 void Button::StartTransitionAnimation()
1355 {
1356   if( mTransitionAnimation )
1357   {
1358     mTransitionAnimation.Play();
1359   }
1360   else
1361   {
1362     ResetImageLayers();
1363   }
1364 }
1365
1366 void Button::StopTransitionAnimation()
1367 {
1368   if( mTransitionAnimation )
1369   {
1370     mTransitionAnimation.Clear();
1371     mTransitionAnimation.Reset();
1372   }
1373 }
1374
1375 Dali::Animation Button::GetTransitionAnimation()
1376 {
1377   if( !mTransitionAnimation )
1378   {
1379     mTransitionAnimation = Dali::Animation::New( GetAnimationTime() );
1380     mTransitionAnimation.FinishedSignal().Connect( this, &Button::TransitionAnimationFinished );
1381   }
1382
1383   return mTransitionAnimation;
1384 }
1385
1386 void Button::TransitionAnimationFinished( Dali::Animation& source )
1387 {
1388   StopTransitionAnimation();
1389   ResetImageLayers();
1390 }
1391
1392 void Button::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
1393 {
1394   Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1395
1396   if ( button )
1397   {
1398     switch ( index )
1399     {
1400       case Toolkit::Button::Property::DISABLED:
1401       {
1402         GetImplementation( button ).SetDisabled( value.Get< bool >() );
1403         break;
1404       }
1405
1406       case Toolkit::Button::Property::AUTO_REPEATING:
1407       {
1408         GetImplementation( button ).SetAutoRepeating( value.Get< bool >() );
1409         break;
1410       }
1411
1412       case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1413       {
1414         GetImplementation( button ).SetInitialAutoRepeatingDelay( value.Get< float >() );
1415         break;
1416       }
1417
1418       case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1419       {
1420         GetImplementation( button ).SetNextAutoRepeatingDelay( value.Get< float >() );
1421         break;
1422       }
1423
1424       case Toolkit::Button::Property::TOGGLABLE:
1425       {
1426         GetImplementation( button ).SetTogglableButton( value.Get< bool >() );
1427         break;
1428       }
1429
1430       case Toolkit::Button::Property::SELECTED:
1431       {
1432         GetImplementation( button ).SetSelected( value.Get< bool >() );
1433         break;
1434       }
1435
1436       case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1437       {
1438         GetImplementation( button ).SetUnselectedImage( value.Get< std::string >() );
1439         break;
1440       }
1441
1442       case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1443       {
1444         GetImplementation( button ).SetSelectedImage( value.Get< std::string >() );
1445         break;
1446       }
1447
1448       case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1449       {
1450         GetImplementation( button ).SetDisabledImage( value.Get< std::string >() );
1451         break;
1452       }
1453
1454       case Toolkit::Button::Property::UNSELECTED_COLOR:
1455       {
1456         GetImplementation( button ).SetUnselectedColor( value.Get< Vector4 >() );
1457         break;
1458       }
1459
1460       case Toolkit::Button::Property::SELECTED_COLOR:
1461       {
1462         GetImplementation( button ).SetSelectedColor( value.Get< Vector4 >() );
1463         break;
1464       }
1465
1466       case Toolkit::Button::Property::LABEL_TEXT:
1467       {
1468         GetImplementation( button ).SetLabelText( value.Get< std::string >() );
1469         break;
1470       }
1471     }
1472   }
1473 }
1474
1475 Property::Value Button::GetProperty( BaseObject* object, Property::Index propertyIndex )
1476 {
1477   Property::Value value;
1478
1479   Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1480
1481   if ( button )
1482   {
1483     switch ( propertyIndex )
1484     {
1485       case Toolkit::Button::Property::DISABLED:
1486       {
1487         value = GetImplementation( button ).mDisabled;
1488         break;
1489       }
1490
1491       case Toolkit::Button::Property::AUTO_REPEATING:
1492       {
1493         value = GetImplementation( button ).mAutoRepeating;
1494         break;
1495       }
1496
1497       case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1498       {
1499         value = GetImplementation( button ).mInitialAutoRepeatingDelay;
1500         break;
1501       }
1502
1503       case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1504       {
1505         value = GetImplementation( button ).mNextAutoRepeatingDelay;
1506         break;
1507       }
1508
1509       case Toolkit::Button::Property::TOGGLABLE:
1510       {
1511         value = GetImplementation( button ).mTogglableButton;
1512         break;
1513       }
1514
1515       case Toolkit::Button::Property::SELECTED:
1516       {
1517         value = GetImplementation( button ).mSelected;
1518         break;
1519       }
1520
1521       case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1522       {
1523         value = GetImplementation( button ).GetUnselectedImageFilename();
1524         break;
1525       }
1526
1527       case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1528       {
1529         value = GetImplementation( button ).GetSelectedImageFilename();
1530         break;
1531       }
1532
1533       case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1534       {
1535         value = GetImplementation( button ).GetDisabledImageFilename();
1536         break;
1537       }
1538
1539       case Toolkit::Button::Property::UNSELECTED_COLOR:
1540       {
1541         value = GetImplementation( button ).GetUnselectedColor();
1542         break;
1543       }
1544
1545       case Toolkit::Button::Property::SELECTED_COLOR:
1546       {
1547         value = GetImplementation( button ).GetSelectedColor();
1548         break;
1549       }
1550
1551       case Toolkit::Button::Property::LABEL_TEXT:
1552       {
1553         value = GetImplementation( button ).GetLabelText();
1554         break;
1555       }
1556     }
1557   }
1558
1559   return value;
1560 }
1561
1562 // Deprecated API
1563
1564 void Button::SetLabel( Actor label )
1565 {
1566   if( mLabel != label )
1567   {
1568     if( mLabel && mLabel.GetParent() )
1569     {
1570       mLabel.GetParent().Remove( mLabel );
1571     }
1572
1573     mLabel = label;
1574     mLabel.SetProperty( Toolkit::Control::Property::STYLE_NAME, STYLE_BUTTON_LABEL );
1575     mLabel.SetPosition( 0.f, 0.f );
1576
1577     // label should be the top of the button
1578     Self().Add( mLabel );
1579
1580     ResetImageLayers();
1581     OnLabelSet( true );
1582
1583     RelayoutRequest();
1584   }
1585 }
1586
1587 void Button::SetButtonImage( Actor image )
1588 {
1589   if( image )
1590   {
1591     StopTransitionAnimation();
1592
1593     SetupContent( mUnselectedContent, image );
1594
1595     OnUnselectedImageSet();
1596     RelayoutRequest();
1597   }
1598 }
1599
1600 void Button::SetSelectedImage( Actor image )
1601 {
1602   if( image )
1603   {
1604     StopTransitionAnimation();
1605
1606     SetupContent( mSelectedContent, image );
1607
1608     OnSelectedImageSet();
1609     RelayoutRequest();
1610   }
1611 }
1612
1613 void Button::SetBackgroundImage( Actor image )
1614 {
1615   if( image )
1616   {
1617     StopTransitionAnimation();
1618
1619     SetupContent( mBackgroundContent, image );
1620
1621     OnBackgroundImageSet();
1622     RelayoutRequest();
1623   }
1624 }
1625
1626 void Button::SetSelectedBackgroundImage( Actor image )
1627 {
1628   if( image )
1629   {
1630     StopTransitionAnimation();
1631
1632     SetupContent( mSelectedBackgroundContent, image );
1633
1634     OnSelectedBackgroundImageSet();
1635     RelayoutRequest();
1636   }
1637 }
1638
1639 void Button::SetDisabledImage( Actor image )
1640 {
1641   if( image )
1642   {
1643     StopTransitionAnimation();
1644
1645     SetupContent( mDisabledContent, image );
1646
1647     OnDisabledImageSet();
1648     RelayoutRequest();
1649   }
1650 }
1651
1652 void Button::SetDisabledSelectedImage( Actor image )
1653 {
1654   if( image )
1655   {
1656     StopTransitionAnimation();
1657
1658     SetupContent( mDisabledSelectedContent, image );
1659
1660     OnDisabledSelectedImageSet();
1661     RelayoutRequest();
1662   }
1663 }
1664
1665 void Button::SetDisabledBackgroundImage( Actor image )
1666 {
1667   if( image )
1668   {
1669     StopTransitionAnimation();
1670
1671     SetupContent( mDisabledBackgroundContent, image );
1672
1673     OnDisabledBackgroundImageSet();
1674     RelayoutRequest();
1675   }
1676 }
1677
1678 Actor Button::GetButtonImage() const
1679 {
1680   return mUnselectedContent;
1681 }
1682
1683 Actor Button::GetSelectedImage() const
1684 {
1685   return mSelectedContent;
1686 }
1687
1688
1689 } // namespace Internal
1690
1691 } // namespace Toolkit
1692
1693 } // namespace Dali