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