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
693 auto result( false );
697 if ( 1 == touch.GetPointCount() )
699 switch( touch.GetState( 0 ) )
701 case PointState::DOWN:
711 case PointState::INTERRUPTED:
713 OnTouchPointInterrupted();
716 case PointState::LEAVE:
721 case PointState::MOTION:
722 case PointState::STATIONARY: // FALLTHROUGH
729 else if( 1 < touch.GetPointCount() )
731 OnTouchPointLeave(); // Notification for derived classes.
733 // Sets the button state to the default
734 mButtonPressedState = UNPRESSED;
741 bool Button::OnKeyboardEnter()
743 // When the enter key is pressed, or button is activated, the click action is performed.
744 Property::Map attributes;
745 bool ret = DoClickAction( attributes );
750 void Button::OnStageDisconnection()
752 if( DEPRESSED == mButtonPressedState )
754 if( !mTogglableButton )
760 mAutoRepeatingTimer.Reset();
765 mButtonPressedState = UNPRESSED;
767 Control::OnStageDisconnection(); // Visuals will be set off stage
770 void Button::OnStageConnection( int depth )
772 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnStageConnection ptr(%p) \n", this );
773 PerformFunctionOnVisualsInState( &Button::OnButtonVisualRemoval, mPreviousButtonState );
774 SelectRequiredVisual( Toolkit::Button::Property::LABEL );
775 PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState );
776 Control::OnStageConnection( depth ); // Enabled visuals will be put on stage
779 Vector3 Button::GetNaturalSize()
781 Vector3 size = Vector3::ZERO;
783 bool horizontalAlignment = mTextLabelAlignment == BEGIN || mTextLabelAlignment == END; // label and visual side by side
785 // Get natural size of foreground ( largest of the possible visuals )
786 Size largestProvidedVisual;
787 Size labelSize = Size::ZERO;
789 bool foreGroundVisualUsed = false;
791 for ( int state = Button::UNSELECTED_STATE; state < Button::STATE_COUNT; state++ )
793 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND] );
797 visual.GetNaturalSize( visualSize );
798 largestProvidedVisual.width = std::max(largestProvidedVisual.width, visualSize.width );
799 largestProvidedVisual.height = std::max(largestProvidedVisual.height, visualSize.height );
800 foreGroundVisualUsed = true;
804 if ( !foreGroundVisualUsed ) // If foreground visual not supplied then use the background visual to calculate Natural size
806 for ( int state = Button::UNSELECTED_STATE; state < Button::STATE_COUNT; state++ )
808 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, GET_VISUAL_INDEX_FOR_STATE[state][BACKGROUND] );
812 visual.GetNaturalSize( visualSize );
813 largestProvidedVisual.width = std::max(largestProvidedVisual.width, visualSize.width );
814 largestProvidedVisual.height = std::max(largestProvidedVisual.height, visualSize.height );
819 // Get horizontal padding total
820 if ( largestProvidedVisual.width > 0 ) // if visual exists
822 size.width += largestProvidedVisual.width + mForegroundPadding.left + mForegroundPadding.right;
824 // Get vertical padding total
825 if ( largestProvidedVisual.height > 0 )
827 size.height += largestProvidedVisual.height + mForegroundPadding.top + mForegroundPadding.bottom;
830 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize visual Size(%f,%f)\n",
831 largestProvidedVisual.width, largestProvidedVisual.height );
833 // Get natural size of label if text has been set
834 if ( mTextStringSetFlag )
836 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, Toolkit::Button::Property::LABEL );
840 visual.GetNaturalSize( labelSize );
842 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize labelSize(%f,%f) padding(%f,%f)\n",
843 labelSize.width, labelSize.height, mLabelPadding.left + mLabelPadding.right, mLabelPadding.top + mLabelPadding.bottom);
845 labelSize.width += mLabelPadding.left + mLabelPadding.right;
846 labelSize.height += mLabelPadding.top + mLabelPadding.bottom;
848 // Add label size to height or width depending on alignment position
849 if ( horizontalAlignment )
851 size.width += labelSize.width;
852 size.height = std::max(size.height, labelSize.height );
856 size.height += labelSize.height;
857 size.width = std::max(size.width, labelSize.width );
862 if( size.width < 1 && size.height < 1 )
864 // if no image or label then use Control's natural size
865 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize Using control natural size\n");
866 size = Control::GetNaturalSize();
869 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "Button GetNaturalSize (%f,%f)\n", size.width, size.height );
874 void Button::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
876 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnSetResizePolicy\n");
881 * Visuals are sized and positioned in this function.
882 * Whilst the control has it's size negotiated it has to size it's visuals explicitly here.
885 void Button::OnRelayout( const Vector2& size, RelayoutContainer& container )
887 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout targetSize(%f,%f) ptr(%p) state[%d]\n", size.width, size.height, this, mButtonState );
889 Toolkit::Visual::Base currentVisual = DevelControl::GetVisual( *this, GET_VISUAL_INDEX_FOR_STATE[mButtonState][FOREGROUND] );
891 Toolkit::Visual::Base currentBackGroundVisual = DevelControl::GetVisual( *this, GET_VISUAL_INDEX_FOR_STATE[mButtonState][BACKGROUND] );
893 // Sizes and padding set to zero, if not present then values will no effect calculations.
894 Vector2 visualPosition = Vector2::ZERO;
895 Vector2 labelPosition = Vector2::ZERO;
896 Size visualSize = Size::ZERO;
897 Padding foregroundVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f );
898 Padding labelVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f );
900 if ( mTextStringSetFlag )
902 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Label padding setting padding:%f,%f,%f,%f\n", mLabelPadding.y, mLabelPadding.x, mLabelPadding.width,mLabelPadding.height );
903 labelVisualPadding = mLabelPadding;
908 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Foreground Visual setting padding:%f,%f,%f,%f\n", mForegroundPadding.y, mForegroundPadding.x, mForegroundPadding.width,mForegroundPadding.height );
909 currentVisual.GetNaturalSize( visualSize );
910 foregroundVisualPadding = mForegroundPadding;
913 Toolkit::Align::Type visualAnchorPoint = Toolkit::Align::TOP_BEGIN;
915 Vector2 visualAndPaddingSize = Vector2( ( foregroundVisualPadding.x + visualSize.width + foregroundVisualPadding.y ),
916 ( foregroundVisualPadding.width + visualSize.height + foregroundVisualPadding.height ));
918 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout visualAndPaddingSize(%f,%f)\n", visualAndPaddingSize.width, visualAndPaddingSize.height);
920 // Text Visual should take all space available after foreground visual size and all padding is considered.
921 // Remaining Space priority, Foreground padding, foreground visual, Text padding then Text visual.
922 Size remainingSpaceForText = Size::ZERO;
924 switch ( mTextLabelAlignment )
928 visualAnchorPoint = Toolkit::Align::TOP_END;
929 visualPosition.x = foregroundVisualPadding.right;
930 visualPosition.y = foregroundVisualPadding.top;
932 labelPosition.x = labelVisualPadding.x;
933 labelPosition.y = labelVisualPadding.top;
935 remainingSpaceForText.width = size.width - visualAndPaddingSize.width - labelVisualPadding.x - labelVisualPadding.y;
936 remainingSpaceForText.height = size.height - labelVisualPadding.top - labelVisualPadding.bottom;
941 visualAnchorPoint = Toolkit::Align::TOP_BEGIN;
942 visualPosition.x = foregroundVisualPadding.left;
943 visualPosition.y = foregroundVisualPadding.top;
945 labelPosition.x = visualAndPaddingSize.width + labelVisualPadding.x;
946 labelPosition.y = labelVisualPadding.top;
948 remainingSpaceForText.width = size.width - visualAndPaddingSize.width - labelVisualPadding.x - labelVisualPadding.y;
949 remainingSpaceForText.height = size.height - labelVisualPadding.top - labelVisualPadding.bottom;
954 visualAnchorPoint = Toolkit::Align::BOTTOM_END;
955 visualPosition.x = foregroundVisualPadding.left;
956 visualPosition.y = foregroundVisualPadding.bottom;
958 labelPosition.x = labelVisualPadding.left;
959 labelPosition.y = labelVisualPadding.top;
961 remainingSpaceForText.width = size.width - labelVisualPadding.x - labelVisualPadding.y;
962 remainingSpaceForText.height = size.height - visualAndPaddingSize.height - labelVisualPadding.top - labelVisualPadding.bottom;
968 visualAnchorPoint = Toolkit::Align::TOP_END;
969 visualPosition.x = foregroundVisualPadding.left;
970 visualPosition.y = foregroundVisualPadding.top;
972 labelPosition.x = labelVisualPadding.left;
973 labelPosition.y = visualAndPaddingSize.height + labelVisualPadding.top;
975 remainingSpaceForText.width = size.width - labelVisualPadding.x - labelVisualPadding.y;
976 remainingSpaceForText.height = size.height - visualAndPaddingSize.height - labelVisualPadding.top - labelVisualPadding.bottom;
982 if ( currentBackGroundVisual )
984 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual background size to(%f,%f)\n", size.width, size.height);
986 Property::Map visualTransform;
988 visualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, size )
989 .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) );
991 currentBackGroundVisual.SetTransformAndSize( visualTransform, size );
996 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual size to(%f,%f)\n", visualSize.width, visualSize.height);
998 Property::Map visualTransform;
1000 visualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, visualSize )
1001 .Add( Toolkit::Visual::Transform::Property::OFFSET, visualPosition )
1002 .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
1003 .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
1004 .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
1005 .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, visualAnchorPoint );
1007 currentVisual.SetTransformAndSize( visualTransform, size );
1010 if ( mTextStringSetFlag )
1012 Toolkit::Visual::Base textVisual = DevelControl::GetVisual( *this, Toolkit::Button::Property::LABEL ); // No need to search for Label visual if no text set.
1016 if ( !currentVisual )
1018 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Only Text\n");
1019 labelPosition.x = labelVisualPadding.left;
1020 labelPosition.y = labelVisualPadding.height;
1023 Vector2 preSize = Vector2( static_cast< int >( remainingSpaceForText.x ), static_cast< int >( remainingSpaceForText.y ));
1025 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout text Size(%f,%f) text Position(%f,%f) \n", remainingSpaceForText.width, remainingSpaceForText.height, labelPosition.x, labelPosition.y);
1027 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout text Size -- (%f,%f) text Position(%f,%f) \n", preSize.width, preSize.height, labelPosition.x, labelPosition.y);
1030 Property::Map textVisualTransform;
1031 textVisualTransform.Add( Toolkit::Visual::Transform::Property::SIZE, preSize )
1032 .Add( Toolkit::Visual::Transform::Property::OFFSET, labelPosition )
1033 .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
1034 .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
1035 .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
1036 .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, visualAnchorPoint );
1038 textVisual.SetTransformAndSize( textVisualTransform, size );
1042 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout selected (%s) \n", IsSelected()?"yes":"no" );
1044 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout << \n");
1047 void Button::OnTap(Actor actor, const TapGesture& tap)
1049 // Prevents Parent getting a tap event
1052 void Button::SetUpTimer( float delay )
1054 mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
1055 mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot );
1056 mAutoRepeatingTimer.Start();
1059 bool Button::AutoRepeatingSlot()
1061 bool consumed = false;
1064 // Restart the autorepeat timer.
1065 SetUpTimer( mNextAutoRepeatingDelay );
1069 Toolkit::Button handle( GetOwner() );
1072 consumed = mReleasedSignal.Emit( handle );
1073 consumed = mClickedSignal.Emit( handle );
1074 consumed |= mPressedSignal.Emit( handle );
1080 void Button::Pressed()
1082 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Pressed\n" );
1084 if( mButtonState == UNSELECTED_STATE )
1086 ChangeState( SELECTED_STATE );
1087 OnPressed(); // Notifies the derived class the button has been pressed.
1091 void Button::Released()
1093 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Released\n" );
1095 if( mButtonState == SELECTED_STATE && !mTogglableButton )
1097 ChangeState( UNSELECTED_STATE );
1098 OnReleased(); // // Notifies the derived class the button has been released.
1100 mButtonPressedState = UNPRESSED;
1103 void Button::SelectRequiredVisual( Property::Index visualIndex )
1105 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SelectRequiredVisual index(%d) state(%d)\n", visualIndex, mButtonState );
1107 DevelControl::EnableVisual( *this, visualIndex, true );
1110 void Button::RemoveVisual( Property::Index visualIndex )
1112 // Use OnButtonVisualRemoval if want button developer to have the option to override removal.
1113 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::RemoveVisual index(%d) state(%d)\n", visualIndex, mButtonState );
1115 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, visualIndex );
1119 DevelControl::EnableVisual( *this, visualIndex, false );
1123 void Button::OnButtonVisualRemoval( Property::Index visualIndex )
1125 // Derived Buttons can over ride this to prevent default removal.
1126 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnButtonVisualRemoval index(%d)\n", visualIndex );
1127 RemoveVisual( visualIndex );
1130 void Button::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
1132 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1134 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetProperty index[%d]\n", index );
1140 case Toolkit::Button::Property::DISABLED:
1142 GetImplementation( button ).SetDisabled( value.Get< bool >() );
1146 case Toolkit::Button::Property::AUTO_REPEATING:
1148 GetImplementation( button ).SetAutoRepeating( value.Get< bool >() );
1152 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1154 GetImplementation( button ).SetInitialAutoRepeatingDelay( value.Get< float >() );
1158 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1160 GetImplementation( button ).SetNextAutoRepeatingDelay( value.Get< float >() );
1164 case Toolkit::Button::Property::TOGGLABLE:
1166 GetImplementation( button ).SetTogglableButton( value.Get< bool >() );
1170 case Toolkit::Button::Property::SELECTED:
1172 GetImplementation( button ).SetSelected( value.Get< bool >() );
1176 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE: // Legacy Tizen 3.0
1178 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1181 case Toolkit::Button::Property::DISABLED_STATE_IMAGE: // Legacy Tizen 3.0
1183 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1186 case Toolkit::Button::Property::SELECTED_STATE_IMAGE: // Legacy Tizen 3.0
1188 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1191 case Toolkit::DevelButton::Property::UNSELECTED_VISUAL:
1192 case Toolkit::DevelButton::Property::SELECTED_VISUAL:
1193 case Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL:
1194 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL:
1196 GetImplementation( button ).CreateVisualsForComponent( index, value, DepthIndex::CONTENT );
1200 case Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL:
1201 case Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL:
1202 case Toolkit::DevelButton::Property::DISABLED_SELECTED_BACKGROUND_VISUAL:
1203 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL:
1205 GetImplementation( button ).CreateVisualsForComponent( index , value, DepthIndex::BACKGROUND);
1209 case Toolkit::Button::Property::UNSELECTED_COLOR:
1211 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::UNSELECTED_COLOR instead use Button::Property::UNSELECTED_BACKGROUND_VISUAL\n", __FUNCTION__);
1212 GetImplementation( button ).SetColor( value.Get< Vector4 >(), Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1216 case Toolkit::Button::Property::SELECTED_COLOR:
1218 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::SELECTED_COLOR instead use Button::Property::SELECTED_BACKGROUND_VISUAL\n", __FUNCTION__);
1219 GetImplementation( button ).SetColor( value.Get< Vector4 >(), Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL );
1223 case Toolkit::Button::Property::LABEL_TEXT:
1225 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::LABEL_TEXT instead use Button::Property::LABEL\n", __FUNCTION__);
1226 GetImplementation( button ).SetLabelText(value.Get< std::string >() );
1230 case Toolkit::Button::Property::LABEL:
1232 Property::Map outTextVisualProperties;
1233 std::string textString;
1235 if ( value.Get( textString ) )
1237 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetProperty Setting TextVisual with string[%s]\n", textString.c_str() );
1239 Property::Map setPropertyMap;
1240 setPropertyMap.Add( Toolkit::Visual::Property::TYPE, Toolkit::Visual::TEXT )
1241 .Add( Toolkit::TextVisual::Property::TEXT, textString );
1243 GetImplementation( button ).MergeWithExistingLabelProperties( setPropertyMap, outTextVisualProperties );
1247 // Get a Property::Map from the property if possible.
1248 Property::Map* setPropertyMap = value.GetMap();
1249 if( setPropertyMap )
1251 TextVisual::ConvertStringKeysToIndexKeys( *setPropertyMap );
1252 GetImplementation( button ).MergeWithExistingLabelProperties( *setPropertyMap, outTextVisualProperties );
1256 if( !outTextVisualProperties.Empty() )
1258 GetImplementation( button ).CreateVisualsForComponent( index, outTextVisualProperties, DepthIndex::CONTENT );
1259 GetImplementation( button ).RelayoutRequest();
1264 case Toolkit::DevelButton::Property::LABEL_RELATIVE_ALIGNMENT:
1266 Button::Align labelAlignment(END);
1267 Scripting::GetEnumeration< Button::Align> ( value.Get< std::string >().c_str(),
1268 ALIGNMENT_TABLE, ALIGNMENT_TABLE_COUNT,
1271 GetImplementation( button ).SetLabelAlignment( labelAlignment );
1272 GetImplementation( button ).RelayoutRequest();
1276 case Toolkit::DevelButton::Property::LABEL_PADDING:
1278 Vector4 padding ( value.Get< Vector4 >() );
1279 GetImplementation( button ).SetLabelPadding( Padding( padding.x, padding.y, padding.z, padding.w ) );
1283 case Toolkit::DevelButton::Property::VISUAL_PADDING:
1285 Vector4 padding ( value.Get< Vector4 >() );
1286 GetImplementation( button ).SetForegroundPadding( Padding( padding.x, padding.y, padding.z, padding.w ) );
1287 GetImplementation( button ).RelayoutRequest();
1294 Property::Value Button::GetProperty( BaseObject* object, Property::Index propertyIndex )
1296 Property::Value value;
1298 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1302 switch ( propertyIndex )
1304 case Toolkit::Button::Property::DISABLED:
1306 value = GetImplementation( button ).IsDisabled();
1310 case Toolkit::Button::Property::AUTO_REPEATING:
1312 value = GetImplementation( button ).mAutoRepeating;
1316 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1318 value = GetImplementation( button ).mInitialAutoRepeatingDelay;
1322 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1324 value = GetImplementation( button ).mNextAutoRepeatingDelay;
1328 case Toolkit::Button::Property::TOGGLABLE:
1330 value = GetImplementation( button ).mTogglableButton;
1334 case Toolkit::Button::Property::SELECTED:
1336 value = GetImplementation( button ).IsSelected();
1340 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1342 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1346 case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1348 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL );
1352 case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1354 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL );
1358 case Toolkit::DevelButton::Property::UNSELECTED_VISUAL:
1359 case Toolkit::DevelButton::Property::SELECTED_VISUAL:
1360 case Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL:
1361 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL:
1362 case Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL:
1363 case Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL:
1364 case Toolkit::DevelButton::Property::DISABLED_SELECTED_BACKGROUND_VISUAL:
1365 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL:
1366 case Toolkit::Button::Property::LABEL:
1368 Property::Map visualProperty;
1369 if ( GetImplementation( button ).GetPropertyMapForVisual( propertyIndex, visualProperty ) )
1371 value = visualProperty;
1376 case Toolkit::Button::Property::UNSELECTED_COLOR:
1378 value = GetImplementation( button ).GetUnselectedColor();
1382 case Toolkit::Button::Property::SELECTED_COLOR:
1384 value = GetImplementation( button ).GetSelectedColor();
1388 case Toolkit::Button::Property::LABEL_TEXT:
1390 value = GetImplementation( button ).GetLabelText();
1394 case Toolkit::DevelButton::Property::LABEL_RELATIVE_ALIGNMENT:
1396 const char* alignment = Scripting::GetEnumerationName< Button::Align >( GetImplementation( button ).GetLabelAlignment(),
1397 ALIGNMENT_STRING_TABLE,
1398 ALIGNMENT_STRING_TABLE_COUNT );
1401 value = std::string( alignment );
1407 case Toolkit::DevelButton::Property::LABEL_PADDING:
1409 Padding padding = GetImplementation( button ).GetLabelPadding();
1410 value = Vector4( padding.x, padding.y, padding.top, padding.bottom);
1414 case Toolkit::DevelButton::Property::VISUAL_PADDING:
1416 Padding padding = GetImplementation( button ).GetForegroundPadding();
1417 value = Vector4( padding.x, padding.y, padding.top, padding.bottom);
1425 void Button::SetLabelPadding( const Padding& padding)
1427 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetLabelPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top );
1428 mLabelPadding = Padding( padding.left, padding.right, padding.bottom, padding.top );
1432 Padding Button::GetLabelPadding()
1434 return mLabelPadding;
1437 void Button::SetForegroundPadding( const Padding& padding)
1439 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetForegroundPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top );
1440 mForegroundPadding = Padding( padding.left, padding.right, padding.bottom, padding.top );
1444 Padding Button::GetForegroundPadding()
1446 return mForegroundPadding;
1449 ////////////////////////////////////////////////////////////////////////
1450 // Legacy functions from Tizen 2.4 and 3.0
1452 // Legacy code needed whilst Color can be set by direct Property setting ( deprecated ) instead of setting a Visual
1453 void Button::SetColor( const Vector4& color, Property::Index visualIndex )
1455 if ( visualIndex == Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL )
1457 mSelectedColor = color;
1461 mUnselectedColor = color;
1465 map[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::COLOR;
1466 map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color;
1468 CreateVisualsForComponent( visualIndex, map, DepthIndex::BACKGROUND );
1471 const Vector4 Button::GetUnselectedColor() const
1473 return mUnselectedColor;
1476 const Vector4 Button::GetSelectedColor() const
1478 return mSelectedColor;
1481 void Button::SetAnimationTime( float animationTime )
1483 // Used by deprecated API
1484 mAnimationTime = animationTime;
1487 float Button::GetAnimationTime() const
1489 // Used by deprecated API
1490 return mAnimationTime;
1493 void Button::SetLabel( Actor label )
1497 Property::Value value ="";
1498 value = label.GetProperty(Toolkit::TextLabel::Property::TEXT);
1500 SetLabelText( value.Get<std::string>() );
1504 void Button::SetUnselectedImage( const std::string& filename )
1506 SetBackgroundImage( filename );
1509 void Button::SetBackgroundImage( const std::string& filename )
1511 if( !filename.empty() )
1513 CreateVisualsForComponent( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1517 DevelControl::UnregisterVisual( *this, Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1521 void Button::SetSelectedImage( const std::string& filename )
1523 SetSelectedBackgroundImage( filename );
1526 void Button::SetSelectedBackgroundImage( const std::string& filename )
1528 if( !filename.empty() )
1530 CreateVisualsForComponent( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1534 DevelControl::UnregisterVisual( *this, Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1538 void Button::SetDisabledBackgroundImage( const std::string& filename )
1540 if( !filename.empty() )
1542 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1546 void Button::SetDisabledImage( const std::string& filename )
1548 if( !filename.empty() )
1550 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL, filename, DepthIndex::CONTENT );
1554 void Button::SetDisabledSelectedImage( const std::string& filename )
1556 if( !filename.empty() )
1558 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL, filename, DepthIndex::CONTENT );
1562 // Used by Deprecated Properties which don't use the Visual Property maps for setting and getting
1563 std::string Button::GetUrlForImageVisual( const Property::Index index ) const
1565 Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, index );
1570 Dali::Property::Map retreivedMap;
1571 visual.CreatePropertyMap( retreivedMap );
1572 Property::Value* value = retreivedMap.Find( Toolkit::ImageVisual::Property::URL, Property::STRING );
1575 result = value->Get<std::string>();
1582 // Below functions DEPRECATED_1_0.50 - Return empty Actors
1586 std::string GetUrlFromImage( Image& image )
1588 ResourceImage resourceImage = ResourceImage::DownCast( image );
1590 std::string imageUrl;
1592 if ( resourceImage )
1594 imageUrl = resourceImage.GetUrl();
1602 void Button::SetButtonImage( Image image )
1604 DALI_LOG_WARNING("Button::SetButtonImage @DEPRECATED_1_0.50\n");
1605 SetUnselectedImage( GetUrlFromImage( image ) );
1606 mSetButtonImage = image;
1609 void Button::SetSelectedImage( Image image )
1611 DALI_LOG_WARNING("Button::SetSelectedImage @DEPRECATED_1_0.50\n");
1612 SetSelectedImage( GetUrlFromImage( image ) );
1613 mSetSelectedImage = image;
1616 Actor Button::GetButtonImage() const
1618 // When deprecated ImageView API removed then this button API can be removed too.
1619 DALI_LOG_WARNING("Button::GetButtonImage @DEPRECATED_1_0.50\n");
1623 if ( mSetButtonImage )
1625 imageView = Toolkit::ImageView::New( mSetButtonImage );
1629 ResourceImage image = ResourceImage::New( GetUrlForImageVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL ) );
1630 imageView = Toolkit::ImageView::New( image );
1636 Actor Button::GetSelectedImage() const
1638 // When deprecated ImageView API removed then this button API can be removed too.
1639 DALI_LOG_WARNING("Button::GetSelectedImage @DEPRECATED_1_0.50\n");
1643 if ( mSetSelectedImage )
1645 imageView = Toolkit::ImageView::New( mSetSelectedImage );
1649 ResourceImage image = ResourceImage::New( GetUrlForImageVisual( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL ) );
1650 imageView = Toolkit::ImageView::New( image );
1655 } // namespace Internal
1657 } // namespace Toolkit