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