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