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