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/buttons/button-devel.h>
41 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
42 #include <dali-toolkit/internal/visuals/text/text-visual.h>
43 #include <dali-toolkit/devel-api/visuals/text-visual-properties.h>
44 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
46 #if defined(DEBUG_ENABLED)
47 Debug::Filter* gLogButtonFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_BUTTON_CONTROL");
64 // empty handle as we cannot create button (but type registered for clicked signal)
68 // Setup properties, signals and actions using the type-registry.
69 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Button, Toolkit::Control, Create )
71 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabled", BOOLEAN, DISABLED )
72 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "autoRepeating", BOOLEAN, AUTO_REPEATING )
73 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "initialAutoRepeatingDelay", FLOAT, INITIAL_AUTO_REPEATING_DELAY )
74 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "nextAutoRepeatingDelay", FLOAT, NEXT_AUTO_REPEATING_DELAY )
75 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "togglable", BOOLEAN, TOGGLABLE )
76 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selected", BOOLEAN, SELECTED )
77 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedStateImage", MAP, UNSELECTED_STATE_IMAGE ) // Deprecated property
78 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedStateImage", MAP, SELECTED_STATE_IMAGE ) // Deprecated property
79 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledStateImage", MAP, DISABLED_STATE_IMAGE ) // Deprecated property
80 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedColor", VECTOR4, UNSELECTED_COLOR ) // Deprecated property
81 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedColor", VECTOR4, SELECTED_COLOR ) // Deprecated property
82 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "label", MAP, LABEL )
83 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "labelText", STRING, LABEL_TEXT ) // Deprecated property
84 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedVisual", MAP, UNSELECTED_VISUAL )
85 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "selectedVisual", MAP, SELECTED_VISUAL )
86 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledSelectedVisual", MAP, DISABLED_SELECTED_VISUAL )
87 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledUnselectedVisual", MAP, DISABLED_UNSELECTED_VISUAL )
88 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedBackgroundVisual", MAP, UNSELECTED_BACKGROUND_VISUAL )
89 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "selectedBackgroundVisual", MAP, SELECTED_BACKGROUND_VISUAL )
90 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledUnselectedBackgroundVisual", MAP, DISABLED_UNSELECTED_BACKGROUND_VISUAL )
91 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledSelectedBackgroundVisual", MAP, DISABLED_SELECTED_BACKGROUND_VISUAL )
92 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "labelRelativeAlignment", STRING, LABEL_RELATIVE_ALIGNMENT )
93 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "labelPadding", VECTOR4, LABEL_PADDING )
94 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "visualPadding", VECTOR4, VISUAL_PADDING )
97 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "pressed", SIGNAL_PRESSED )
98 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "released", SIGNAL_RELEASED )
99 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "clicked", SIGNAL_CLICKED )
100 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "stateChanged", SIGNAL_STATE_CHANGED )
103 DALI_ACTION_REGISTRATION( Toolkit, Button, "buttonClick", ACTION_BUTTON_CLICK )
105 DALI_TYPE_REGISTRATION_END()
107 DALI_ENUM_TO_STRING_TABLE_BEGIN( ALIGNMENT )
108 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, BEGIN )
109 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, END )
110 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, TOP )
111 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, BOTTOM )
112 DALI_ENUM_TO_STRING_TABLE_END( ALIGNMENT )
114 const Scripting::StringEnum ALIGNMENT_STRING_TABLE[] =
116 { "BEGIN", Button::BEGIN },
117 { "END", Button::END },
118 { "TOP", Button::TOP },
119 { "BOTTOM", Button::BOTTOM },
122 const unsigned int ALIGNMENT_STRING_TABLE_COUNT = sizeof( ALIGNMENT_STRING_TABLE ) / sizeof( ALIGNMENT_STRING_TABLE[0] );
124 const Property::Index GET_VISUAL_INDEX_FOR_STATE[][Button::STATE_COUNT] =
126 { Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, Toolkit::DevelButton::Property::UNSELECTED_VISUAL },
127 { Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, Toolkit::DevelButton::Property::SELECTED_VISUAL },
128 { Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL },
129 { Toolkit::DevelButton::Property::DISABLED_SELECTED_BACKGROUND_VISUAL, Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL }
133 * Checks if given map contains a text string
135 bool MapContainsTextString( Property::Map& map )
138 Property::Value* value = map.Find( Toolkit::TextVisual::Property::TEXT );
141 std::string textString;
142 value->Get( textString );
143 if ( !textString.empty() )
151 } // unnamed namespace
154 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
155 mAutoRepeatingTimer(),
156 mTextLabelAlignment( END ),
157 mAutoRepeating( false ),
158 mTogglableButton( false ),
159 mTextStringSetFlag( false ),
160 mInitialAutoRepeatingDelay( 0.0f ),
161 mNextAutoRepeatingDelay( 0.0f ),
162 mAnimationTime( 0.0f ),
163 mButtonPressedState( UNPRESSED ),
164 mButtonState( UNSELECTED_STATE ),
165 mPreviousButtonState( mButtonState ),
166 mClickActionPerforming( false )
174 void Button::SetAutoRepeating( bool autoRepeating )
176 mAutoRepeating = autoRepeating;
178 // An autorepeating button can't be a toggle button.
183 SetSelected( false ); // UnSelect before switching off Toggle feature.
185 mTogglableButton = false;
189 bool Button::IsAutoRepeating() const
191 return mAutoRepeating;
194 void Button::SetInitialAutoRepeatingDelay( float initialAutoRepeatingDelay )
196 DALI_ASSERT_DEBUG( initialAutoRepeatingDelay > 0.f );
197 mInitialAutoRepeatingDelay = initialAutoRepeatingDelay;
200 float Button::GetInitialAutoRepeatingDelay() const
202 return mInitialAutoRepeatingDelay;
205 void Button::SetNextAutoRepeatingDelay( float nextAutoRepeatingDelay )
207 DALI_ASSERT_DEBUG( nextAutoRepeatingDelay > 0.f );
208 mNextAutoRepeatingDelay = nextAutoRepeatingDelay;
211 float Button::GetNextAutoRepeatingDelay() const
213 return mNextAutoRepeatingDelay;
216 void Button::SetTogglableButton( bool togglable )
218 mTogglableButton = togglable;
220 // A toggle button can't be an autorepeating button.
223 mAutoRepeating = false;
227 bool Button::IsTogglableButton() const
229 return mTogglableButton;
232 void Button::SetSelected( bool selected )
234 if( mTogglableButton )
236 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetSelected (%s)\n", (selected?"true":"false") );
238 if ( selected && ( mButtonState != SELECTED_STATE ) )
240 ChangeState( SELECTED_STATE );
242 else if ( !selected && ( mButtonState != UNSELECTED_STATE ) )
244 ChangeState( UNSELECTED_STATE );
249 void Button::SetDisabled( bool disabled )
251 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetDisabled(%s) state(%d)\n", (disabled)?"disabled":"active", mButtonState );
255 if ( mButtonState == SELECTED_STATE )
257 ChangeState( DISABLED_SELECTED_STATE );
259 else if ( mButtonState == UNSELECTED_STATE )
261 ChangeState( DISABLED_UNSELECTED_STATE );
266 if ( mButtonState == DISABLED_SELECTED_STATE )
268 ChangeState( SELECTED_STATE );
270 else if ( mButtonState == DISABLED_UNSELECTED_STATE )
272 ChangeState( UNSELECTED_STATE );
277 bool Button::IsDisabled() const
279 return ( mButtonState == DISABLED_SELECTED_STATE || mButtonState == DISABLED_UNSELECTED_STATE ) ;
282 bool Button::ValidateState( State requestedState )
284 /* Below tables shows allowed state transitions
285 * Match rows in first column to following columns, if true then transition allowed.
286 * eg UNSELECTED_STATE to DISABLED_UNSELECTED_STATE is true so state transition allowed.
288 to| UNSELECTED_STATE | SELECTED_STATE | DISABLED_UNSELECTED_STATE | DISABLED_SELECTED_STATE |*/
290 bool transitionTable[4][4] = { /* UNSELECTED_STATE*/ { false, true, true, false },
291 /* SELECTED_STATE*/ { true, false, false, true },
292 /* DISABLED_UNSELECTED_STATE*/{ true, true, false, false },
293 /* DISABLED_SELECTED_STATE*/ { false, true, false, false }
296 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ValidateState ReuestedState:%d, CurrentState:%d, result:%s\n",
297 requestedState, mButtonState, (transitionTable[mButtonState][requestedState])?"change-accepted":"change-denied");
299 return transitionTable[mButtonState][requestedState];
302 void Button::PerformFunctionOnVisualsInState( void(Button::*functionPtr)( Property::Index visualIndex), State state )
304 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::PerformFunctionOnVisualsInState BACKROUND visual(%d) for state (%d)\n",
305 GET_VISUAL_INDEX_FOR_STATE[state][BACKGROUND], state );
306 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::PerformFunctionOnVisualsInState FOREGROUND visuals(%d) for state (%d)\n",
307 GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND], state );
309 (this->*functionPtr)( GET_VISUAL_INDEX_FOR_STATE[state][BACKGROUND] );
310 (this->*functionPtr)( GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND] );
315 void Button::ChangeState( State requestedState )
317 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ChangeState ReuestedState(%d)\n", requestedState );
319 // Validate State before changing
320 if ( !ValidateState( requestedState ))
322 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ChangeState ReuestedState(%d) not validated\n", requestedState );
326 // If not on stage the button could have still been set to selected so update state
327 mPreviousButtonState = mButtonState; // Store previous state for visual removal (used when animations ended)
328 mButtonState = requestedState; // Update current state
330 if ( Self().OnStage() )
332 OnStateChange( mButtonState ); // Notify derived buttons
333 PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState );
334 // If animation supported then visual removal should be performed after any transition animation has completed.
335 // If Required Visual is not loaded before current visual is removed then a flickering will be evident.
336 PerformFunctionOnVisualsInState( &Button::OnButtonVisualRemoval, mPreviousButtonState ); // Derived button can override OnButtonVisualRemoval
339 Toolkit::Button handle( GetOwner() );
341 mStateChangedSignal.Emit( handle );
344 bool Button::IsSelected() const
346 bool selected = ( mButtonState == SELECTED_STATE ) || ( mButtonState == DISABLED_SELECTED_STATE );
347 return mTogglableButton && selected;
350 void Button::SetLabelText( const std::string& label )
352 Self().SetProperty( Toolkit::Button::Property::LABEL, label );
355 std::string Button::GetLabelText() const
357 Property::Value value = Self().GetProperty( Toolkit::Button::Property::LABEL );
359 Property::Map *labelProperty = value.GetMap();
361 std::string textLabel;
365 Property::Value* value = labelProperty->Find( Toolkit::TextVisual::Property::TEXT );
366 value->Get( textLabel );
372 void Button::MergeWithExistingLabelProperties( const Property::Map& inMap, Property::Map& outMap )
374 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties with %d properties\n", inMap.Count() );
377 * Properties for the Label visual could be from a style sheet but after being set the "TEXT" property could be set.
378 * Hence would need to create the Text Visual with the complete merged set of properties.
380 * 1) Find Label Visual
381 * 2) Retrieve current properties ( settings )
382 * 3) Merge with new properties ( settings )
383 * 4) Return new merged map
385 Toolkit::Visual::Base visual = GetVisual( Toolkit::Button::Property::LABEL );
388 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties Visual already exists, retrieving existing map\n");
389 visual.CreatePropertyMap( outMap );
390 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties retrieved %d properties\n", outMap.Count() );
393 outMap.Merge( inMap );
395 // Store if a text string has been supplied.
397 mTextStringSetFlag = MapContainsTextString( outMap );
399 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties now has %d properties\n", outMap.Count() );
402 void Button::SetLabelAlignment( Button::Align labelAlignment)
404 mTextLabelAlignment = labelAlignment;
408 Button::Align Button::GetLabelAlignment()
410 return mTextLabelAlignment;
414 * Create Visual for given index from a property map or url.
415 * 1) Check if value passed in is a url and create visual
416 * 2) Create visual from map if step (1) is false
417 * 3) Register visual with control with false for enable flag. Button will later enable visual when needed ( Button::SelectRequiredVisual )
418 * 4) Unregister visual if empty map was provided. This is the method to remove a visual
421 void Button::CreateVisualsForComponent( Property::Index index, const Property::Value& value, const float visualDepth )
423 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent index(%d)\n", index );
424 Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
425 Toolkit::Visual::Base buttonVisual;
427 std::string imageUrl;
428 if( value.Get( imageUrl ) )
430 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent Using image URL(%d)\n", index );
431 if ( !imageUrl.empty() )
433 DALI_ASSERT_DEBUG( index != Toolkit::Button::Property::LABEL && "Creating a Image Visual instead of Text Visual " );
434 buttonVisual = visualFactory.CreateVisual( imageUrl, ImageDimensions() );
439 // if its not a string then get a Property::Map from the property if possible.
440 Property::Map *map = value.GetMap();
441 if( map && !map->Empty() ) // Empty map results in current visual removal.
443 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent Using Map(%d)\n", index );
444 buttonVisual = visualFactory.CreateVisual( *map );
450 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent RegisterVisual index(%d) enabled(%s)\n",
451 index, IsVisualEnabled( index )?"true":"false" );
452 buttonVisual.SetDepthIndex( visualDepth );
453 RegisterVisual( index, buttonVisual, IsVisualEnabled( index ) );
457 UnregisterVisual( index );
458 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "CreateVisualsForComponent Visual not created or empty map (clearing visual).(%d)\n", index);
460 PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState );
463 bool Button::GetPropertyMapForVisual( Property::Index visualIndex, Property::Map& retreivedMap ) const
465 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetPropertyMapForVisual visual(%d)\n", visualIndex);
466 bool success = false;
467 Toolkit::Visual::Base visual = GetVisual( visualIndex );
470 visual.CreatePropertyMap( retreivedMap );
473 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetPropertyMapForVisual %s\n", success?"Success":"Failure");
477 bool Button::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
481 Dali::BaseHandle handle( object );
483 Toolkit::Button button = Toolkit::Button::DownCast( handle );
485 DALI_ASSERT_DEBUG( button );
487 if( 0 == strcmp( actionName.c_str(), ACTION_BUTTON_CLICK ) )
489 ret = GetImplementation( button ).DoClickAction( attributes );
495 bool Button::DoClickAction( const Property::Map& attributes )
497 // Prevents the button signals from doing a recursive loop by sending an action
498 // and re-emitting the signals.
499 if( !mClickActionPerforming )
501 mClickActionPerforming = true;
503 if ( !mTogglableButton )
505 mButtonPressedState = DEPRESSED;
508 mClickActionPerforming = false;
516 void Button::ButtonDown()
518 if( mTogglableButton )
520 if ( mButtonState != SELECTED_STATE )
523 mButtonPressedState = TOGGLE_DEPRESSED;
527 mButtonPressedState = DEPRESSED;
533 mButtonPressedState = DEPRESSED;
536 SetUpTimer( mInitialAutoRepeatingDelay );
540 // The pressed signal should be emitted regardless of toggle mode.
541 Toolkit::Button handle( GetOwner() );
542 mPressedSignal.Emit( handle );
545 void Button::ButtonUp()
547 bool emitSignalsForPressAndReleaseAction = false;
549 if( DEPRESSED == mButtonPressedState )
551 if( mTogglableButton ) // Button up will change state
553 emitSignalsForPressAndReleaseAction = OnToggleReleased(); // Derived toggle buttons can override this to provide custom behaviour
557 Released(); // Button up will result in unselected state
560 mAutoRepeatingTimer.Reset();
562 emitSignalsForPressAndReleaseAction = true;
565 else if ( TOGGLE_DEPRESSED == mButtonPressedState )
567 emitSignalsForPressAndReleaseAction = true; // toggle released after being pressed, a click
570 if ( emitSignalsForPressAndReleaseAction )
572 // The clicked and released signals should be emitted regardless of toggle mode.
573 Toolkit::Button handle( GetOwner() );
574 mReleasedSignal.Emit( handle );
575 mClickedSignal.Emit( handle );
579 bool Button::OnToggleReleased()
581 SetSelected( !IsSelected() );
582 mButtonPressedState = UNPRESSED;
587 void Button::OnTouchPointLeave()
589 if( DEPRESSED == mButtonPressedState )
591 if( !mTogglableButton )
597 mAutoRepeatingTimer.Reset();
601 mButtonPressedState = UNPRESSED;
603 // The released signal should be emitted regardless of toggle mode.
604 Toolkit::Button handle( GetOwner() );
605 mReleasedSignal.Emit( handle );
609 void Button::OnTouchPointInterrupted()
614 Toolkit::Button::ButtonSignalType& Button::PressedSignal()
616 return mPressedSignal;
619 Toolkit::Button::ButtonSignalType& Button::ReleasedSignal()
621 return mReleasedSignal;
624 Toolkit::Button::ButtonSignalType& Button::ClickedSignal()
626 return mClickedSignal;
629 Toolkit::Button::ButtonSignalType& Button::StateChangedSignal()
631 return mStateChangedSignal;
634 bool Button::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
636 Dali::BaseHandle handle( object );
638 bool connected( true );
639 Toolkit::Button button = Toolkit::Button::DownCast( handle );
641 if( 0 == strcmp( signalName.c_str(), SIGNAL_PRESSED ) )
643 button.PressedSignal().Connect( tracker, functor );
645 else if( 0 == strcmp( signalName.c_str(), SIGNAL_RELEASED ) )
647 button.ReleasedSignal().Connect( tracker, functor );
649 else if( 0 == strcmp( signalName.c_str(), SIGNAL_CLICKED ) )
651 button.ClickedSignal().Connect( tracker, functor );
653 else if( 0 == strcmp( signalName.c_str(), SIGNAL_STATE_CHANGED ) )
655 button.StateChangedSignal().Connect( tracker, functor );
659 // signalName does not match any signal
666 void Button::OnInitialize()
668 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnInitialize\n" );
672 mTapDetector = TapGestureDetector::New();
673 mTapDetector.Attach( self );
674 mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
676 self.SetKeyboardFocusable( true );
678 self.TouchSignal().Connect( this, &Button::OnTouch );
681 bool Button::OnAccessibilityActivated()
683 return OnKeyboardEnter();
686 bool Button::OnTouch( Actor actor, const TouchData& touch )
689 // Only events are processed when the button is not disabled and the touch event has only
692 if( !IsDisabled() && ( 1 == touch.GetPointCount() ) )
694 switch( touch.GetState( 0 ) )
696 case PointState::DOWN:
706 case PointState::INTERRUPTED:
708 OnTouchPointInterrupted();
711 case PointState::LEAVE:
716 case PointState::MOTION:
717 case PointState::STATIONARY: // FALLTHROUGH
724 else if( 1 < touch.GetPointCount() )
726 OnTouchPointLeave(); // Notification for derived classes.
728 // Sets the button state to the default
729 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 PerformFunctionOnVisualsInState( &Button::OnButtonVisualRemoval, mPreviousButtonState );
768 SelectRequiredVisual( Toolkit::Button::Property::LABEL );
769 PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState );
770 Control::OnStageConnection( depth ); // Enabled visuals will be put on stage
773 Vector3 Button::GetNaturalSize()
775 Vector3 size = Vector3::ZERO;
777 bool horizontalAlignment = mTextLabelAlignment == BEGIN || mTextLabelAlignment == END; // label and visual side by side
779 // Get natural size of foreground ( largest of the possible visuals )
780 Size largestProvidedVisual;
781 Size labelSize = Size::ZERO;
783 bool foreGroundVisualUsed = false;
785 for ( int state = Button::UNSELECTED_STATE; state < Button::STATE_COUNT; state++ )
787 Toolkit::Visual::Base visual = GetVisual( GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND] );
791 visual.GetNaturalSize( visualSize );
792 largestProvidedVisual.width = std::max(largestProvidedVisual.width, visualSize.width );
793 largestProvidedVisual.height = std::max(largestProvidedVisual.height, visualSize.height );
794 foreGroundVisualUsed = true;
798 if ( !foreGroundVisualUsed ) // If foreground visual not supplied then use the background visual to calculate Natural size
800 for ( int state = Button::UNSELECTED_STATE; state < Button::STATE_COUNT; state++ )
802 Toolkit::Visual::Base visual = GetVisual( GET_VISUAL_INDEX_FOR_STATE[state][BACKGROUND] );
806 visual.GetNaturalSize( visualSize );
807 largestProvidedVisual.width = std::max(largestProvidedVisual.width, visualSize.width );
808 largestProvidedVisual.height = std::max(largestProvidedVisual.height, visualSize.height );
813 // Get horizontal padding total
814 if ( largestProvidedVisual.width > 0 ) // if visual exists
816 size.width += largestProvidedVisual.width + mForegroundPadding.left + mForegroundPadding.right;
818 // Get vertical padding total
819 if ( largestProvidedVisual.height > 0 )
821 size.height += largestProvidedVisual.height + mForegroundPadding.top + mForegroundPadding.bottom;
824 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize visual Size(%f,%f)\n",
825 largestProvidedVisual.width, largestProvidedVisual.height );
827 // Get natural size of label if text has been set
828 if ( mTextStringSetFlag )
830 Toolkit::Visual::Base visual = GetVisual( Toolkit::Button::Property::LABEL );
834 visual.GetNaturalSize( labelSize );
836 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize labelSize(%f,%f) padding(%f,%f)\n",
837 labelSize.width, labelSize.height, mLabelPadding.left + mLabelPadding.right, mLabelPadding.top + mLabelPadding.bottom);
839 labelSize.width += mLabelPadding.left + mLabelPadding.right;
840 labelSize.height += mLabelPadding.top + mLabelPadding.bottom;
842 // Add label size to height or width depending on alignment position
843 if ( horizontalAlignment )
845 size.width += labelSize.width;
846 size.height = std::max(size.height, labelSize.height );
850 size.height += labelSize.height;
851 size.width = std::max(size.width, labelSize.width );
856 if( size.width < 1 && size.height < 1 )
858 // if no image or label then use Control's natural size
859 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize Using control natural size\n");
860 size = Control::GetNaturalSize();
863 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "Button GetNaturalSize (%f,%f)\n", size.width, size.height );
868 void Button::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
870 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnSetResizePolicy\n");
875 * Visuals are sized and positioned in this function.
876 * Whilst the control has it's size negotiated it has to size it's visuals explicitly here.
879 void Button::OnRelayout( const Vector2& size, RelayoutContainer& container )
881 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout targetSize(%f,%f) ptr(%p) state[%d]\n", size.width, size.height, this, mButtonState );
883 Toolkit::Visual::Base currentVisual = GetVisual( GET_VISUAL_INDEX_FOR_STATE[mButtonState][FOREGROUND] );
885 Toolkit::Visual::Base currentBackGroundVisual = GetVisual( GET_VISUAL_INDEX_FOR_STATE[mButtonState][BACKGROUND] );
887 // Sizes and padding set to zero, if not present then values will no effect calculations.
888 Vector2 visualPosition = Vector2::ZERO;
889 Vector2 labelPosition = Vector2::ZERO;
890 Size visualSize = Size::ZERO;
891 Padding foregroundVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f );
892 Padding labelVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f );
894 if ( mTextStringSetFlag )
896 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Label padding setting padding:%f,%f,%f,%f\n", mLabelPadding.y, mLabelPadding.x, mLabelPadding.width,mLabelPadding.height );
897 labelVisualPadding = mLabelPadding;
902 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Foreground Visual setting padding:%f,%f,%f,%f\n", mForegroundPadding.y, mForegroundPadding.x, mForegroundPadding.width,mForegroundPadding.height );
903 currentVisual.GetNaturalSize( visualSize );
904 foregroundVisualPadding = mForegroundPadding;
907 Toolkit::Align::Type visualAnchorPoint = Toolkit::Align::TOP_BEGIN;
909 Vector2 visualAndPaddingSize = Vector2( ( foregroundVisualPadding.x + visualSize.width + foregroundVisualPadding.y ),
910 ( foregroundVisualPadding.width + visualSize.height + foregroundVisualPadding.height ));
912 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout visualAndPaddingSize(%f,%f)\n", visualAndPaddingSize.width, visualAndPaddingSize.height);
914 // Text Visual should take all space available after foreground visual size and all padding is considered.
915 // Remaining Space priority, Foreground padding, foreground visual, Text padding then Text visual.
916 Size remainingSpaceForText = Size::ZERO;
918 switch ( mTextLabelAlignment )
922 visualAnchorPoint = Toolkit::Align::TOP_END;
923 visualPosition.x = foregroundVisualPadding.right;
924 visualPosition.y = foregroundVisualPadding.top;
926 labelPosition.x = labelVisualPadding.x;
927 labelPosition.y = labelVisualPadding.top;
929 remainingSpaceForText.width = size.width - visualAndPaddingSize.width - labelVisualPadding.x - labelVisualPadding.y;
930 remainingSpaceForText.height = size.height - labelVisualPadding.top - labelVisualPadding.bottom;
935 visualAnchorPoint = Toolkit::Align::TOP_BEGIN;
936 visualPosition.x = foregroundVisualPadding.left;
937 visualPosition.y = foregroundVisualPadding.top;
939 labelPosition.x = visualAndPaddingSize.width + labelVisualPadding.x;
940 labelPosition.y = labelVisualPadding.top;
942 remainingSpaceForText.width = size.width - visualAndPaddingSize.width - labelVisualPadding.x - labelVisualPadding.y;
943 remainingSpaceForText.height = size.height - labelVisualPadding.top - labelVisualPadding.bottom;
948 visualAnchorPoint = Toolkit::Align::BOTTOM_END;
949 visualPosition.x = foregroundVisualPadding.left;
950 visualPosition.y = foregroundVisualPadding.bottom;
952 labelPosition.x = labelVisualPadding.left;
953 labelPosition.y = labelVisualPadding.top;
955 remainingSpaceForText.width = size.width - labelVisualPadding.x - labelVisualPadding.y;
956 remainingSpaceForText.height = size.height - visualAndPaddingSize.height - labelVisualPadding.top - labelVisualPadding.bottom;
962 visualAnchorPoint = Toolkit::Align::TOP_END;
963 visualPosition.x = foregroundVisualPadding.left;
964 visualPosition.y = foregroundVisualPadding.top;
966 labelPosition.x = labelVisualPadding.left;
967 labelPosition.y = visualAndPaddingSize.height + labelVisualPadding.top;
969 remainingSpaceForText.width = size.width - labelVisualPadding.x - labelVisualPadding.y;
970 remainingSpaceForText.height = size.height - visualAndPaddingSize.height - labelVisualPadding.top - labelVisualPadding.bottom;
976 if ( currentBackGroundVisual )
978 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual background size to(%f,%f)\n", size.width, size.height);
980 Property::Map visualTransform;
982 visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, size )
983 .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) );
985 currentBackGroundVisual.SetTransformAndSize( visualTransform, size );
990 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual size to(%f,%f)\n", visualSize.width, visualSize.height);
992 Property::Map visualTransform;
994 visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, visualSize )
995 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET, visualPosition )
996 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
997 .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
998 .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
999 .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, visualAnchorPoint );
1001 currentVisual.SetTransformAndSize( visualTransform, size );
1004 if ( mTextStringSetFlag )
1006 Toolkit::Visual::Base textVisual = GetVisual( Toolkit::Button::Property::LABEL ); // No need to search for Label visual if no text set.
1010 if ( !currentVisual )
1012 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Only Text\n");
1013 labelPosition.x = labelVisualPadding.left;
1014 labelPosition.y = labelVisualPadding.height;
1017 Vector2 preSize = Vector2( static_cast< int >( remainingSpaceForText.x ), static_cast< int >( remainingSpaceForText.y ));
1019 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout text Size(%f,%f) text Position(%f,%f) \n", remainingSpaceForText.width, remainingSpaceForText.height, labelPosition.x, labelPosition.y);
1021 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout text Size -- (%f,%f) text Position(%f,%f) \n", preSize.width, preSize.height, labelPosition.x, labelPosition.y);
1024 Property::Map textVisualTransform;
1025 textVisualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, preSize )
1026 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET, labelPosition )
1027 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
1028 .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
1029 .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
1030 .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, visualAnchorPoint );
1032 textVisual.SetTransformAndSize( textVisualTransform, size );
1036 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout selected (%s) \n", IsSelected()?"yes":"no" );
1038 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout << \n");
1041 void Button::OnTap(Actor actor, const TapGesture& tap)
1043 // Prevents Parent getting a tap event
1046 void Button::SetUpTimer( float delay )
1048 mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
1049 mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot );
1050 mAutoRepeatingTimer.Start();
1053 bool Button::AutoRepeatingSlot()
1055 bool consumed = false;
1058 // Restart the autorepeat timer.
1059 SetUpTimer( mNextAutoRepeatingDelay );
1063 Toolkit::Button handle( GetOwner() );
1066 consumed = mReleasedSignal.Emit( handle );
1067 consumed = mClickedSignal.Emit( handle );
1068 consumed |= mPressedSignal.Emit( handle );
1074 void Button::Pressed()
1076 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Pressed\n" );
1078 if( mButtonState == UNSELECTED_STATE )
1080 ChangeState( SELECTED_STATE );
1081 OnPressed(); // Notifies the derived class the button has been pressed.
1085 void Button::Released()
1087 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Released\n" );
1089 if( mButtonState == SELECTED_STATE && !mTogglableButton )
1091 ChangeState( UNSELECTED_STATE );
1092 OnReleased(); // // Notifies the derived class the button has been released.
1094 mButtonPressedState = UNPRESSED;
1097 void Button::SelectRequiredVisual( Property::Index visualIndex )
1099 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SelectRequiredVisual index(%d) state(%d)\n", visualIndex, mButtonState );
1101 EnableVisual( visualIndex, true );
1104 void Button::RemoveVisual( Property::Index visualIndex )
1106 // Use OnButtonVisualRemoval if want button developer to have the option to override removal.
1107 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::RemoveVisual index(%d) state(%d)\n", visualIndex, mButtonState );
1109 Toolkit::Visual::Base visual = GetVisual( visualIndex );
1113 EnableVisual( visualIndex, false );
1117 void Button::OnButtonVisualRemoval( Property::Index visualIndex )
1119 // Derived Buttons can over ride this to prevent default removal.
1120 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnButtonVisualRemoval index(%d)\n", visualIndex );
1121 RemoveVisual( visualIndex );
1124 void Button::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
1126 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1128 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetProperty index[%d]\n", index );
1134 case Toolkit::Button::Property::DISABLED:
1136 GetImplementation( button ).SetDisabled( value.Get< bool >() );
1140 case Toolkit::Button::Property::AUTO_REPEATING:
1142 GetImplementation( button ).SetAutoRepeating( value.Get< bool >() );
1146 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1148 GetImplementation( button ).SetInitialAutoRepeatingDelay( value.Get< float >() );
1152 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1154 GetImplementation( button ).SetNextAutoRepeatingDelay( value.Get< float >() );
1158 case Toolkit::Button::Property::TOGGLABLE:
1160 GetImplementation( button ).SetTogglableButton( value.Get< bool >() );
1164 case Toolkit::Button::Property::SELECTED:
1166 GetImplementation( button ).SetSelected( value.Get< bool >() );
1170 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE: // Legacy Tizen 3.0
1172 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1175 case Toolkit::Button::Property::DISABLED_STATE_IMAGE: // Legacy Tizen 3.0
1177 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1180 case Toolkit::Button::Property::SELECTED_STATE_IMAGE: // Legacy Tizen 3.0
1182 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1185 case Toolkit::DevelButton::Property::UNSELECTED_VISUAL:
1186 case Toolkit::DevelButton::Property::SELECTED_VISUAL:
1187 case Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL:
1188 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL:
1190 GetImplementation( button ).CreateVisualsForComponent( index, value, DepthIndex::CONTENT );
1194 case Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL:
1195 case Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL:
1196 case Toolkit::DevelButton::Property::DISABLED_SELECTED_BACKGROUND_VISUAL:
1197 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL:
1199 GetImplementation( button ).CreateVisualsForComponent( index , value, DepthIndex::BACKGROUND);
1203 case Toolkit::Button::Property::UNSELECTED_COLOR:
1205 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::UNSELECTED_COLOR instead use Button::Property::UNSELECTED_BACKGROUND_VISUAL\n", __FUNCTION__);
1206 GetImplementation( button ).SetColor( value.Get< Vector4 >(), Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1210 case Toolkit::Button::Property::SELECTED_COLOR:
1212 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::SELECTED_COLOR instead use Button::Property::SELECTED_BACKGROUND_VISUAL\n", __FUNCTION__);
1213 GetImplementation( button ).SetColor( value.Get< Vector4 >(), Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL );
1217 case Toolkit::Button::Property::LABEL_TEXT:
1219 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::LABEL_TEXT instead use Button::Property::LABEL\n", __FUNCTION__);
1220 GetImplementation( button ).SetLabelText(value.Get< std::string >() );
1224 case Toolkit::Button::Property::LABEL:
1226 Property::Map outTextVisualProperties;
1227 std::string textString;
1229 if ( value.Get( textString ) )
1231 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetProperty Setting TextVisual with string[%s]\n", textString.c_str() );
1233 Property::Map setPropertyMap;
1234 setPropertyMap.Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT )
1235 .Add( Toolkit::TextVisual::Property::TEXT, textString );
1237 GetImplementation( button ).MergeWithExistingLabelProperties( setPropertyMap, outTextVisualProperties );
1241 // Get a Property::Map from the property if possible.
1242 Property::Map* setPropertyMap = value.GetMap();
1243 if( setPropertyMap )
1245 TextVisual::ConvertStringKeysToIndexKeys( *setPropertyMap );
1246 GetImplementation( button ).MergeWithExistingLabelProperties( *setPropertyMap, outTextVisualProperties );
1250 if( !outTextVisualProperties.Empty() )
1252 GetImplementation( button ).CreateVisualsForComponent( index, outTextVisualProperties, DepthIndex::CONTENT );
1253 GetImplementation( button ).RelayoutRequest();
1258 case Toolkit::DevelButton::Property::LABEL_RELATIVE_ALIGNMENT:
1260 Button::Align labelAlignment(END);
1261 Scripting::GetEnumeration< Button::Align> ( value.Get< std::string >().c_str(),
1262 ALIGNMENT_TABLE, ALIGNMENT_TABLE_COUNT,
1265 GetImplementation( button ).SetLabelAlignment( labelAlignment );
1266 GetImplementation( button ).RelayoutRequest();
1270 case Toolkit::DevelButton::Property::LABEL_PADDING:
1272 Vector4 padding ( value.Get< Vector4 >() );
1273 GetImplementation( button ).SetLabelPadding( Padding( padding.x, padding.y, padding.z, padding.w ) );
1277 case Toolkit::DevelButton::Property::VISUAL_PADDING:
1279 Vector4 padding ( value.Get< Vector4 >() );
1280 GetImplementation( button ).SetForegroundPadding( Padding( padding.x, padding.y, padding.z, padding.w ) );
1281 GetImplementation( button ).RelayoutRequest();
1288 Property::Value Button::GetProperty( BaseObject* object, Property::Index propertyIndex )
1290 Property::Value value;
1292 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1296 switch ( propertyIndex )
1298 case Toolkit::Button::Property::DISABLED:
1300 value = GetImplementation( button ).IsDisabled();
1304 case Toolkit::Button::Property::AUTO_REPEATING:
1306 value = GetImplementation( button ).mAutoRepeating;
1310 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1312 value = GetImplementation( button ).mInitialAutoRepeatingDelay;
1316 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1318 value = GetImplementation( button ).mNextAutoRepeatingDelay;
1322 case Toolkit::Button::Property::TOGGLABLE:
1324 value = GetImplementation( button ).mTogglableButton;
1328 case Toolkit::Button::Property::SELECTED:
1330 value = GetImplementation( button ).IsSelected();
1334 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1336 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1340 case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1342 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL );
1346 case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1348 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL );
1352 case Toolkit::DevelButton::Property::UNSELECTED_VISUAL:
1353 case Toolkit::DevelButton::Property::SELECTED_VISUAL:
1354 case Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL:
1355 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL:
1356 case Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL:
1357 case Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL:
1358 case Toolkit::DevelButton::Property::DISABLED_SELECTED_BACKGROUND_VISUAL:
1359 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL:
1360 case Toolkit::Button::Property::LABEL:
1362 Property::Map visualProperty;
1363 if ( GetImplementation( button ).GetPropertyMapForVisual( propertyIndex, visualProperty ) )
1365 value = visualProperty;
1370 case Toolkit::Button::Property::UNSELECTED_COLOR:
1372 value = GetImplementation( button ).GetUnselectedColor();
1376 case Toolkit::Button::Property::SELECTED_COLOR:
1378 value = GetImplementation( button ).GetSelectedColor();
1382 case Toolkit::Button::Property::LABEL_TEXT:
1384 value = GetImplementation( button ).GetLabelText();
1388 case Toolkit::DevelButton::Property::LABEL_RELATIVE_ALIGNMENT:
1390 const char* alignment = Scripting::GetEnumerationName< Button::Align >( GetImplementation( button ).GetLabelAlignment(),
1391 ALIGNMENT_STRING_TABLE,
1392 ALIGNMENT_STRING_TABLE_COUNT );
1395 value = std::string( alignment );
1401 case Toolkit::DevelButton::Property::LABEL_PADDING:
1403 Padding padding = GetImplementation( button ).GetLabelPadding();
1404 value = Vector4( padding.x, padding.y, padding.top, padding.bottom);
1408 case Toolkit::DevelButton::Property::VISUAL_PADDING:
1410 Padding padding = GetImplementation( button ).GetForegroundPadding();
1411 value = Vector4( padding.x, padding.y, padding.top, padding.bottom);
1419 void Button::SetLabelPadding( const Padding& padding)
1421 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetLabelPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top );
1422 mLabelPadding = Padding( padding.left, padding.right, padding.bottom, padding.top );
1426 Padding Button::GetLabelPadding()
1428 return mLabelPadding;
1431 void Button::SetForegroundPadding( const Padding& padding)
1433 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetForegroundPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top );
1434 mForegroundPadding = Padding( padding.left, padding.right, padding.bottom, padding.top );
1438 Padding Button::GetForegroundPadding()
1440 return mForegroundPadding;
1443 ////////////////////////////////////////////////////////////////////////
1444 // Legacy functions from Tizen 2.4 and 3.0
1446 // Legacy code needed whilst Color can be set by direct Property setting ( deprecated ) instead of setting a Visual
1447 void Button::SetColor( const Vector4& color, Property::Index visualIndex )
1449 if ( visualIndex == Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL )
1451 mSelectedColor = color;
1455 mUnselectedColor = color;
1459 map[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::COLOR;
1460 map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color;
1462 CreateVisualsForComponent( visualIndex, map, DepthIndex::BACKGROUND );
1465 const Vector4 Button::GetUnselectedColor() const
1467 return mUnselectedColor;
1470 const Vector4 Button::GetSelectedColor() const
1472 return mSelectedColor;
1475 void Button::SetAnimationTime( float animationTime )
1477 // Used by deprecated API
1478 mAnimationTime = animationTime;
1481 float Button::GetAnimationTime() const
1483 // Used by deprecated API
1484 return mAnimationTime;
1487 void Button::SetLabel( Actor label )
1491 Property::Value value ="";
1492 value = label.GetProperty(Toolkit::TextLabel::Property::TEXT);
1494 SetLabelText( value.Get<std::string>() );
1498 void Button::SetUnselectedImage( const std::string& filename )
1500 SetBackgroundImage( filename );
1503 void Button::SetBackgroundImage( const std::string& filename )
1505 if( !filename.empty() )
1507 CreateVisualsForComponent( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1511 UnregisterVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1515 void Button::SetSelectedImage( const std::string& filename )
1517 SetSelectedBackgroundImage( filename );
1520 void Button::SetSelectedBackgroundImage( const std::string& filename )
1522 if( !filename.empty() )
1524 CreateVisualsForComponent( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1528 UnregisterVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1532 void Button::SetDisabledBackgroundImage( const std::string& filename )
1534 if( !filename.empty() )
1536 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1540 void Button::SetDisabledImage( const std::string& filename )
1542 if( !filename.empty() )
1544 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL, filename, DepthIndex::CONTENT );
1548 void Button::SetDisabledSelectedImage( const std::string& filename )
1550 if( !filename.empty() )
1552 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL, filename, DepthIndex::CONTENT );
1556 // Used by Deprecated Properties which don't use the Visual Property maps for setting and getting
1557 std::string Button::GetUrlForImageVisual( const Property::Index index ) const
1559 Toolkit::Visual::Base visual = GetVisual( index );
1564 Dali::Property::Map retreivedMap;
1565 visual.CreatePropertyMap( retreivedMap );
1566 Property::Value* value = retreivedMap.Find( Toolkit::ImageVisual::Property::URL, Property::STRING );
1569 result = value->Get<std::string>();
1576 // Below functions DEPRECATED_1_0.50 - Return empty Actors
1580 std::string GetUrlFromImage( Image& image )
1582 ResourceImage resourceImage = ResourceImage::DownCast( image );
1584 std::string imageUrl;
1586 if ( resourceImage )
1588 imageUrl = resourceImage.GetUrl();
1596 void Button::SetButtonImage( Image image )
1598 DALI_LOG_WARNING("Button::SetButtonImage @DEPRECATED_1_0.50\n");
1599 SetUnselectedImage( GetUrlFromImage( image ) );
1602 void Button::SetSelectedImage( Image image )
1604 DALI_LOG_WARNING("Button::SetSelectedImage @DEPRECATED_1_0.50\n");
1605 SetSelectedImage( GetUrlFromImage( image ) );
1608 Actor Button::GetButtonImage() const
1610 DALI_LOG_WARNING("Button::GetButtonImage @DEPRECATED_1_0.50\n");
1611 Actor imageView = Toolkit::ImageView::New( GetUrlForImageVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL ) );
1616 Actor Button::GetSelectedImage() const
1618 DALI_LOG_WARNING("Button::GetSelectedImage @DEPRECATED_1_0.50\n");
1619 Actor imageView = Toolkit::ImageView::New( GetUrlForImageVisual( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL ) );
1624 } // namespace Internal
1626 } // namespace Toolkit