Buttons to use Visuals
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / buttons / button-impl.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "button-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <cstring> // for strcmp
23 #include <dali/devel-api/scripting/enum-helper.h>
24 #include <dali/integration-api/debug.h>
25 #include <dali/public-api/events/touch-data.h>
26 #include <dali/public-api/images/resource-image.h>
27 #include <dali/public-api/object/type-registry.h>
28 #include <dali/public-api/object/type-registry-helper.h>
29 #include <dali/public-api/size-negotiation/relayout-container.h>
30 #include <dali/devel-api/scripting/scripting.h>
31
32 // INTERNAL INCLUDES
33 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
34 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
35 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
36 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
37 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
38 #include <dali-toolkit/devel-api/align-enums.h>
39 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
40 #include <dali-toolkit/devel-api/visual-factory/devel-visual-properties.h>
41 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
42
43
44 #if defined(DEBUG_ENABLED)
45     Debug::Filter* gLogButtonFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_BUTTON_CONTROL");
46 #endif
47
48 namespace Dali
49 {
50
51 namespace Toolkit
52 {
53
54 namespace Internal
55 {
56
57 namespace
58 {
59
60 BaseHandle Create()
61 {
62   // empty handle as we cannot create button (but type registered for clicked signal)
63   return BaseHandle();
64 }
65
66 // Setup properties, signals and actions using the type-registry.
67 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Button, Toolkit::Control, Create )
68
69 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabled",                           BOOLEAN, DISABLED                              )
70 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "autoRepeating",                      BOOLEAN, AUTO_REPEATING                        )
71 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "initialAutoRepeatingDelay",          FLOAT,   INITIAL_AUTO_REPEATING_DELAY          )
72 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "nextAutoRepeatingDelay",             FLOAT,   NEXT_AUTO_REPEATING_DELAY             )
73 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "togglable",                          BOOLEAN, TOGGLABLE                             )
74 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selected",                           BOOLEAN, SELECTED                              )
75 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedStateImage",               MAP,     UNSELECTED_STATE_IMAGE                ) // Deprecated property
76 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedStateImage",                 MAP,     SELECTED_STATE_IMAGE                  ) // Deprecated property
77 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledStateImage",                 MAP,     DISABLED_STATE_IMAGE                  ) // Deprecated property
78 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedColor",                    VECTOR4, UNSELECTED_COLOR                      ) // Deprecated property
79 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedColor",                      VECTOR4, SELECTED_COLOR                        ) // Deprecated property
80 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "label",                              MAP,     LABEL                                 )
81 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "labelText",                          STRING,  LABEL_TEXT                            ) // Deprecated property
82 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedVisual",                   MAP,     UNSELECTED_VISUAL                     )
83 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedVisual",                     MAP,     SELECTED_VISUAL                       )
84 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledSelectedVisual",             MAP,     DISABLED_SELECTED_VISUAL              )
85 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledUnselectedVisual",           MAP,     DISABLED_UNSELECTED_VISUAL            )
86 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedBackgroundVisual",         MAP,     UNSELECTED_BACKGROUND_VISUAL          )
87 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedBackgroundVisual",           MAP,     SELECTED_BACKGROUND_VISUAL            )
88 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledUnselectedBackgroundVisual", MAP,     DISABLED_UNSELECTED_BACKGROUND_VISUAL )
89 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledSelectedBackgroundVisual",   MAP,     DISABLED_SELECTED_BACKGROUND_VISUAL   )
90 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "labelStrutLength",                   INTEGER, LABEL_STRUT_LENGTH                    )
91 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "labelRelativeAlignment",             STRING,  LABEL_RELATIVE_ALIGNMENT              )
92
93 // Signals:
94 DALI_SIGNAL_REGISTRATION(   Toolkit, Button, "pressed",                               SIGNAL_PRESSED               )
95 DALI_SIGNAL_REGISTRATION(   Toolkit, Button, "released",                              SIGNAL_RELEASED              )
96 DALI_SIGNAL_REGISTRATION(   Toolkit, Button, "clicked",                               SIGNAL_CLICKED               )
97 DALI_SIGNAL_REGISTRATION(   Toolkit, Button, "stateChanged",                          SIGNAL_STATE_CHANGED         )
98
99 // Actions:
100 DALI_ACTION_REGISTRATION(   Toolkit, Button, "buttonClick",                           ACTION_BUTTON_CLICK          )
101
102 DALI_TYPE_REGISTRATION_END()
103
104 DALI_ENUM_TO_STRING_TABLE_BEGIN( ALIGNMENT )
105 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, BEGIN )
106 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, END )
107 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, TOP )
108 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, BOTTOM )
109 DALI_ENUM_TO_STRING_TABLE_END( ALIGNMENT )
110
111 const Scripting::StringEnum ALIGNMENT_STRING_TABLE[] =
112 {
113   { "BEGIN",  Button::BEGIN   },
114   { "END",    Button::END     },
115   { "TOP",    Button::TOP     },
116   { "BOTTOM", Button::BOTTOM  },
117 };
118
119 const unsigned int ALIGNMENT_STRING_TABLE_COUNT = sizeof( ALIGNMENT_STRING_TABLE ) / sizeof( ALIGNMENT_STRING_TABLE[0] );
120
121 const Property::Index GET_VISUAL_INDEX_FOR_STATE[][Button::STATE_COUNT] =
122 {
123   { Toolkit::Button::Property::UNSELECTED_BACKGROUND_VISUAL, Toolkit::Button::Property::UNSELECTED_VISUAL },
124   { Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL, Toolkit::Button::Property::SELECTED_VISUAL  },
125   { Toolkit::Button::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, Toolkit::Button::Property::DISABLED_UNSELECTED_VISUAL },
126   { Toolkit::Button::Property::DISABLED_SELECTED_BACKGROUND_VISUAL, Toolkit::Button::Property::DISABLED_SELECTED_VISUAL }
127 };
128
129 } // unnamed namespace
130
131 Button::Button()
132 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
133   mAutoRepeatingTimer(),
134   mForeGroundToLabelStrutLength( 0.0f ),
135   mTextLabelAlignment( END ),
136   mAutoRepeating( false ),
137   mTogglableButton( false ),
138   mInitialAutoRepeatingDelay( 0.0f ),
139   mNextAutoRepeatingDelay( 0.0f ),
140   mAnimationTime( 0.0f ),
141   mButtonPressedState( UNPRESSED ),
142   mButtonState( UNSELECTED_STATE ),
143   mPreviousButtonState( mButtonState ),
144   mClickActionPerforming( false )
145 {
146 }
147
148 Button::~Button()
149 {
150 }
151
152 void Button::SetAutoRepeating( bool autoRepeating )
153 {
154   mAutoRepeating = autoRepeating;
155
156   // An autorepeating button can't be a togglable button.
157   if( autoRepeating )
158   {
159     mTogglableButton = false;
160
161     if( IsSelected() )
162     {
163       SetSelected( false );
164     }
165   }
166 }
167
168 bool Button::IsAutoRepeating() const
169 {
170   return mAutoRepeating;
171 }
172
173 void Button::SetInitialAutoRepeatingDelay( float initialAutoRepeatingDelay )
174 {
175   DALI_ASSERT_DEBUG( initialAutoRepeatingDelay > 0.f );
176   mInitialAutoRepeatingDelay = initialAutoRepeatingDelay;
177 }
178
179 float Button::GetInitialAutoRepeatingDelay() const
180 {
181   return mInitialAutoRepeatingDelay;
182 }
183
184 void Button::SetNextAutoRepeatingDelay( float nextAutoRepeatingDelay )
185 {
186   DALI_ASSERT_DEBUG( nextAutoRepeatingDelay > 0.f );
187   mNextAutoRepeatingDelay = nextAutoRepeatingDelay;
188 }
189
190 float Button::GetNextAutoRepeatingDelay() const
191 {
192   return mNextAutoRepeatingDelay;
193 }
194
195 void Button::SetTogglableButton( bool togglable )
196 {
197   mTogglableButton = togglable;
198
199   // A toggle button can't be an autorepeating button.
200   if( togglable )
201   {
202     mAutoRepeating = false;
203   }
204 }
205
206 bool Button::IsTogglableButton() const
207 {
208   return mTogglableButton;
209 }
210
211 void Button::SetSelected( bool selected )
212 {
213   if( mTogglableButton )
214   {
215     DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetSelected (%s)\n", (selected?"true":"false") );
216
217     if ( selected && ( mButtonState != SELECTED_STATE ) )
218     {
219       ChangeState( SELECTED_STATE );
220     }
221     else if ( !selected && ( mButtonState != UNSELECTED_STATE ) )
222     {
223       ChangeState( UNSELECTED_STATE );
224     }
225   }
226 }
227
228 void Button::SetDisabled( bool disabled )
229 {
230   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetDisabled(%s) state(%d)\n", (disabled)?"disabled":"active", mButtonState );
231
232   if ( disabled )
233   {
234     if ( mButtonState == SELECTED_STATE )
235     {
236       ChangeState( DISABLED_SELECTED_STATE );
237     }
238     else if ( mButtonState == UNSELECTED_STATE )
239     {
240       ChangeState( DISABLED_UNSELECTED_STATE );
241     }
242   }
243   else
244   {
245     if ( mButtonState == DISABLED_SELECTED_STATE )
246     {
247       ChangeState( SELECTED_STATE );
248     }
249     else if ( mButtonState == DISABLED_UNSELECTED_STATE )
250     {
251       ChangeState( UNSELECTED_STATE );
252     }
253   }
254 }
255
256 bool Button::IsDisabled() const
257 {
258   return ( mButtonState == DISABLED_SELECTED_STATE || mButtonState == DISABLED_UNSELECTED_STATE ) ;
259 }
260
261 bool Button::ValidateState( State requestedState )
262 {
263   /*  Below tables shows allowed state transitions
264    *  Match rows in first column to following columns, if true then transition allowed.
265    *  eg UNSELECTED_STATE to DISABLED_UNSELECTED_STATE is true so state transition allowed.
266    *
267                                                              to| UNSELECTED_STATE | SELECTED_STATE | DISABLED_UNSELECTED_STATE | DISABLED_SELECTED_STATE |*/
268                                  /* from*/
269   bool transitionTable[4][4] = { /* UNSELECTED_STATE*/         {      false,            true,               true,                   false         },
270                                  /* SELECTED_STATE*/           {      true,             false,              false,                  true          },
271                                  /* DISABLED_UNSELECTED_STATE*/{      true,             true,               false,                  false         },
272                                  /* DISABLED_SELECTED_STATE*/  {      false,            true,               false,                  false         }
273                                };
274
275   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ValidateState ReuestedState:%d, CurrentState:%d, result:%s\n",
276                  requestedState, mButtonState, (transitionTable[mButtonState][requestedState])?"change-accepted":"change-denied");
277
278   return transitionTable[mButtonState][requestedState];
279 }
280
281 void Button::PerformFunctionOnVisualsInState( void(Button::*functionPtr)( Property::Index visualIndex), State state )
282 {
283   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::PerformFunctionOnVisualsInState BACKROUND visual(%d) for state (%d)\n", GET_VISUAL_INDEX_FOR_STATE[state][BACKGROUND], state );
284   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::PerformFunctionOnVisualsInState FOREGROUND visuals(%d)  for state (%d)\n", GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND], state );
285
286   (this->*functionPtr)( GET_VISUAL_INDEX_FOR_STATE[state][BACKGROUND] );
287   (this->*functionPtr)( GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND] );
288
289   RelayoutRequest();
290 }
291
292 void Button::ChangeState( State requestedState )
293 {
294   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ChangeState ReuestedState(%d)\n", requestedState );
295
296   // Validate State before changing
297   if ( !ValidateState( requestedState ))
298   {
299     DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ChangeState ReuestedState(%d) not validated\n", requestedState );
300     return;
301   }
302
303   // If not on stage the button could have still been set to selected so update state/
304   mPreviousButtonState = mButtonState; // Store previous state for visual removal (used when animations ended)
305   mButtonState = requestedState; // Update current state
306
307   if ( Self().OnStage() )
308   {
309     // Clear existing animation and remove visual being transitioned out before starting a new transition of visuals. ClearTransitionAnimation();
310     OnStateChange( mButtonState ); // Notify derived buttons
311     //// When animations enabled PerformFunctionOnVisualsInState( &Button::TransitionButtonVisualOut, mPreviousButtonState );
312     PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState );
313     // When animations enabled then call PerformFunctionOnVisualsInState( &Button::TransitionButtonVisualIn, mButtonState );
314     // then StartTransitionAnimation();
315     // and ClearTransitionAnimation();
316     PerformFunctionOnVisualsInState( &Button::OnButtonVisualRemoval, mPreviousButtonState ); // Derived button can override OnButtonVisualRemoval
317   }
318
319   Toolkit::Button handle( GetOwner() );
320   // Emit signal.
321   mStateChangedSignal.Emit( handle );
322 }
323
324 bool Button::IsSelected() const
325 {
326   bool selected = ( mButtonState == SELECTED_STATE ) || ( mButtonState == DISABLED_SELECTED_STATE );
327   return mTogglableButton && selected;
328 }
329
330 void Button::SetAnimationTime( float animationTime )
331 {
332   mAnimationTime = animationTime;
333 }
334
335 float Button::GetAnimationTime() const
336 {
337   return mAnimationTime;
338 }
339
340 void Button::SetLabelText( const std::string& label )
341 {
342   Property::Map labelProperty;
343   labelProperty.Insert( "text", label );
344   SetupLabel( labelProperty );
345 }
346
347 std::string Button::GetLabelText() const
348 {
349   Toolkit::TextLabel label = Dali::Toolkit::TextLabel::DownCast( mLabel );
350   if( label )
351   {
352     return label.GetProperty<std::string>( Dali::Toolkit::TextLabel::Property::TEXT );
353   }
354   return std::string();
355 }
356
357 void Button::SetupLabel( const Property::Map& properties )
358 {
359   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "SetupLabel\n");
360
361   // If we don't have a label yet, create one.
362   if( !mLabel )
363   {
364     // If we don't have a label, create one and set it up.
365     // Note: The label text is set from the passed in property map after creation.
366     mLabel = Toolkit::TextLabel::New();
367     mLabel.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
368     mLabel.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
369     mLabel.SetParentOrigin( ParentOrigin::TOP_LEFT );
370     mLabel.SetAnchorPoint( AnchorPoint::TOP_LEFT );
371
372     // todo DEBUG
373     mLabel.SetProperty( Toolkit::Control::Property::BACKGROUND, Dali::Property::Map()
374                         .Add( Toolkit::Visual::Property::TYPE, Dali::Toolkit::Visual::COLOR )
375                         .Add( Toolkit::ColorVisual::Property::MIX_COLOR, Color::RED )
376                       );
377
378     ResizePolicy::Type policy = Self().GetResizePolicy(  Dimension::ALL_DIMENSIONS );
379     if ( policy == ResizePolicy::USE_NATURAL_SIZE || policy == ResizePolicy::FIT_TO_CHILDREN  )
380     {
381       mLabel.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
382     }
383     else
384     {
385       // todo Can't set Text Label to USE_ASSIGNED_SIZE as causes a relayout in it whilst doing a relayout = error
386      //mLabel.SetResizePolicy(ResizePolicy::USE_ASSIGNED_SIZE, Dimension::ALL_DIMENSIONS );
387     }
388     Self().Add( mLabel );
389   }
390
391   // Set any properties specified for the label by iterating through all property key-value pairs.
392   for( unsigned int i = 0, mapCount = properties.Count(); i < mapCount; ++i )
393   {
394     const StringValuePair& propertyPair( properties.GetPair( i ) );
395
396     // Convert the property string to a property index.
397     Property::Index setPropertyIndex = mLabel.GetPropertyIndex( propertyPair.first );
398     if( setPropertyIndex != Property::INVALID_INDEX )
399     {
400       // If the conversion worked, we have a valid property index,
401       // Set the property to the new value.
402       mLabel.SetProperty( setPropertyIndex, propertyPair.second );
403     }
404   }
405
406   // Notify derived button classes of the change.
407   OnLabelSet( false );
408
409   RelayoutRequest();
410 }
411
412 void Button::SetLabelStrutLength( unsigned int length )
413 {
414   mForeGroundToLabelStrutLength = length;
415 }
416
417 void Button::SetLabelAlignment( Button::Align labelAlignment)
418 {
419   mTextLabelAlignment = labelAlignment;
420   RelayoutRequest();
421 }
422
423 float Button::GetLabelStrutLength()
424 {
425   return mForeGroundToLabelStrutLength;
426 }
427
428 Button::Align Button::GetLabelAlignment()
429 {
430   return mTextLabelAlignment;
431 }
432
433 void Button::CreateVisualsForComponent( Property::Index index, const Property::Value& value, const float visualDepth )
434 {
435   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent index(%d)\n", index );
436   Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
437   Toolkit::Visual::Base buttonVisual;
438
439   std::string imageUrl;
440   if( value.Get( imageUrl ) )
441   {
442     DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent Using image URL(%d)\n", index );
443     if ( !imageUrl.empty() )
444     {
445       buttonVisual = visualFactory.CreateVisual(  imageUrl, ImageDimensions()  );
446     }
447   }
448   else
449   {
450     // if its not a string then get a Property::Map from the property if possible.
451     Property::Map *map = value.GetMap();
452     if( map && !map->Empty()  ) // Empty map results in current visual removal.
453     {
454       DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent Using Map(%d)\n", index );
455       buttonVisual = visualFactory.CreateVisual( *map );
456     }
457   }
458
459   if ( buttonVisual )
460   {
461     DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "RegisterVisual index(%d)\n", index );
462     buttonVisual.SetDepthIndex( visualDepth );
463     // Background Visuals take full size of control
464     RegisterVisual( index, buttonVisual, false );
465   }
466   else
467   {
468     UnregisterVisual( index );
469     DALI_LOG_INFO( gLogButtonFilter, Debug::General, "Button visual not created or empty map provided (clearing visual).(%d)\n", index);
470   }
471 }
472
473 const Vector4 Button::GetUnselectedColor() const
474 {
475   return mUnselectedColor;
476 }
477
478 const Vector4 Button::GetSelectedColor() const
479 {
480   return mSelectedColor;
481 }
482
483 // Legacy code whilst Color can be set by direct Property setting ( deprecated ) instead of setting a Visual
484 void Button::SetColor( const Vector4& color, Property::Index visualIndex )
485 {
486   if ( visualIndex == Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL )
487   {
488     mSelectedColor = color;
489   }
490   else
491   {
492     mUnselectedColor = color;
493   }
494
495   Property::Map map;
496   map[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::COLOR;
497   map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color;
498
499   CreateVisualsForComponent( visualIndex, map, DepthIndex::BACKGROUND );
500 }
501
502 bool Button::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
503 {
504   bool ret = false;
505
506   Dali::BaseHandle handle( object );
507
508   Toolkit::Button button = Toolkit::Button::DownCast( handle );
509
510   DALI_ASSERT_DEBUG( button );
511
512   if( 0 == strcmp( actionName.c_str(), ACTION_BUTTON_CLICK ) )
513   {
514     ret = GetImplementation( button ).DoClickAction( attributes );
515   }
516
517   return ret;
518 }
519
520 bool Button::DoClickAction( const Property::Map& attributes )
521 {
522   // Prevents the button signals from doing a recursive loop by sending an action
523   // and re-emitting the signals.
524   if( !mClickActionPerforming )
525   {
526     mClickActionPerforming = true;
527     OnButtonDown();
528     if ( !mTogglableButton )
529     {
530       mButtonPressedState = DEPRESSED;
531     }
532     OnButtonUp();
533     mClickActionPerforming = false;
534
535     return true;
536   }
537
538   return false;
539 }
540
541 void Button::OnButtonDown()
542 {
543   if( mTogglableButton )
544   {
545     if ( mButtonState != SELECTED_STATE )
546     {
547       SetSelected( true );
548       mButtonPressedState = TOGGLE_DEPRESSED;
549     }
550     else
551     {
552       mButtonPressedState = DEPRESSED;
553     }
554   }
555   else
556   {
557     Pressed();
558     mButtonPressedState = DEPRESSED;
559     if( mAutoRepeating )
560     {
561        SetUpTimer( mInitialAutoRepeatingDelay );
562     }
563   }
564
565   // The pressed signal should be emitted regardless of toggle mode.
566   Toolkit::Button handle( GetOwner() );
567   mPressedSignal.Emit( handle );
568 }
569
570 void Button::OnButtonUp()
571 {
572   if( DEPRESSED == mButtonPressedState )
573   {
574     if( mTogglableButton )
575     {
576       if ( TOGGLE_DEPRESSED != mButtonPressedState )
577       {
578         SetSelected( !IsSelected() );
579         mButtonPressedState = UNPRESSED;
580       }
581     }
582     else
583     {
584       Released();
585       if( mAutoRepeating )
586       {
587         mAutoRepeatingTimer.Reset();
588       }
589     }
590
591     // The clicked and released signals should be emitted regardless of toggle mode.
592     Toolkit::Button handle( GetOwner() );
593     mReleasedSignal.Emit( handle );
594     mClickedSignal.Emit( handle );
595   }
596 }
597
598 void Button::OnTouchPointLeave()
599 {
600   if( DEPRESSED == mButtonPressedState )
601   {
602     if( !mTogglableButton )
603     {
604       Released();
605
606       if( mAutoRepeating )
607       {
608         mAutoRepeatingTimer.Reset();
609       }
610     }
611
612     mButtonPressedState = UNPRESSED;
613
614     // The released signal should be emitted regardless of toggle mode.
615     Toolkit::Button handle( GetOwner() );
616     mReleasedSignal.Emit( handle );
617   }
618 }
619
620 void Button::OnTouchPointInterrupted()
621 {
622   OnTouchPointLeave();
623 }
624
625 Toolkit::Button::ButtonSignalType& Button::PressedSignal()
626 {
627   return mPressedSignal;
628 }
629
630 Toolkit::Button::ButtonSignalType& Button::ReleasedSignal()
631 {
632   return mReleasedSignal;
633 }
634
635 Toolkit::Button::ButtonSignalType& Button::ClickedSignal()
636 {
637   return mClickedSignal;
638 }
639
640 Toolkit::Button::ButtonSignalType& Button::StateChangedSignal()
641 {
642   return mStateChangedSignal;
643 }
644
645 bool Button::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
646 {
647   Dali::BaseHandle handle( object );
648
649   bool connected( true );
650   Toolkit::Button button = Toolkit::Button::DownCast( handle );
651
652   if( 0 == strcmp( signalName.c_str(), SIGNAL_PRESSED ) )
653   {
654     button.PressedSignal().Connect( tracker, functor );
655   }
656   else if( 0 == strcmp( signalName.c_str(), SIGNAL_RELEASED ) )
657   {
658     button.ReleasedSignal().Connect( tracker, functor );
659   }
660   else if( 0 == strcmp( signalName.c_str(), SIGNAL_CLICKED ) )
661   {
662     button.ClickedSignal().Connect( tracker, functor );
663   }
664   else if( 0 == strcmp( signalName.c_str(), SIGNAL_STATE_CHANGED ) )
665   {
666     button.StateChangedSignal().Connect( tracker, functor );
667   }
668   else
669   {
670     // signalName does not match any signal
671     connected = false;
672   }
673
674   return connected;
675 }
676
677 void Button::OnInitialize()
678 {
679   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnInitialize\n" );
680
681   Actor self = Self();
682
683   mTapDetector = TapGestureDetector::New();
684   mTapDetector.Attach( self );
685   mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
686
687   self.SetKeyboardFocusable( true );
688
689   self.TouchSignal().Connect( this, &Button::OnTouch );
690 }
691
692 bool Button::OnAccessibilityActivated()
693 {
694   return OnKeyboardEnter();
695 }
696
697 bool Button::OnTouch( Actor actor, const TouchData& touch )
698 {
699
700   // Only events are processed when the button is not disabled and the touch event has only
701   // one touch point.
702
703   if( !IsDisabled() && ( 1 == touch.GetPointCount() ) )
704   {
705     switch( touch.GetState( 0 ) )
706     {
707       case PointState::DOWN:
708       {
709         OnButtonDown();
710         break;
711       }
712       case PointState::UP:
713       {
714         OnButtonUp();
715         break;
716       }
717       case PointState::INTERRUPTED:
718       {
719         OnTouchPointInterrupted();
720         break;
721       }
722       case PointState::LEAVE:
723       {
724         OnTouchPointLeave();
725         break;
726       }
727       case PointState::MOTION:
728       case PointState::STATIONARY: // FALLTHROUGH
729       {
730         // Nothing to do
731         break;
732       }
733     }
734   }
735   else if( 1 < touch.GetPointCount() )
736   {
737     OnTouchPointLeave(); // Notification for derived classes.
738
739     // Sets the button state to the default
740     mButtonPressedState = UNPRESSED;
741   }
742
743   return false;
744 }
745
746 bool Button::OnKeyboardEnter()
747 {
748   // When the enter key is pressed, or button is activated, the click action is performed.
749   Property::Map attributes;
750   bool ret = DoClickAction( attributes );
751
752   return ret;
753 }
754
755 void Button::OnStageDisconnection()
756 {
757   if( DEPRESSED == mButtonPressedState )
758   {
759     if( !mTogglableButton )
760     {
761       Released();
762
763       if( mAutoRepeating )
764       {
765         mAutoRepeatingTimer.Reset();
766       }
767     }
768   }
769
770   mButtonPressedState = UNPRESSED;
771
772   Control::OnStageDisconnection(); // Visuals will be set off stage
773 }
774
775 void Button::OnStageConnection( int depth )
776 {
777   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnStageConnection ptr(%p) \n", this );
778   PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState );
779   Control::OnStageConnection( depth ); // Enabled visuals will be put on stage
780
781 }
782
783 Vector3 Button::GetNaturalSize()
784 {
785   Vector3 size = Vector3::ZERO;
786
787   bool horizontalAlignment = mTextLabelAlignment == BEGIN || mTextLabelAlignment == END; // label and visual side by side
788
789   // Get natural size of foreground ( largest of the possible visuals )
790   Size largestForegroundVisual;
791   Size labelSize;
792
793   for ( int state = Button::UNSELECTED_STATE; state < Button::STATE_COUNT; state++)
794   {
795     Toolkit::Visual::Base visual = GetVisual( GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND] );
796     Size visualSize;
797     if ( visual )
798     {
799       visual.GetNaturalSize( visualSize );
800       largestForegroundVisual.width = std::max(largestForegroundVisual.width, visualSize.width );
801       largestForegroundVisual.height = std::max(largestForegroundVisual.height, visualSize.height );
802     }
803   }
804
805   // Get horizontal padding total
806   if ( largestForegroundVisual.width > 0 )  // if visual exists
807   {
808     size.width += largestForegroundVisual.width + mForegroundPadding.left + mForegroundPadding.right;
809   }
810   // Get vertical padding total
811   if ( largestForegroundVisual.height > 0 )
812   {
813     size.height += largestForegroundVisual.height + mForegroundPadding.top + mForegroundPadding.bottom;
814   }
815
816   DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize visual Size(%f,%f)\n",
817                  largestForegroundVisual.width, largestForegroundVisual.height );
818
819   // Get natural size of label
820   if ( mLabel )
821   {
822     labelSize = Vector2( mLabel.GetNaturalSize());
823
824     DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize labelSize(%f,%f) padding(%f,%f)\n",
825                    labelSize.width, labelSize.height, mLabelPadding.left + mLabelPadding.right, mLabelPadding.top + mLabelPadding.bottom);
826
827     labelSize.width += mLabelPadding.left + mLabelPadding.right;
828     labelSize.height += mLabelPadding.top + mLabelPadding.bottom;
829
830     // Add label size to height or width depending on alignment position
831     if ( horizontalAlignment )
832     {
833       size.width += labelSize.width;
834       size.height = std::max(size.height, labelSize.height );
835     }
836     else
837     {
838       size.height += labelSize.height;
839       size.width = std::max(size.width, labelSize.width );
840     }
841   }
842
843   if( size.width < 1 && size.height < 1 )
844   {
845     // if no image or label then use Control's natural size
846     DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize Using control natural size\n");
847     size = Control::GetNaturalSize();
848   }
849
850   DALI_LOG_INFO( gLogButtonFilter, Debug::General, "Button GetNaturalSize (%f,%f)\n", size.width, size.height );
851
852   return size;
853 }
854
855 void Button::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
856 {
857   DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnSetResizePolicy\n");
858
859   if ( policy != ResizePolicy::USE_NATURAL_SIZE || policy != ResizePolicy::FIT_TO_CHILDREN  )
860   {
861     if ( mLabel )
862     {
863       // todo Can't set Text Label to USE_ASSIGNED_SIZE as causes a relayout in it whilst doing a relayout = error
864       //mLabel.SetResizePolicy(ResizePolicy::USE_ASSIGNED_SIZE, Dimension::ALL_DIMENSIONS );
865     }
866   }
867
868   RelayoutRequest();
869 }
870
871 void Button::OnRelayout( const Vector2& size, RelayoutContainer& container )
872 {
873   DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout targetSize(%f,%f) ptr(%p) state[%d]\n", size.width, size.height, this, mButtonState );
874
875   PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState );
876
877   ResizePolicy::Type widthResizePolicy = Self().GetResizePolicy(  Dimension::WIDTH );
878   ResizePolicy::Type heightResizePolicy = Self().GetResizePolicy(  Dimension::HEIGHT );
879
880   DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout resize policy: width:%d height:%d\n", heightResizePolicy, widthResizePolicy);
881
882   Toolkit::Visual::Base currentVisual = GetVisual( GET_VISUAL_INDEX_FOR_STATE[mButtonState][FOREGROUND] );
883
884   Toolkit::Visual::Base currentBackGroundVisual = GetVisual( GET_VISUAL_INDEX_FOR_STATE[mButtonState][BACKGROUND] );
885
886   // Sizes and padding set to zero, if not present then values will no effect calculations.
887   Vector2 visualPosition = Vector2::ZERO;
888   Vector2 labelPosition = Vector2::ZERO;
889   Size visualSize = Size::ZERO;
890   Padding foregroundVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f );
891   Padding labelVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f );
892
893   if ( mLabel )
894   {
895     DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Label padding setting padding:%f,%f,%f,%f\n", mLabelPadding.y, mLabelPadding.x, mLabelPadding.width,mLabelPadding.height );
896     labelVisualPadding = mLabelPadding;
897   }
898
899   if ( currentVisual )
900   {
901     DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Foreground Visual setting padding:%f,%f,%f,%f\n", mForegroundPadding.y, mForegroundPadding.x, mForegroundPadding.width,mForegroundPadding.height );
902     currentVisual.GetNaturalSize( visualSize );
903     foregroundVisualPadding = mForegroundPadding;
904   }
905
906   Toolkit::Align::Type visualAnchorPoint = Toolkit::Align::TOP_BEGIN;
907
908   Vector2 visualAndPaddingSize = Vector2( ( foregroundVisualPadding.x + visualSize.width + foregroundVisualPadding.y ),
909                                           ( foregroundVisualPadding.width + visualSize.height + foregroundVisualPadding.height ));
910
911   DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout visualAndPaddingSize(%f,%f)\n", visualAndPaddingSize.width, visualAndPaddingSize.height);
912
913   switch ( mTextLabelAlignment )
914   {
915     case BEGIN :
916     {
917       visualAnchorPoint = Toolkit::Align::TOP_END;
918       visualPosition.x = foregroundVisualPadding.right;
919       visualPosition.y = foregroundVisualPadding.top;
920
921       labelPosition.x = labelVisualPadding.x;
922       labelPosition.y = labelVisualPadding.top;
923       break;
924     }
925     case END :
926     {
927       visualAnchorPoint = Toolkit::Align::TOP_BEGIN;
928       visualPosition.x = foregroundVisualPadding.left;
929       visualPosition.y = foregroundVisualPadding.top;
930
931       labelPosition.x = visualAndPaddingSize.width + labelVisualPadding.x;
932       labelPosition.y = labelVisualPadding.top;
933       break;
934     }
935     case TOP :
936     {
937       visualAnchorPoint = Toolkit::Align::BOTTOM_END;
938       visualPosition.x = foregroundVisualPadding.left;
939       visualPosition.y = foregroundVisualPadding.bottom;
940
941       labelPosition.x = labelVisualPadding.left;
942       labelPosition.y = labelVisualPadding.top;
943       break;
944     }
945     case BOTTOM :
946     {
947       visualAnchorPoint = Toolkit::Align::TOP_END;
948       visualPosition.x = foregroundVisualPadding.left;
949       visualPosition.y = foregroundVisualPadding.top;
950
951       labelPosition.x = labelVisualPadding.left;
952       labelPosition.y = visualAndPaddingSize.height + labelVisualPadding.top;
953       break;
954     }
955   }
956
957   if ( currentBackGroundVisual )
958   {
959     DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual bakcground size to(%f,%f)\n", size.width, size.height);
960
961     Property::Map visualTransform;
962
963     visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, size )
964                    .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4( 0.0f, 0.0f, 1.0f, 1.0f) );  // Use relative size
965
966     currentBackGroundVisual.SetTransformAndSize( visualTransform, size );
967   }
968
969   if ( currentVisual )
970   {
971       DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual size to(%f,%f)\n", visualSize.width, visualSize.height);
972
973       currentVisual.SetProperty( Toolkit::Visual::DevelProperty::TRANSFORM,
974                                  Dali::Property::Map()
975                                  .Add( Toolkit::Visual::DevelProperty::Transform::Property::SIZE, visualSize )
976                                  .Add( Toolkit::Visual::DevelProperty::Transform::Property::OFFSET, visualPosition )
977                                  .Add( Toolkit::Visual::DevelProperty::Transform::Property::OFFSET_SIZE_MODE, Vector4(1.0f, 1.0f, 1.0f,1.0f) )
978                                  .Add( Toolkit::Visual::DevelProperty::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
979                                  .Add( Toolkit::Visual::DevelProperty::Transform::Property::ANCHOR_POINT, visualAnchorPoint )
980                                 );
981   }
982
983   if ( mLabel )
984   {
985     // When Text visual size can be set, determine the size here.
986     // Text Visual should take all space available after foreground visual size and all padding is considered.
987     // Remaining Space priority, Foreground padding, foreground visual, Text padding then Text visual.
988
989     Size remainingSpaceForText = Size::ZERO;
990     remainingSpaceForText.width = size.width - visualAndPaddingSize.width - labelVisualPadding.x - labelVisualPadding.y;
991     remainingSpaceForText.height = size.height - visualAndPaddingSize.height - labelVisualPadding.width - labelVisualPadding.height;
992
993     if ( !currentVisual )
994     {
995       DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Only Text\n");
996
997       // Center Text if no foreground visual
998       Size labelNaturalSize = Vector2( mLabel.GetNaturalSize() );
999
1000       // A Text visual will take up all the remainingSpaceForText, for now TextLabel natural size needed for positioning.
1001       labelPosition.x = labelVisualPadding.left + remainingSpaceForText.width*0.5 - labelNaturalSize.width *0.5;
1002       labelPosition.y = labelVisualPadding.height + remainingSpaceForText.height*0.5 - labelNaturalSize.height *0.5;
1003     }
1004
1005     DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout text Size(%f,%f) text Position(%f,%f) \n", remainingSpaceForText.width, remainingSpaceForText.height, labelPosition.x, labelPosition.y);
1006
1007     mLabel.SetPosition( labelPosition.x, labelPosition.y );
1008     container.Add( mLabel, remainingSpaceForText ); // Currently a TextLabel is used and size can not be set here.
1009   }
1010
1011   DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout << \n");
1012 }
1013
1014 void Button::OnTap(Actor actor, const TapGesture& tap)
1015 {
1016   DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnTap\n" );
1017 }
1018
1019 void Button::SetUpTimer( float delay )
1020 {
1021   mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
1022   mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot );
1023   mAutoRepeatingTimer.Start();
1024 }
1025
1026 bool Button::AutoRepeatingSlot()
1027 {
1028   bool consumed = false;
1029   if( !IsDisabled() )
1030   {
1031     // Restart the autorepeat timer.
1032     SetUpTimer( mNextAutoRepeatingDelay );
1033
1034     Pressed();
1035
1036     Toolkit::Button handle( GetOwner() );
1037
1038     //Emit signal.
1039     consumed = mReleasedSignal.Emit( handle );
1040     consumed = mClickedSignal.Emit( handle );
1041     consumed |= mPressedSignal.Emit( handle );
1042  }
1043
1044   return consumed;
1045 }
1046
1047 void Button::Pressed()
1048 {
1049   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Pressed\n" );
1050
1051   if( mButtonState == UNSELECTED_STATE )
1052   {
1053     ClearTransitionAnimation();
1054     ChangeState( SELECTED_STATE );
1055     OnPressed();  // Notifies the derived class the button has been pressed.
1056   }
1057 }
1058
1059 void Button::Released()
1060 {
1061   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Released\n" );
1062
1063   if( mButtonState == SELECTED_STATE && !mTogglableButton )
1064   {
1065     ClearTransitionAnimation();
1066     ChangeState( UNSELECTED_STATE );
1067     OnReleased(); //    // Notifies the derived class the button has been released.
1068   }
1069   mButtonPressedState = UNPRESSED;
1070 }
1071
1072 Button::PressState Button::GetPressedState()
1073 {
1074   return mButtonPressedState;
1075 }
1076
1077 Button::State Button::GetButtonState()
1078 {
1079   return mButtonState;
1080 }
1081
1082 void Button::SelectRequiredVisual( Property::Index visualIndex )
1083 {
1084   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SelectRequiredVisual index(%d) state(%d)\n", visualIndex, mButtonState );
1085
1086   EnableVisual( visualIndex, true );
1087 }
1088
1089 void Button::TransitionButtonVisualOut( Property::Index visualIndex )
1090 {
1091   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::TransitionButtonVisualOut index(%d)\n", visualIndex);
1092
1093   // PrepareForTranstionOut and OnTransitionOut needs to be called on visual instead of Actor once animating is possible
1094 }
1095
1096 void Button::TransitionButtonVisualIn( Property::Index visualIndex )
1097 {
1098   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::TransitionButtonVisualIn index(%d)\n", visualIndex );
1099 }
1100
1101 void Button::OnTransitionIn( Actor actor )
1102 {
1103   PerformFunctionOnVisualsInState( &Button::OnButtonVisualRemoval, mPreviousButtonState ); // Derived button can override OnButtonVisualRemoval
1104 }
1105
1106 void Button::RemoveVisual( Property::Index visualIndex )
1107 {
1108   // Use OnButtonVisualRemoval if want button developer to have the option to override removal.
1109   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::RemoveVisual index(%d) state(%d)\n", visualIndex, mButtonState );
1110
1111   Toolkit::Visual::Base visual = GetVisual( visualIndex );
1112
1113   if( visual )
1114   {
1115     EnableVisual( visualIndex, false );
1116   }
1117 }
1118
1119 void Button::OnButtonVisualRemoval( Property::Index visualIndex )
1120 {
1121   // Derived Buttons can over ride this to prevent default removal.
1122   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnButtonVisualRemoval index(%d)\n", visualIndex );
1123   RemoveVisual( visualIndex );
1124 }
1125
1126 void Button::StartTransitionAnimation()
1127 {
1128   if( mTransitionAnimation )
1129   {
1130     DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::StartTransitionAnimation progress(%f) duration(%f) state(%d) \n",
1131                    mTransitionAnimation.GetCurrentProgress(), mTransitionAnimation.GetDuration(),
1132                    mTransitionAnimation.GetState());
1133     mTransitionAnimation.Play();
1134   }
1135 }
1136
1137 void Button::ClearTransitionAnimation()
1138 {
1139   if( mTransitionAnimation )
1140   {
1141     DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ClearTransitionAnimation progress(%f) duration(%f) state(%d) \n",
1142                    mTransitionAnimation.GetCurrentProgress(), mTransitionAnimation.GetDuration(),
1143                    mTransitionAnimation.GetState());
1144     mTransitionAnimation.Clear();
1145     mTransitionAnimation.Reset();
1146   }
1147 }
1148
1149 Dali::Animation Button::GetTransitionAnimation()
1150 {
1151   if( !mTransitionAnimation )
1152   {
1153     mTransitionAnimation = Dali::Animation::New( GetAnimationTime() );
1154     mTransitionAnimation.FinishedSignal().Connect( this, &Button::TransitionAnimationFinished );
1155   }
1156
1157   return mTransitionAnimation;
1158 }
1159
1160 void Button::TransitionAnimationFinished( Dali::Animation& source )
1161 {
1162   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::TransitionAnimationFinished\n" );
1163   ClearTransitionAnimation();
1164   PerformFunctionOnVisualsInState( &Button::OnButtonVisualRemoval, mPreviousButtonState ); // Derived button can override OnButtonVisualRemoval
1165 }
1166
1167 void Button::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
1168 {
1169   Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1170
1171   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetProperty index[%d]\n", index );
1172
1173   if ( button )
1174   {
1175     switch ( index )
1176     {
1177       case Toolkit::Button::Property::DISABLED:
1178       {
1179         GetImplementation( button ).SetDisabled( value.Get< bool >() );
1180         break;
1181       }
1182
1183       case Toolkit::Button::Property::AUTO_REPEATING:
1184       {
1185         GetImplementation( button ).SetAutoRepeating( value.Get< bool >() );
1186         break;
1187       }
1188
1189       case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1190       {
1191         GetImplementation( button ).SetInitialAutoRepeatingDelay( value.Get< float >() );
1192         break;
1193       }
1194
1195       case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1196       {
1197         GetImplementation( button ).SetNextAutoRepeatingDelay( value.Get< float >() );
1198         break;
1199       }
1200
1201       case Toolkit::Button::Property::TOGGLABLE:
1202       {
1203         GetImplementation( button ).SetTogglableButton( value.Get< bool >() );
1204         break;
1205       }
1206
1207       case Toolkit::Button::Property::SELECTED:
1208       {
1209         GetImplementation( button ).SetSelected( value.Get< bool >() );
1210         break;
1211       }
1212
1213       case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE: // Legacy Tizen 3.0
1214       {
1215         GetImplementation( button ).CreateVisualsForComponent( Toolkit::Button::Property::UNSELECTED_VISUAL, value, DepthIndex::CONTENT );
1216         break;
1217       }
1218       case Toolkit::Button::Property::DISABLED_STATE_IMAGE:  // Legacy Tizen 3.0
1219       {
1220         GetImplementation( button ).CreateVisualsForComponent( Toolkit::Button::Property::DISABLED_UNSELECTED_VISUAL, value, DepthIndex::CONTENT );
1221         break;
1222       }
1223       case Toolkit::Button::Property::SELECTED_STATE_IMAGE:  // Legacy Tizen 3.0
1224       {
1225         GetImplementation( button ).CreateVisualsForComponent( Toolkit::Button::Property::SELECTED_VISUAL, value, DepthIndex::CONTENT );
1226         break;
1227       }
1228       case Toolkit::Button::Property::UNSELECTED_VISUAL:
1229       case Toolkit::Button::Property::SELECTED_VISUAL:
1230       case Toolkit::Button::Property::DISABLED_SELECTED_VISUAL:
1231       case Toolkit::Button::Property::DISABLED_UNSELECTED_VISUAL:
1232       {
1233         GetImplementation( button ).CreateVisualsForComponent( index, value, DepthIndex::CONTENT );
1234         break;
1235       }
1236
1237       case Toolkit::Button::Property::UNSELECTED_BACKGROUND_VISUAL:
1238       case Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL:
1239       case Toolkit::Button::Property::DISABLED_SELECTED_BACKGROUND_VISUAL:
1240       case Toolkit::Button::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL:
1241       {
1242         GetImplementation( button ).CreateVisualsForComponent( index , value, DepthIndex::BACKGROUND);
1243         break;
1244       }
1245
1246       case Toolkit::Button::Property::UNSELECTED_COLOR:
1247       {
1248         DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::UNSELECTED_COLOR instead use Button::Property::UNSELECTED_BACKGROUND_VISUAL\n", __FUNCTION__);
1249         GetImplementation( button ).SetColor( value.Get< Vector4 >(), Toolkit::Button::Property::UNSELECTED_BACKGROUND_VISUAL );
1250         break;
1251       }
1252
1253       case Toolkit::Button::Property::SELECTED_COLOR:
1254       {
1255         DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::SELECTED_COLOR instead use Button::Property::SELECTED_BACKGROUND_VISUAL\n", __FUNCTION__);
1256         GetImplementation( button ).SetColor( value.Get< Vector4 >(), Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL );
1257         break;
1258       }
1259
1260       case Toolkit::Button::Property::LABEL_TEXT:
1261       {
1262         DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::LABEL_TEXT instead use Button::Property::LABEL\n", __FUNCTION__);
1263         Property::Map labelTextProperty;
1264         labelTextProperty.Insert( "text", value.Get< std::string >() );
1265         GetImplementation( button ).SetupLabel( labelTextProperty );
1266         break;
1267       }
1268
1269       case Toolkit::Button::Property::LABEL:
1270       {
1271         // Get a Property::Map from the property if possible.
1272         Property::Map setPropertyMap;
1273         if( value.Get( setPropertyMap ) )
1274         {
1275           GetImplementation( button ).SetupLabel( setPropertyMap );
1276         }
1277         break;
1278       }
1279
1280       case Toolkit::Button::Property::LABEL_STRUT_LENGTH:
1281       {
1282         GetImplementation( button ).SetLabelStrutLength( value.Get< int >() );
1283         break;
1284       }
1285
1286       case Toolkit::Button::Property::LABEL_RELATIVE_ALIGNMENT:
1287       {
1288         Button::Align labelAlignment(END);
1289         Scripting::GetEnumeration< Button::Align> ( value.Get< std::string >().c_str(),
1290                                                     ALIGNMENT_TABLE, ALIGNMENT_TABLE_COUNT,
1291                                                     labelAlignment );
1292
1293         GetImplementation( button ).SetLabelAlignment( labelAlignment );
1294         break;
1295       }
1296     }
1297   }
1298 }
1299
1300 Property::Value Button::GetProperty( BaseObject* object, Property::Index propertyIndex )
1301 {
1302   Property::Value value;
1303
1304   Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1305
1306   if ( button )
1307   {
1308     switch ( propertyIndex )
1309     {
1310       case Toolkit::Button::Property::DISABLED:
1311       {
1312         value = GetImplementation( button ).IsDisabled();
1313         break;
1314       }
1315
1316       case Toolkit::Button::Property::AUTO_REPEATING:
1317       {
1318         value = GetImplementation( button ).mAutoRepeating;
1319         break;
1320       }
1321
1322       case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1323       {
1324         value = GetImplementation( button ).mInitialAutoRepeatingDelay;
1325         break;
1326       }
1327
1328       case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1329       {
1330         value = GetImplementation( button ).mNextAutoRepeatingDelay;
1331         break;
1332       }
1333
1334       case Toolkit::Button::Property::TOGGLABLE:
1335       {
1336         value = GetImplementation( button ).mTogglableButton;
1337         break;
1338       }
1339
1340       case Toolkit::Button::Property::SELECTED:
1341       {
1342         value = GetImplementation( button ).IsSelected();
1343         break;
1344       }
1345
1346       case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1347       {
1348         value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::Button::Property::UNSELECTED_VISUAL );
1349         break;
1350       }
1351
1352       case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1353       {
1354         value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::Button::Property::SELECTED_VISUAL );
1355         break;
1356       }
1357
1358       case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1359       {
1360         value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::Button::Property::DISABLED_UNSELECTED_VISUAL );
1361         break;
1362       }
1363
1364       case Toolkit::Button::Property::UNSELECTED_COLOR:
1365       {
1366         value = GetImplementation( button ).GetUnselectedColor();
1367         break;
1368       }
1369
1370       case Toolkit::Button::Property::SELECTED_COLOR:
1371       {
1372         value = GetImplementation( button ).GetSelectedColor();
1373         break;
1374       }
1375
1376       case Toolkit::Button::Property::LABEL_TEXT:
1377       {
1378         value = GetImplementation( button ).GetLabelText();
1379         break;
1380       }
1381
1382       case Toolkit::Button::Property::LABEL:
1383       {
1384         Property::Map emptyMap;
1385         value = emptyMap;
1386         break;
1387       }
1388
1389       case Toolkit::Button::Property::LABEL_STRUT_LENGTH:
1390       {
1391         value = GetImplementation( button ).GetLabelStrutLength();
1392         break;
1393       }
1394
1395       case Toolkit::Button::Property::LABEL_RELATIVE_ALIGNMENT:
1396       {
1397         const char* alignment = Scripting::GetEnumerationName< Button::Align >( GetImplementation( button ).GetLabelAlignment(),
1398                                                                                 ALIGNMENT_STRING_TABLE,
1399                                                                                 ALIGNMENT_STRING_TABLE_COUNT );
1400         if( alignment )
1401         {
1402           value = std::string( alignment );
1403         }
1404
1405         break;
1406       }
1407     }
1408   }
1409
1410   return value;
1411 }
1412
1413 void Button::SetLabelPadding( const Padding& padding)
1414 {
1415   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetLabelPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top );
1416   mLabelPadding = Padding( padding.left, padding.right, padding.bottom, padding.top );
1417   RelayoutRequest();
1418 }
1419
1420 Padding Button::GetLabelPadding()
1421 {
1422   return mLabelPadding;
1423 }
1424
1425 void Button::SetForegroundPadding( const Padding& padding)
1426 {
1427   DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetForegroundPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top );
1428   mForegroundPadding = Padding( padding.left, padding.right, padding.bottom, padding.top );
1429   RelayoutRequest();
1430 }
1431
1432 Padding Button::GetForegroundPadding()
1433 {
1434   return mForegroundPadding;
1435 }
1436
1437 ////////////////////////////////////////////////////////////////////////
1438 // Legacy functions from Tizen 2.4 and 3.0
1439
1440 void Button::SetLabel( Actor label )
1441 {
1442   if ( label )
1443   {
1444     Property::Value value ="";
1445     value = label.GetProperty(Toolkit::TextLabel::Property::TEXT);
1446
1447     SetLabelText( value.Get<std::string>() );
1448   }
1449 }
1450
1451 void Button::SetUnselectedImage( const std::string& filename )
1452 {
1453   if( !filename.empty() )
1454   {
1455     CreateVisualsForComponent( Toolkit::Button::Property::UNSELECTED_VISUAL, filename, DepthIndex::CONTENT );
1456   }
1457 }
1458
1459 void Button::SetBackgroundImage( const std::string& filename )
1460 {
1461   if( !filename.empty() )
1462   {
1463     CreateVisualsForComponent( Toolkit::Button::Property::UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1464   }
1465 }
1466
1467 void Button::SetSelectedImage( const std::string& filename )
1468 {
1469   if( !filename.empty() )
1470   {
1471     CreateVisualsForComponent( Toolkit::Button::Property::SELECTED_VISUAL, filename, DepthIndex::CONTENT );
1472   }
1473 }
1474
1475 void Button::SetSelectedBackgroundImage( const std::string& filename )
1476 {
1477   if( !filename.empty() )
1478   {
1479     CreateVisualsForComponent( Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1480   }
1481 }
1482
1483 void Button::SetDisabledBackgroundImage( const std::string& filename )
1484 {
1485   if( !filename.empty() )
1486   {
1487     CreateVisualsForComponent( Toolkit::Button::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1488   }
1489 }
1490
1491 void Button::SetDisabledImage( const std::string& filename )
1492 {
1493   if( !filename.empty() )
1494   {
1495     CreateVisualsForComponent( Toolkit::Button::Property::DISABLED_UNSELECTED_VISUAL, filename, DepthIndex::CONTENT );
1496   }
1497 }
1498
1499 void Button::SetDisabledSelectedImage( const std::string& filename )
1500 {
1501   if( !filename.empty() )
1502   {
1503     CreateVisualsForComponent( Toolkit::Button::Property::DISABLED_SELECTED_VISUAL, filename, DepthIndex::CONTENT );
1504   }
1505 }
1506
1507 std::string Button::GetUrlForImageVisual( Property::Index index )
1508 {
1509   Toolkit::Visual::Base visual = GetVisual( index );
1510   std::string result;
1511
1512   if ( visual )
1513   {
1514     Dali::Property::Map retreivedMap;
1515     visual.CreatePropertyMap( retreivedMap );
1516     Property::Value* value = retreivedMap.Find(  Toolkit::ImageVisual::Property::URL,  Property::STRING );
1517     if ( value )
1518     {
1519       result = value->Get<std::string>();
1520     }
1521   }
1522
1523   return result;
1524 }
1525
1526 // Below functions DEPRECATED_1_0.50 - Return empty Actors
1527
1528 Actor Button::GetButtonImage() const
1529 {
1530   DALI_LOG_WARNING("Button::GetButtonImage @DEPRECATED_1_0.50 Returning empty Actor \n");
1531   return Actor();;
1532 }
1533
1534 Actor Button::GetSelectedImage() const
1535 {
1536   DALI_LOG_WARNING("Button::GetSelectedImage @DEPRECATED_1_0.50 Returning empty Actor \n");
1537   return Actor();
1538 }
1539
1540 } // namespace Internal
1541
1542 } // namespace Toolkit
1543
1544 } // namespace Dali