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/devel-api/align-enums.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/devel-api/visuals/text-visual-properties.h>
45 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.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 GET_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::PerformFunctionOnVisualsInState( void(Button::*functionPtr)( Property::Index visualIndex), State state )
305 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::PerformFunctionOnVisualsInState BACKROUND visual(%d) for state (%d)\n",
306 GET_VISUAL_INDEX_FOR_STATE[state][BACKGROUND], state );
307 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::PerformFunctionOnVisualsInState FOREGROUND visuals(%d) for state (%d)\n",
308 GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND], state );
310 (this->*functionPtr)( GET_VISUAL_INDEX_FOR_STATE[state][BACKGROUND] );
311 (this->*functionPtr)( GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND] );
316 void Button::ChangeState( State requestedState )
318 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ChangeState ReuestedState(%d)\n", requestedState );
320 // Validate State before changing
321 if ( !ValidateState( requestedState ))
323 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ChangeState ReuestedState(%d) not validated\n", requestedState );
327 // If not on stage the button could have still been set to selected so update state
328 mPreviousButtonState = mButtonState; // Store previous state for visual removal (used when animations ended)
329 mButtonState = requestedState; // Update current state
331 if ( Self().OnStage() )
333 OnStateChange( mButtonState ); // Notify derived buttons
334 PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState );
335 // If animation supported then visual removal should be performed after any transition animation has completed.
336 // If Required Visual is not loaded before current visual is removed then a flickering will be evident.
337 PerformFunctionOnVisualsInState( &Button::OnButtonVisualRemoval, mPreviousButtonState ); // Derived button can override OnButtonVisualRemoval
340 Toolkit::Button handle( GetOwner() );
342 mStateChangedSignal.Emit( handle );
345 bool Button::IsSelected() const
347 bool selected = ( mButtonState == SELECTED_STATE ) || ( mButtonState == DISABLED_SELECTED_STATE );
348 return mTogglableButton && selected;
351 void Button::SetLabelText( const std::string& label )
353 Self().SetProperty( Toolkit::Button::Property::LABEL, label );
356 std::string Button::GetLabelText() const
358 Property::Value value = Self().GetProperty( Toolkit::Button::Property::LABEL );
360 Property::Map *labelProperty = value.GetMap();
362 std::string textLabel;
366 Property::Value* value = labelProperty->Find( Toolkit::TextVisual::Property::TEXT );
369 value->Get( textLabel );
376 void Button::MergeWithExistingLabelProperties( const Property::Map& inMap, Property::Map& outMap )
378 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties with %d properties\n", inMap.Count() );
381 * Properties for the Label visual could be from a style sheet but after being set the "TEXT" property could be set.
382 * Hence would need to create the Text Visual with the complete merged set of properties.
384 * 1) Find Label Visual
385 * 2) Retrieve current properties ( settings )
386 * 3) Merge with new properties ( settings )
387 * 4) Return new merged map
389 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, Toolkit::Button::Property::LABEL );
392 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties Visual already exists, retrieving existing map\n");
393 visual.CreatePropertyMap( outMap );
394 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties retrieved %d properties\n", outMap.Count() );
397 outMap.Merge( inMap );
399 // Store if a text string has been supplied.
401 mTextStringSetFlag = MapContainsTextString( outMap );
403 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties now has %d properties\n", outMap.Count() );
406 void Button::SetLabelAlignment( Button::Align labelAlignment)
408 mTextLabelAlignment = labelAlignment;
412 Button::Align Button::GetLabelAlignment()
414 return mTextLabelAlignment;
418 * Create Visual for given index from a property map or url.
419 * 1) Check if value passed in is a url and create visual
420 * 2) Create visual from map if step (1) is false
421 * 3) Register visual with control with false for enable flag. Button will later enable visual when needed ( Button::SelectRequiredVisual )
422 * 4) Unregister visual if empty map was provided. This is the method to remove a visual
425 void Button::CreateVisualsForComponent( Property::Index index, const Property::Value& value, const float visualDepth )
427 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent index(%d)\n", index );
428 Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
429 Toolkit::Visual::Base buttonVisual;
431 std::string imageUrl;
432 if( value.Get( imageUrl ) )
434 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent Using image URL(%d)\n", index );
435 if ( !imageUrl.empty() )
437 DALI_ASSERT_DEBUG( index != Toolkit::Button::Property::LABEL && "Creating a Image Visual instead of Text Visual " );
438 buttonVisual = visualFactory.CreateVisual( imageUrl, ImageDimensions() );
443 // if its not a string then get a Property::Map from the property if possible.
444 Property::Map *map = value.GetMap();
445 if( map && !map->Empty() ) // Empty map results in current visual removal.
447 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent Using Map(%d)\n", index );
448 buttonVisual = visualFactory.CreateVisual( *map );
454 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent RegisterVisual index(%d) enabled(%s)\n",
455 index, DevelControl::IsVisualEnabled( *this, index )?"true":"false" );
456 buttonVisual.SetDepthIndex( visualDepth );
457 DevelControl::RegisterVisual( *this, index, buttonVisual, DevelControl::IsVisualEnabled( *this, index ) );
461 DevelControl::UnregisterVisual( *this, index );
462 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "CreateVisualsForComponent Visual not created or empty map (clearing visual).(%d)\n", index);
464 PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState );
467 bool Button::GetPropertyMapForVisual( Property::Index visualIndex, Property::Map& retreivedMap ) const
469 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetPropertyMapForVisual visual(%d)\n", visualIndex);
470 bool success = false;
471 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, visualIndex );
474 visual.CreatePropertyMap( retreivedMap );
477 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetPropertyMapForVisual %s\n", success?"Success":"Failure");
481 bool Button::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
485 Dali::BaseHandle handle( object );
487 Toolkit::Button button = Toolkit::Button::DownCast( handle );
489 DALI_ASSERT_DEBUG( button );
491 if( 0 == strcmp( actionName.c_str(), ACTION_BUTTON_CLICK ) )
493 ret = GetImplementation( button ).DoClickAction( attributes );
499 bool Button::DoClickAction( const Property::Map& attributes )
501 // Prevents the button signals from doing a recursive loop by sending an action
502 // and re-emitting the signals.
503 if( !mClickActionPerforming )
505 mClickActionPerforming = true;
507 if ( !mTogglableButton )
509 mButtonPressedState = DEPRESSED;
512 mClickActionPerforming = false;
520 void Button::ButtonDown()
522 if( mTogglableButton )
524 if ( mButtonState != SELECTED_STATE )
527 mButtonPressedState = TOGGLE_DEPRESSED;
531 mButtonPressedState = DEPRESSED;
537 mButtonPressedState = DEPRESSED;
540 SetUpTimer( mInitialAutoRepeatingDelay );
544 // The pressed signal should be emitted regardless of toggle mode.
545 Toolkit::Button handle( GetOwner() );
546 mPressedSignal.Emit( handle );
549 void Button::ButtonUp()
551 bool emitSignalsForPressAndReleaseAction = false;
553 if( DEPRESSED == mButtonPressedState )
555 if( mTogglableButton ) // Button up will change state
557 emitSignalsForPressAndReleaseAction = OnToggleReleased(); // Derived toggle buttons can override this to provide custom behaviour
561 Released(); // Button up will result in unselected state
564 mAutoRepeatingTimer.Reset();
566 emitSignalsForPressAndReleaseAction = true;
569 else if ( TOGGLE_DEPRESSED == mButtonPressedState )
571 emitSignalsForPressAndReleaseAction = true; // toggle released after being pressed, a click
574 if ( emitSignalsForPressAndReleaseAction )
576 // The clicked and released signals should be emitted regardless of toggle mode.
577 Toolkit::Button handle( GetOwner() );
578 mReleasedSignal.Emit( handle );
579 mClickedSignal.Emit( handle );
583 bool Button::OnToggleReleased()
585 SetSelected( !IsSelected() );
586 mButtonPressedState = UNPRESSED;
591 void Button::OnTouchPointLeave()
593 if( DEPRESSED == mButtonPressedState )
595 if( !mTogglableButton )
601 mAutoRepeatingTimer.Reset();
605 mButtonPressedState = UNPRESSED;
607 // The released signal should be emitted regardless of toggle mode.
608 Toolkit::Button handle( GetOwner() );
609 mReleasedSignal.Emit( handle );
613 void Button::OnTouchPointInterrupted()
618 Toolkit::Button::ButtonSignalType& Button::PressedSignal()
620 return mPressedSignal;
623 Toolkit::Button::ButtonSignalType& Button::ReleasedSignal()
625 return mReleasedSignal;
628 Toolkit::Button::ButtonSignalType& Button::ClickedSignal()
630 return mClickedSignal;
633 Toolkit::Button::ButtonSignalType& Button::StateChangedSignal()
635 return mStateChangedSignal;
638 bool Button::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
640 Dali::BaseHandle handle( object );
642 bool connected( true );
643 Toolkit::Button button = Toolkit::Button::DownCast( handle );
645 if( 0 == strcmp( signalName.c_str(), SIGNAL_PRESSED ) )
647 button.PressedSignal().Connect( tracker, functor );
649 else if( 0 == strcmp( signalName.c_str(), SIGNAL_RELEASED ) )
651 button.ReleasedSignal().Connect( tracker, functor );
653 else if( 0 == strcmp( signalName.c_str(), SIGNAL_CLICKED ) )
655 button.ClickedSignal().Connect( tracker, functor );
657 else if( 0 == strcmp( signalName.c_str(), SIGNAL_STATE_CHANGED ) )
659 button.StateChangedSignal().Connect( tracker, functor );
663 // signalName does not match any signal
670 void Button::OnInitialize()
672 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnInitialize\n" );
676 mTapDetector = TapGestureDetector::New();
677 mTapDetector.Attach( self );
678 mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
680 self.SetKeyboardFocusable( true );
682 self.TouchSignal().Connect( this, &Button::OnTouch );
685 bool Button::OnAccessibilityActivated()
687 return OnKeyboardEnter();
690 bool Button::OnTouch( Actor actor, const TouchData& touch )
693 // Only events are processed when the button is not disabled and the touch event has only
696 if( !IsDisabled() && ( 1 == touch.GetPointCount() ) )
698 switch( touch.GetState( 0 ) )
700 case PointState::DOWN:
710 case PointState::INTERRUPTED:
712 OnTouchPointInterrupted();
715 case PointState::LEAVE:
720 case PointState::MOTION:
721 case PointState::STATIONARY: // FALLTHROUGH
728 else if( 1 < touch.GetPointCount() )
730 OnTouchPointLeave(); // Notification for derived classes.
732 // Sets the button state to the default
733 mButtonPressedState = UNPRESSED;
739 bool Button::OnKeyboardEnter()
741 // When the enter key is pressed, or button is activated, the click action is performed.
742 Property::Map attributes;
743 bool ret = DoClickAction( attributes );
748 void Button::OnStageDisconnection()
750 if( DEPRESSED == mButtonPressedState )
752 if( !mTogglableButton )
758 mAutoRepeatingTimer.Reset();
763 mButtonPressedState = UNPRESSED;
765 Control::OnStageDisconnection(); // Visuals will be set off stage
768 void Button::OnStageConnection( int depth )
770 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnStageConnection ptr(%p) \n", this );
771 PerformFunctionOnVisualsInState( &Button::OnButtonVisualRemoval, mPreviousButtonState );
772 SelectRequiredVisual( Toolkit::Button::Property::LABEL );
773 PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState );
774 Control::OnStageConnection( depth ); // Enabled visuals will be put on stage
777 Vector3 Button::GetNaturalSize()
779 Vector3 size = Vector3::ZERO;
781 bool horizontalAlignment = mTextLabelAlignment == BEGIN || mTextLabelAlignment == END; // label and visual side by side
783 // Get natural size of foreground ( largest of the possible visuals )
784 Size largestProvidedVisual;
785 Size labelSize = Size::ZERO;
787 bool foreGroundVisualUsed = false;
789 for ( int state = Button::UNSELECTED_STATE; state < Button::STATE_COUNT; state++ )
791 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND] );
795 visual.GetNaturalSize( visualSize );
796 largestProvidedVisual.width = std::max(largestProvidedVisual.width, visualSize.width );
797 largestProvidedVisual.height = std::max(largestProvidedVisual.height, visualSize.height );
798 foreGroundVisualUsed = true;
802 if ( !foreGroundVisualUsed ) // If foreground visual not supplied then use the background visual to calculate Natural size
804 for ( int state = Button::UNSELECTED_STATE; state < Button::STATE_COUNT; state++ )
806 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, GET_VISUAL_INDEX_FOR_STATE[state][BACKGROUND] );
810 visual.GetNaturalSize( visualSize );
811 largestProvidedVisual.width = std::max(largestProvidedVisual.width, visualSize.width );
812 largestProvidedVisual.height = std::max(largestProvidedVisual.height, visualSize.height );
817 // Get horizontal padding total
818 if ( largestProvidedVisual.width > 0 ) // if visual exists
820 size.width += largestProvidedVisual.width + mForegroundPadding.left + mForegroundPadding.right;
822 // Get vertical padding total
823 if ( largestProvidedVisual.height > 0 )
825 size.height += largestProvidedVisual.height + mForegroundPadding.top + mForegroundPadding.bottom;
828 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize visual Size(%f,%f)\n",
829 largestProvidedVisual.width, largestProvidedVisual.height );
831 // Get natural size of label if text has been set
832 if ( mTextStringSetFlag )
834 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, Toolkit::Button::Property::LABEL );
838 visual.GetNaturalSize( labelSize );
840 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize labelSize(%f,%f) padding(%f,%f)\n",
841 labelSize.width, labelSize.height, mLabelPadding.left + mLabelPadding.right, mLabelPadding.top + mLabelPadding.bottom);
843 labelSize.width += mLabelPadding.left + mLabelPadding.right;
844 labelSize.height += mLabelPadding.top + mLabelPadding.bottom;
846 // Add label size to height or width depending on alignment position
847 if ( horizontalAlignment )
849 size.width += labelSize.width;
850 size.height = std::max(size.height, labelSize.height );
854 size.height += labelSize.height;
855 size.width = std::max(size.width, labelSize.width );
860 if( size.width < 1 && size.height < 1 )
862 // if no image or label then use Control's natural size
863 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize Using control natural size\n");
864 size = Control::GetNaturalSize();
867 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "Button GetNaturalSize (%f,%f)\n", size.width, size.height );
872 void Button::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
874 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnSetResizePolicy\n");
879 * Visuals are sized and positioned in this function.
880 * Whilst the control has it's size negotiated it has to size it's visuals explicitly here.
883 void Button::OnRelayout( const Vector2& size, RelayoutContainer& container )
885 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout targetSize(%f,%f) ptr(%p) state[%d]\n", size.width, size.height, this, mButtonState );
887 Toolkit::Visual::Base currentVisual = DevelControl::GetVisual( *this, GET_VISUAL_INDEX_FOR_STATE[mButtonState][FOREGROUND] );
889 Toolkit::Visual::Base currentBackGroundVisual = DevelControl::GetVisual( *this, GET_VISUAL_INDEX_FOR_STATE[mButtonState][BACKGROUND] );
891 // Sizes and padding set to zero, if not present then values will no effect calculations.
892 Vector2 visualPosition = Vector2::ZERO;
893 Vector2 labelPosition = Vector2::ZERO;
894 Size visualSize = Size::ZERO;
895 Padding foregroundVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f );
896 Padding labelVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f );
898 if ( mTextStringSetFlag )
900 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Label padding setting padding:%f,%f,%f,%f\n", mLabelPadding.y, mLabelPadding.x, mLabelPadding.width,mLabelPadding.height );
901 labelVisualPadding = mLabelPadding;
906 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Foreground Visual setting padding:%f,%f,%f,%f\n", mForegroundPadding.y, mForegroundPadding.x, mForegroundPadding.width,mForegroundPadding.height );
907 currentVisual.GetNaturalSize( visualSize );
908 foregroundVisualPadding = mForegroundPadding;
911 Toolkit::Align::Type visualAnchorPoint = Toolkit::Align::TOP_BEGIN;
913 Vector2 visualAndPaddingSize = Vector2( ( foregroundVisualPadding.x + visualSize.width + foregroundVisualPadding.y ),
914 ( foregroundVisualPadding.width + visualSize.height + foregroundVisualPadding.height ));
916 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout visualAndPaddingSize(%f,%f)\n", visualAndPaddingSize.width, visualAndPaddingSize.height);
918 // Text Visual should take all space available after foreground visual size and all padding is considered.
919 // Remaining Space priority, Foreground padding, foreground visual, Text padding then Text visual.
920 Size remainingSpaceForText = Size::ZERO;
922 switch ( mTextLabelAlignment )
926 visualAnchorPoint = Toolkit::Align::TOP_END;
927 visualPosition.x = foregroundVisualPadding.right;
928 visualPosition.y = foregroundVisualPadding.top;
930 labelPosition.x = labelVisualPadding.x;
931 labelPosition.y = labelVisualPadding.top;
933 remainingSpaceForText.width = size.width - visualAndPaddingSize.width - labelVisualPadding.x - labelVisualPadding.y;
934 remainingSpaceForText.height = size.height - labelVisualPadding.top - labelVisualPadding.bottom;
939 visualAnchorPoint = Toolkit::Align::TOP_BEGIN;
940 visualPosition.x = foregroundVisualPadding.left;
941 visualPosition.y = foregroundVisualPadding.top;
943 labelPosition.x = visualAndPaddingSize.width + labelVisualPadding.x;
944 labelPosition.y = labelVisualPadding.top;
946 remainingSpaceForText.width = size.width - visualAndPaddingSize.width - labelVisualPadding.x - labelVisualPadding.y;
947 remainingSpaceForText.height = size.height - labelVisualPadding.top - labelVisualPadding.bottom;
952 visualAnchorPoint = Toolkit::Align::BOTTOM_END;
953 visualPosition.x = foregroundVisualPadding.left;
954 visualPosition.y = foregroundVisualPadding.bottom;
956 labelPosition.x = labelVisualPadding.left;
957 labelPosition.y = labelVisualPadding.top;
959 remainingSpaceForText.width = size.width - labelVisualPadding.x - labelVisualPadding.y;
960 remainingSpaceForText.height = size.height - visualAndPaddingSize.height - labelVisualPadding.top - labelVisualPadding.bottom;
966 visualAnchorPoint = Toolkit::Align::TOP_END;
967 visualPosition.x = foregroundVisualPadding.left;
968 visualPosition.y = foregroundVisualPadding.top;
970 labelPosition.x = labelVisualPadding.left;
971 labelPosition.y = visualAndPaddingSize.height + labelVisualPadding.top;
973 remainingSpaceForText.width = size.width - labelVisualPadding.x - labelVisualPadding.y;
974 remainingSpaceForText.height = size.height - visualAndPaddingSize.height - labelVisualPadding.top - labelVisualPadding.bottom;
980 if ( currentBackGroundVisual )
982 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual background size to(%f,%f)\n", size.width, size.height);
984 Property::Map visualTransform;
986 visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, size )
987 .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) );
989 currentBackGroundVisual.SetTransformAndSize( visualTransform, size );
994 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual size to(%f,%f)\n", visualSize.width, visualSize.height);
996 Property::Map visualTransform;
998 visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, visualSize )
999 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET, visualPosition )
1000 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
1001 .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
1002 .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
1003 .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, visualAnchorPoint );
1005 currentVisual.SetTransformAndSize( visualTransform, size );
1008 if ( mTextStringSetFlag )
1010 Toolkit::Visual::Base textVisual = DevelControl::GetVisual( *this, Toolkit::Button::Property::LABEL ); // No need to search for Label visual if no text set.
1014 if ( !currentVisual )
1016 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Only Text\n");
1017 labelPosition.x = labelVisualPadding.left;
1018 labelPosition.y = labelVisualPadding.height;
1021 Vector2 preSize = Vector2( static_cast< int >( remainingSpaceForText.x ), static_cast< int >( remainingSpaceForText.y ));
1023 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout text Size(%f,%f) text Position(%f,%f) \n", remainingSpaceForText.width, remainingSpaceForText.height, labelPosition.x, labelPosition.y);
1025 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout text Size -- (%f,%f) text Position(%f,%f) \n", preSize.width, preSize.height, labelPosition.x, labelPosition.y);
1028 Property::Map textVisualTransform;
1029 textVisualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, preSize )
1030 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET, labelPosition )
1031 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
1032 .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
1033 .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
1034 .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, visualAnchorPoint );
1036 textVisual.SetTransformAndSize( textVisualTransform, size );
1040 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout selected (%s) \n", IsSelected()?"yes":"no" );
1042 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout << \n");
1045 void Button::OnTap(Actor actor, const TapGesture& tap)
1047 // Prevents Parent getting a tap event
1050 void Button::SetUpTimer( float delay )
1052 mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
1053 mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot );
1054 mAutoRepeatingTimer.Start();
1057 bool Button::AutoRepeatingSlot()
1059 bool consumed = false;
1062 // Restart the autorepeat timer.
1063 SetUpTimer( mNextAutoRepeatingDelay );
1067 Toolkit::Button handle( GetOwner() );
1070 consumed = mReleasedSignal.Emit( handle );
1071 consumed = mClickedSignal.Emit( handle );
1072 consumed |= mPressedSignal.Emit( handle );
1078 void Button::Pressed()
1080 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Pressed\n" );
1082 if( mButtonState == UNSELECTED_STATE )
1084 ChangeState( SELECTED_STATE );
1085 OnPressed(); // Notifies the derived class the button has been pressed.
1089 void Button::Released()
1091 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Released\n" );
1093 if( mButtonState == SELECTED_STATE && !mTogglableButton )
1095 ChangeState( UNSELECTED_STATE );
1096 OnReleased(); // // Notifies the derived class the button has been released.
1098 mButtonPressedState = UNPRESSED;
1101 void Button::SelectRequiredVisual( Property::Index visualIndex )
1103 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SelectRequiredVisual index(%d) state(%d)\n", visualIndex, mButtonState );
1105 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::DevelVisual::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 );
1257 GetImplementation( button ).RelayoutRequest();
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 );
1270 GetImplementation( button ).RelayoutRequest();
1274 case Toolkit::DevelButton::Property::LABEL_PADDING:
1276 Vector4 padding ( value.Get< Vector4 >() );
1277 GetImplementation( button ).SetLabelPadding( Padding( padding.x, padding.y, padding.z, padding.w ) );
1281 case Toolkit::DevelButton::Property::VISUAL_PADDING:
1283 Vector4 padding ( value.Get< Vector4 >() );
1284 GetImplementation( button ).SetForegroundPadding( Padding( padding.x, padding.y, padding.z, padding.w ) );
1285 GetImplementation( button ).RelayoutRequest();
1292 Property::Value Button::GetProperty( BaseObject* object, Property::Index propertyIndex )
1294 Property::Value value;
1296 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1300 switch ( propertyIndex )
1302 case Toolkit::Button::Property::DISABLED:
1304 value = GetImplementation( button ).IsDisabled();
1308 case Toolkit::Button::Property::AUTO_REPEATING:
1310 value = GetImplementation( button ).mAutoRepeating;
1314 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1316 value = GetImplementation( button ).mInitialAutoRepeatingDelay;
1320 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1322 value = GetImplementation( button ).mNextAutoRepeatingDelay;
1326 case Toolkit::Button::Property::TOGGLABLE:
1328 value = GetImplementation( button ).mTogglableButton;
1332 case Toolkit::Button::Property::SELECTED:
1334 value = GetImplementation( button ).IsSelected();
1338 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1340 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1344 case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1346 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL );
1350 case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1352 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL );
1356 case Toolkit::DevelButton::Property::UNSELECTED_VISUAL:
1357 case Toolkit::DevelButton::Property::SELECTED_VISUAL:
1358 case Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL:
1359 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL:
1360 case Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL:
1361 case Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL:
1362 case Toolkit::DevelButton::Property::DISABLED_SELECTED_BACKGROUND_VISUAL:
1363 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL:
1364 case Toolkit::Button::Property::LABEL:
1366 Property::Map visualProperty;
1367 if ( GetImplementation( button ).GetPropertyMapForVisual( propertyIndex, visualProperty ) )
1369 value = visualProperty;
1374 case Toolkit::Button::Property::UNSELECTED_COLOR:
1376 value = GetImplementation( button ).GetUnselectedColor();
1380 case Toolkit::Button::Property::SELECTED_COLOR:
1382 value = GetImplementation( button ).GetSelectedColor();
1386 case Toolkit::Button::Property::LABEL_TEXT:
1388 value = GetImplementation( button ).GetLabelText();
1392 case Toolkit::DevelButton::Property::LABEL_RELATIVE_ALIGNMENT:
1394 const char* alignment = Scripting::GetEnumerationName< Button::Align >( GetImplementation( button ).GetLabelAlignment(),
1395 ALIGNMENT_STRING_TABLE,
1396 ALIGNMENT_STRING_TABLE_COUNT );
1399 value = std::string( alignment );
1405 case Toolkit::DevelButton::Property::LABEL_PADDING:
1407 Padding padding = GetImplementation( button ).GetLabelPadding();
1408 value = Vector4( padding.x, padding.y, padding.top, padding.bottom);
1412 case Toolkit::DevelButton::Property::VISUAL_PADDING:
1414 Padding padding = GetImplementation( button ).GetForegroundPadding();
1415 value = Vector4( padding.x, padding.y, padding.top, padding.bottom);
1423 void Button::SetLabelPadding( const Padding& padding)
1425 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetLabelPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top );
1426 mLabelPadding = Padding( padding.left, padding.right, padding.bottom, padding.top );
1430 Padding Button::GetLabelPadding()
1432 return mLabelPadding;
1435 void Button::SetForegroundPadding( const Padding& padding)
1437 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetForegroundPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top );
1438 mForegroundPadding = Padding( padding.left, padding.right, padding.bottom, padding.top );
1442 Padding Button::GetForegroundPadding()
1444 return mForegroundPadding;
1447 ////////////////////////////////////////////////////////////////////////
1448 // Legacy functions from Tizen 2.4 and 3.0
1450 // Legacy code needed whilst Color can be set by direct Property setting ( deprecated ) instead of setting a Visual
1451 void Button::SetColor( const Vector4& color, Property::Index visualIndex )
1453 if ( visualIndex == Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL )
1455 mSelectedColor = color;
1459 mUnselectedColor = color;
1463 map[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::COLOR;
1464 map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color;
1466 CreateVisualsForComponent( visualIndex, map, DepthIndex::BACKGROUND );
1469 const Vector4 Button::GetUnselectedColor() const
1471 return mUnselectedColor;
1474 const Vector4 Button::GetSelectedColor() const
1476 return mSelectedColor;
1479 void Button::SetAnimationTime( float animationTime )
1481 // Used by deprecated API
1482 mAnimationTime = animationTime;
1485 float Button::GetAnimationTime() const
1487 // Used by deprecated API
1488 return mAnimationTime;
1491 void Button::SetLabel( Actor label )
1495 Property::Value value ="";
1496 value = label.GetProperty(Toolkit::TextLabel::Property::TEXT);
1498 SetLabelText( value.Get<std::string>() );
1502 void Button::SetUnselectedImage( const std::string& filename )
1504 SetBackgroundImage( filename );
1507 void Button::SetBackgroundImage( const std::string& filename )
1509 if( !filename.empty() )
1511 CreateVisualsForComponent( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1515 DevelControl::UnregisterVisual( *this, Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1519 void Button::SetSelectedImage( const std::string& filename )
1521 SetSelectedBackgroundImage( filename );
1524 void Button::SetSelectedBackgroundImage( const std::string& filename )
1526 if( !filename.empty() )
1528 CreateVisualsForComponent( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1532 DevelControl::UnregisterVisual( *this, Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1536 void Button::SetDisabledBackgroundImage( const std::string& filename )
1538 if( !filename.empty() )
1540 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1544 void Button::SetDisabledImage( const std::string& filename )
1546 if( !filename.empty() )
1548 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL, filename, DepthIndex::CONTENT );
1552 void Button::SetDisabledSelectedImage( const std::string& filename )
1554 if( !filename.empty() )
1556 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL, filename, DepthIndex::CONTENT );
1560 // Used by Deprecated Properties which don't use the Visual Property maps for setting and getting
1561 std::string Button::GetUrlForImageVisual( const Property::Index index ) const
1563 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, index );
1568 Dali::Property::Map retreivedMap;
1569 visual.CreatePropertyMap( retreivedMap );
1570 Property::Value* value = retreivedMap.Find( Toolkit::ImageVisual::Property::URL, Property::STRING );
1573 result = value->Get<std::string>();
1580 // Below functions DEPRECATED_1_0.50 - Return empty Actors
1584 std::string GetUrlFromImage( Image& image )
1586 ResourceImage resourceImage = ResourceImage::DownCast( image );
1588 std::string imageUrl;
1590 if ( resourceImage )
1592 imageUrl = resourceImage.GetUrl();
1600 void Button::SetButtonImage( Image image )
1602 DALI_LOG_WARNING("Button::SetButtonImage @DEPRECATED_1_0.50\n");
1603 SetUnselectedImage( GetUrlFromImage( image ) );
1604 mSetButtonImage = image;
1607 void Button::SetSelectedImage( Image image )
1609 DALI_LOG_WARNING("Button::SetSelectedImage @DEPRECATED_1_0.50\n");
1610 SetSelectedImage( GetUrlFromImage( image ) );
1611 mSetSelectedImage = image;
1614 Actor Button::GetButtonImage() const
1616 // When deprecated ImageView API removed then this button API can be removed too.
1617 DALI_LOG_WARNING("Button::GetButtonImage @DEPRECATED_1_0.50\n");
1621 if ( mSetButtonImage )
1623 imageView = Toolkit::ImageView::New( mSetButtonImage );
1627 ResourceImage image = ResourceImage::New( GetUrlForImageVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL ) );
1628 imageView = Toolkit::ImageView::New( image );
1634 Actor Button::GetSelectedImage() const
1636 // When deprecated ImageView API removed then this button API can be removed too.
1637 DALI_LOG_WARNING("Button::GetSelectedImage @DEPRECATED_1_0.50\n");
1641 if ( mSetSelectedImage )
1643 imageView = Toolkit::ImageView::New( mSetSelectedImage );
1647 ResourceImage image = ResourceImage::New( GetUrlForImageVisual( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL ) );
1648 imageView = Toolkit::ImageView::New( image );
1653 } // namespace Internal
1655 } // namespace Toolkit