2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "button-impl.h"
22 #include <cstring> // for strcmp
23 #include <dali/devel-api/scripting/enum-helper.h>
24 #include <dali/integration-api/debug.h>
25 #include <dali/public-api/events/touch-data.h>
26 #include <dali/public-api/images/resource-image.h>
27 #include <dali/public-api/object/type-registry.h>
28 #include <dali/public-api/object/type-registry-helper.h>
29 #include <dali/public-api/size-negotiation/relayout-container.h>
30 #include <dali/devel-api/object/property-helper-devel.h>
31 #include <dali/devel-api/scripting/scripting.h>
34 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
35 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
36 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
37 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
38 #include <dali-toolkit/devel-api/align-enums.h>
39 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
40 #include <dali-toolkit/devel-api/controls/buttons/button-devel.h>
41 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
42 #include <dali-toolkit/internal/visuals/text/text-visual.h>
43 #include <dali-toolkit/devel-api/visuals/text-visual-properties.h>
44 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
46 #if defined(DEBUG_ENABLED)
47 Debug::Filter* gLogButtonFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_BUTTON_CONTROL");
64 // empty handle as we cannot create button (but type registered for clicked signal)
68 // Setup properties, signals and actions using the type-registry.
69 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Button, Toolkit::Control, Create )
71 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabled", BOOLEAN, DISABLED )
72 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "autoRepeating", BOOLEAN, AUTO_REPEATING )
73 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "initialAutoRepeatingDelay", FLOAT, INITIAL_AUTO_REPEATING_DELAY )
74 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "nextAutoRepeatingDelay", FLOAT, NEXT_AUTO_REPEATING_DELAY )
75 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "togglable", BOOLEAN, TOGGLABLE )
76 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selected", BOOLEAN, SELECTED )
77 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedStateImage", MAP, UNSELECTED_STATE_IMAGE ) // Deprecated property
78 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedStateImage", MAP, SELECTED_STATE_IMAGE ) // Deprecated property
79 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledStateImage", MAP, DISABLED_STATE_IMAGE ) // Deprecated property
80 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedColor", VECTOR4, UNSELECTED_COLOR ) // Deprecated property
81 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedColor", VECTOR4, SELECTED_COLOR ) // Deprecated property
82 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "label", MAP, LABEL )
83 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "labelText", STRING, LABEL_TEXT ) // Deprecated property
84 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedVisual", MAP, UNSELECTED_VISUAL )
85 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "selectedVisual", MAP, SELECTED_VISUAL )
86 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledSelectedVisual", MAP, DISABLED_SELECTED_VISUAL )
87 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledUnselectedVisual", MAP, DISABLED_UNSELECTED_VISUAL )
88 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedBackgroundVisual", MAP, UNSELECTED_BACKGROUND_VISUAL )
89 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "selectedBackgroundVisual", MAP, SELECTED_BACKGROUND_VISUAL )
90 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledUnselectedBackgroundVisual", MAP, DISABLED_UNSELECTED_BACKGROUND_VISUAL )
91 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledSelectedBackgroundVisual", MAP, DISABLED_SELECTED_BACKGROUND_VISUAL )
92 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "labelRelativeAlignment", STRING, LABEL_RELATIVE_ALIGNMENT )
93 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "labelPadding", VECTOR4, LABEL_PADDING )
94 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "visualPadding", VECTOR4, VISUAL_PADDING )
97 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "pressed", SIGNAL_PRESSED )
98 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "released", SIGNAL_RELEASED )
99 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "clicked", SIGNAL_CLICKED )
100 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "stateChanged", SIGNAL_STATE_CHANGED )
103 DALI_ACTION_REGISTRATION( Toolkit, Button, "buttonClick", ACTION_BUTTON_CLICK )
105 DALI_TYPE_REGISTRATION_END()
107 DALI_ENUM_TO_STRING_TABLE_BEGIN( ALIGNMENT )
108 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, BEGIN )
109 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, END )
110 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, TOP )
111 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, BOTTOM )
112 DALI_ENUM_TO_STRING_TABLE_END( ALIGNMENT )
114 const Scripting::StringEnum ALIGNMENT_STRING_TABLE[] =
116 { "BEGIN", Button::BEGIN },
117 { "END", Button::END },
118 { "TOP", Button::TOP },
119 { "BOTTOM", Button::BOTTOM },
122 const unsigned int ALIGNMENT_STRING_TABLE_COUNT = sizeof( ALIGNMENT_STRING_TABLE ) / sizeof( ALIGNMENT_STRING_TABLE[0] );
124 const Property::Index GET_VISUAL_INDEX_FOR_STATE[][Button::STATE_COUNT] =
126 { Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, Toolkit::DevelButton::Property::UNSELECTED_VISUAL },
127 { Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, Toolkit::DevelButton::Property::SELECTED_VISUAL },
128 { Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL },
129 { Toolkit::DevelButton::Property::DISABLED_SELECTED_BACKGROUND_VISUAL, Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL }
133 * Checks if given map contains a text string
135 bool MapContainsTextString( Property::Map& map )
138 Property::Value* value = map.Find( Toolkit::TextVisual::Property::TEXT );
141 std::string textString;
142 value->Get( textString );
143 if ( !textString.empty() )
151 } // unnamed namespace
154 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
155 mAutoRepeatingTimer(),
156 mTextLabelAlignment( END ),
157 mAutoRepeating( false ),
158 mTogglableButton( false ),
159 mTextStringSetFlag( false ),
160 mInitialAutoRepeatingDelay( 0.0f ),
161 mNextAutoRepeatingDelay( 0.0f ),
162 mAnimationTime( 0.0f ),
163 mButtonPressedState( UNPRESSED ),
164 mButtonState( UNSELECTED_STATE ),
165 mPreviousButtonState( mButtonState ),
166 mClickActionPerforming( false )
174 void Button::SetAutoRepeating( bool autoRepeating )
176 mAutoRepeating = autoRepeating;
178 // An autorepeating button can't be a toggle button.
183 SetSelected( false ); // UnSelect before switching off Toggle feature.
185 mTogglableButton = false;
189 bool Button::IsAutoRepeating() const
191 return mAutoRepeating;
194 void Button::SetInitialAutoRepeatingDelay( float initialAutoRepeatingDelay )
196 DALI_ASSERT_DEBUG( initialAutoRepeatingDelay > 0.f );
197 mInitialAutoRepeatingDelay = initialAutoRepeatingDelay;
200 float Button::GetInitialAutoRepeatingDelay() const
202 return mInitialAutoRepeatingDelay;
205 void Button::SetNextAutoRepeatingDelay( float nextAutoRepeatingDelay )
207 DALI_ASSERT_DEBUG( nextAutoRepeatingDelay > 0.f );
208 mNextAutoRepeatingDelay = nextAutoRepeatingDelay;
211 float Button::GetNextAutoRepeatingDelay() const
213 return mNextAutoRepeatingDelay;
216 void Button::SetTogglableButton( bool togglable )
218 mTogglableButton = togglable;
220 // A toggle button can't be an autorepeating button.
223 mAutoRepeating = false;
227 bool Button::IsTogglableButton() const
229 return mTogglableButton;
232 void Button::SetSelected( bool selected )
234 if( mTogglableButton )
236 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetSelected (%s)\n", (selected?"true":"false") );
238 if ( selected && ( mButtonState != SELECTED_STATE ) )
240 ChangeState( SELECTED_STATE );
242 else if ( !selected && ( mButtonState != UNSELECTED_STATE ) )
244 ChangeState( UNSELECTED_STATE );
249 void Button::SetDisabled( bool disabled )
251 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetDisabled(%s) state(%d)\n", (disabled)?"disabled":"active", mButtonState );
255 if ( mButtonState == SELECTED_STATE )
257 ChangeState( DISABLED_SELECTED_STATE );
259 else if ( mButtonState == UNSELECTED_STATE )
261 ChangeState( DISABLED_UNSELECTED_STATE );
266 if ( mButtonState == DISABLED_SELECTED_STATE )
268 ChangeState( SELECTED_STATE );
270 else if ( mButtonState == DISABLED_UNSELECTED_STATE )
272 ChangeState( UNSELECTED_STATE );
277 bool Button::IsDisabled() const
279 return ( mButtonState == DISABLED_SELECTED_STATE || mButtonState == DISABLED_UNSELECTED_STATE ) ;
282 bool Button::ValidateState( State requestedState )
284 /* Below tables shows allowed state transitions
285 * Match rows in first column to following columns, if true then transition allowed.
286 * eg UNSELECTED_STATE to DISABLED_UNSELECTED_STATE is true so state transition allowed.
288 to| UNSELECTED_STATE | SELECTED_STATE | DISABLED_UNSELECTED_STATE | DISABLED_SELECTED_STATE |*/
290 bool transitionTable[4][4] = { /* UNSELECTED_STATE*/ { false, true, true, false },
291 /* SELECTED_STATE*/ { true, false, false, true },
292 /* DISABLED_UNSELECTED_STATE*/{ true, true, false, false },
293 /* DISABLED_SELECTED_STATE*/ { false, true, false, false }
296 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ValidateState ReuestedState:%d, CurrentState:%d, result:%s\n",
297 requestedState, mButtonState, (transitionTable[mButtonState][requestedState])?"change-accepted":"change-denied");
299 return transitionTable[mButtonState][requestedState];
302 void Button::PerformFunctionOnVisualsInState( void(Button::*functionPtr)( Property::Index visualIndex), State state )
304 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::PerformFunctionOnVisualsInState BACKROUND visual(%d) for state (%d)\n",
305 GET_VISUAL_INDEX_FOR_STATE[state][BACKGROUND], state );
306 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::PerformFunctionOnVisualsInState FOREGROUND visuals(%d) for state (%d)\n",
307 GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND], state );
309 (this->*functionPtr)( GET_VISUAL_INDEX_FOR_STATE[state][BACKGROUND] );
310 (this->*functionPtr)( GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND] );
315 void Button::ChangeState( State requestedState )
317 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ChangeState ReuestedState(%d)\n", requestedState );
319 // Validate State before changing
320 if ( !ValidateState( requestedState ))
322 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ChangeState ReuestedState(%d) not validated\n", requestedState );
326 // If not on stage the button could have still been set to selected so update state
327 mPreviousButtonState = mButtonState; // Store previous state for visual removal (used when animations ended)
328 mButtonState = requestedState; // Update current state
330 if ( Self().OnStage() )
332 OnStateChange( mButtonState ); // Notify derived buttons
333 PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState );
334 // If animation supported then visual removal should be performed after any transition animation has completed.
335 // If Required Visual is not loaded before current visual is removed then a flickering will be evident.
336 PerformFunctionOnVisualsInState( &Button::OnButtonVisualRemoval, mPreviousButtonState ); // Derived button can override OnButtonVisualRemoval
339 Toolkit::Button handle( GetOwner() );
341 mStateChangedSignal.Emit( handle );
344 bool Button::IsSelected() const
346 bool selected = ( mButtonState == SELECTED_STATE ) || ( mButtonState == DISABLED_SELECTED_STATE );
347 return mTogglableButton && selected;
350 void Button::SetLabelText( const std::string& label )
352 Self().SetProperty( Toolkit::Button::Property::LABEL, label );
355 std::string Button::GetLabelText() const
357 Property::Value value = Self().GetProperty( Toolkit::Button::Property::LABEL );
359 Property::Map *labelProperty = value.GetMap();
361 std::string textLabel;
365 Property::Value* value = labelProperty->Find( Toolkit::TextVisual::Property::TEXT );
368 value->Get( textLabel );
375 void Button::MergeWithExistingLabelProperties( const Property::Map& inMap, Property::Map& outMap )
377 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties with %d properties\n", inMap.Count() );
380 * Properties for the Label visual could be from a style sheet but after being set the "TEXT" property could be set.
381 * Hence would need to create the Text Visual with the complete merged set of properties.
383 * 1) Find Label Visual
384 * 2) Retrieve current properties ( settings )
385 * 3) Merge with new properties ( settings )
386 * 4) Return new merged map
388 Toolkit::Visual::Base visual = GetVisual( Toolkit::Button::Property::LABEL );
391 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties Visual already exists, retrieving existing map\n");
392 visual.CreatePropertyMap( outMap );
393 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties retrieved %d properties\n", outMap.Count() );
396 outMap.Merge( inMap );
398 // Store if a text string has been supplied.
400 mTextStringSetFlag = MapContainsTextString( outMap );
402 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties now has %d properties\n", outMap.Count() );
405 void Button::SetLabelAlignment( Button::Align labelAlignment)
407 mTextLabelAlignment = labelAlignment;
411 Button::Align Button::GetLabelAlignment()
413 return mTextLabelAlignment;
417 * Create Visual for given index from a property map or url.
418 * 1) Check if value passed in is a url and create visual
419 * 2) Create visual from map if step (1) is false
420 * 3) Register visual with control with false for enable flag. Button will later enable visual when needed ( Button::SelectRequiredVisual )
421 * 4) Unregister visual if empty map was provided. This is the method to remove a visual
424 void Button::CreateVisualsForComponent( Property::Index index, const Property::Value& value, const float visualDepth )
426 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent index(%d)\n", index );
427 Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
428 Toolkit::Visual::Base buttonVisual;
430 std::string imageUrl;
431 if( value.Get( imageUrl ) )
433 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent Using image URL(%d)\n", index );
434 if ( !imageUrl.empty() )
436 DALI_ASSERT_DEBUG( index != Toolkit::Button::Property::LABEL && "Creating a Image Visual instead of Text Visual " );
437 buttonVisual = visualFactory.CreateVisual( imageUrl, ImageDimensions() );
442 // if its not a string then get a Property::Map from the property if possible.
443 Property::Map *map = value.GetMap();
444 if( map && !map->Empty() ) // Empty map results in current visual removal.
446 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent Using Map(%d)\n", index );
447 buttonVisual = visualFactory.CreateVisual( *map );
453 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent RegisterVisual index(%d) enabled(%s)\n",
454 index, IsVisualEnabled( index )?"true":"false" );
455 buttonVisual.SetDepthIndex( visualDepth );
456 RegisterVisual( index, buttonVisual, IsVisualEnabled( index ) );
460 UnregisterVisual( 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 = GetVisual( 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 = GetVisual( 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 = GetVisual( 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 = GetVisual( 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 = GetVisual( GET_VISUAL_INDEX_FOR_STATE[mButtonState][FOREGROUND] );
888 Toolkit::Visual::Base currentBackGroundVisual = GetVisual( 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::DevelVisual::Transform::Property::SIZE, size )
986 .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::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::DevelVisual::Transform::Property::SIZE, visualSize )
998 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET, visualPosition )
999 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
1000 .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
1001 .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
1002 .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, visualAnchorPoint );
1004 currentVisual.SetTransformAndSize( visualTransform, size );
1007 if ( mTextStringSetFlag )
1009 Toolkit::Visual::Base textVisual = GetVisual( 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::DevelVisual::Transform::Property::SIZE, preSize )
1029 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET, labelPosition )
1030 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
1031 .Add( Toolkit::DevelVisual::Transform::Property::SIZE_POLICY, Vector2( DevelVisual::Transform::Policy::ABSOLUTE, DevelVisual::Transform::Policy::ABSOLUTE ) )
1032 .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
1033 .Add( Toolkit::DevelVisual::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 EnableVisual( 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 = GetVisual( visualIndex );
1116 EnableVisual( 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::DevelVisual::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 UnregisterVisual( 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 UnregisterVisual( 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 = GetVisual( 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