(Visuals) Added visual indices
[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( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
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
543   if ( selectedState == SelectedState || selectedState == DisabledSelectedState )
544   {
545     mSelectedColor = color;
546     contentActor = &mSelectedContent;
547     imageFileExists = !GetSelectedImageFilename().empty();
548   }
549   else
550   {
551     mUnselectedColor = color;
552     contentActor = &mUnselectedContent;
553     imageFileExists = !GetUnselectedImageFilename().empty();
554   }
555
556   if ( contentActor )
557   {
558     if( imageFileExists )
559     {
560       // If there is existing unselected content, change the color on it directly.
561       contentActor->SetColor( color );
562     }
563     else
564     {
565       // If there is no existing content, create a new actor to use for flat color.
566       Actor placementActor = Actor::New();
567       Toolkit::VisualFactory rendererFactory = Toolkit::VisualFactory::Get();
568       Toolkit::Visual::Base colorRenderer;
569
570       Property::Map map;
571       map[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::COLOR;
572       map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color;
573
574       colorRenderer = rendererFactory.CreateVisual( map );
575       colorRenderer.SetOnStage( placementActor );
576
577       SetupContent( *contentActor, placementActor ); //
578       contentActor->SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
579     }
580   }
581 }
582
583 const Vector4 Button::GetSelectedColor() const
584 {
585   return mSelectedColor;
586 }
587
588 void Button::SetUnselectedImage( const std::string& filename )
589 {
590   Toolkit::ImageView newContent;
591   if( !filename.empty() )
592   {
593     newContent = Toolkit::ImageView::New( filename );
594   }
595   else
596   {
597     newContent = Toolkit::ImageView::New();
598   }
599
600   if( newContent )
601   {
602     SetupContent( mUnselectedContent, newContent );
603
604     mUnselectedContent.SetColor( mUnselectedColor );
605
606     OnUnselectedImageSet();
607     RelayoutRequest();
608   }
609 }
610
611 Actor& Button::GetUnselectedImage()
612 {
613   return mUnselectedContent;
614 }
615
616 void Button::SetSelectedImage( const std::string& filename )
617 {
618   Toolkit::ImageView newContent;
619   if( !filename.empty() )
620   {
621    newContent = Toolkit::ImageView::New( filename );
622   }
623   else
624   {
625     newContent = Toolkit::ImageView::New();
626   }
627
628   if( newContent )
629   {
630     SetupContent( mSelectedContent, newContent );
631
632     mSelectedContent.SetColor( mSelectedColor );
633
634     OnSelectedImageSet();
635     RelayoutRequest();
636   }
637 }
638
639 Actor& Button::GetSelectedImage()
640 {
641   return mSelectedContent;
642 }
643
644 void Button::SetBackgroundImage( const std::string& filename )
645 {
646   SetupContent( mBackgroundContent, Toolkit::ImageView::New( filename ) );
647
648   OnBackgroundImageSet();
649   RelayoutRequest();
650 }
651
652 Actor& Button::GetBackgroundImage()
653 {
654   return mBackgroundContent;
655 }
656
657 void Button::SetSelectedBackgroundImage( const std::string& filename )
658 {
659   SetupContent( mSelectedBackgroundContent, Toolkit::ImageView::New( filename ) );
660
661   OnSelectedBackgroundImageSet();
662   RelayoutRequest();
663 }
664
665 Actor& Button::GetSelectedBackgroundImage()
666 {
667   return mSelectedBackgroundContent;
668 }
669
670 void Button::SetDisabledImage( const std::string& filename )
671 {
672   SetupContent( mDisabledContent, Toolkit::ImageView::New( filename ) );
673
674   OnDisabledImageSet();
675   RelayoutRequest();
676 }
677
678 Actor& Button::GetDisabledImage()
679 {
680   return mDisabledContent;
681 }
682
683 void Button::SetDisabledSelectedImage( const std::string& filename )
684 {
685   SetupContent( mDisabledSelectedContent, Toolkit::ImageView::New( filename ) );
686
687   OnDisabledSelectedImageSet();
688   RelayoutRequest();
689 }
690
691 Actor& Button::GetDisabledSelectedImage()
692 {
693   return mDisabledSelectedContent;
694 }
695
696 void Button::SetDisabledBackgroundImage( const std::string& filename )
697 {
698   SetupContent( mDisabledBackgroundContent, Toolkit::ImageView::New( filename ) );
699
700   OnDisabledBackgroundImageSet();
701   RelayoutRequest();
702 }
703
704 Actor& Button::GetDisabledBackgroundImage()
705 {
706   return mDisabledBackgroundContent;
707 }
708
709 std::string Button::GetUnselectedImageFilename() const
710 {
711   if( mUnselectedContent )
712   {
713     ResourceImage image = ResourceImage::DownCast( mUnselectedContent );
714     if( image )
715     {
716       return image.GetUrl();
717     }
718   }
719   return std::string();
720 }
721
722 std::string Button::GetSelectedImageFilename() const
723 {
724   if( mSelectedContent )
725   {
726     ResourceImage image = ResourceImage::DownCast( mSelectedContent );
727     if( image )
728     {
729       return image.GetUrl();
730     }
731   }
732   return std::string();
733 }
734
735 std::string Button::GetDisabledImageFilename() const
736 {
737   if( mDisabledContent )
738   {
739     ResourceImage image = ResourceImage::DownCast( mDisabledContent );
740     if( image )
741     {
742       return image.GetUrl();
743     }
744   }
745   return std::string();
746 }
747
748 bool Button::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
749 {
750   bool ret = false;
751
752   Dali::BaseHandle handle( object );
753
754   Toolkit::Button button = Toolkit::Button::DownCast( handle );
755
756   DALI_ASSERT_ALWAYS( button );
757
758   if( 0 == strcmp( actionName.c_str(), ACTION_BUTTON_CLICK ) )
759   {
760     ret = GetImplementation( button ).DoClickAction( attributes );
761   }
762
763   return ret;
764 }
765
766 bool Button::DoClickAction( const Property::Map& attributes )
767 {
768   // Prevents the button signals from doing a recursive loop by sending an action
769   // and re-emitting the signals.
770   if( !mClickActionPerforming )
771   {
772     mClickActionPerforming = true;
773     OnButtonDown();
774     mState = ButtonDown;
775     OnButtonUp();
776     mClickActionPerforming = false;
777
778     return true;
779   }
780
781   return false;
782 }
783
784 void Button::OnButtonDown()
785 {
786   if( !mTogglableButton )
787   {
788     Pressed();
789
790     if( mAutoRepeating )
791     {
792       SetUpTimer( mInitialAutoRepeatingDelay );
793     }
794   }
795
796   // The pressed signal should be emitted regardless of toggle mode.
797   Toolkit::Button handle( GetOwner() );
798   mPressedSignal.Emit( handle );
799 }
800
801 void Button::OnButtonUp()
802 {
803   if( ButtonDown == mState )
804   {
805     if( mTogglableButton )
806     {
807       SetSelected( !mSelected );
808     }
809     else
810     {
811       Released();
812
813       if( mAutoRepeating )
814       {
815         mAutoRepeatingTimer.Reset();
816       }
817     }
818
819     // The clicked and released signals should be emitted regardless of toggle mode.
820     Toolkit::Button handle( GetOwner() );
821     mReleasedSignal.Emit( handle );
822     mClickedSignal.Emit( handle );
823   }
824 }
825
826 void Button::OnTouchPointLeave()
827 {
828   if( ButtonDown == mState )
829   {
830     if( !mTogglableButton )
831     {
832       Released();
833
834       if( mAutoRepeating )
835       {
836         mAutoRepeatingTimer.Reset();
837       }
838     }
839
840     // The released signal should be emitted regardless of toggle mode.
841     Toolkit::Button handle( GetOwner() );
842     mReleasedSignal.Emit( handle );
843   }
844 }
845
846 void Button::OnTouchPointInterrupted()
847 {
848   OnTouchPointLeave();
849 }
850
851 Toolkit::Button::ButtonSignalType& Button::PressedSignal()
852 {
853   return mPressedSignal;
854 }
855
856 Toolkit::Button::ButtonSignalType& Button::ReleasedSignal()
857 {
858   return mReleasedSignal;
859 }
860
861 Toolkit::Button::ButtonSignalType& Button::ClickedSignal()
862 {
863   return mClickedSignal;
864 }
865
866 Toolkit::Button::ButtonSignalType& Button::StateChangedSignal()
867 {
868   return mStateChangedSignal;
869 }
870
871 bool Button::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
872 {
873   Dali::BaseHandle handle( object );
874
875   bool connected( true );
876   Toolkit::Button button = Toolkit::Button::DownCast( handle );
877
878   if( 0 == strcmp( signalName.c_str(), SIGNAL_PRESSED ) )
879   {
880     button.PressedSignal().Connect( tracker, functor );
881   }
882   else if( 0 == strcmp( signalName.c_str(), SIGNAL_RELEASED ) )
883   {
884     button.ReleasedSignal().Connect( tracker, functor );
885   }
886   else if( 0 == strcmp( signalName.c_str(), SIGNAL_CLICKED ) )
887   {
888     button.ClickedSignal().Connect( tracker, functor );
889   }
890   else if( 0 == strcmp( signalName.c_str(), SIGNAL_STATE_CHANGED ) )
891   {
892     button.StateChangedSignal().Connect( tracker, functor );
893   }
894   else
895   {
896     // signalName does not match any signal
897     connected = false;
898   }
899
900   return connected;
901 }
902
903 void Button::OnInitialize()
904 {
905   Actor self = Self();
906
907   mTapDetector = TapGestureDetector::New();
908   mTapDetector.Attach( self );
909   mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
910
911   self.SetKeyboardFocusable( true );
912
913   self.TouchSignal().Connect( this, &Button::OnTouch );
914 }
915
916 bool Button::OnAccessibilityActivated()
917 {
918   return OnKeyboardEnter();
919 }
920
921 bool Button::OnKeyboardEnter()
922 {
923   // When the enter key is pressed, or button is activated, the click action is performed.
924   Property::Map attributes;
925   bool ret = DoClickAction( attributes );
926
927   return ret;
928 }
929
930 void Button::OnStageDisconnection()
931 {
932   if( ButtonDown == mState )
933   {
934     if( !mTogglableButton )
935     {
936       Released();
937
938       if( mAutoRepeating )
939       {
940         mAutoRepeatingTimer.Reset();
941       }
942     }
943   }
944
945   mState = ButtonUp;
946
947   Control::OnStageDisconnection();
948 }
949
950 bool Button::OnTouch( Actor actor, const TouchData& touch )
951 {
952   // Only events are processed when the button is not disabled and the touch event has only
953   // one touch point.
954   if( ( !mDisabled ) && ( 1 == touch.GetPointCount() ) )
955   {
956     switch( touch.GetState( 0 ) )
957     {
958       case PointState::DOWN:
959       {
960         OnButtonDown(); // Notification for derived classes.
961
962         // Sets the button state to ButtonDown.
963         mState = ButtonDown;
964         break;
965       }
966       case PointState::UP:
967       {
968         OnButtonUp(); // Notification for derived classes.
969
970         // Sets the button state to ButtonUp.
971         mState = ButtonUp;
972         break;
973       }
974       case PointState::INTERRUPTED:
975       {
976         OnTouchPointInterrupted(); // Notification for derived classes.
977
978         // Sets the button state to the default (ButtonUp).
979         mState = ButtonUp;
980         break;
981       }
982       case PointState::LEAVE:
983       {
984         OnTouchPointLeave(); // Notification for derived classes.
985
986         // Sets the button state to the default (ButtonUp).
987         mState = ButtonUp;
988         break;
989       }
990       case PointState::MOTION:
991       case PointState::STATIONARY: // FALLTHROUGH
992       {
993         // Nothing to do
994         break;
995       }
996     }
997   }
998   else if( 1 < touch.GetPointCount() )
999   {
1000     OnTouchPointLeave(); // Notification for derived classes.
1001
1002     // Sets the button state to the default (ButtonUp).
1003     mState = ButtonUp;
1004   }
1005
1006   return false;
1007 }
1008
1009 void Button::OnTap(Actor actor, const TapGesture& tap)
1010 {
1011   // Do nothing.
1012 }
1013
1014 void Button::SetUpTimer( float delay )
1015 {
1016   mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
1017   mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot );
1018   mAutoRepeatingTimer.Start();
1019 }
1020
1021 bool Button::AutoRepeatingSlot()
1022 {
1023   bool consumed = false;
1024   if( !mDisabled )
1025   {
1026     // Restart the autorepeat timer.
1027     SetUpTimer( mNextAutoRepeatingDelay );
1028
1029     Pressed();
1030
1031     Toolkit::Button handle( GetOwner() );
1032
1033     //Emit signal.
1034     consumed = mReleasedSignal.Emit( handle );
1035     consumed |= mClickedSignal.Emit( handle );
1036     consumed |= mPressedSignal.Emit( handle );
1037  }
1038
1039   return consumed;
1040 }
1041
1042 void Button::Pressed()
1043 {
1044   if( mPaintState == UnselectedState )
1045   {
1046     StopTransitionAnimation();
1047
1048     // Notifies the derived class the button has been pressed.
1049     OnPressed();
1050
1051     //Layer Order
1052     //(4) mSelectedContent (Inserted)
1053     //(3) mUnselectedContent
1054     //(2) mSelectedBackgroundContent (Inserted)
1055     //(1) mBackgroundContent
1056
1057     AddButtonImage( mBackgroundContent );
1058     TransitionButtonImage( mSelectedBackgroundContent );
1059     AddButtonImage( mUnselectedContent );
1060     TransitionButtonImage( mSelectedContent );
1061
1062     AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1063     TransitionButtonImage( mDecoration[ SELECTED_DECORATION ] );
1064     ReAddLabel();
1065
1066     TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
1067     TransitionOut( mUnselectedContent );
1068     TransitionOut( mDisabledContent );
1069     TransitionOut( mDisabledSelectedContent );
1070     TransitionOut( mDisabledBackgroundContent );
1071
1072     mPaintState = SelectedState;
1073
1074     StartTransitionAnimation();
1075   }
1076 }
1077
1078 void Button::Released()
1079 {
1080   if( mPaintState == SelectedState )
1081   {
1082     StopTransitionAnimation();
1083
1084     // Notifies the derived class the button has been released.
1085     OnReleased();
1086
1087     //Layer Order
1088     //(3) mUnselectedContent (Inserted)
1089     //(2) mSelectedContent
1090     //(1) mBackgroundContent
1091
1092     AddButtonImage( mBackgroundContent );
1093     AddButtonImage( mSelectedContent );
1094     TransitionButtonImage( mUnselectedContent );
1095
1096     AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1097     TransitionButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1098     ReAddLabel();
1099
1100     TransitionOut( mDecoration[ SELECTED_DECORATION ] );
1101     TransitionOut( mSelectedContent );
1102     TransitionOut( mSelectedBackgroundContent );
1103     TransitionOut( mDisabledContent );
1104     TransitionOut( mDisabledSelectedContent );
1105     TransitionOut( mDisabledBackgroundContent );
1106
1107     mPaintState = UnselectedState;
1108
1109     StartTransitionAnimation();
1110   }
1111 }
1112
1113 Button::ButtonState Button::GetState()
1114 {
1115   return mState;
1116 }
1117
1118 Button::PaintState Button::GetPaintState()
1119 {
1120   return mPaintState;
1121 }
1122
1123 void Button::PrepareAddButtonImage( Actor& actor )
1124 {
1125   if( actor )
1126   {
1127     Self().Add( actor );
1128     PrepareForTranstionOut( actor );
1129   }
1130 }
1131
1132 void Button::TransitionButtonImage( Actor& actor )
1133 {
1134   if( actor )
1135   {
1136     if( !actor.GetParent() )
1137     {
1138       Self().Add( actor );
1139     }
1140
1141     OnTransitionIn( actor );
1142   }
1143 }
1144
1145 void Button::AddButtonImage( Actor& actor )
1146 {
1147   if( actor )
1148   {
1149     Self().Add( actor );
1150   }
1151 }
1152
1153 void Button::ReAddLabel()
1154 {
1155   if( mLabel )
1156   {
1157     mLabel.Unparent();
1158     Self().Add( mLabel );
1159   }
1160 }
1161
1162 void Button::RemoveButtonImage( Actor& actor )
1163 {
1164   if( actor )
1165   {
1166     if( actor.GetParent() )
1167     {
1168       Self().Remove( actor );
1169     }
1170     PrepareForTranstionIn( actor );
1171   }
1172 }
1173
1174 unsigned int Button::FindChildIndex( Actor& actor )
1175 {
1176   Actor self = Self();
1177   unsigned int childrenNum = self.GetChildCount();
1178
1179   for( unsigned int i = 0; i < childrenNum; i++ )
1180   {
1181     Actor child = self.GetChildAt( i );
1182     if( child == actor )
1183     {
1184       return i;
1185     }
1186   }
1187
1188   return childrenNum;
1189 }
1190
1191 void Button::TransitionOut( Actor actor )
1192 {
1193   OnTransitionOut( actor );
1194 }
1195
1196 void Button::ResetImageLayers()
1197 {
1198   // Ensure that all layers are in the correct order and state according to the paint state
1199
1200   switch( mPaintState )
1201   {
1202     case UnselectedState:
1203     {
1204       //Layer Order
1205       //(2) mUnselectedContent
1206       //(1) mBackgroundContent
1207
1208       RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1209       RemoveButtonImage( mSelectedContent );
1210       RemoveButtonImage( mSelectedBackgroundContent );
1211       RemoveButtonImage( mDisabledContent );
1212       RemoveButtonImage( mDisabledSelectedContent );
1213       RemoveButtonImage( mDisabledBackgroundContent );
1214
1215       PrepareAddButtonImage( mBackgroundContent );
1216       PrepareAddButtonImage( mUnselectedContent );
1217
1218       PrepareAddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1219       ReAddLabel();
1220       break;
1221     }
1222     case SelectedState:
1223     {
1224       //Layer Order
1225       //(3) mSelectedContent
1226       //(2) mSelectedBackgroundContent
1227       //(1) mBackgroundContent
1228
1229       RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1230       RemoveButtonImage( mUnselectedContent );
1231       RemoveButtonImage( mDisabledContent );
1232       RemoveButtonImage( mDisabledSelectedContent );
1233       RemoveButtonImage( mDisabledBackgroundContent );
1234
1235       PrepareAddButtonImage( mBackgroundContent );
1236       PrepareAddButtonImage( mSelectedBackgroundContent );
1237       PrepareAddButtonImage( mSelectedContent );
1238
1239       PrepareAddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1240       ReAddLabel();
1241       break;
1242     }
1243     case DisabledUnselectedState:
1244     {
1245       //Layer Order
1246       //(2) mDisabledContent
1247       //(1) mDisabledBackgroundContent
1248
1249       RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1250       RemoveButtonImage( mUnselectedContent );
1251       RemoveButtonImage( mBackgroundContent );
1252       RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1253       RemoveButtonImage( mSelectedContent );
1254       RemoveButtonImage( mDisabledSelectedContent );
1255       RemoveButtonImage( mSelectedBackgroundContent );
1256
1257       PrepareAddButtonImage( mDisabledBackgroundContent ? mDisabledBackgroundContent : mBackgroundContent );
1258       PrepareAddButtonImage( mDisabledContent ? mDisabledContent : mUnselectedContent );
1259
1260       PrepareAddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1261       ReAddLabel();
1262       break;
1263     }
1264     case DisabledSelectedState:
1265     {
1266       //Layer Order
1267       // (2) mDisabledSelectedContent
1268       // (1) mDisabledBackgroundContent
1269
1270       RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1271       RemoveButtonImage( mUnselectedContent );
1272       RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1273       RemoveButtonImage( mSelectedContent );
1274       RemoveButtonImage( mBackgroundContent );
1275       RemoveButtonImage( mSelectedBackgroundContent );
1276       RemoveButtonImage( mDisabledContent );
1277
1278       if( mDisabledBackgroundContent )
1279       {
1280         PrepareAddButtonImage( mDisabledBackgroundContent );
1281       }
1282       else
1283       {
1284         PrepareAddButtonImage( mBackgroundContent );
1285         PrepareAddButtonImage( mSelectedBackgroundContent );
1286       }
1287
1288       PrepareAddButtonImage( mDisabledSelectedContent ? mDisabledSelectedContent : mSelectedContent );
1289
1290       PrepareAddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1291       ReAddLabel();
1292       break;
1293     }
1294   }
1295 }
1296
1297 void Button::StartTransitionAnimation()
1298 {
1299   if( mTransitionAnimation )
1300   {
1301     mTransitionAnimation.Play();
1302   }
1303   else
1304   {
1305     ResetImageLayers();
1306   }
1307 }
1308
1309 void Button::StopTransitionAnimation()
1310 {
1311   if( mTransitionAnimation )
1312   {
1313     mTransitionAnimation.Clear();
1314     mTransitionAnimation.Reset();
1315   }
1316 }
1317
1318 Dali::Animation Button::GetTransitionAnimation()
1319 {
1320   if( !mTransitionAnimation )
1321   {
1322     mTransitionAnimation = Dali::Animation::New( GetAnimationTime() );
1323     mTransitionAnimation.FinishedSignal().Connect( this, &Button::TransitionAnimationFinished );
1324   }
1325
1326   return mTransitionAnimation;
1327 }
1328
1329 void Button::TransitionAnimationFinished( Dali::Animation& source )
1330 {
1331   StopTransitionAnimation();
1332   ResetImageLayers();
1333 }
1334
1335 void Button::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
1336 {
1337   Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1338
1339   if ( button )
1340   {
1341     switch ( index )
1342     {
1343       case Toolkit::Button::Property::DISABLED:
1344       {
1345         GetImplementation( button ).SetDisabled( value.Get< bool >() );
1346         break;
1347       }
1348
1349       case Toolkit::Button::Property::AUTO_REPEATING:
1350       {
1351         GetImplementation( button ).SetAutoRepeating( value.Get< bool >() );
1352         break;
1353       }
1354
1355       case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1356       {
1357         GetImplementation( button ).SetInitialAutoRepeatingDelay( value.Get< float >() );
1358         break;
1359       }
1360
1361       case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1362       {
1363         GetImplementation( button ).SetNextAutoRepeatingDelay( value.Get< float >() );
1364         break;
1365       }
1366
1367       case Toolkit::Button::Property::TOGGLABLE:
1368       {
1369         GetImplementation( button ).SetTogglableButton( value.Get< bool >() );
1370         break;
1371       }
1372
1373       case Toolkit::Button::Property::SELECTED:
1374       {
1375         GetImplementation( button ).SetSelected( value.Get< bool >() );
1376         break;
1377       }
1378
1379       case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1380       {
1381         GetImplementation( button ).SetUnselectedImage( value.Get< std::string >() );
1382         break;
1383       }
1384
1385       case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1386       {
1387         GetImplementation( button ).SetSelectedImage( value.Get< std::string >() );
1388         break;
1389       }
1390
1391       case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1392       {
1393         GetImplementation( button ).SetDisabledImage( value.Get< std::string >() );
1394         break;
1395       }
1396
1397       case Toolkit::Button::Property::UNSELECTED_COLOR:
1398       {
1399         GetImplementation( button ).SetColor( value.Get< Vector4 >(), UnselectedState );
1400         break;
1401       }
1402
1403       case Toolkit::Button::Property::SELECTED_COLOR:
1404       {
1405         GetImplementation( button ).SetColor( value.Get< Vector4 >(), SelectedState );
1406         break;
1407       }
1408
1409       case Toolkit::Button::Property::LABEL_TEXT:
1410       {
1411         GetImplementation( button ).SetLabelText( value.Get< std::string >() );
1412         break;
1413       }
1414
1415       case Toolkit::Button::Property::LABEL:
1416       {
1417         // Get a Property::Map from the property if possible.
1418         Property::Map setPropertyMap;
1419         if( value.Get( setPropertyMap ) )
1420         {
1421           GetImplementation( button ).ModifyLabel( setPropertyMap );
1422         }
1423       }
1424       break;
1425     }
1426   }
1427 }
1428
1429 Property::Value Button::GetProperty( BaseObject* object, Property::Index propertyIndex )
1430 {
1431   Property::Value value;
1432
1433   Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1434
1435   if ( button )
1436   {
1437     switch ( propertyIndex )
1438     {
1439       case Toolkit::Button::Property::DISABLED:
1440       {
1441         value = GetImplementation( button ).mDisabled;
1442         break;
1443       }
1444
1445       case Toolkit::Button::Property::AUTO_REPEATING:
1446       {
1447         value = GetImplementation( button ).mAutoRepeating;
1448         break;
1449       }
1450
1451       case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1452       {
1453         value = GetImplementation( button ).mInitialAutoRepeatingDelay;
1454         break;
1455       }
1456
1457       case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1458       {
1459         value = GetImplementation( button ).mNextAutoRepeatingDelay;
1460         break;
1461       }
1462
1463       case Toolkit::Button::Property::TOGGLABLE:
1464       {
1465         value = GetImplementation( button ).mTogglableButton;
1466         break;
1467       }
1468
1469       case Toolkit::Button::Property::SELECTED:
1470       {
1471         value = GetImplementation( button ).mSelected;
1472         break;
1473       }
1474
1475       case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1476       {
1477         value = GetImplementation( button ).GetUnselectedImageFilename();
1478         break;
1479       }
1480
1481       case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1482       {
1483         value = GetImplementation( button ).GetSelectedImageFilename();
1484         break;
1485       }
1486
1487       case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1488       {
1489         value = GetImplementation( button ).GetDisabledImageFilename();
1490         break;
1491       }
1492
1493       case Toolkit::Button::Property::UNSELECTED_COLOR:
1494       {
1495         value = GetImplementation( button ).GetUnselectedColor();
1496         break;
1497       }
1498
1499       case Toolkit::Button::Property::SELECTED_COLOR:
1500       {
1501         value = GetImplementation( button ).GetSelectedColor();
1502         break;
1503       }
1504
1505       case Toolkit::Button::Property::LABEL_TEXT:
1506       {
1507         value = GetImplementation( button ).GetLabelText();
1508         break;
1509       }
1510
1511       case Toolkit::Button::Property::LABEL:
1512       {
1513         Property::Map emptyMap;
1514         value = emptyMap;
1515         break;
1516       }
1517     }
1518   }
1519
1520   return value;
1521 }
1522
1523 // Deprecated API
1524
1525 void Button::SetLabel( Actor label )
1526 {
1527   if( mLabel != label )
1528   {
1529     if( mLabel && mLabel.GetParent() )
1530     {
1531       mLabel.GetParent().Remove( mLabel );
1532     }
1533
1534     mLabel = label;
1535     mLabel.SetPosition( 0.0f, 0.0f );
1536
1537     // label should be the top of the button
1538     Self().Add( mLabel );
1539
1540     ResetImageLayers();
1541     OnLabelSet( true );
1542
1543     RelayoutRequest();
1544   }
1545 }
1546
1547 void Button::SetButtonImage( Actor image )
1548 {
1549   if( image )
1550   {
1551     StopTransitionAnimation();
1552
1553     SetupContent( mUnselectedContent, image );
1554
1555     OnUnselectedImageSet();
1556     RelayoutRequest();
1557   }
1558 }
1559
1560 void Button::SetSelectedImage( Actor image )
1561 {
1562   if( image )
1563   {
1564     StopTransitionAnimation();
1565
1566     SetupContent( mSelectedContent, image );
1567
1568     OnSelectedImageSet();
1569     RelayoutRequest();
1570   }
1571 }
1572
1573 void Button::SetBackgroundImage( Actor image )
1574 {
1575   if( image )
1576   {
1577     StopTransitionAnimation();
1578
1579     SetupContent( mBackgroundContent, image );
1580
1581     OnBackgroundImageSet();
1582     RelayoutRequest();
1583   }
1584 }
1585
1586 void Button::SetSelectedBackgroundImage( Actor image )
1587 {
1588   if( image )
1589   {
1590     StopTransitionAnimation();
1591
1592     SetupContent( mSelectedBackgroundContent, image );
1593
1594     OnSelectedBackgroundImageSet();
1595     RelayoutRequest();
1596   }
1597 }
1598
1599 void Button::SetDisabledImage( Actor image )
1600 {
1601   if( image )
1602   {
1603     StopTransitionAnimation();
1604
1605     SetupContent( mDisabledContent, image );
1606
1607     OnDisabledImageSet();
1608     RelayoutRequest();
1609   }
1610 }
1611
1612 void Button::SetDisabledSelectedImage( Actor image )
1613 {
1614   if( image )
1615   {
1616     StopTransitionAnimation();
1617
1618     SetupContent( mDisabledSelectedContent, image );
1619
1620     OnDisabledSelectedImageSet();
1621     RelayoutRequest();
1622   }
1623 }
1624
1625 void Button::SetDisabledBackgroundImage( Actor image )
1626 {
1627   if( image )
1628   {
1629     StopTransitionAnimation();
1630
1631     SetupContent( mDisabledBackgroundContent, image );
1632
1633     OnDisabledBackgroundImageSet();
1634     RelayoutRequest();
1635   }
1636 }
1637
1638 Actor Button::GetButtonImage() const
1639 {
1640   return mUnselectedContent;
1641 }
1642
1643 Actor Button::GetSelectedImage() const
1644 {
1645   return mSelectedContent;
1646 }
1647
1648
1649 } // namespace Internal
1650
1651 } // namespace Toolkit
1652
1653 } // namespace Dali