2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "button-impl.h"
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>
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/public-api/align-enumerations.h>
39 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
40 #include <dali-toolkit/devel-api/controls/control-devel.h>
41 #include <dali-toolkit/devel-api/controls/buttons/button-devel.h>
42 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
43 #include <dali-toolkit/internal/visuals/text/text-visual.h>
44 #include <dali-toolkit/public-api/visuals/text-visual-properties.h>
45 #include <dali-toolkit/public-api/visuals/visual-properties.h>
47 #if defined(DEBUG_ENABLED)
48 Debug::Filter* gLogButtonFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_BUTTON_CONTROL");
65 // empty handle as we cannot create button (but type registered for clicked signal)
69 // Setup properties, signals and actions using the type-registry.
70 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Button, Toolkit::Control, Create )
72 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabled", BOOLEAN, DISABLED )
73 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "autoRepeating", BOOLEAN, AUTO_REPEATING )
74 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "initialAutoRepeatingDelay", FLOAT, INITIAL_AUTO_REPEATING_DELAY )
75 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "nextAutoRepeatingDelay", FLOAT, NEXT_AUTO_REPEATING_DELAY )
76 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "togglable", BOOLEAN, TOGGLABLE )
77 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selected", BOOLEAN, SELECTED )
78 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedStateImage", MAP, UNSELECTED_STATE_IMAGE ) // Deprecated property
79 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedStateImage", MAP, SELECTED_STATE_IMAGE ) // Deprecated property
80 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledStateImage", MAP, DISABLED_STATE_IMAGE ) // Deprecated property
81 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedColor", VECTOR4, UNSELECTED_COLOR ) // Deprecated property
82 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedColor", VECTOR4, SELECTED_COLOR ) // Deprecated property
83 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "label", MAP, LABEL )
84 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "labelText", STRING, LABEL_TEXT ) // Deprecated property
85 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedVisual", MAP, UNSELECTED_VISUAL )
86 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "selectedVisual", MAP, SELECTED_VISUAL )
87 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledSelectedVisual", MAP, DISABLED_SELECTED_VISUAL )
88 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledUnselectedVisual", MAP, DISABLED_UNSELECTED_VISUAL )
89 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedBackgroundVisual", MAP, UNSELECTED_BACKGROUND_VISUAL )
90 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "selectedBackgroundVisual", MAP, SELECTED_BACKGROUND_VISUAL )
91 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledUnselectedBackgroundVisual", MAP, DISABLED_UNSELECTED_BACKGROUND_VISUAL )
92 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledSelectedBackgroundVisual", MAP, DISABLED_SELECTED_BACKGROUND_VISUAL )
93 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "labelRelativeAlignment", STRING, LABEL_RELATIVE_ALIGNMENT )
94 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "labelPadding", VECTOR4, LABEL_PADDING )
95 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "visualPadding", VECTOR4, VISUAL_PADDING )
98 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "pressed", SIGNAL_PRESSED )
99 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "released", SIGNAL_RELEASED )
100 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "clicked", SIGNAL_CLICKED )
101 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "stateChanged", SIGNAL_STATE_CHANGED )
104 DALI_ACTION_REGISTRATION( Toolkit, Button, "buttonClick", ACTION_BUTTON_CLICK )
106 DALI_TYPE_REGISTRATION_END()
108 DALI_ENUM_TO_STRING_TABLE_BEGIN( ALIGNMENT )
109 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, BEGIN )
110 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, END )
111 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, TOP )
112 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, BOTTOM )
113 DALI_ENUM_TO_STRING_TABLE_END( ALIGNMENT )
115 const Scripting::StringEnum ALIGNMENT_STRING_TABLE[] =
117 { "BEGIN", Button::BEGIN },
118 { "END", Button::END },
119 { "TOP", Button::TOP },
120 { "BOTTOM", Button::BOTTOM },
123 const unsigned int ALIGNMENT_STRING_TABLE_COUNT = sizeof( ALIGNMENT_STRING_TABLE ) / sizeof( ALIGNMENT_STRING_TABLE[0] );
125 const Property::Index VISUAL_INDEX_FOR_STATE[][Button::STATE_COUNT] =
127 { Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, Toolkit::DevelButton::Property::UNSELECTED_VISUAL },
128 { Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, Toolkit::DevelButton::Property::SELECTED_VISUAL },
129 { Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL },
130 { Toolkit::DevelButton::Property::DISABLED_SELECTED_BACKGROUND_VISUAL, Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL }
134 * Checks if given map contains a text string
136 bool MapContainsTextString( Property::Map& map )
139 Property::Value* value = map.Find( Toolkit::TextVisual::Property::TEXT );
142 std::string textString;
143 value->Get( textString );
144 if ( !textString.empty() )
152 } // unnamed namespace
155 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
156 mAutoRepeatingTimer(),
157 mTextLabelAlignment( END ),
158 mAutoRepeating( false ),
159 mTogglableButton( false ),
160 mTextStringSetFlag( false ),
161 mInitialAutoRepeatingDelay( 0.0f ),
162 mNextAutoRepeatingDelay( 0.0f ),
163 mAnimationTime( 0.0f ),
164 mButtonPressedState( UNPRESSED ),
165 mButtonState( UNSELECTED_STATE ),
166 mPreviousButtonState( mButtonState ),
167 mClickActionPerforming( false )
175 void Button::SetAutoRepeating( bool autoRepeating )
177 mAutoRepeating = autoRepeating;
179 // An autorepeating button can't be a toggle button.
184 SetSelected( false ); // UnSelect before switching off Toggle feature.
186 mTogglableButton = false;
190 bool Button::IsAutoRepeating() const
192 return mAutoRepeating;
195 void Button::SetInitialAutoRepeatingDelay( float initialAutoRepeatingDelay )
197 DALI_ASSERT_DEBUG( initialAutoRepeatingDelay > 0.f );
198 mInitialAutoRepeatingDelay = initialAutoRepeatingDelay;
201 float Button::GetInitialAutoRepeatingDelay() const
203 return mInitialAutoRepeatingDelay;
206 void Button::SetNextAutoRepeatingDelay( float nextAutoRepeatingDelay )
208 DALI_ASSERT_DEBUG( nextAutoRepeatingDelay > 0.f );
209 mNextAutoRepeatingDelay = nextAutoRepeatingDelay;
212 float Button::GetNextAutoRepeatingDelay() const
214 return mNextAutoRepeatingDelay;
217 void Button::SetTogglableButton( bool togglable )
219 mTogglableButton = togglable;
221 // A toggle button can't be an autorepeating button.
224 mAutoRepeating = false;
228 bool Button::IsTogglableButton() const
230 return mTogglableButton;
233 void Button::SetSelected( bool selected )
235 if( mTogglableButton )
237 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetSelected (%s)\n", (selected?"true":"false") );
239 if ( selected && ( mButtonState != SELECTED_STATE ) )
241 ChangeState( SELECTED_STATE );
243 else if ( !selected && ( mButtonState != UNSELECTED_STATE ) )
245 ChangeState( UNSELECTED_STATE );
250 void Button::SetDisabled( bool disabled )
252 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetDisabled(%s) state(%d)\n", (disabled)?"disabled":"active", mButtonState );
256 if ( mButtonState == SELECTED_STATE )
258 ChangeState( DISABLED_SELECTED_STATE );
260 else if ( mButtonState == UNSELECTED_STATE )
262 ChangeState( DISABLED_UNSELECTED_STATE );
267 if ( mButtonState == DISABLED_SELECTED_STATE )
269 ChangeState( SELECTED_STATE );
271 else if ( mButtonState == DISABLED_UNSELECTED_STATE )
273 ChangeState( UNSELECTED_STATE );
278 bool Button::IsDisabled() const
280 return ( mButtonState == DISABLED_SELECTED_STATE || mButtonState == DISABLED_UNSELECTED_STATE ) ;
283 bool Button::ValidateState( State requestedState )
285 /* Below tables shows allowed state transitions
286 * Match rows in first column to following columns, if true then transition allowed.
287 * eg UNSELECTED_STATE to DISABLED_UNSELECTED_STATE is true so state transition allowed.
289 to| UNSELECTED_STATE | SELECTED_STATE | DISABLED_UNSELECTED_STATE | DISABLED_SELECTED_STATE |*/
291 bool transitionTable[4][4] = { /* UNSELECTED_STATE*/ { false, true, true, false },
292 /* SELECTED_STATE*/ { true, false, false, true },
293 /* DISABLED_UNSELECTED_STATE*/{ true, true, false, false },
294 /* DISABLED_SELECTED_STATE*/ { false, true, false, false }
297 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ValidateState ReuestedState:%d, CurrentState:%d, result:%s\n",
298 requestedState, mButtonState, (transitionTable[mButtonState][requestedState])?"change-accepted":"change-denied");
300 return transitionTable[mButtonState][requestedState];
303 void Button::ChangeState( State requestedState )
305 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ChangeState ReuestedState(%d)\n", requestedState );
307 // Validate State before changing
308 if ( !ValidateState( requestedState ))
310 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ChangeState ReuestedState(%d) not validated\n", requestedState );
314 // If not on stage the button could have still been set to selected so update state
315 mPreviousButtonState = mButtonState; // Store previous state for visual removal (used when animations ended)
316 mButtonState = requestedState; // Update current state
318 if ( Self().OnStage() )
320 OnStateChange( mButtonState ); // Notify derived buttons
321 SelectRequiredVisual( VISUAL_INDEX_FOR_STATE[ mButtonState ][ BACKGROUND ] );
322 SelectRequiredVisual( VISUAL_INDEX_FOR_STATE[ mButtonState ][ FOREGROUND ] );
323 // If animation supported then visual removal should be performed after any transition animation has completed.
324 // If Required Visual is not loaded before current visual is removed then a flickering will be evident.
325 // Derived button can override OnButtonVisualRemoval
326 OnButtonVisualRemoval( VISUAL_INDEX_FOR_STATE[ mPreviousButtonState ][ BACKGROUND ] );
327 OnButtonVisualRemoval( VISUAL_INDEX_FOR_STATE[ mPreviousButtonState ][ FOREGROUND ] );
331 Toolkit::Button handle( GetOwner() );
333 mStateChangedSignal.Emit( handle );
336 bool Button::IsSelected() const
338 bool selected = ( mButtonState == SELECTED_STATE ) || ( mButtonState == DISABLED_SELECTED_STATE );
339 return mTogglableButton && selected;
342 void Button::SetLabelText( const std::string& label )
344 Self().SetProperty( Toolkit::Button::Property::LABEL, label );
347 std::string Button::GetLabelText() const
349 Property::Value value = Self().GetProperty( Toolkit::Button::Property::LABEL );
351 Property::Map *labelProperty = value.GetMap();
353 std::string textLabel;
357 Property::Value* value = labelProperty->Find( Toolkit::TextVisual::Property::TEXT );
360 value->Get( textLabel );
367 void Button::MergeWithExistingLabelProperties( const Property::Map& inMap, Property::Map& outMap )
369 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties with %d properties\n", inMap.Count() );
372 * Properties for the Label visual could be from a style sheet but after being set the "TEXT" property could be set.
373 * Hence would need to create the Text Visual with the complete merged set of properties.
375 * 1) Find Label Visual
376 * 2) Retrieve current properties ( settings )
377 * 3) Merge with new properties ( settings )
378 * 4) Return new merged map
380 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, Toolkit::Button::Property::LABEL );
383 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties Visual already exists, retrieving existing map\n");
384 visual.CreatePropertyMap( outMap );
385 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties retrieved %d properties\n", outMap.Count() );
388 outMap.Merge( inMap );
390 // Store if a text string has been supplied.
392 mTextStringSetFlag = MapContainsTextString( outMap );
394 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties now has %d properties\n", outMap.Count() );
397 void Button::SetLabelAlignment( Button::Align labelAlignment)
399 mTextLabelAlignment = labelAlignment;
403 Button::Align Button::GetLabelAlignment()
405 return mTextLabelAlignment;
409 * Create Visual for given index from a property map or url.
410 * 1) Check if value passed in is a url and create visual
411 * 2) Create visual from map if step (1) is false
412 * 3) Register visual with control with false for enable flag. Button will later enable visual when needed ( Button::SelectRequiredVisual )
413 * 4) Unregister visual if empty map was provided. This is the method to remove a visual
415 void Button::CreateVisualsForComponent( Property::Index index, const Property::Value& value, const int visualDepth )
417 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent index(%d)\n", index );
418 Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
419 Toolkit::Visual::Base buttonVisual;
421 std::string imageUrl;
422 if( value.Get( imageUrl ) )
424 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent Using image URL(%d)\n", index );
425 if ( !imageUrl.empty() )
427 DALI_ASSERT_DEBUG( index != Toolkit::Button::Property::LABEL && "Creating a Image Visual instead of Text Visual " );
428 buttonVisual = visualFactory.CreateVisual( imageUrl, ImageDimensions() );
433 // if its not a string then get a Property::Map from the property if possible.
434 Property::Map *map = value.GetMap();
435 if( map && !map->Empty() ) // Empty map results in current visual removal.
437 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent Using Map(%d)\n", index );
438 buttonVisual = visualFactory.CreateVisual( *map );
444 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent RegisterVisual index(%d) enabled(%s)\n",
445 index, DevelControl::IsVisualEnabled( *this, index )?"true":"false" );
446 // enable the visual if needed for current state
447 const bool enabled = ( ( index == VISUAL_INDEX_FOR_STATE[ mButtonState ][ BACKGROUND ] )||
448 ( index == VISUAL_INDEX_FOR_STATE[ mButtonState ][ FOREGROUND ] ) );
449 DevelControl::RegisterVisual( *this, index, buttonVisual, enabled, visualDepth );
453 DevelControl::UnregisterVisual( *this, index );
454 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "CreateVisualsForComponent Visual not created or empty map (clearing visual).(%d)\n", index);
459 bool Button::GetPropertyMapForVisual( Property::Index visualIndex, Property::Map& retreivedMap ) const
461 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetPropertyMapForVisual visual(%d)\n", visualIndex);
462 bool success = false;
463 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, visualIndex );
466 visual.CreatePropertyMap( retreivedMap );
469 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetPropertyMapForVisual %s\n", success?"Success":"Failure");
473 bool Button::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
477 Dali::BaseHandle handle( object );
479 Toolkit::Button button = Toolkit::Button::DownCast( handle );
481 DALI_ASSERT_DEBUG( button );
483 if( 0 == strcmp( actionName.c_str(), ACTION_BUTTON_CLICK ) )
485 ret = GetImplementation( button ).DoClickAction( attributes );
491 bool Button::DoClickAction( const Property::Map& attributes )
493 // Prevents the button signals from doing a recursive loop by sending an action
494 // and re-emitting the signals.
495 if( !mClickActionPerforming )
497 mClickActionPerforming = true;
499 if ( !mTogglableButton )
501 mButtonPressedState = DEPRESSED;
504 mClickActionPerforming = false;
512 void Button::ButtonDown()
514 if( mTogglableButton )
516 if ( mButtonState != SELECTED_STATE )
519 mButtonPressedState = TOGGLE_DEPRESSED;
523 mButtonPressedState = DEPRESSED;
529 mButtonPressedState = DEPRESSED;
532 SetUpTimer( mInitialAutoRepeatingDelay );
536 // The pressed signal should be emitted regardless of toggle mode.
537 Toolkit::Button handle( GetOwner() );
538 mPressedSignal.Emit( handle );
541 void Button::ButtonUp()
543 bool emitSignalsForPressAndReleaseAction = false;
545 if( DEPRESSED == mButtonPressedState )
547 if( mTogglableButton ) // Button up will change state
549 emitSignalsForPressAndReleaseAction = OnToggleReleased(); // Derived toggle buttons can override this to provide custom behaviour
553 Released(); // Button up will result in unselected state
556 mAutoRepeatingTimer.Reset();
558 emitSignalsForPressAndReleaseAction = true;
561 else if ( TOGGLE_DEPRESSED == mButtonPressedState )
563 emitSignalsForPressAndReleaseAction = true; // toggle released after being pressed, a click
566 if ( emitSignalsForPressAndReleaseAction )
568 // The clicked and released signals should be emitted regardless of toggle mode.
569 Toolkit::Button handle( GetOwner() );
570 mReleasedSignal.Emit( handle );
571 mClickedSignal.Emit( handle );
575 bool Button::OnToggleReleased()
577 SetSelected( !IsSelected() );
578 mButtonPressedState = UNPRESSED;
583 void Button::OnTouchPointLeave()
585 if( DEPRESSED == mButtonPressedState )
587 if( !mTogglableButton )
593 mAutoRepeatingTimer.Reset();
597 mButtonPressedState = UNPRESSED;
599 // The released signal should be emitted regardless of toggle mode.
600 Toolkit::Button handle( GetOwner() );
601 mReleasedSignal.Emit( handle );
605 void Button::OnTouchPointInterrupted()
610 Toolkit::Button::ButtonSignalType& Button::PressedSignal()
612 return mPressedSignal;
615 Toolkit::Button::ButtonSignalType& Button::ReleasedSignal()
617 return mReleasedSignal;
620 Toolkit::Button::ButtonSignalType& Button::ClickedSignal()
622 return mClickedSignal;
625 Toolkit::Button::ButtonSignalType& Button::StateChangedSignal()
627 return mStateChangedSignal;
630 bool Button::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
632 Dali::BaseHandle handle( object );
634 bool connected( true );
635 Toolkit::Button button = Toolkit::Button::DownCast( handle );
637 if( 0 == strcmp( signalName.c_str(), SIGNAL_PRESSED ) )
639 button.PressedSignal().Connect( tracker, functor );
641 else if( 0 == strcmp( signalName.c_str(), SIGNAL_RELEASED ) )
643 button.ReleasedSignal().Connect( tracker, functor );
645 else if( 0 == strcmp( signalName.c_str(), SIGNAL_CLICKED ) )
647 button.ClickedSignal().Connect( tracker, functor );
649 else if( 0 == strcmp( signalName.c_str(), SIGNAL_STATE_CHANGED ) )
651 button.StateChangedSignal().Connect( tracker, functor );
655 // signalName does not match any signal
662 void Button::OnInitialize()
664 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnInitialize\n" );
668 mTapDetector = TapGestureDetector::New();
669 mTapDetector.Attach( self );
670 mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
672 self.SetKeyboardFocusable( true );
674 self.TouchSignal().Connect( this, &Button::OnTouch );
677 bool Button::OnAccessibilityActivated()
679 return OnKeyboardEnter();
682 bool Button::OnTouch( Actor actor, const TouchData& touch )
685 // Only events are processed when the button is not disabled
686 auto result( false );
690 if ( 1 == touch.GetPointCount() )
692 switch( touch.GetState( 0 ) )
694 case PointState::DOWN:
704 case PointState::INTERRUPTED:
706 OnTouchPointInterrupted();
709 case PointState::LEAVE:
714 case PointState::MOTION:
715 case PointState::STATIONARY: // FALLTHROUGH
722 else if( 1 < touch.GetPointCount() )
724 OnTouchPointLeave(); // Notification for derived classes.
726 // Sets the button state to the default
727 mButtonPressedState = UNPRESSED;
734 bool Button::OnKeyboardEnter()
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 );
743 void Button::OnStageDisconnection()
745 if( DEPRESSED == mButtonPressedState )
747 if( !mTogglableButton )
753 mAutoRepeatingTimer.Reset();
758 mButtonPressedState = UNPRESSED;
760 Control::OnStageDisconnection(); // Visuals will be set off stage
763 void Button::OnStageConnection( int depth )
765 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnStageConnection ptr(%p) \n", this );
766 OnButtonVisualRemoval( VISUAL_INDEX_FOR_STATE[ mPreviousButtonState ][ BACKGROUND ] );
767 OnButtonVisualRemoval( VISUAL_INDEX_FOR_STATE[ mPreviousButtonState ][ FOREGROUND ] );
768 SelectRequiredVisual( Toolkit::Button::Property::LABEL );
769 SelectRequiredVisual( VISUAL_INDEX_FOR_STATE[ mButtonState ][ BACKGROUND ] );
770 SelectRequiredVisual( VISUAL_INDEX_FOR_STATE[ mButtonState ][ FOREGROUND ] );
771 Control::OnStageConnection( depth ); // Enabled visuals will be put on stage
775 Vector3 Button::GetNaturalSize()
777 Vector3 size = Vector3::ZERO;
779 bool horizontalAlignment = mTextLabelAlignment == BEGIN || mTextLabelAlignment == END; // label and visual side by side
781 // Get natural size of foreground ( largest of the possible visuals )
782 Size largestProvidedVisual;
783 Size labelSize = Size::ZERO;
785 bool foreGroundVisualUsed = false;
787 for ( int state = Button::UNSELECTED_STATE; state < Button::STATE_COUNT; state++ )
789 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, VISUAL_INDEX_FOR_STATE[state][FOREGROUND] );
793 visual.GetNaturalSize( visualSize );
794 largestProvidedVisual.width = std::max(largestProvidedVisual.width, visualSize.width );
795 largestProvidedVisual.height = std::max(largestProvidedVisual.height, visualSize.height );
796 foreGroundVisualUsed = true;
800 if ( !foreGroundVisualUsed ) // If foreground visual not supplied then use the background visual to calculate Natural size
802 for ( int state = Button::UNSELECTED_STATE; state < Button::STATE_COUNT; state++ )
804 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, VISUAL_INDEX_FOR_STATE[state][BACKGROUND] );
808 visual.GetNaturalSize( visualSize );
809 largestProvidedVisual.width = std::max(largestProvidedVisual.width, visualSize.width );
810 largestProvidedVisual.height = std::max(largestProvidedVisual.height, visualSize.height );
815 // Get horizontal padding total
816 if ( largestProvidedVisual.width > 0 ) // if visual exists
818 size.width += largestProvidedVisual.width + mForegroundPadding.left + mForegroundPadding.right;
820 // Get vertical padding total
821 if ( largestProvidedVisual.height > 0 )
823 size.height += largestProvidedVisual.height + mForegroundPadding.top + mForegroundPadding.bottom;
826 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize visual Size(%f,%f)\n",
827 largestProvidedVisual.width, largestProvidedVisual.height );
829 // Get natural size of label if text has been set
830 if ( mTextStringSetFlag )
832 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, Toolkit::Button::Property::LABEL );
836 visual.GetNaturalSize( labelSize );
838 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize labelSize(%f,%f) padding(%f,%f)\n",
839 labelSize.width, labelSize.height, mLabelPadding.left + mLabelPadding.right, mLabelPadding.top + mLabelPadding.bottom);
841 labelSize.width += mLabelPadding.left + mLabelPadding.right;
842 labelSize.height += mLabelPadding.top + mLabelPadding.bottom;
844 // Add label size to height or width depending on alignment position
845 if ( horizontalAlignment )
847 size.width += labelSize.width;
848 size.height = std::max(size.height, labelSize.height );
852 size.height += labelSize.height;
853 size.width = std::max(size.width, labelSize.width );
858 if( size.width < 1 && size.height < 1 )
860 // if no image or label then use Control's natural size
861 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize Using control natural size\n");
862 size = Control::GetNaturalSize();
865 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "Button GetNaturalSize (%f,%f)\n", size.width, size.height );
870 void Button::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
872 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnSetResizePolicy\n");
877 * Visuals are sized and positioned in this function.
878 * Whilst the control has it's size negotiated it has to size it's visuals explicitly here.
881 void Button::OnRelayout( const Vector2& size, RelayoutContainer& container )
883 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout targetSize(%f,%f) ptr(%p) state[%d]\n", size.width, size.height, this, mButtonState );
885 Toolkit::Visual::Base currentVisual = DevelControl::GetVisual( *this, VISUAL_INDEX_FOR_STATE[mButtonState][FOREGROUND] );
886 Toolkit::Visual::Base currentBackGroundVisual = DevelControl::GetVisual( *this, VISUAL_INDEX_FOR_STATE[mButtonState][BACKGROUND] );
888 // Sizes and padding set to zero, if not present then values will no effect calculations.
889 Vector2 visualPosition = Vector2::ZERO;
890 Vector2 labelPosition = Vector2::ZERO;
891 Size visualSize = Size::ZERO;
892 Padding foregroundVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f );
893 Padding labelVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f );
895 if ( mTextStringSetFlag )
897 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Label padding setting padding:%f,%f,%f,%f\n", mLabelPadding.y, mLabelPadding.x, mLabelPadding.width,mLabelPadding.height );
898 labelVisualPadding = mLabelPadding;
903 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Foreground Visual setting padding:%f,%f,%f,%f\n", mForegroundPadding.y, mForegroundPadding.x, mForegroundPadding.width,mForegroundPadding.height );
904 currentVisual.GetNaturalSize( visualSize );
905 foregroundVisualPadding = mForegroundPadding;
908 Toolkit::Align::Type visualAnchorPoint = Toolkit::Align::TOP_BEGIN;
910 Vector2 visualAndPaddingSize = Vector2( ( foregroundVisualPadding.x + visualSize.width + foregroundVisualPadding.y ),
911 ( foregroundVisualPadding.width + visualSize.height + foregroundVisualPadding.height ));
913 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout visualAndPaddingSize(%f,%f)\n", visualAndPaddingSize.width, visualAndPaddingSize.height);
915 // Text Visual should take all space available after foreground visual size and all padding is considered.
916 // Remaining Space priority, Foreground padding, foreground visual, Text padding then Text visual.
917 Size remainingSpaceForText = Size::ZERO;
919 switch ( mTextLabelAlignment )
923 visualAnchorPoint = Toolkit::Align::TOP_END;
924 visualPosition.x = foregroundVisualPadding.right;
925 visualPosition.y = foregroundVisualPadding.top;
927 labelPosition.x = labelVisualPadding.x;
928 labelPosition.y = labelVisualPadding.top;
930 remainingSpaceForText.width = size.width - visualAndPaddingSize.width - labelVisualPadding.x - labelVisualPadding.y;
931 remainingSpaceForText.height = size.height - labelVisualPadding.top - labelVisualPadding.bottom;
936 visualAnchorPoint = Toolkit::Align::TOP_BEGIN;
937 visualPosition.x = foregroundVisualPadding.left;
938 visualPosition.y = foregroundVisualPadding.top;
940 labelPosition.x = visualAndPaddingSize.width + labelVisualPadding.x;
941 labelPosition.y = labelVisualPadding.top;
943 remainingSpaceForText.width = size.width - visualAndPaddingSize.width - labelVisualPadding.x - labelVisualPadding.y;
944 remainingSpaceForText.height = size.height - labelVisualPadding.top - labelVisualPadding.bottom;
949 visualAnchorPoint = Toolkit::Align::BOTTOM_END;
950 visualPosition.x = foregroundVisualPadding.left;
951 visualPosition.y = foregroundVisualPadding.bottom;
953 labelPosition.x = labelVisualPadding.left;
954 labelPosition.y = labelVisualPadding.top;
956 remainingSpaceForText.width = size.width - labelVisualPadding.x - labelVisualPadding.y;
957 remainingSpaceForText.height = size.height - visualAndPaddingSize.height - labelVisualPadding.top - labelVisualPadding.bottom;
963 visualAnchorPoint = Toolkit::Align::TOP_END;
964 visualPosition.x = foregroundVisualPadding.left;
965 visualPosition.y = foregroundVisualPadding.top;
967 labelPosition.x = labelVisualPadding.left;
968 labelPosition.y = visualAndPaddingSize.height + labelVisualPadding.top;
970 remainingSpaceForText.width = size.width - labelVisualPadding.x - labelVisualPadding.y;
971 remainingSpaceForText.height = size.height - visualAndPaddingSize.height - labelVisualPadding.top - labelVisualPadding.bottom;
977 if ( currentBackGroundVisual )
979 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual background size to(%f,%f)\n", size.width, size.height);
981 Property::Map visualTransform;
983 visualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, size )
984 .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) );
986 currentBackGroundVisual.SetTransformAndSize( visualTransform, size );
991 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual size to(%f,%f)\n", visualSize.width, visualSize.height);
993 Property::Map visualTransform;
995 visualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, visualSize )
996 .Add( Toolkit::Visual::Transform::Property::OFFSET, visualPosition )
997 .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
998 .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
999 .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
1000 .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, visualAnchorPoint );
1002 currentVisual.SetTransformAndSize( visualTransform, size );
1005 if ( mTextStringSetFlag )
1007 Toolkit::Visual::Base textVisual = DevelControl::GetVisual( *this, Toolkit::Button::Property::LABEL ); // No need to search for Label visual if no text set.
1011 if ( !currentVisual )
1013 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Only Text\n");
1014 labelPosition.x = labelVisualPadding.left;
1015 labelPosition.y = labelVisualPadding.height;
1018 Vector2 preSize = Vector2( static_cast< int >( remainingSpaceForText.x ), static_cast< int >( remainingSpaceForText.y ));
1020 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout text Size(%f,%f) text Position(%f,%f) \n", remainingSpaceForText.width, remainingSpaceForText.height, labelPosition.x, labelPosition.y);
1022 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout text Size -- (%f,%f) text Position(%f,%f) \n", preSize.width, preSize.height, labelPosition.x, labelPosition.y);
1025 Property::Map textVisualTransform;
1026 textVisualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, preSize )
1027 .Add( Toolkit::Visual::Transform::Property::OFFSET, labelPosition )
1028 .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
1029 .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
1030 .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
1031 .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, visualAnchorPoint );
1033 textVisual.SetTransformAndSize( textVisualTransform, size );
1037 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout selected (%s) \n", IsSelected()?"yes":"no" );
1039 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout << \n");
1042 void Button::OnTap(Actor actor, const TapGesture& tap)
1044 // Prevents Parent getting a tap event
1047 void Button::SetUpTimer( float delay )
1049 mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
1050 mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot );
1051 mAutoRepeatingTimer.Start();
1054 bool Button::AutoRepeatingSlot()
1056 bool consumed = false;
1059 // Restart the autorepeat timer.
1060 SetUpTimer( mNextAutoRepeatingDelay );
1064 Toolkit::Button handle( GetOwner() );
1067 consumed = mReleasedSignal.Emit( handle );
1068 consumed = mClickedSignal.Emit( handle );
1069 consumed |= mPressedSignal.Emit( handle );
1075 void Button::Pressed()
1077 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Pressed\n" );
1079 if( mButtonState == UNSELECTED_STATE )
1081 ChangeState( SELECTED_STATE );
1082 OnPressed(); // Notifies the derived class the button has been pressed.
1086 void Button::Released()
1088 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Released\n" );
1090 if( mButtonState == SELECTED_STATE && !mTogglableButton )
1092 ChangeState( UNSELECTED_STATE );
1093 OnReleased(); // // Notifies the derived class the button has been released.
1095 mButtonPressedState = UNPRESSED;
1098 void Button::SelectRequiredVisual( Property::Index visualIndex )
1100 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SelectRequiredVisual index(%d) state(%d)\n", visualIndex, mButtonState );
1101 // only enable visuals that exist
1102 if( DevelControl::GetVisual( *this, visualIndex ) )
1104 DevelControl::EnableVisual( *this, visualIndex, true );
1108 void Button::RemoveVisual( Property::Index visualIndex )
1110 // Use OnButtonVisualRemoval if want button developer to have the option to override removal.
1111 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::RemoveVisual index(%d) state(%d)\n", visualIndex, mButtonState );
1113 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, visualIndex );
1117 DevelControl::EnableVisual( *this, visualIndex, false );
1121 void Button::OnButtonVisualRemoval( Property::Index visualIndex )
1123 // Derived Buttons can over ride this to prevent default removal.
1124 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnButtonVisualRemoval index(%d)\n", visualIndex );
1125 RemoveVisual( visualIndex );
1128 void Button::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
1130 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1132 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetProperty index[%d]\n", index );
1138 case Toolkit::Button::Property::DISABLED:
1140 GetImplementation( button ).SetDisabled( value.Get< bool >() );
1144 case Toolkit::Button::Property::AUTO_REPEATING:
1146 GetImplementation( button ).SetAutoRepeating( value.Get< bool >() );
1150 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1152 GetImplementation( button ).SetInitialAutoRepeatingDelay( value.Get< float >() );
1156 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1158 GetImplementation( button ).SetNextAutoRepeatingDelay( value.Get< float >() );
1162 case Toolkit::Button::Property::TOGGLABLE:
1164 GetImplementation( button ).SetTogglableButton( value.Get< bool >() );
1168 case Toolkit::Button::Property::SELECTED:
1170 GetImplementation( button ).SetSelected( value.Get< bool >() );
1174 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE: // Legacy Tizen 3.0
1176 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1179 case Toolkit::Button::Property::DISABLED_STATE_IMAGE: // Legacy Tizen 3.0
1181 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1184 case Toolkit::Button::Property::SELECTED_STATE_IMAGE: // Legacy Tizen 3.0
1186 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1189 case Toolkit::DevelButton::Property::UNSELECTED_VISUAL:
1190 case Toolkit::DevelButton::Property::SELECTED_VISUAL:
1191 case Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL:
1192 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL:
1194 GetImplementation( button ).CreateVisualsForComponent( index, value, DepthIndex::CONTENT );
1198 case Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL:
1199 case Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL:
1200 case Toolkit::DevelButton::Property::DISABLED_SELECTED_BACKGROUND_VISUAL:
1201 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL:
1203 GetImplementation( button ).CreateVisualsForComponent( index , value, DepthIndex::BACKGROUND);
1207 case Toolkit::Button::Property::UNSELECTED_COLOR:
1209 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::UNSELECTED_COLOR instead use Button::Property::UNSELECTED_BACKGROUND_VISUAL\n", __FUNCTION__);
1210 GetImplementation( button ).SetColor( value.Get< Vector4 >(), Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1214 case Toolkit::Button::Property::SELECTED_COLOR:
1216 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::SELECTED_COLOR instead use Button::Property::SELECTED_BACKGROUND_VISUAL\n", __FUNCTION__);
1217 GetImplementation( button ).SetColor( value.Get< Vector4 >(), Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL );
1221 case Toolkit::Button::Property::LABEL_TEXT:
1223 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::LABEL_TEXT instead use Button::Property::LABEL\n", __FUNCTION__);
1224 GetImplementation( button ).SetLabelText(value.Get< std::string >() );
1228 case Toolkit::Button::Property::LABEL:
1230 Property::Map outTextVisualProperties;
1231 std::string textString;
1233 if ( value.Get( textString ) )
1235 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetProperty Setting TextVisual with string[%s]\n", textString.c_str() );
1237 Property::Map setPropertyMap;
1238 setPropertyMap.Add( Toolkit::Visual::Property::TYPE, Toolkit::Visual::TEXT )
1239 .Add( Toolkit::TextVisual::Property::TEXT, textString );
1241 GetImplementation( button ).MergeWithExistingLabelProperties( setPropertyMap, outTextVisualProperties );
1245 // Get a Property::Map from the property if possible.
1246 Property::Map* setPropertyMap = value.GetMap();
1247 if( setPropertyMap )
1249 TextVisual::ConvertStringKeysToIndexKeys( *setPropertyMap );
1250 GetImplementation( button ).MergeWithExistingLabelProperties( *setPropertyMap, outTextVisualProperties );
1254 if( !outTextVisualProperties.Empty() )
1256 GetImplementation( button ).CreateVisualsForComponent( index, outTextVisualProperties, DepthIndex::CONTENT );
1261 case Toolkit::DevelButton::Property::LABEL_RELATIVE_ALIGNMENT:
1263 Button::Align labelAlignment(END);
1264 Scripting::GetEnumeration< Button::Align> ( value.Get< std::string >().c_str(),
1265 ALIGNMENT_TABLE, ALIGNMENT_TABLE_COUNT,
1268 GetImplementation( button ).SetLabelAlignment( labelAlignment );
1272 case Toolkit::DevelButton::Property::LABEL_PADDING:
1274 Vector4 padding ( value.Get< Vector4 >() );
1275 GetImplementation( button ).SetLabelPadding( Padding( padding.x, padding.y, padding.z, padding.w ) );
1279 case Toolkit::DevelButton::Property::VISUAL_PADDING:
1281 Vector4 padding ( value.Get< Vector4 >() );
1282 GetImplementation( button ).SetForegroundPadding( Padding( padding.x, padding.y, padding.z, padding.w ) );
1289 Property::Value Button::GetProperty( BaseObject* object, Property::Index propertyIndex )
1291 Property::Value value;
1293 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1297 switch ( propertyIndex )
1299 case Toolkit::Button::Property::DISABLED:
1301 value = GetImplementation( button ).IsDisabled();
1305 case Toolkit::Button::Property::AUTO_REPEATING:
1307 value = GetImplementation( button ).mAutoRepeating;
1311 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1313 value = GetImplementation( button ).mInitialAutoRepeatingDelay;
1317 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1319 value = GetImplementation( button ).mNextAutoRepeatingDelay;
1323 case Toolkit::Button::Property::TOGGLABLE:
1325 value = GetImplementation( button ).mTogglableButton;
1329 case Toolkit::Button::Property::SELECTED:
1331 value = GetImplementation( button ).IsSelected();
1335 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1337 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1341 case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1343 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL );
1347 case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1349 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL );
1353 case Toolkit::DevelButton::Property::UNSELECTED_VISUAL:
1354 case Toolkit::DevelButton::Property::SELECTED_VISUAL:
1355 case Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL:
1356 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL:
1357 case Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL:
1358 case Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL:
1359 case Toolkit::DevelButton::Property::DISABLED_SELECTED_BACKGROUND_VISUAL:
1360 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL:
1361 case Toolkit::Button::Property::LABEL:
1363 Property::Map visualProperty;
1364 if ( GetImplementation( button ).GetPropertyMapForVisual( propertyIndex, visualProperty ) )
1366 value = visualProperty;
1371 case Toolkit::Button::Property::UNSELECTED_COLOR:
1373 value = GetImplementation( button ).GetUnselectedColor();
1377 case Toolkit::Button::Property::SELECTED_COLOR:
1379 value = GetImplementation( button ).GetSelectedColor();
1383 case Toolkit::Button::Property::LABEL_TEXT:
1385 value = GetImplementation( button ).GetLabelText();
1389 case Toolkit::DevelButton::Property::LABEL_RELATIVE_ALIGNMENT:
1391 const char* alignment = Scripting::GetEnumerationName< Button::Align >( GetImplementation( button ).GetLabelAlignment(),
1392 ALIGNMENT_STRING_TABLE,
1393 ALIGNMENT_STRING_TABLE_COUNT );
1396 value = std::string( alignment );
1402 case Toolkit::DevelButton::Property::LABEL_PADDING:
1404 Padding padding = GetImplementation( button ).GetLabelPadding();
1405 value = Vector4( padding.x, padding.y, padding.top, padding.bottom);
1409 case Toolkit::DevelButton::Property::VISUAL_PADDING:
1411 Padding padding = GetImplementation( button ).GetForegroundPadding();
1412 value = Vector4( padding.x, padding.y, padding.top, padding.bottom);
1420 void Button::SetLabelPadding( const Padding& padding)
1422 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetLabelPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top );
1423 mLabelPadding = Padding( padding.left, padding.right, padding.bottom, padding.top );
1427 Padding Button::GetLabelPadding()
1429 return mLabelPadding;
1432 void Button::SetForegroundPadding( const Padding& padding)
1434 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetForegroundPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top );
1435 mForegroundPadding = Padding( padding.left, padding.right, padding.bottom, padding.top );
1439 Padding Button::GetForegroundPadding()
1441 return mForegroundPadding;
1444 ////////////////////////////////////////////////////////////////////////
1445 // Legacy functions from Tizen 2.4 and 3.0
1447 // Legacy code needed whilst Color can be set by direct Property setting ( deprecated ) instead of setting a Visual
1448 void Button::SetColor( const Vector4& color, Property::Index visualIndex )
1450 if ( visualIndex == Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL )
1452 mSelectedColor = color;
1456 mUnselectedColor = color;
1460 map[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::COLOR;
1461 map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color;
1463 CreateVisualsForComponent( visualIndex, map, DepthIndex::BACKGROUND );
1466 const Vector4 Button::GetUnselectedColor() const
1468 return mUnselectedColor;
1471 const Vector4 Button::GetSelectedColor() const
1473 return mSelectedColor;
1476 void Button::SetAnimationTime( float animationTime )
1478 // Used by deprecated API
1479 mAnimationTime = animationTime;
1482 float Button::GetAnimationTime() const
1484 // Used by deprecated API
1485 return mAnimationTime;
1488 void Button::SetLabel( Actor label )
1492 Property::Value value ="";
1493 value = label.GetProperty(Toolkit::TextLabel::Property::TEXT);
1495 SetLabelText( value.Get<std::string>() );
1499 void Button::SetUnselectedImage( const std::string& filename )
1501 SetBackgroundImage( filename );
1504 void Button::SetBackgroundImage( const std::string& filename )
1506 if( !filename.empty() )
1508 CreateVisualsForComponent( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1512 DevelControl::UnregisterVisual( *this, Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1516 void Button::SetSelectedImage( const std::string& filename )
1518 SetSelectedBackgroundImage( filename );
1521 void Button::SetSelectedBackgroundImage( const std::string& filename )
1523 if( !filename.empty() )
1525 CreateVisualsForComponent( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1529 DevelControl::UnregisterVisual( *this, Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1533 void Button::SetDisabledBackgroundImage( const std::string& filename )
1535 if( !filename.empty() )
1537 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1541 void Button::SetDisabledImage( const std::string& filename )
1543 if( !filename.empty() )
1545 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL, filename, DepthIndex::CONTENT );
1549 void Button::SetDisabledSelectedImage( const std::string& filename )
1551 if( !filename.empty() )
1553 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL, filename, DepthIndex::CONTENT );
1557 // Used by Deprecated Properties which don't use the Visual Property maps for setting and getting
1558 std::string Button::GetUrlForImageVisual( const Property::Index index ) const
1560 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, index );
1565 Dali::Property::Map retreivedMap;
1566 visual.CreatePropertyMap( retreivedMap );
1567 Property::Value* value = retreivedMap.Find( Toolkit::ImageVisual::Property::URL, Property::STRING );
1570 result = value->Get<std::string>();
1577 // Below functions DEPRECATED_1_0.50 - Return empty Actors
1581 std::string GetUrlFromImage( Image& image )
1583 ResourceImage resourceImage = ResourceImage::DownCast( image );
1585 std::string imageUrl;
1587 if ( resourceImage )
1589 imageUrl = resourceImage.GetUrl();
1597 void Button::SetButtonImage( Image image )
1599 DALI_LOG_WARNING("Button::SetButtonImage @DEPRECATED_1_0.50\n");
1600 SetUnselectedImage( GetUrlFromImage( image ) );
1601 mSetButtonImage = image;
1604 void Button::SetSelectedImage( Image image )
1606 DALI_LOG_WARNING("Button::SetSelectedImage @DEPRECATED_1_0.50\n");
1607 SetSelectedImage( GetUrlFromImage( image ) );
1608 mSetSelectedImage = image;
1611 Actor Button::GetButtonImage() const
1613 // When deprecated ImageView API removed then this button API can be removed too.
1614 DALI_LOG_WARNING("Button::GetButtonImage @DEPRECATED_1_0.50\n");
1618 if ( mSetButtonImage )
1620 imageView = Toolkit::ImageView::New( mSetButtonImage );
1624 ResourceImage image = ResourceImage::New( GetUrlForImageVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL ) );
1625 imageView = Toolkit::ImageView::New( image );
1631 Actor Button::GetSelectedImage() const
1633 // When deprecated ImageView API removed then this button API can be removed too.
1634 DALI_LOG_WARNING("Button::GetSelectedImage @DEPRECATED_1_0.50\n");
1638 if ( mSetSelectedImage )
1640 imageView = Toolkit::ImageView::New( mSetSelectedImage );
1644 ResourceImage image = ResourceImage::New( GetUrlForImageVisual( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL ) );
1645 imageView = Toolkit::ImageView::New( image );
1650 } // namespace Internal
1652 } // namespace Toolkit