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