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 ( index == Toolkit::Button::Property::LABEL ) );
450 DevelControl::RegisterVisual( *this, index, buttonVisual, enabled, visualDepth );
454 DevelControl::UnregisterVisual( *this, index );
455 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "CreateVisualsForComponent Visual not created or empty map (clearing visual).(%d)\n", index);
460 bool Button::GetPropertyMapForVisual( Property::Index visualIndex, Property::Map& retreivedMap ) const
462 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetPropertyMapForVisual visual(%d)\n", visualIndex);
463 bool success = false;
464 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, visualIndex );
467 visual.CreatePropertyMap( retreivedMap );
470 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetPropertyMapForVisual %s\n", success?"Success":"Failure");
474 bool Button::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
478 Dali::BaseHandle handle( object );
480 Toolkit::Button button = Toolkit::Button::DownCast( handle );
482 DALI_ASSERT_DEBUG( button );
484 if( 0 == strcmp( actionName.c_str(), ACTION_BUTTON_CLICK ) )
486 ret = GetImplementation( button ).DoClickAction( attributes );
492 bool Button::DoClickAction( const Property::Map& attributes )
494 // Prevents the button signals from doing a recursive loop by sending an action
495 // and re-emitting the signals.
496 if( !mClickActionPerforming )
498 mClickActionPerforming = true;
500 if ( !mTogglableButton )
502 mButtonPressedState = DEPRESSED;
505 mClickActionPerforming = false;
513 void Button::ButtonDown()
515 if( mTogglableButton )
517 if ( mButtonState != SELECTED_STATE )
520 mButtonPressedState = TOGGLE_DEPRESSED;
524 mButtonPressedState = DEPRESSED;
530 mButtonPressedState = DEPRESSED;
533 SetUpTimer( mInitialAutoRepeatingDelay );
537 // The pressed signal should be emitted regardless of toggle mode.
538 Toolkit::Button handle( GetOwner() );
539 mPressedSignal.Emit( handle );
542 void Button::ButtonUp()
544 bool emitSignalsForPressAndReleaseAction = false;
546 if( DEPRESSED == mButtonPressedState )
548 if( mTogglableButton ) // Button up will change state
550 emitSignalsForPressAndReleaseAction = OnToggleReleased(); // Derived toggle buttons can override this to provide custom behaviour
554 Released(); // Button up will result in unselected state
557 mAutoRepeatingTimer.Reset();
559 emitSignalsForPressAndReleaseAction = true;
562 else if ( TOGGLE_DEPRESSED == mButtonPressedState )
564 emitSignalsForPressAndReleaseAction = true; // toggle released after being pressed, a click
567 if ( emitSignalsForPressAndReleaseAction )
569 // The clicked and released signals should be emitted regardless of toggle mode.
570 Toolkit::Button handle( GetOwner() );
571 mReleasedSignal.Emit( handle );
572 mClickedSignal.Emit( handle );
576 bool Button::OnToggleReleased()
578 SetSelected( !IsSelected() );
579 mButtonPressedState = UNPRESSED;
584 void Button::OnTouchPointLeave()
586 if( DEPRESSED == mButtonPressedState )
588 if( !mTogglableButton )
594 mAutoRepeatingTimer.Reset();
598 mButtonPressedState = UNPRESSED;
600 // The released signal should be emitted regardless of toggle mode.
601 Toolkit::Button handle( GetOwner() );
602 mReleasedSignal.Emit( handle );
606 void Button::OnTouchPointInterrupted()
611 Toolkit::Button::ButtonSignalType& Button::PressedSignal()
613 return mPressedSignal;
616 Toolkit::Button::ButtonSignalType& Button::ReleasedSignal()
618 return mReleasedSignal;
621 Toolkit::Button::ButtonSignalType& Button::ClickedSignal()
623 return mClickedSignal;
626 Toolkit::Button::ButtonSignalType& Button::StateChangedSignal()
628 return mStateChangedSignal;
631 bool Button::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
633 Dali::BaseHandle handle( object );
635 bool connected( true );
636 Toolkit::Button button = Toolkit::Button::DownCast( handle );
638 if( 0 == strcmp( signalName.c_str(), SIGNAL_PRESSED ) )
640 button.PressedSignal().Connect( tracker, functor );
642 else if( 0 == strcmp( signalName.c_str(), SIGNAL_RELEASED ) )
644 button.ReleasedSignal().Connect( tracker, functor );
646 else if( 0 == strcmp( signalName.c_str(), SIGNAL_CLICKED ) )
648 button.ClickedSignal().Connect( tracker, functor );
650 else if( 0 == strcmp( signalName.c_str(), SIGNAL_STATE_CHANGED ) )
652 button.StateChangedSignal().Connect( tracker, functor );
656 // signalName does not match any signal
663 void Button::OnInitialize()
665 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnInitialize\n" );
669 mTapDetector = TapGestureDetector::New();
670 mTapDetector.Attach( self );
671 mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
673 self.SetKeyboardFocusable( true );
675 self.TouchSignal().Connect( this, &Button::OnTouch );
678 bool Button::OnAccessibilityActivated()
680 return OnKeyboardEnter();
683 bool Button::OnTouch( Actor actor, const TouchData& touch )
686 // Only events are processed when the button is not disabled
687 auto result( false );
691 if ( 1 == touch.GetPointCount() )
693 switch( touch.GetState( 0 ) )
695 case PointState::DOWN:
705 case PointState::INTERRUPTED:
707 OnTouchPointInterrupted();
710 case PointState::LEAVE:
715 case PointState::MOTION:
716 case PointState::STATIONARY: // FALLTHROUGH
723 else if( 1 < touch.GetPointCount() )
725 OnTouchPointLeave(); // Notification for derived classes.
727 // Sets the button state to the default
728 mButtonPressedState = UNPRESSED;
735 bool Button::OnKeyboardEnter()
737 // When the enter key is pressed, or button is activated, the click action is performed.
738 Property::Map attributes;
739 bool ret = DoClickAction( attributes );
744 void Button::OnStageDisconnection()
746 if( DEPRESSED == mButtonPressedState )
748 if( !mTogglableButton )
754 mAutoRepeatingTimer.Reset();
759 mButtonPressedState = UNPRESSED;
761 Control::OnStageDisconnection(); // Visuals will be set off stage
764 void Button::OnStageConnection( int depth )
766 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnStageConnection ptr(%p) \n", this );
767 OnButtonVisualRemoval( VISUAL_INDEX_FOR_STATE[ mPreviousButtonState ][ BACKGROUND ] );
768 OnButtonVisualRemoval( VISUAL_INDEX_FOR_STATE[ mPreviousButtonState ][ FOREGROUND ] );
769 SelectRequiredVisual( Toolkit::Button::Property::LABEL );
770 SelectRequiredVisual( VISUAL_INDEX_FOR_STATE[ mButtonState ][ BACKGROUND ] );
771 SelectRequiredVisual( VISUAL_INDEX_FOR_STATE[ mButtonState ][ FOREGROUND ] );
772 Control::OnStageConnection( depth ); // Enabled visuals will be put on stage
776 Vector3 Button::GetNaturalSize()
778 Vector3 size = Vector3::ZERO;
780 bool horizontalAlignment = mTextLabelAlignment == BEGIN || mTextLabelAlignment == END; // label and visual side by side
782 // Get natural size of foreground ( largest of the possible visuals )
783 Size largestProvidedVisual;
784 Size labelSize = Size::ZERO;
786 bool foreGroundVisualUsed = false;
788 for ( int state = Button::UNSELECTED_STATE; state < Button::STATE_COUNT; state++ )
790 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, VISUAL_INDEX_FOR_STATE[state][FOREGROUND] );
794 visual.GetNaturalSize( visualSize );
795 largestProvidedVisual.width = std::max(largestProvidedVisual.width, visualSize.width );
796 largestProvidedVisual.height = std::max(largestProvidedVisual.height, visualSize.height );
797 foreGroundVisualUsed = true;
801 if ( !foreGroundVisualUsed ) // If foreground visual not supplied then use the background visual to calculate Natural size
803 for ( int state = Button::UNSELECTED_STATE; state < Button::STATE_COUNT; state++ )
805 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, VISUAL_INDEX_FOR_STATE[state][BACKGROUND] );
809 visual.GetNaturalSize( visualSize );
810 largestProvidedVisual.width = std::max(largestProvidedVisual.width, visualSize.width );
811 largestProvidedVisual.height = std::max(largestProvidedVisual.height, visualSize.height );
816 // Get horizontal padding total
817 if ( largestProvidedVisual.width > 0 ) // if visual exists
819 size.width += largestProvidedVisual.width + mForegroundPadding.left + mForegroundPadding.right;
821 // Get vertical padding total
822 if ( largestProvidedVisual.height > 0 )
824 size.height += largestProvidedVisual.height + mForegroundPadding.top + mForegroundPadding.bottom;
827 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize visual Size(%f,%f)\n",
828 largestProvidedVisual.width, largestProvidedVisual.height );
830 // Get natural size of label if text has been set
831 if ( mTextStringSetFlag )
833 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, Toolkit::Button::Property::LABEL );
837 visual.GetNaturalSize( labelSize );
839 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize labelSize(%f,%f) padding(%f,%f)\n",
840 labelSize.width, labelSize.height, mLabelPadding.left + mLabelPadding.right, mLabelPadding.top + mLabelPadding.bottom);
842 labelSize.width += mLabelPadding.left + mLabelPadding.right;
843 labelSize.height += mLabelPadding.top + mLabelPadding.bottom;
845 // Add label size to height or width depending on alignment position
846 if ( horizontalAlignment )
848 size.width += labelSize.width;
849 size.height = std::max(size.height, labelSize.height );
853 size.height += labelSize.height;
854 size.width = std::max(size.width, labelSize.width );
859 if( size.width < 1 && size.height < 1 )
861 // if no image or label then use Control's natural size
862 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize Using control natural size\n");
863 size = Control::GetNaturalSize();
866 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "Button GetNaturalSize (%f,%f)\n", size.width, size.height );
871 void Button::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
873 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnSetResizePolicy\n");
878 * Visuals are sized and positioned in this function.
879 * Whilst the control has it's size negotiated it has to size it's visuals explicitly here.
882 void Button::OnRelayout( const Vector2& size, RelayoutContainer& container )
884 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout targetSize(%f,%f) ptr(%p) state[%d]\n", size.width, size.height, this, mButtonState );
886 Toolkit::Visual::Base currentVisual = DevelControl::GetVisual( *this, VISUAL_INDEX_FOR_STATE[mButtonState][FOREGROUND] );
887 Toolkit::Visual::Base currentBackGroundVisual = DevelControl::GetVisual( *this, VISUAL_INDEX_FOR_STATE[mButtonState][BACKGROUND] );
889 // Sizes and padding set to zero, if not present then values will no effect calculations.
890 Vector2 visualPosition = Vector2::ZERO;
891 Vector2 labelPosition = Vector2::ZERO;
892 Size visualSize = Size::ZERO;
893 Padding foregroundVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f );
894 Padding labelVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f );
896 if ( mTextStringSetFlag )
898 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Label padding setting padding:%f,%f,%f,%f\n", mLabelPadding.y, mLabelPadding.x, mLabelPadding.width,mLabelPadding.height );
899 labelVisualPadding = mLabelPadding;
904 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Foreground Visual setting padding:%f,%f,%f,%f\n", mForegroundPadding.y, mForegroundPadding.x, mForegroundPadding.width,mForegroundPadding.height );
905 currentVisual.GetNaturalSize( visualSize );
906 foregroundVisualPadding = mForegroundPadding;
909 Toolkit::Align::Type visualAnchorPoint = Toolkit::Align::TOP_BEGIN;
911 Vector2 visualAndPaddingSize = Vector2( ( foregroundVisualPadding.x + visualSize.width + foregroundVisualPadding.y ),
912 ( foregroundVisualPadding.width + visualSize.height + foregroundVisualPadding.height ));
914 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout visualAndPaddingSize(%f,%f)\n", visualAndPaddingSize.width, visualAndPaddingSize.height);
916 // Text Visual should take all space available after foreground visual size and all padding is considered.
917 // Remaining Space priority, Foreground padding, foreground visual, Text padding then Text visual.
918 Size remainingSpaceForText = Size::ZERO;
920 switch ( mTextLabelAlignment )
924 visualAnchorPoint = Toolkit::Align::TOP_END;
925 visualPosition.x = foregroundVisualPadding.right;
926 visualPosition.y = foregroundVisualPadding.top;
928 labelPosition.x = labelVisualPadding.x;
929 labelPosition.y = labelVisualPadding.top;
931 remainingSpaceForText.width = size.width - visualAndPaddingSize.width - labelVisualPadding.x - labelVisualPadding.y;
932 remainingSpaceForText.height = size.height - labelVisualPadding.top - labelVisualPadding.bottom;
937 visualAnchorPoint = Toolkit::Align::TOP_BEGIN;
938 visualPosition.x = foregroundVisualPadding.left;
939 visualPosition.y = foregroundVisualPadding.top;
941 labelPosition.x = visualAndPaddingSize.width + labelVisualPadding.x;
942 labelPosition.y = labelVisualPadding.top;
944 remainingSpaceForText.width = size.width - visualAndPaddingSize.width - labelVisualPadding.x - labelVisualPadding.y;
945 remainingSpaceForText.height = size.height - labelVisualPadding.top - labelVisualPadding.bottom;
950 visualAnchorPoint = Toolkit::Align::BOTTOM_END;
951 visualPosition.x = foregroundVisualPadding.left;
952 visualPosition.y = foregroundVisualPadding.bottom;
954 labelPosition.x = labelVisualPadding.left;
955 labelPosition.y = labelVisualPadding.top;
957 remainingSpaceForText.width = size.width - labelVisualPadding.x - labelVisualPadding.y;
958 remainingSpaceForText.height = size.height - visualAndPaddingSize.height - labelVisualPadding.top - labelVisualPadding.bottom;
964 visualAnchorPoint = Toolkit::Align::TOP_END;
965 visualPosition.x = foregroundVisualPadding.left;
966 visualPosition.y = foregroundVisualPadding.top;
968 labelPosition.x = labelVisualPadding.left;
969 labelPosition.y = visualAndPaddingSize.height + labelVisualPadding.top;
971 remainingSpaceForText.width = size.width - labelVisualPadding.x - labelVisualPadding.y;
972 remainingSpaceForText.height = size.height - visualAndPaddingSize.height - labelVisualPadding.top - labelVisualPadding.bottom;
978 if ( currentBackGroundVisual )
980 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual background size to(%f,%f)\n", size.width, size.height);
982 Property::Map visualTransform;
984 visualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, size )
985 .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) );
987 currentBackGroundVisual.SetTransformAndSize( visualTransform, size );
992 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual size to(%f,%f)\n", visualSize.width, visualSize.height);
994 Property::Map visualTransform;
996 visualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, visualSize )
997 .Add( Toolkit::Visual::Transform::Property::OFFSET, visualPosition )
998 .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
999 .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
1000 .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
1001 .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, visualAnchorPoint );
1003 currentVisual.SetTransformAndSize( visualTransform, size );
1006 if ( mTextStringSetFlag )
1008 Toolkit::Visual::Base textVisual = DevelControl::GetVisual( *this, Toolkit::Button::Property::LABEL ); // No need to search for Label visual if no text set.
1012 if ( !currentVisual )
1014 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Only Text\n");
1015 labelPosition.x = labelVisualPadding.left;
1016 labelPosition.y = labelVisualPadding.height;
1019 Vector2 preSize = Vector2( static_cast< int >( remainingSpaceForText.x ), static_cast< int >( remainingSpaceForText.y ));
1021 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout text Size(%f,%f) text Position(%f,%f) \n", remainingSpaceForText.width, remainingSpaceForText.height, labelPosition.x, labelPosition.y);
1023 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout text Size -- (%f,%f) text Position(%f,%f) \n", preSize.width, preSize.height, labelPosition.x, labelPosition.y);
1026 Property::Map textVisualTransform;
1027 textVisualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, preSize )
1028 .Add( Toolkit::Visual::Transform::Property::OFFSET, labelPosition )
1029 .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
1030 .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
1031 .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
1032 .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, visualAnchorPoint );
1034 textVisual.SetTransformAndSize( textVisualTransform, size );
1038 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout selected (%s) \n", IsSelected()?"yes":"no" );
1040 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout << \n");
1043 void Button::OnTap(Actor actor, const TapGesture& tap)
1045 // Prevents Parent getting a tap event
1048 void Button::SetUpTimer( float delay )
1050 mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
1051 mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot );
1052 mAutoRepeatingTimer.Start();
1055 bool Button::AutoRepeatingSlot()
1057 bool consumed = false;
1060 // Restart the autorepeat timer.
1061 SetUpTimer( mNextAutoRepeatingDelay );
1065 Toolkit::Button handle( GetOwner() );
1068 consumed = mReleasedSignal.Emit( handle );
1069 consumed = mClickedSignal.Emit( handle );
1070 consumed |= mPressedSignal.Emit( handle );
1076 void Button::Pressed()
1078 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Pressed\n" );
1080 if( mButtonState == UNSELECTED_STATE )
1082 ChangeState( SELECTED_STATE );
1083 OnPressed(); // Notifies the derived class the button has been pressed.
1087 void Button::Released()
1089 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Released\n" );
1091 if( mButtonState == SELECTED_STATE && !mTogglableButton )
1093 ChangeState( UNSELECTED_STATE );
1094 OnReleased(); // // Notifies the derived class the button has been released.
1096 mButtonPressedState = UNPRESSED;
1099 void Button::SelectRequiredVisual( Property::Index visualIndex )
1101 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SelectRequiredVisual index(%d) state(%d)\n", visualIndex, mButtonState );
1102 // only enable visuals that exist
1103 if( DevelControl::GetVisual( *this, visualIndex ) )
1105 DevelControl::EnableVisual( *this, visualIndex, true );
1109 void Button::RemoveVisual( Property::Index visualIndex )
1111 // Use OnButtonVisualRemoval if want button developer to have the option to override removal.
1112 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::RemoveVisual index(%d) state(%d)\n", visualIndex, mButtonState );
1114 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, visualIndex );
1118 DevelControl::EnableVisual( *this, visualIndex, false );
1122 void Button::OnButtonVisualRemoval( Property::Index visualIndex )
1124 // Derived Buttons can over ride this to prevent default removal.
1125 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnButtonVisualRemoval index(%d)\n", visualIndex );
1126 RemoveVisual( visualIndex );
1129 void Button::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
1131 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1133 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetProperty index[%d]\n", index );
1139 case Toolkit::Button::Property::DISABLED:
1141 GetImplementation( button ).SetDisabled( value.Get< bool >() );
1145 case Toolkit::Button::Property::AUTO_REPEATING:
1147 GetImplementation( button ).SetAutoRepeating( value.Get< bool >() );
1151 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1153 GetImplementation( button ).SetInitialAutoRepeatingDelay( value.Get< float >() );
1157 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1159 GetImplementation( button ).SetNextAutoRepeatingDelay( value.Get< float >() );
1163 case Toolkit::Button::Property::TOGGLABLE:
1165 GetImplementation( button ).SetTogglableButton( value.Get< bool >() );
1169 case Toolkit::Button::Property::SELECTED:
1171 GetImplementation( button ).SetSelected( value.Get< bool >() );
1175 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE: // Legacy Tizen 3.0
1177 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1180 case Toolkit::Button::Property::DISABLED_STATE_IMAGE: // Legacy Tizen 3.0
1182 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1185 case Toolkit::Button::Property::SELECTED_STATE_IMAGE: // Legacy Tizen 3.0
1187 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1190 case Toolkit::DevelButton::Property::UNSELECTED_VISUAL:
1191 case Toolkit::DevelButton::Property::SELECTED_VISUAL:
1192 case Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL:
1193 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL:
1195 GetImplementation( button ).CreateVisualsForComponent( index, value, DepthIndex::CONTENT );
1199 case Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL:
1200 case Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL:
1201 case Toolkit::DevelButton::Property::DISABLED_SELECTED_BACKGROUND_VISUAL:
1202 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL:
1204 GetImplementation( button ).CreateVisualsForComponent( index , value, DepthIndex::BACKGROUND);
1208 case Toolkit::Button::Property::UNSELECTED_COLOR:
1210 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::UNSELECTED_COLOR instead use Button::Property::UNSELECTED_BACKGROUND_VISUAL\n", __FUNCTION__);
1211 GetImplementation( button ).SetColor( value.Get< Vector4 >(), Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1215 case Toolkit::Button::Property::SELECTED_COLOR:
1217 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::SELECTED_COLOR instead use Button::Property::SELECTED_BACKGROUND_VISUAL\n", __FUNCTION__);
1218 GetImplementation( button ).SetColor( value.Get< Vector4 >(), Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL );
1222 case Toolkit::Button::Property::LABEL_TEXT:
1224 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::LABEL_TEXT instead use Button::Property::LABEL\n", __FUNCTION__);
1225 GetImplementation( button ).SetLabelText(value.Get< std::string >() );
1229 case Toolkit::Button::Property::LABEL:
1231 Property::Map outTextVisualProperties;
1232 std::string textString;
1234 if ( value.Get( textString ) )
1236 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetProperty Setting TextVisual with string[%s]\n", textString.c_str() );
1238 Property::Map setPropertyMap;
1239 setPropertyMap.Add( Toolkit::Visual::Property::TYPE, Toolkit::Visual::TEXT )
1240 .Add( Toolkit::TextVisual::Property::TEXT, textString );
1242 GetImplementation( button ).MergeWithExistingLabelProperties( setPropertyMap, outTextVisualProperties );
1246 // Get a Property::Map from the property if possible.
1247 Property::Map* setPropertyMap = value.GetMap();
1248 if( setPropertyMap )
1250 TextVisual::ConvertStringKeysToIndexKeys( *setPropertyMap );
1251 GetImplementation( button ).MergeWithExistingLabelProperties( *setPropertyMap, outTextVisualProperties );
1255 if( !outTextVisualProperties.Empty() )
1257 GetImplementation( button ).CreateVisualsForComponent( index, outTextVisualProperties, DepthIndex::CONTENT );
1262 case Toolkit::DevelButton::Property::LABEL_RELATIVE_ALIGNMENT:
1264 Button::Align labelAlignment(END);
1265 Scripting::GetEnumeration< Button::Align> ( value.Get< std::string >().c_str(),
1266 ALIGNMENT_TABLE, ALIGNMENT_TABLE_COUNT,
1269 GetImplementation( button ).SetLabelAlignment( labelAlignment );
1273 case Toolkit::DevelButton::Property::LABEL_PADDING:
1275 Vector4 padding ( value.Get< Vector4 >() );
1276 GetImplementation( button ).SetLabelPadding( Padding( padding.x, padding.y, padding.z, padding.w ) );
1280 case Toolkit::DevelButton::Property::VISUAL_PADDING:
1282 Vector4 padding ( value.Get< Vector4 >() );
1283 GetImplementation( button ).SetForegroundPadding( Padding( padding.x, padding.y, padding.z, padding.w ) );
1290 Property::Value Button::GetProperty( BaseObject* object, Property::Index propertyIndex )
1292 Property::Value value;
1294 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1298 switch ( propertyIndex )
1300 case Toolkit::Button::Property::DISABLED:
1302 value = GetImplementation( button ).IsDisabled();
1306 case Toolkit::Button::Property::AUTO_REPEATING:
1308 value = GetImplementation( button ).mAutoRepeating;
1312 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1314 value = GetImplementation( button ).mInitialAutoRepeatingDelay;
1318 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1320 value = GetImplementation( button ).mNextAutoRepeatingDelay;
1324 case Toolkit::Button::Property::TOGGLABLE:
1326 value = GetImplementation( button ).mTogglableButton;
1330 case Toolkit::Button::Property::SELECTED:
1332 value = GetImplementation( button ).IsSelected();
1336 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1338 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1342 case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1344 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL );
1348 case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1350 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL );
1354 case Toolkit::DevelButton::Property::UNSELECTED_VISUAL:
1355 case Toolkit::DevelButton::Property::SELECTED_VISUAL:
1356 case Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL:
1357 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL:
1358 case Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL:
1359 case Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL:
1360 case Toolkit::DevelButton::Property::DISABLED_SELECTED_BACKGROUND_VISUAL:
1361 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL:
1362 case Toolkit::Button::Property::LABEL:
1364 Property::Map visualProperty;
1365 if ( GetImplementation( button ).GetPropertyMapForVisual( propertyIndex, visualProperty ) )
1367 value = visualProperty;
1372 case Toolkit::Button::Property::UNSELECTED_COLOR:
1374 value = GetImplementation( button ).GetUnselectedColor();
1378 case Toolkit::Button::Property::SELECTED_COLOR:
1380 value = GetImplementation( button ).GetSelectedColor();
1384 case Toolkit::Button::Property::LABEL_TEXT:
1386 value = GetImplementation( button ).GetLabelText();
1390 case Toolkit::DevelButton::Property::LABEL_RELATIVE_ALIGNMENT:
1392 const char* alignment = Scripting::GetEnumerationName< Button::Align >( GetImplementation( button ).GetLabelAlignment(),
1393 ALIGNMENT_STRING_TABLE,
1394 ALIGNMENT_STRING_TABLE_COUNT );
1397 value = std::string( alignment );
1403 case Toolkit::DevelButton::Property::LABEL_PADDING:
1405 Padding padding = GetImplementation( button ).GetLabelPadding();
1406 value = Vector4( padding.x, padding.y, padding.top, padding.bottom);
1410 case Toolkit::DevelButton::Property::VISUAL_PADDING:
1412 Padding padding = GetImplementation( button ).GetForegroundPadding();
1413 value = Vector4( padding.x, padding.y, padding.top, padding.bottom);
1421 void Button::SetLabelPadding( const Padding& padding)
1423 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetLabelPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top );
1424 mLabelPadding = Padding( padding.left, padding.right, padding.bottom, padding.top );
1428 Padding Button::GetLabelPadding()
1430 return mLabelPadding;
1433 void Button::SetForegroundPadding( const Padding& padding)
1435 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetForegroundPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top );
1436 mForegroundPadding = Padding( padding.left, padding.right, padding.bottom, padding.top );
1440 Padding Button::GetForegroundPadding()
1442 return mForegroundPadding;
1445 ////////////////////////////////////////////////////////////////////////
1446 // Legacy functions from Tizen 2.4 and 3.0
1448 // Legacy code needed whilst Color can be set by direct Property setting ( deprecated ) instead of setting a Visual
1449 void Button::SetColor( const Vector4& color, Property::Index visualIndex )
1451 if ( visualIndex == Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL )
1453 mSelectedColor = color;
1457 mUnselectedColor = color;
1461 map[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::COLOR;
1462 map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color;
1464 CreateVisualsForComponent( visualIndex, map, DepthIndex::BACKGROUND );
1467 const Vector4 Button::GetUnselectedColor() const
1469 return mUnselectedColor;
1472 const Vector4 Button::GetSelectedColor() const
1474 return mSelectedColor;
1477 void Button::SetAnimationTime( float animationTime )
1479 // Used by deprecated API
1480 mAnimationTime = animationTime;
1483 float Button::GetAnimationTime() const
1485 // Used by deprecated API
1486 return mAnimationTime;
1489 void Button::SetLabel( Actor label )
1493 Property::Value value ="";
1494 value = label.GetProperty(Toolkit::TextLabel::Property::TEXT);
1496 SetLabelText( value.Get<std::string>() );
1500 void Button::SetUnselectedImage( const std::string& filename )
1502 SetBackgroundImage( filename );
1505 void Button::SetBackgroundImage( const std::string& filename )
1507 if( !filename.empty() )
1509 CreateVisualsForComponent( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1513 DevelControl::UnregisterVisual( *this, Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1517 void Button::SetSelectedImage( const std::string& filename )
1519 SetSelectedBackgroundImage( filename );
1522 void Button::SetSelectedBackgroundImage( const std::string& filename )
1524 if( !filename.empty() )
1526 CreateVisualsForComponent( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1530 DevelControl::UnregisterVisual( *this, Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1534 void Button::SetDisabledBackgroundImage( const std::string& filename )
1536 if( !filename.empty() )
1538 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1542 void Button::SetDisabledImage( const std::string& filename )
1544 if( !filename.empty() )
1546 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL, filename, DepthIndex::CONTENT );
1550 void Button::SetDisabledSelectedImage( const std::string& filename )
1552 if( !filename.empty() )
1554 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL, filename, DepthIndex::CONTENT );
1558 // Used by Deprecated Properties which don't use the Visual Property maps for setting and getting
1559 std::string Button::GetUrlForImageVisual( const Property::Index index ) const
1561 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, index );
1566 Dali::Property::Map retreivedMap;
1567 visual.CreatePropertyMap( retreivedMap );
1568 Property::Value* value = retreivedMap.Find( Toolkit::ImageVisual::Property::URL, Property::STRING );
1571 result = value->Get<std::string>();
1578 // Below functions DEPRECATED_1_0.50 - Return empty Actors
1582 std::string GetUrlFromImage( Image& image )
1584 ResourceImage resourceImage = ResourceImage::DownCast( image );
1586 std::string imageUrl;
1588 if ( resourceImage )
1590 imageUrl = resourceImage.GetUrl();
1598 void Button::SetButtonImage( Image image )
1600 DALI_LOG_WARNING("Button::SetButtonImage @DEPRECATED_1_0.50\n");
1601 SetUnselectedImage( GetUrlFromImage( image ) );
1602 mSetButtonImage = image;
1605 void Button::SetSelectedImage( Image image )
1607 DALI_LOG_WARNING("Button::SetSelectedImage @DEPRECATED_1_0.50\n");
1608 SetSelectedImage( GetUrlFromImage( image ) );
1609 mSetSelectedImage = image;
1612 Actor Button::GetButtonImage() const
1614 // When deprecated ImageView API removed then this button API can be removed too.
1615 DALI_LOG_WARNING("Button::GetButtonImage @DEPRECATED_1_0.50\n");
1619 if ( mSetButtonImage )
1621 imageView = Toolkit::ImageView::New( mSetButtonImage );
1625 ResourceImage image = ResourceImage::New( GetUrlForImageVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL ) );
1626 imageView = Toolkit::ImageView::New( image );
1632 Actor Button::GetSelectedImage() const
1634 // When deprecated ImageView API removed then this button API can be removed too.
1635 DALI_LOG_WARNING("Button::GetSelectedImage @DEPRECATED_1_0.50\n");
1639 if ( mSetSelectedImage )
1641 imageView = Toolkit::ImageView::New( mSetSelectedImage );
1645 ResourceImage image = ResourceImage::New( GetUrlForImageVisual( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL ) );
1646 imageView = Toolkit::ImageView::New( image );
1651 } // namespace Internal
1653 } // namespace Toolkit