2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "button-impl.h"
22 #include <cstring> // for strcmp
23 #include <dali/devel-api/scripting/enum-helper.h>
24 #include <dali/integration-api/debug.h>
25 #include <dali/public-api/events/touch-data.h>
26 #include <dali/public-api/images/resource-image.h>
27 #include <dali/public-api/object/type-registry.h>
28 #include <dali/public-api/object/type-registry-helper.h>
29 #include <dali/public-api/size-negotiation/relayout-container.h>
30 #include <dali/devel-api/object/property-helper-devel.h>
31 #include <dali/devel-api/scripting/scripting.h>
34 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
35 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
36 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
37 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
38 #include <dali-toolkit/public-api/align-enumerations.h>
39 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
40 #include <dali-toolkit/devel-api/controls/control-devel.h>
41 #include <dali-toolkit/devel-api/controls/buttons/button-devel.h>
42 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
43 #include <dali-toolkit/internal/visuals/text/text-visual.h>
44 #include <dali-toolkit/public-api/visuals/text-visual-properties.h>
45 #include <dali-toolkit/public-api/visuals/visual-properties.h>
47 #if defined(DEBUG_ENABLED)
48 Debug::Filter* gLogButtonFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_BUTTON_CONTROL");
65 // empty handle as we cannot create button (but type registered for clicked signal)
69 // Setup properties, signals and actions using the type-registry.
70 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Button, Toolkit::Control, Create )
72 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabled", BOOLEAN, DISABLED )
73 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "autoRepeating", BOOLEAN, AUTO_REPEATING )
74 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "initialAutoRepeatingDelay", FLOAT, INITIAL_AUTO_REPEATING_DELAY )
75 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "nextAutoRepeatingDelay", FLOAT, NEXT_AUTO_REPEATING_DELAY )
76 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "togglable", BOOLEAN, TOGGLABLE )
77 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selected", BOOLEAN, SELECTED )
78 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedStateImage", MAP, UNSELECTED_STATE_IMAGE ) // Deprecated property
79 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedStateImage", MAP, SELECTED_STATE_IMAGE ) // Deprecated property
80 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledStateImage", MAP, DISABLED_STATE_IMAGE ) // Deprecated property
81 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedColor", VECTOR4, UNSELECTED_COLOR ) // Deprecated property
82 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedColor", VECTOR4, SELECTED_COLOR ) // Deprecated property
83 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "label", MAP, LABEL )
84 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "labelText", STRING, LABEL_TEXT ) // Deprecated property
85 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedVisual", MAP, UNSELECTED_VISUAL )
86 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "selectedVisual", MAP, SELECTED_VISUAL )
87 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledSelectedVisual", MAP, DISABLED_SELECTED_VISUAL )
88 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledUnselectedVisual", MAP, DISABLED_UNSELECTED_VISUAL )
89 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedBackgroundVisual", MAP, UNSELECTED_BACKGROUND_VISUAL )
90 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "selectedBackgroundVisual", MAP, SELECTED_BACKGROUND_VISUAL )
91 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledUnselectedBackgroundVisual", MAP, DISABLED_UNSELECTED_BACKGROUND_VISUAL )
92 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledSelectedBackgroundVisual", MAP, DISABLED_SELECTED_BACKGROUND_VISUAL )
93 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "labelRelativeAlignment", STRING, LABEL_RELATIVE_ALIGNMENT )
94 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "labelPadding", VECTOR4, LABEL_PADDING )
95 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "visualPadding", VECTOR4, VISUAL_PADDING )
98 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "pressed", SIGNAL_PRESSED )
99 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "released", SIGNAL_RELEASED )
100 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "clicked", SIGNAL_CLICKED )
101 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "stateChanged", SIGNAL_STATE_CHANGED )
104 DALI_ACTION_REGISTRATION( Toolkit, Button, "buttonClick", ACTION_BUTTON_CLICK )
106 DALI_TYPE_REGISTRATION_END()
108 DALI_ENUM_TO_STRING_TABLE_BEGIN( ALIGNMENT )
109 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, BEGIN )
110 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, END )
111 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, TOP )
112 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, BOTTOM )
113 DALI_ENUM_TO_STRING_TABLE_END( ALIGNMENT )
115 const Scripting::StringEnum ALIGNMENT_STRING_TABLE[] =
117 { "BEGIN", Button::BEGIN },
118 { "END", Button::END },
119 { "TOP", Button::TOP },
120 { "BOTTOM", Button::BOTTOM },
123 const unsigned int ALIGNMENT_STRING_TABLE_COUNT = sizeof( ALIGNMENT_STRING_TABLE ) / sizeof( ALIGNMENT_STRING_TABLE[0] );
125 const Property::Index 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 int 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 DevelControl::RegisterVisual( *this, index, buttonVisual, DevelControl::IsVisualEnabled( *this, index ), visualDepth );
460 DevelControl::UnregisterVisual( *this, index );
461 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "CreateVisualsForComponent Visual not created or empty map (clearing visual).(%d)\n", index);
463 PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState );
466 bool Button::GetPropertyMapForVisual( Property::Index visualIndex, Property::Map& retreivedMap ) const
468 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetPropertyMapForVisual visual(%d)\n", visualIndex);
469 bool success = false;
470 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, visualIndex );
473 visual.CreatePropertyMap( retreivedMap );
476 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetPropertyMapForVisual %s\n", success?"Success":"Failure");
480 bool Button::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
484 Dali::BaseHandle handle( object );
486 Toolkit::Button button = Toolkit::Button::DownCast( handle );
488 DALI_ASSERT_DEBUG( button );
490 if( 0 == strcmp( actionName.c_str(), ACTION_BUTTON_CLICK ) )
492 ret = GetImplementation( button ).DoClickAction( attributes );
498 bool Button::DoClickAction( const Property::Map& attributes )
500 // Prevents the button signals from doing a recursive loop by sending an action
501 // and re-emitting the signals.
502 if( !mClickActionPerforming )
504 mClickActionPerforming = true;
506 if ( !mTogglableButton )
508 mButtonPressedState = DEPRESSED;
511 mClickActionPerforming = false;
519 void Button::ButtonDown()
521 if( mTogglableButton )
523 if ( mButtonState != SELECTED_STATE )
526 mButtonPressedState = TOGGLE_DEPRESSED;
530 mButtonPressedState = DEPRESSED;
536 mButtonPressedState = DEPRESSED;
539 SetUpTimer( mInitialAutoRepeatingDelay );
543 // The pressed signal should be emitted regardless of toggle mode.
544 Toolkit::Button handle( GetOwner() );
545 mPressedSignal.Emit( handle );
548 void Button::ButtonUp()
550 bool emitSignalsForPressAndReleaseAction = false;
552 if( DEPRESSED == mButtonPressedState )
554 if( mTogglableButton ) // Button up will change state
556 emitSignalsForPressAndReleaseAction = OnToggleReleased(); // Derived toggle buttons can override this to provide custom behaviour
560 Released(); // Button up will result in unselected state
563 mAutoRepeatingTimer.Reset();
565 emitSignalsForPressAndReleaseAction = true;
568 else if ( TOGGLE_DEPRESSED == mButtonPressedState )
570 emitSignalsForPressAndReleaseAction = true; // toggle released after being pressed, a click
573 if ( emitSignalsForPressAndReleaseAction )
575 // The clicked and released signals should be emitted regardless of toggle mode.
576 Toolkit::Button handle( GetOwner() );
577 mReleasedSignal.Emit( handle );
578 mClickedSignal.Emit( handle );
582 bool Button::OnToggleReleased()
584 SetSelected( !IsSelected() );
585 mButtonPressedState = UNPRESSED;
590 void Button::OnTouchPointLeave()
592 if( DEPRESSED == mButtonPressedState )
594 if( !mTogglableButton )
600 mAutoRepeatingTimer.Reset();
604 mButtonPressedState = UNPRESSED;
606 // The released signal should be emitted regardless of toggle mode.
607 Toolkit::Button handle( GetOwner() );
608 mReleasedSignal.Emit( handle );
612 void Button::OnTouchPointInterrupted()
617 Toolkit::Button::ButtonSignalType& Button::PressedSignal()
619 return mPressedSignal;
622 Toolkit::Button::ButtonSignalType& Button::ReleasedSignal()
624 return mReleasedSignal;
627 Toolkit::Button::ButtonSignalType& Button::ClickedSignal()
629 return mClickedSignal;
632 Toolkit::Button::ButtonSignalType& Button::StateChangedSignal()
634 return mStateChangedSignal;
637 bool Button::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
639 Dali::BaseHandle handle( object );
641 bool connected( true );
642 Toolkit::Button button = Toolkit::Button::DownCast( handle );
644 if( 0 == strcmp( signalName.c_str(), SIGNAL_PRESSED ) )
646 button.PressedSignal().Connect( tracker, functor );
648 else if( 0 == strcmp( signalName.c_str(), SIGNAL_RELEASED ) )
650 button.ReleasedSignal().Connect( tracker, functor );
652 else if( 0 == strcmp( signalName.c_str(), SIGNAL_CLICKED ) )
654 button.ClickedSignal().Connect( tracker, functor );
656 else if( 0 == strcmp( signalName.c_str(), SIGNAL_STATE_CHANGED ) )
658 button.StateChangedSignal().Connect( tracker, functor );
662 // signalName does not match any signal
669 void Button::OnInitialize()
671 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnInitialize\n" );
675 mTapDetector = TapGestureDetector::New();
676 mTapDetector.Attach( self );
677 mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
679 self.SetKeyboardFocusable( true );
681 self.TouchSignal().Connect( this, &Button::OnTouch );
684 bool Button::OnAccessibilityActivated()
686 return OnKeyboardEnter();
689 bool Button::OnTouch( Actor actor, const TouchData& touch )
692 // Only events are processed when the button is not disabled and the touch event has only
695 if( !IsDisabled() && ( 1 == touch.GetPointCount() ) )
697 switch( touch.GetState( 0 ) )
699 case PointState::DOWN:
709 case PointState::INTERRUPTED:
711 OnTouchPointInterrupted();
714 case PointState::LEAVE:
719 case PointState::MOTION:
720 case PointState::STATIONARY: // FALLTHROUGH
727 else if( 1 < touch.GetPointCount() )
729 OnTouchPointLeave(); // Notification for derived classes.
731 // Sets the button state to the default
732 mButtonPressedState = UNPRESSED;
738 bool Button::OnKeyboardEnter()
740 // When the enter key is pressed, or button is activated, the click action is performed.
741 Property::Map attributes;
742 bool ret = DoClickAction( attributes );
747 void Button::OnStageDisconnection()
749 if( DEPRESSED == mButtonPressedState )
751 if( !mTogglableButton )
757 mAutoRepeatingTimer.Reset();
762 mButtonPressedState = UNPRESSED;
764 Control::OnStageDisconnection(); // Visuals will be set off stage
767 void Button::OnStageConnection( int depth )
769 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnStageConnection ptr(%p) \n", this );
770 PerformFunctionOnVisualsInState( &Button::OnButtonVisualRemoval, mPreviousButtonState );
771 SelectRequiredVisual( Toolkit::Button::Property::LABEL );
772 PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState );
773 Control::OnStageConnection( depth ); // Enabled visuals will be put on stage
776 Vector3 Button::GetNaturalSize()
778 Vector3 size = Vector3::ZERO;
780 bool horizontalAlignment = mTextLabelAlignment == BEGIN || mTextLabelAlignment == END; // label and visual side by side
782 // Get natural size of foreground ( largest of the possible visuals )
783 Size largestProvidedVisual;
784 Size labelSize = Size::ZERO;
786 bool foreGroundVisualUsed = false;
788 for ( int state = Button::UNSELECTED_STATE; state < Button::STATE_COUNT; state++ )
790 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND] );
794 visual.GetNaturalSize( visualSize );
795 largestProvidedVisual.width = std::max(largestProvidedVisual.width, visualSize.width );
796 largestProvidedVisual.height = std::max(largestProvidedVisual.height, visualSize.height );
797 foreGroundVisualUsed = true;
801 if ( !foreGroundVisualUsed ) // If foreground visual not supplied then use the background visual to calculate Natural size
803 for ( int state = Button::UNSELECTED_STATE; state < Button::STATE_COUNT; state++ )
805 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, GET_VISUAL_INDEX_FOR_STATE[state][BACKGROUND] );
809 visual.GetNaturalSize( visualSize );
810 largestProvidedVisual.width = std::max(largestProvidedVisual.width, visualSize.width );
811 largestProvidedVisual.height = std::max(largestProvidedVisual.height, visualSize.height );
816 // Get horizontal padding total
817 if ( largestProvidedVisual.width > 0 ) // if visual exists
819 size.width += largestProvidedVisual.width + mForegroundPadding.left + mForegroundPadding.right;
821 // Get vertical padding total
822 if ( largestProvidedVisual.height > 0 )
824 size.height += largestProvidedVisual.height + mForegroundPadding.top + mForegroundPadding.bottom;
827 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize visual Size(%f,%f)\n",
828 largestProvidedVisual.width, largestProvidedVisual.height );
830 // Get natural size of label if text has been set
831 if ( mTextStringSetFlag )
833 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, Toolkit::Button::Property::LABEL );
837 visual.GetNaturalSize( labelSize );
839 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize labelSize(%f,%f) padding(%f,%f)\n",
840 labelSize.width, labelSize.height, mLabelPadding.left + mLabelPadding.right, mLabelPadding.top + mLabelPadding.bottom);
842 labelSize.width += mLabelPadding.left + mLabelPadding.right;
843 labelSize.height += mLabelPadding.top + mLabelPadding.bottom;
845 // Add label size to height or width depending on alignment position
846 if ( horizontalAlignment )
848 size.width += labelSize.width;
849 size.height = std::max(size.height, labelSize.height );
853 size.height += labelSize.height;
854 size.width = std::max(size.width, labelSize.width );
859 if( size.width < 1 && size.height < 1 )
861 // if no image or label then use Control's natural size
862 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize Using control natural size\n");
863 size = Control::GetNaturalSize();
866 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "Button GetNaturalSize (%f,%f)\n", size.width, size.height );
871 void Button::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
873 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnSetResizePolicy\n");
878 * Visuals are sized and positioned in this function.
879 * Whilst the control has it's size negotiated it has to size it's visuals explicitly here.
882 void Button::OnRelayout( const Vector2& size, RelayoutContainer& container )
884 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout targetSize(%f,%f) ptr(%p) state[%d]\n", size.width, size.height, this, mButtonState );
886 Toolkit::Visual::Base currentVisual = DevelControl::GetVisual( *this, GET_VISUAL_INDEX_FOR_STATE[mButtonState][FOREGROUND] );
888 Toolkit::Visual::Base currentBackGroundVisual = DevelControl::GetVisual( *this, GET_VISUAL_INDEX_FOR_STATE[mButtonState][BACKGROUND] );
890 // Sizes and padding set to zero, if not present then values will no effect calculations.
891 Vector2 visualPosition = Vector2::ZERO;
892 Vector2 labelPosition = Vector2::ZERO;
893 Size visualSize = Size::ZERO;
894 Padding foregroundVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f );
895 Padding labelVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f );
897 if ( mTextStringSetFlag )
899 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Label padding setting padding:%f,%f,%f,%f\n", mLabelPadding.y, mLabelPadding.x, mLabelPadding.width,mLabelPadding.height );
900 labelVisualPadding = mLabelPadding;
905 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Foreground Visual setting padding:%f,%f,%f,%f\n", mForegroundPadding.y, mForegroundPadding.x, mForegroundPadding.width,mForegroundPadding.height );
906 currentVisual.GetNaturalSize( visualSize );
907 foregroundVisualPadding = mForegroundPadding;
910 Toolkit::Align::Type visualAnchorPoint = Toolkit::Align::TOP_BEGIN;
912 Vector2 visualAndPaddingSize = Vector2( ( foregroundVisualPadding.x + visualSize.width + foregroundVisualPadding.y ),
913 ( foregroundVisualPadding.width + visualSize.height + foregroundVisualPadding.height ));
915 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout visualAndPaddingSize(%f,%f)\n", visualAndPaddingSize.width, visualAndPaddingSize.height);
917 // Text Visual should take all space available after foreground visual size and all padding is considered.
918 // Remaining Space priority, Foreground padding, foreground visual, Text padding then Text visual.
919 Size remainingSpaceForText = Size::ZERO;
921 switch ( mTextLabelAlignment )
925 visualAnchorPoint = Toolkit::Align::TOP_END;
926 visualPosition.x = foregroundVisualPadding.right;
927 visualPosition.y = foregroundVisualPadding.top;
929 labelPosition.x = labelVisualPadding.x;
930 labelPosition.y = labelVisualPadding.top;
932 remainingSpaceForText.width = size.width - visualAndPaddingSize.width - labelVisualPadding.x - labelVisualPadding.y;
933 remainingSpaceForText.height = size.height - labelVisualPadding.top - labelVisualPadding.bottom;
938 visualAnchorPoint = Toolkit::Align::TOP_BEGIN;
939 visualPosition.x = foregroundVisualPadding.left;
940 visualPosition.y = foregroundVisualPadding.top;
942 labelPosition.x = visualAndPaddingSize.width + labelVisualPadding.x;
943 labelPosition.y = labelVisualPadding.top;
945 remainingSpaceForText.width = size.width - visualAndPaddingSize.width - labelVisualPadding.x - labelVisualPadding.y;
946 remainingSpaceForText.height = size.height - labelVisualPadding.top - labelVisualPadding.bottom;
951 visualAnchorPoint = Toolkit::Align::BOTTOM_END;
952 visualPosition.x = foregroundVisualPadding.left;
953 visualPosition.y = foregroundVisualPadding.bottom;
955 labelPosition.x = labelVisualPadding.left;
956 labelPosition.y = labelVisualPadding.top;
958 remainingSpaceForText.width = size.width - labelVisualPadding.x - labelVisualPadding.y;
959 remainingSpaceForText.height = size.height - visualAndPaddingSize.height - labelVisualPadding.top - labelVisualPadding.bottom;
965 visualAnchorPoint = Toolkit::Align::TOP_END;
966 visualPosition.x = foregroundVisualPadding.left;
967 visualPosition.y = foregroundVisualPadding.top;
969 labelPosition.x = labelVisualPadding.left;
970 labelPosition.y = visualAndPaddingSize.height + labelVisualPadding.top;
972 remainingSpaceForText.width = size.width - labelVisualPadding.x - labelVisualPadding.y;
973 remainingSpaceForText.height = size.height - visualAndPaddingSize.height - labelVisualPadding.top - labelVisualPadding.bottom;
979 if ( currentBackGroundVisual )
981 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual background size to(%f,%f)\n", size.width, size.height);
983 Property::Map visualTransform;
985 visualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, size )
986 .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) );
988 currentBackGroundVisual.SetTransformAndSize( visualTransform, size );
993 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual size to(%f,%f)\n", visualSize.width, visualSize.height);
995 Property::Map visualTransform;
997 visualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, visualSize )
998 .Add( Toolkit::Visual::Transform::Property::OFFSET, visualPosition )
999 .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
1000 .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
1001 .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
1002 .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, visualAnchorPoint );
1004 currentVisual.SetTransformAndSize( visualTransform, size );
1007 if ( mTextStringSetFlag )
1009 Toolkit::Visual::Base textVisual = DevelControl::GetVisual( *this, Toolkit::Button::Property::LABEL ); // No need to search for Label visual if no text set.
1013 if ( !currentVisual )
1015 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Only Text\n");
1016 labelPosition.x = labelVisualPadding.left;
1017 labelPosition.y = labelVisualPadding.height;
1020 Vector2 preSize = Vector2( static_cast< int >( remainingSpaceForText.x ), static_cast< int >( remainingSpaceForText.y ));
1022 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout text Size(%f,%f) text Position(%f,%f) \n", remainingSpaceForText.width, remainingSpaceForText.height, labelPosition.x, labelPosition.y);
1024 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout text Size -- (%f,%f) text Position(%f,%f) \n", preSize.width, preSize.height, labelPosition.x, labelPosition.y);
1027 Property::Map textVisualTransform;
1028 textVisualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, preSize )
1029 .Add( Toolkit::Visual::Transform::Property::OFFSET, labelPosition )
1030 .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
1031 .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
1032 .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
1033 .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, visualAnchorPoint );
1035 textVisual.SetTransformAndSize( textVisualTransform, size );
1039 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout selected (%s) \n", IsSelected()?"yes":"no" );
1041 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout << \n");
1044 void Button::OnTap(Actor actor, const TapGesture& tap)
1046 // Prevents Parent getting a tap event
1049 void Button::SetUpTimer( float delay )
1051 mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
1052 mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot );
1053 mAutoRepeatingTimer.Start();
1056 bool Button::AutoRepeatingSlot()
1058 bool consumed = false;
1061 // Restart the autorepeat timer.
1062 SetUpTimer( mNextAutoRepeatingDelay );
1066 Toolkit::Button handle( GetOwner() );
1069 consumed = mReleasedSignal.Emit( handle );
1070 consumed = mClickedSignal.Emit( handle );
1071 consumed |= mPressedSignal.Emit( handle );
1077 void Button::Pressed()
1079 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Pressed\n" );
1081 if( mButtonState == UNSELECTED_STATE )
1083 ChangeState( SELECTED_STATE );
1084 OnPressed(); // Notifies the derived class the button has been pressed.
1088 void Button::Released()
1090 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Released\n" );
1092 if( mButtonState == SELECTED_STATE && !mTogglableButton )
1094 ChangeState( UNSELECTED_STATE );
1095 OnReleased(); // // Notifies the derived class the button has been released.
1097 mButtonPressedState = UNPRESSED;
1100 void Button::SelectRequiredVisual( Property::Index visualIndex )
1102 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SelectRequiredVisual index(%d) state(%d)\n", visualIndex, mButtonState );
1104 DevelControl::EnableVisual( *this, visualIndex, true );
1107 void Button::RemoveVisual( Property::Index visualIndex )
1109 // Use OnButtonVisualRemoval if want button developer to have the option to override removal.
1110 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::RemoveVisual index(%d) state(%d)\n", visualIndex, mButtonState );
1112 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, visualIndex );
1116 DevelControl::EnableVisual( *this, visualIndex, false );
1120 void Button::OnButtonVisualRemoval( Property::Index visualIndex )
1122 // Derived Buttons can over ride this to prevent default removal.
1123 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnButtonVisualRemoval index(%d)\n", visualIndex );
1124 RemoveVisual( visualIndex );
1127 void Button::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
1129 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1131 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetProperty index[%d]\n", index );
1137 case Toolkit::Button::Property::DISABLED:
1139 GetImplementation( button ).SetDisabled( value.Get< bool >() );
1143 case Toolkit::Button::Property::AUTO_REPEATING:
1145 GetImplementation( button ).SetAutoRepeating( value.Get< bool >() );
1149 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1151 GetImplementation( button ).SetInitialAutoRepeatingDelay( value.Get< float >() );
1155 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1157 GetImplementation( button ).SetNextAutoRepeatingDelay( value.Get< float >() );
1161 case Toolkit::Button::Property::TOGGLABLE:
1163 GetImplementation( button ).SetTogglableButton( value.Get< bool >() );
1167 case Toolkit::Button::Property::SELECTED:
1169 GetImplementation( button ).SetSelected( value.Get< bool >() );
1173 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE: // Legacy Tizen 3.0
1175 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1178 case Toolkit::Button::Property::DISABLED_STATE_IMAGE: // Legacy Tizen 3.0
1180 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1183 case Toolkit::Button::Property::SELECTED_STATE_IMAGE: // Legacy Tizen 3.0
1185 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1188 case Toolkit::DevelButton::Property::UNSELECTED_VISUAL:
1189 case Toolkit::DevelButton::Property::SELECTED_VISUAL:
1190 case Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL:
1191 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL:
1193 GetImplementation( button ).CreateVisualsForComponent( index, value, DepthIndex::CONTENT );
1197 case Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL:
1198 case Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL:
1199 case Toolkit::DevelButton::Property::DISABLED_SELECTED_BACKGROUND_VISUAL:
1200 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL:
1202 GetImplementation( button ).CreateVisualsForComponent( index , value, DepthIndex::BACKGROUND);
1206 case Toolkit::Button::Property::UNSELECTED_COLOR:
1208 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::UNSELECTED_COLOR instead use Button::Property::UNSELECTED_BACKGROUND_VISUAL\n", __FUNCTION__);
1209 GetImplementation( button ).SetColor( value.Get< Vector4 >(), Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1213 case Toolkit::Button::Property::SELECTED_COLOR:
1215 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::SELECTED_COLOR instead use Button::Property::SELECTED_BACKGROUND_VISUAL\n", __FUNCTION__);
1216 GetImplementation( button ).SetColor( value.Get< Vector4 >(), Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL );
1220 case Toolkit::Button::Property::LABEL_TEXT:
1222 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::LABEL_TEXT instead use Button::Property::LABEL\n", __FUNCTION__);
1223 GetImplementation( button ).SetLabelText(value.Get< std::string >() );
1227 case Toolkit::Button::Property::LABEL:
1229 Property::Map outTextVisualProperties;
1230 std::string textString;
1232 if ( value.Get( textString ) )
1234 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetProperty Setting TextVisual with string[%s]\n", textString.c_str() );
1236 Property::Map setPropertyMap;
1237 setPropertyMap.Add( Toolkit::Visual::Property::TYPE, Toolkit::Visual::TEXT )
1238 .Add( Toolkit::TextVisual::Property::TEXT, textString );
1240 GetImplementation( button ).MergeWithExistingLabelProperties( setPropertyMap, outTextVisualProperties );
1244 // Get a Property::Map from the property if possible.
1245 Property::Map* setPropertyMap = value.GetMap();
1246 if( setPropertyMap )
1248 TextVisual::ConvertStringKeysToIndexKeys( *setPropertyMap );
1249 GetImplementation( button ).MergeWithExistingLabelProperties( *setPropertyMap, outTextVisualProperties );
1253 if( !outTextVisualProperties.Empty() )
1255 GetImplementation( button ).CreateVisualsForComponent( index, outTextVisualProperties, DepthIndex::CONTENT );
1256 GetImplementation( button ).RelayoutRequest();
1261 case Toolkit::DevelButton::Property::LABEL_RELATIVE_ALIGNMENT:
1263 Button::Align labelAlignment(END);
1264 Scripting::GetEnumeration< Button::Align> ( value.Get< std::string >().c_str(),
1265 ALIGNMENT_TABLE, ALIGNMENT_TABLE_COUNT,
1268 GetImplementation( button ).SetLabelAlignment( labelAlignment );
1269 GetImplementation( button ).RelayoutRequest();
1273 case Toolkit::DevelButton::Property::LABEL_PADDING:
1275 Vector4 padding ( value.Get< Vector4 >() );
1276 GetImplementation( button ).SetLabelPadding( Padding( padding.x, padding.y, padding.z, padding.w ) );
1280 case Toolkit::DevelButton::Property::VISUAL_PADDING:
1282 Vector4 padding ( value.Get< Vector4 >() );
1283 GetImplementation( button ).SetForegroundPadding( Padding( padding.x, padding.y, padding.z, padding.w ) );
1284 GetImplementation( button ).RelayoutRequest();
1291 Property::Value Button::GetProperty( BaseObject* object, Property::Index propertyIndex )
1293 Property::Value value;
1295 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1299 switch ( propertyIndex )
1301 case Toolkit::Button::Property::DISABLED:
1303 value = GetImplementation( button ).IsDisabled();
1307 case Toolkit::Button::Property::AUTO_REPEATING:
1309 value = GetImplementation( button ).mAutoRepeating;
1313 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1315 value = GetImplementation( button ).mInitialAutoRepeatingDelay;
1319 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1321 value = GetImplementation( button ).mNextAutoRepeatingDelay;
1325 case Toolkit::Button::Property::TOGGLABLE:
1327 value = GetImplementation( button ).mTogglableButton;
1331 case Toolkit::Button::Property::SELECTED:
1333 value = GetImplementation( button ).IsSelected();
1337 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1339 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1343 case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1345 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL );
1349 case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1351 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL );
1355 case Toolkit::DevelButton::Property::UNSELECTED_VISUAL:
1356 case Toolkit::DevelButton::Property::SELECTED_VISUAL:
1357 case Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL:
1358 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL:
1359 case Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL:
1360 case Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL:
1361 case Toolkit::DevelButton::Property::DISABLED_SELECTED_BACKGROUND_VISUAL:
1362 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL:
1363 case Toolkit::Button::Property::LABEL:
1365 Property::Map visualProperty;
1366 if ( GetImplementation( button ).GetPropertyMapForVisual( propertyIndex, visualProperty ) )
1368 value = visualProperty;
1373 case Toolkit::Button::Property::UNSELECTED_COLOR:
1375 value = GetImplementation( button ).GetUnselectedColor();
1379 case Toolkit::Button::Property::SELECTED_COLOR:
1381 value = GetImplementation( button ).GetSelectedColor();
1385 case Toolkit::Button::Property::LABEL_TEXT:
1387 value = GetImplementation( button ).GetLabelText();
1391 case Toolkit::DevelButton::Property::LABEL_RELATIVE_ALIGNMENT:
1393 const char* alignment = Scripting::GetEnumerationName< Button::Align >( GetImplementation( button ).GetLabelAlignment(),
1394 ALIGNMENT_STRING_TABLE,
1395 ALIGNMENT_STRING_TABLE_COUNT );
1398 value = std::string( alignment );
1404 case Toolkit::DevelButton::Property::LABEL_PADDING:
1406 Padding padding = GetImplementation( button ).GetLabelPadding();
1407 value = Vector4( padding.x, padding.y, padding.top, padding.bottom);
1411 case Toolkit::DevelButton::Property::VISUAL_PADDING:
1413 Padding padding = GetImplementation( button ).GetForegroundPadding();
1414 value = Vector4( padding.x, padding.y, padding.top, padding.bottom);
1422 void Button::SetLabelPadding( const Padding& padding)
1424 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetLabelPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top );
1425 mLabelPadding = Padding( padding.left, padding.right, padding.bottom, padding.top );
1429 Padding Button::GetLabelPadding()
1431 return mLabelPadding;
1434 void Button::SetForegroundPadding( const Padding& padding)
1436 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetForegroundPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top );
1437 mForegroundPadding = Padding( padding.left, padding.right, padding.bottom, padding.top );
1441 Padding Button::GetForegroundPadding()
1443 return mForegroundPadding;
1446 ////////////////////////////////////////////////////////////////////////
1447 // Legacy functions from Tizen 2.4 and 3.0
1449 // Legacy code needed whilst Color can be set by direct Property setting ( deprecated ) instead of setting a Visual
1450 void Button::SetColor( const Vector4& color, Property::Index visualIndex )
1452 if ( visualIndex == Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL )
1454 mSelectedColor = color;
1458 mUnselectedColor = color;
1462 map[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::COLOR;
1463 map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color;
1465 CreateVisualsForComponent( visualIndex, map, DepthIndex::BACKGROUND );
1468 const Vector4 Button::GetUnselectedColor() const
1470 return mUnselectedColor;
1473 const Vector4 Button::GetSelectedColor() const
1475 return mSelectedColor;
1478 void Button::SetAnimationTime( float animationTime )
1480 // Used by deprecated API
1481 mAnimationTime = animationTime;
1484 float Button::GetAnimationTime() const
1486 // Used by deprecated API
1487 return mAnimationTime;
1490 void Button::SetLabel( Actor label )
1494 Property::Value value ="";
1495 value = label.GetProperty(Toolkit::TextLabel::Property::TEXT);
1497 SetLabelText( value.Get<std::string>() );
1501 void Button::SetUnselectedImage( const std::string& filename )
1503 SetBackgroundImage( filename );
1506 void Button::SetBackgroundImage( const std::string& filename )
1508 if( !filename.empty() )
1510 CreateVisualsForComponent( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1514 DevelControl::UnregisterVisual( *this, Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1518 void Button::SetSelectedImage( const std::string& filename )
1520 SetSelectedBackgroundImage( filename );
1523 void Button::SetSelectedBackgroundImage( const std::string& filename )
1525 if( !filename.empty() )
1527 CreateVisualsForComponent( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1531 DevelControl::UnregisterVisual( *this, Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1535 void Button::SetDisabledBackgroundImage( const std::string& filename )
1537 if( !filename.empty() )
1539 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1543 void Button::SetDisabledImage( const std::string& filename )
1545 if( !filename.empty() )
1547 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL, filename, DepthIndex::CONTENT );
1551 void Button::SetDisabledSelectedImage( const std::string& filename )
1553 if( !filename.empty() )
1555 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL, filename, DepthIndex::CONTENT );
1559 // Used by Deprecated Properties which don't use the Visual Property maps for setting and getting
1560 std::string Button::GetUrlForImageVisual( const Property::Index index ) const
1562 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, index );
1567 Dali::Property::Map retreivedMap;
1568 visual.CreatePropertyMap( retreivedMap );
1569 Property::Value* value = retreivedMap.Find( Toolkit::ImageVisual::Property::URL, Property::STRING );
1572 result = value->Get<std::string>();
1579 // Below functions DEPRECATED_1_0.50 - Return empty Actors
1583 std::string GetUrlFromImage( Image& image )
1585 ResourceImage resourceImage = ResourceImage::DownCast( image );
1587 std::string imageUrl;
1589 if ( resourceImage )
1591 imageUrl = resourceImage.GetUrl();
1599 void Button::SetButtonImage( Image image )
1601 DALI_LOG_WARNING("Button::SetButtonImage @DEPRECATED_1_0.50\n");
1602 SetUnselectedImage( GetUrlFromImage( image ) );
1603 mSetButtonImage = image;
1606 void Button::SetSelectedImage( Image image )
1608 DALI_LOG_WARNING("Button::SetSelectedImage @DEPRECATED_1_0.50\n");
1609 SetSelectedImage( GetUrlFromImage( image ) );
1610 mSetSelectedImage = image;
1613 Actor Button::GetButtonImage() const
1615 // When deprecated ImageView API removed then this button API can be removed too.
1616 DALI_LOG_WARNING("Button::GetButtonImage @DEPRECATED_1_0.50\n");
1620 if ( mSetButtonImage )
1622 imageView = Toolkit::ImageView::New( mSetButtonImage );
1626 ResourceImage image = ResourceImage::New( GetUrlForImageVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL ) );
1627 imageView = Toolkit::ImageView::New( image );
1633 Actor Button::GetSelectedImage() const
1635 // When deprecated ImageView API removed then this button API can be removed too.
1636 DALI_LOG_WARNING("Button::GetSelectedImage @DEPRECATED_1_0.50\n");
1640 if ( mSetSelectedImage )
1642 imageView = Toolkit::ImageView::New( mSetSelectedImage );
1646 ResourceImage image = ResourceImage::New( GetUrlForImageVisual( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL ) );
1647 imageView = Toolkit::ImageView::New( image );
1652 } // namespace Internal
1654 } // namespace Toolkit