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