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