2 * Copyright (c) 2016 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/devel-api/visuals/text-visual-properties.h>
43 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
45 #if defined(DEBUG_ENABLED)
46 Debug::Filter* gLogButtonFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_BUTTON_CONTROL");
63 // empty handle as we cannot create button (but type registered for clicked signal)
67 // Setup properties, signals and actions using the type-registry.
68 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Button, Toolkit::Control, Create )
70 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabled", BOOLEAN, DISABLED )
71 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "autoRepeating", BOOLEAN, AUTO_REPEATING )
72 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "initialAutoRepeatingDelay", FLOAT, INITIAL_AUTO_REPEATING_DELAY )
73 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "nextAutoRepeatingDelay", FLOAT, NEXT_AUTO_REPEATING_DELAY )
74 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "togglable", BOOLEAN, TOGGLABLE )
75 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selected", BOOLEAN, SELECTED )
76 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedStateImage", MAP, UNSELECTED_STATE_IMAGE ) // Deprecated property
77 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedStateImage", MAP, SELECTED_STATE_IMAGE ) // Deprecated property
78 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledStateImage", MAP, DISABLED_STATE_IMAGE ) // Deprecated property
79 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedColor", VECTOR4, UNSELECTED_COLOR ) // Deprecated property
80 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedColor", VECTOR4, SELECTED_COLOR ) // Deprecated property
81 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "label", MAP, LABEL )
82 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "labelText", STRING, LABEL_TEXT ) // Deprecated property
83 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedVisual", MAP, UNSELECTED_VISUAL )
84 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "selectedVisual", MAP, SELECTED_VISUAL )
85 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledSelectedVisual", MAP, DISABLED_SELECTED_VISUAL )
86 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledUnselectedVisual", MAP, DISABLED_UNSELECTED_VISUAL )
87 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedBackgroundVisual", MAP, UNSELECTED_BACKGROUND_VISUAL )
88 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "selectedBackgroundVisual", MAP, SELECTED_BACKGROUND_VISUAL )
89 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledUnselectedBackgroundVisual", MAP, DISABLED_UNSELECTED_BACKGROUND_VISUAL )
90 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "disabledSelectedBackgroundVisual", MAP, DISABLED_SELECTED_BACKGROUND_VISUAL )
91 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "labelRelativeAlignment", STRING, LABEL_RELATIVE_ALIGNMENT )
92 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "labelPadding", VECTOR4, LABEL_PADDING )
93 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, Button, "visualPadding", VECTOR4, VISUAL_PADDING )
96 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "pressed", SIGNAL_PRESSED )
97 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "released", SIGNAL_RELEASED )
98 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "clicked", SIGNAL_CLICKED )
99 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "stateChanged", SIGNAL_STATE_CHANGED )
102 DALI_ACTION_REGISTRATION( Toolkit, Button, "buttonClick", ACTION_BUTTON_CLICK )
104 DALI_TYPE_REGISTRATION_END()
106 DALI_ENUM_TO_STRING_TABLE_BEGIN( ALIGNMENT )
107 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, BEGIN )
108 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, END )
109 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, TOP )
110 DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, BOTTOM )
111 DALI_ENUM_TO_STRING_TABLE_END( ALIGNMENT )
113 const Scripting::StringEnum ALIGNMENT_STRING_TABLE[] =
115 { "BEGIN", Button::BEGIN },
116 { "END", Button::END },
117 { "TOP", Button::TOP },
118 { "BOTTOM", Button::BOTTOM },
121 const unsigned int ALIGNMENT_STRING_TABLE_COUNT = sizeof( ALIGNMENT_STRING_TABLE ) / sizeof( ALIGNMENT_STRING_TABLE[0] );
123 const Property::Index GET_VISUAL_INDEX_FOR_STATE[][Button::STATE_COUNT] =
125 { Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, Toolkit::DevelButton::Property::UNSELECTED_VISUAL },
126 { Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, Toolkit::DevelButton::Property::SELECTED_VISUAL },
127 { Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL },
128 { Toolkit::DevelButton::Property::DISABLED_SELECTED_BACKGROUND_VISUAL, Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL }
132 * Checks if given map contains a text string
134 bool MapContainsTextString( Property::Map& map )
137 Property::Value* value = map.Find( Toolkit::TextVisual::Property::TEXT );
140 std::string textString;
141 value->Get( textString );
142 if ( !textString.empty() )
150 } // unnamed namespace
153 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
154 mAutoRepeatingTimer(),
155 mTextLabelAlignment( END ),
156 mAutoRepeating( false ),
157 mTogglableButton( false ),
158 mTextStringSetFlag( false ),
159 mInitialAutoRepeatingDelay( 0.0f ),
160 mNextAutoRepeatingDelay( 0.0f ),
161 mAnimationTime( 0.0f ),
162 mButtonPressedState( UNPRESSED ),
163 mButtonState( UNSELECTED_STATE ),
164 mPreviousButtonState( mButtonState ),
165 mClickActionPerforming( false )
173 void Button::SetAutoRepeating( bool autoRepeating )
175 mAutoRepeating = autoRepeating;
177 // An autorepeating button can't be a toggle button.
182 SetSelected( false ); // UnSelect before switching off Toggle feature.
184 mTogglableButton = false;
188 bool Button::IsAutoRepeating() const
190 return mAutoRepeating;
193 void Button::SetInitialAutoRepeatingDelay( float initialAutoRepeatingDelay )
195 DALI_ASSERT_DEBUG( initialAutoRepeatingDelay > 0.f );
196 mInitialAutoRepeatingDelay = initialAutoRepeatingDelay;
199 float Button::GetInitialAutoRepeatingDelay() const
201 return mInitialAutoRepeatingDelay;
204 void Button::SetNextAutoRepeatingDelay( float nextAutoRepeatingDelay )
206 DALI_ASSERT_DEBUG( nextAutoRepeatingDelay > 0.f );
207 mNextAutoRepeatingDelay = nextAutoRepeatingDelay;
210 float Button::GetNextAutoRepeatingDelay() const
212 return mNextAutoRepeatingDelay;
215 void Button::SetTogglableButton( bool togglable )
217 mTogglableButton = togglable;
219 // A toggle button can't be an autorepeating button.
222 mAutoRepeating = false;
226 bool Button::IsTogglableButton() const
228 return mTogglableButton;
231 void Button::SetSelected( bool selected )
233 if( mTogglableButton )
235 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetSelected (%s)\n", (selected?"true":"false") );
237 if ( selected && ( mButtonState != SELECTED_STATE ) )
239 ChangeState( SELECTED_STATE );
241 else if ( !selected && ( mButtonState != UNSELECTED_STATE ) )
243 ChangeState( UNSELECTED_STATE );
248 void Button::SetDisabled( bool disabled )
250 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetDisabled(%s) state(%d)\n", (disabled)?"disabled":"active", mButtonState );
254 if ( mButtonState == SELECTED_STATE )
256 ChangeState( DISABLED_SELECTED_STATE );
258 else if ( mButtonState == UNSELECTED_STATE )
260 ChangeState( DISABLED_UNSELECTED_STATE );
265 if ( mButtonState == DISABLED_SELECTED_STATE )
267 ChangeState( SELECTED_STATE );
269 else if ( mButtonState == DISABLED_UNSELECTED_STATE )
271 ChangeState( UNSELECTED_STATE );
276 bool Button::IsDisabled() const
278 return ( mButtonState == DISABLED_SELECTED_STATE || mButtonState == DISABLED_UNSELECTED_STATE ) ;
281 bool Button::ValidateState( State requestedState )
283 /* Below tables shows allowed state transitions
284 * Match rows in first column to following columns, if true then transition allowed.
285 * eg UNSELECTED_STATE to DISABLED_UNSELECTED_STATE is true so state transition allowed.
287 to| UNSELECTED_STATE | SELECTED_STATE | DISABLED_UNSELECTED_STATE | DISABLED_SELECTED_STATE |*/
289 bool transitionTable[4][4] = { /* UNSELECTED_STATE*/ { false, true, true, false },
290 /* SELECTED_STATE*/ { true, false, false, true },
291 /* DISABLED_UNSELECTED_STATE*/{ true, true, false, false },
292 /* DISABLED_SELECTED_STATE*/ { false, true, false, false }
295 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ValidateState ReuestedState:%d, CurrentState:%d, result:%s\n",
296 requestedState, mButtonState, (transitionTable[mButtonState][requestedState])?"change-accepted":"change-denied");
298 return transitionTable[mButtonState][requestedState];
301 void Button::PerformFunctionOnVisualsInState( void(Button::*functionPtr)( Property::Index visualIndex), State state )
303 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::PerformFunctionOnVisualsInState BACKROUND visual(%d) for state (%d)\n",
304 GET_VISUAL_INDEX_FOR_STATE[state][BACKGROUND], state );
305 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::PerformFunctionOnVisualsInState FOREGROUND visuals(%d) for state (%d)\n",
306 GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND], state );
308 (this->*functionPtr)( GET_VISUAL_INDEX_FOR_STATE[state][BACKGROUND] );
309 (this->*functionPtr)( GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND] );
314 void Button::ChangeState( State requestedState )
316 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ChangeState ReuestedState(%d)\n", requestedState );
318 // Validate State before changing
319 if ( !ValidateState( requestedState ))
321 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ChangeState ReuestedState(%d) not validated\n", requestedState );
325 // If not on stage the button could have still been set to selected so update state
326 mPreviousButtonState = mButtonState; // Store previous state for visual removal (used when animations ended)
327 mButtonState = requestedState; // Update current state
329 if ( Self().OnStage() )
331 OnStateChange( mButtonState ); // Notify derived buttons
332 PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState );
333 // If animation supported then visual removal should be performed after any transition animation has completed.
334 // If Required Visual is not loaded before current visual is removed then a flickering will be evident.
335 PerformFunctionOnVisualsInState( &Button::OnButtonVisualRemoval, mPreviousButtonState ); // Derived button can override OnButtonVisualRemoval
338 Toolkit::Button handle( GetOwner() );
340 mStateChangedSignal.Emit( handle );
343 bool Button::IsSelected() const
345 bool selected = ( mButtonState == SELECTED_STATE ) || ( mButtonState == DISABLED_SELECTED_STATE );
346 return mTogglableButton && selected;
349 void Button::SetLabelText( const std::string& label )
351 Self().SetProperty( Toolkit::Button::Property::LABEL, label );
354 std::string Button::GetLabelText() const
356 Property::Value value = Self().GetProperty( Toolkit::Button::Property::LABEL );
358 Property::Map *labelProperty = value.GetMap();
360 std::string textLabel;
364 Property::Value* value = labelProperty->Find( Toolkit::TextVisual::Property::TEXT );
365 value->Get( textLabel );
371 void Button::MergeWithExistingLabelProperties( const Property::Map& inMap, Property::Map& outMap )
373 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties with %d properties\n", inMap.Count() );
376 * Properties for the Label visual could be from a style sheet but after being set the "TEXT" property could be set.
377 * Hence would need to create the Text Visual with the complete merged set of properties.
379 * 1) Find Label Visual
380 * 2) Retrieve current properties ( settings )
381 * 3) Merge with new properties ( settings )
382 * 4) Return new merged map
384 Toolkit::Visual::Base visual = GetVisual( Toolkit::Button::Property::LABEL );
387 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties Visual already exists, retrieving existing map\n");
388 visual.CreatePropertyMap( outMap );
389 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties retrieved %d properties\n", outMap.Count() );
392 outMap.Merge( inMap );
394 // Store if a text string has been supplied.
396 mTextStringSetFlag = MapContainsTextString( outMap );
398 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties now has %d properties\n", outMap.Count() );
401 void Button::SetLabelAlignment( Button::Align labelAlignment)
403 mTextLabelAlignment = labelAlignment;
407 Button::Align Button::GetLabelAlignment()
409 return mTextLabelAlignment;
413 * Create Visual for given index from a property map or url.
414 * 1) Check if value passed in is a url and create visual
415 * 2) Create visual from map if step (1) is false
416 * 3) Register visual with control with false for enable flag. Button will later enable visual when needed ( Button::SelectRequiredVisual )
417 * 4) Unregister visual if empty map was provided. This is the method to remove a visual
420 void Button::CreateVisualsForComponent( Property::Index index, const Property::Value& value, const float visualDepth )
422 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent index(%d)\n", index );
423 Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
424 Toolkit::Visual::Base buttonVisual;
426 std::string imageUrl;
427 if( value.Get( imageUrl ) )
429 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent Using image URL(%d)\n", index );
430 if ( !imageUrl.empty() )
432 DALI_ASSERT_DEBUG( index != Toolkit::Button::Property::LABEL && "Creating a Image Visual instead of Text Visual " );
433 buttonVisual = visualFactory.CreateVisual( imageUrl, ImageDimensions() );
438 // if its not a string then get a Property::Map from the property if possible.
439 Property::Map *map = value.GetMap();
440 if( map && !map->Empty() ) // Empty map results in current visual removal.
442 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent Using Map(%d)\n", index );
443 buttonVisual = visualFactory.CreateVisual( *map );
449 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent RegisterVisual index(%d) enabled(%s)\n",
450 index, IsVisualEnabled( index )?"true":"false" );
451 buttonVisual.SetDepthIndex( visualDepth );
452 RegisterVisual( index, buttonVisual, IsVisualEnabled( index ) );
456 UnregisterVisual( index );
457 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "CreateVisualsForComponent Visual not created or empty map (clearing visual).(%d)\n", index);
459 PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState );
462 bool Button::GetPropertyMapForVisual( Property::Index visualIndex, Property::Map& retreivedMap ) const
464 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetPropertyMapForVisual visual(%d)\n", visualIndex);
465 bool success = false;
466 Toolkit::Visual::Base visual = GetVisual( visualIndex );
469 visual.CreatePropertyMap( retreivedMap );
472 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetPropertyMapForVisual %s\n", success?"Success":"Failure");
476 bool Button::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
480 Dali::BaseHandle handle( object );
482 Toolkit::Button button = Toolkit::Button::DownCast( handle );
484 DALI_ASSERT_DEBUG( button );
486 if( 0 == strcmp( actionName.c_str(), ACTION_BUTTON_CLICK ) )
488 ret = GetImplementation( button ).DoClickAction( attributes );
494 bool Button::DoClickAction( const Property::Map& attributes )
496 // Prevents the button signals from doing a recursive loop by sending an action
497 // and re-emitting the signals.
498 if( !mClickActionPerforming )
500 mClickActionPerforming = true;
502 if ( !mTogglableButton )
504 mButtonPressedState = DEPRESSED;
507 mClickActionPerforming = false;
515 void Button::ButtonDown()
517 if( mTogglableButton )
519 if ( mButtonState != SELECTED_STATE )
522 mButtonPressedState = TOGGLE_DEPRESSED;
526 mButtonPressedState = DEPRESSED;
532 mButtonPressedState = DEPRESSED;
535 SetUpTimer( mInitialAutoRepeatingDelay );
539 // The pressed signal should be emitted regardless of toggle mode.
540 Toolkit::Button handle( GetOwner() );
541 mPressedSignal.Emit( handle );
544 void Button::ButtonUp()
546 bool emitSignalsForPressAndReleaseAction = false;
548 if( DEPRESSED == mButtonPressedState )
550 if( mTogglableButton ) // Button up will change state
552 emitSignalsForPressAndReleaseAction = OnToggleReleased(); // Derived toggle buttons can override this to provide custom behaviour
556 Released(); // Button up will result in unselected state
559 mAutoRepeatingTimer.Reset();
561 emitSignalsForPressAndReleaseAction = true;
564 else if ( TOGGLE_DEPRESSED == mButtonPressedState )
566 emitSignalsForPressAndReleaseAction = true; // toggle released after being pressed, a click
569 if ( emitSignalsForPressAndReleaseAction )
571 // The clicked and released signals should be emitted regardless of toggle mode.
572 Toolkit::Button handle( GetOwner() );
573 mReleasedSignal.Emit( handle );
574 mClickedSignal.Emit( handle );
578 bool Button::OnToggleReleased()
580 SetSelected( !IsSelected() );
581 mButtonPressedState = UNPRESSED;
586 void Button::OnTouchPointLeave()
588 if( DEPRESSED == mButtonPressedState )
590 if( !mTogglableButton )
596 mAutoRepeatingTimer.Reset();
600 mButtonPressedState = UNPRESSED;
602 // The released signal should be emitted regardless of toggle mode.
603 Toolkit::Button handle( GetOwner() );
604 mReleasedSignal.Emit( handle );
608 void Button::OnTouchPointInterrupted()
613 Toolkit::Button::ButtonSignalType& Button::PressedSignal()
615 return mPressedSignal;
618 Toolkit::Button::ButtonSignalType& Button::ReleasedSignal()
620 return mReleasedSignal;
623 Toolkit::Button::ButtonSignalType& Button::ClickedSignal()
625 return mClickedSignal;
628 Toolkit::Button::ButtonSignalType& Button::StateChangedSignal()
630 return mStateChangedSignal;
633 bool Button::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
635 Dali::BaseHandle handle( object );
637 bool connected( true );
638 Toolkit::Button button = Toolkit::Button::DownCast( handle );
640 if( 0 == strcmp( signalName.c_str(), SIGNAL_PRESSED ) )
642 button.PressedSignal().Connect( tracker, functor );
644 else if( 0 == strcmp( signalName.c_str(), SIGNAL_RELEASED ) )
646 button.ReleasedSignal().Connect( tracker, functor );
648 else if( 0 == strcmp( signalName.c_str(), SIGNAL_CLICKED ) )
650 button.ClickedSignal().Connect( tracker, functor );
652 else if( 0 == strcmp( signalName.c_str(), SIGNAL_STATE_CHANGED ) )
654 button.StateChangedSignal().Connect( tracker, functor );
658 // signalName does not match any signal
665 void Button::OnInitialize()
667 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnInitialize\n" );
671 mTapDetector = TapGestureDetector::New();
672 mTapDetector.Attach( self );
673 mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
675 self.SetKeyboardFocusable( true );
677 self.TouchSignal().Connect( this, &Button::OnTouch );
680 bool Button::OnAccessibilityActivated()
682 return OnKeyboardEnter();
685 bool Button::OnTouch( Actor actor, const TouchData& touch )
688 // Only events are processed when the button is not disabled and the touch event has only
691 if( !IsDisabled() && ( 1 == touch.GetPointCount() ) )
693 switch( touch.GetState( 0 ) )
695 case PointState::DOWN:
705 case PointState::INTERRUPTED:
707 OnTouchPointInterrupted();
710 case PointState::LEAVE:
715 case PointState::MOTION:
716 case PointState::STATIONARY: // FALLTHROUGH
723 else if( 1 < touch.GetPointCount() )
725 OnTouchPointLeave(); // Notification for derived classes.
727 // Sets the button state to the default
728 mButtonPressedState = UNPRESSED;
734 bool Button::OnKeyboardEnter()
736 // When the enter key is pressed, or button is activated, the click action is performed.
737 Property::Map attributes;
738 bool ret = DoClickAction( attributes );
743 void Button::OnStageDisconnection()
745 if( DEPRESSED == mButtonPressedState )
747 if( !mTogglableButton )
753 mAutoRepeatingTimer.Reset();
758 mButtonPressedState = UNPRESSED;
760 Control::OnStageDisconnection(); // Visuals will be set off stage
763 void Button::OnStageConnection( int depth )
765 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnStageConnection ptr(%p) \n", this );
766 PerformFunctionOnVisualsInState( &Button::OnButtonVisualRemoval, mPreviousButtonState );
767 SelectRequiredVisual( Toolkit::Button::Property::LABEL );
768 PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState );
769 Control::OnStageConnection( depth ); // Enabled visuals will be put on stage
772 Vector3 Button::GetNaturalSize()
774 Vector3 size = Vector3::ZERO;
776 bool horizontalAlignment = mTextLabelAlignment == BEGIN || mTextLabelAlignment == END; // label and visual side by side
778 // Get natural size of foreground ( largest of the possible visuals )
779 Size largestProvidedVisual;
780 Size labelSize = Size::ZERO;
782 bool foreGroundVisualUsed = false;
784 for ( int state = Button::UNSELECTED_STATE; state < Button::STATE_COUNT; state++ )
786 Toolkit::Visual::Base visual = GetVisual( GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND] );
790 visual.GetNaturalSize( visualSize );
791 largestProvidedVisual.width = std::max(largestProvidedVisual.width, visualSize.width );
792 largestProvidedVisual.height = std::max(largestProvidedVisual.height, visualSize.height );
793 foreGroundVisualUsed = true;
797 if ( !foreGroundVisualUsed ) // If foreground visual not supplied then use the background visual to calculate Natural size
799 for ( int state = Button::UNSELECTED_STATE; state < Button::STATE_COUNT; state++ )
801 Toolkit::Visual::Base visual = GetVisual( GET_VISUAL_INDEX_FOR_STATE[state][BACKGROUND] );
805 visual.GetNaturalSize( visualSize );
806 largestProvidedVisual.width = std::max(largestProvidedVisual.width, visualSize.width );
807 largestProvidedVisual.height = std::max(largestProvidedVisual.height, visualSize.height );
812 // Get horizontal padding total
813 if ( largestProvidedVisual.width > 0 ) // if visual exists
815 size.width += largestProvidedVisual.width + mForegroundPadding.left + mForegroundPadding.right;
817 // Get vertical padding total
818 if ( largestProvidedVisual.height > 0 )
820 size.height += largestProvidedVisual.height + mForegroundPadding.top + mForegroundPadding.bottom;
823 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize visual Size(%f,%f)\n",
824 largestProvidedVisual.width, largestProvidedVisual.height );
826 // Get natural size of label if text has been set
827 if ( mTextStringSetFlag )
829 Toolkit::Visual::Base visual = GetVisual( Toolkit::Button::Property::LABEL );
833 visual.GetNaturalSize( labelSize );
835 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize labelSize(%f,%f) padding(%f,%f)\n",
836 labelSize.width, labelSize.height, mLabelPadding.left + mLabelPadding.right, mLabelPadding.top + mLabelPadding.bottom);
838 labelSize.width += mLabelPadding.left + mLabelPadding.right;
839 labelSize.height += mLabelPadding.top + mLabelPadding.bottom;
841 // Add label size to height or width depending on alignment position
842 if ( horizontalAlignment )
844 size.width += labelSize.width;
845 size.height = std::max(size.height, labelSize.height );
849 size.height += labelSize.height;
850 size.width = std::max(size.width, labelSize.width );
855 if( size.width < 1 && size.height < 1 )
857 // if no image or label then use Control's natural size
858 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize Using control natural size\n");
859 size = Control::GetNaturalSize();
862 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "Button GetNaturalSize (%f,%f)\n", size.width, size.height );
867 void Button::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
869 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnSetResizePolicy\n");
874 * Visuals are sized and positioned in this function.
875 * Whilst the control has it's size negotiated it has to size it's visuals explicitly here.
878 void Button::OnRelayout( const Vector2& size, RelayoutContainer& container )
880 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout targetSize(%f,%f) ptr(%p) state[%d]\n", size.width, size.height, this, mButtonState );
882 Toolkit::Visual::Base currentVisual = GetVisual( GET_VISUAL_INDEX_FOR_STATE[mButtonState][FOREGROUND] );
884 Toolkit::Visual::Base currentBackGroundVisual = GetVisual( GET_VISUAL_INDEX_FOR_STATE[mButtonState][BACKGROUND] );
886 // Sizes and padding set to zero, if not present then values will no effect calculations.
887 Vector2 visualPosition = Vector2::ZERO;
888 Vector2 labelPosition = Vector2::ZERO;
889 Size visualSize = Size::ZERO;
890 Padding foregroundVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f );
891 Padding labelVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f );
893 if ( mTextStringSetFlag )
895 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Label padding setting padding:%f,%f,%f,%f\n", mLabelPadding.y, mLabelPadding.x, mLabelPadding.width,mLabelPadding.height );
896 labelVisualPadding = mLabelPadding;
901 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Foreground Visual setting padding:%f,%f,%f,%f\n", mForegroundPadding.y, mForegroundPadding.x, mForegroundPadding.width,mForegroundPadding.height );
902 currentVisual.GetNaturalSize( visualSize );
903 foregroundVisualPadding = mForegroundPadding;
906 Toolkit::Align::Type visualAnchorPoint = Toolkit::Align::TOP_BEGIN;
908 Vector2 visualAndPaddingSize = Vector2( ( foregroundVisualPadding.x + visualSize.width + foregroundVisualPadding.y ),
909 ( foregroundVisualPadding.width + visualSize.height + foregroundVisualPadding.height ));
911 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout visualAndPaddingSize(%f,%f)\n", visualAndPaddingSize.width, visualAndPaddingSize.height);
913 // Text Visual should take all space available after foreground visual size and all padding is considered.
914 // Remaining Space priority, Foreground padding, foreground visual, Text padding then Text visual.
915 Size remainingSpaceForText = Size::ZERO;
917 switch ( mTextLabelAlignment )
921 visualAnchorPoint = Toolkit::Align::TOP_END;
922 visualPosition.x = foregroundVisualPadding.right;
923 visualPosition.y = foregroundVisualPadding.top;
925 labelPosition.x = labelVisualPadding.x;
926 labelPosition.y = labelVisualPadding.top;
928 remainingSpaceForText.width = size.width - visualAndPaddingSize.width - labelVisualPadding.x - labelVisualPadding.y;
929 remainingSpaceForText.height = size.height - labelVisualPadding.top - labelVisualPadding.bottom;
934 visualAnchorPoint = Toolkit::Align::TOP_BEGIN;
935 visualPosition.x = foregroundVisualPadding.left;
936 visualPosition.y = foregroundVisualPadding.top;
938 labelPosition.x = visualAndPaddingSize.width + labelVisualPadding.x;
939 labelPosition.y = labelVisualPadding.top;
941 remainingSpaceForText.width = size.width - visualAndPaddingSize.width - labelVisualPadding.x - labelVisualPadding.y;
942 remainingSpaceForText.height = size.height - labelVisualPadding.top - labelVisualPadding.bottom;
947 visualAnchorPoint = Toolkit::Align::BOTTOM_END;
948 visualPosition.x = foregroundVisualPadding.left;
949 visualPosition.y = foregroundVisualPadding.bottom;
951 labelPosition.x = labelVisualPadding.left;
952 labelPosition.y = labelVisualPadding.top;
954 remainingSpaceForText.width = size.width - labelVisualPadding.x - labelVisualPadding.y;
955 remainingSpaceForText.height = size.height - visualAndPaddingSize.height - labelVisualPadding.top - labelVisualPadding.bottom;
961 visualAnchorPoint = Toolkit::Align::TOP_END;
962 visualPosition.x = foregroundVisualPadding.left;
963 visualPosition.y = foregroundVisualPadding.top;
965 labelPosition.x = labelVisualPadding.left;
966 labelPosition.y = visualAndPaddingSize.height + labelVisualPadding.top;
968 remainingSpaceForText.width = size.width - labelVisualPadding.x - labelVisualPadding.y;
969 remainingSpaceForText.height = size.height - visualAndPaddingSize.height - labelVisualPadding.top - labelVisualPadding.bottom;
975 if ( currentBackGroundVisual )
977 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual background size to(%f,%f)\n", size.width, size.height);
979 Property::Map visualTransform;
981 visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, size )
982 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4( 0.0f, 0.0f, 1.0f, 1.0f) ); // Use relative size
984 currentBackGroundVisual.SetTransformAndSize( visualTransform, size );
989 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual size to(%f,%f)\n", visualSize.width, visualSize.height);
991 Property::Map visualTransform;
993 visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, visualSize )
994 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET, visualPosition )
995 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4( 1.0f, 1.0f, 1.0f, 1.0f) ) // Use absolute size
996 .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
997 .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, visualAnchorPoint );
999 currentVisual.SetTransformAndSize( visualTransform, size );
1002 if ( mTextStringSetFlag )
1004 Toolkit::Visual::Base textVisual = GetVisual( Toolkit::Button::Property::LABEL ); // No need to search for Label visual if no text set.
1008 if ( !currentVisual )
1010 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Only Text\n");
1011 labelPosition.x = labelVisualPadding.left;
1012 labelPosition.y = labelVisualPadding.height;
1015 Vector2 preSize = Vector2( static_cast< int >( remainingSpaceForText.x ), static_cast< int >( remainingSpaceForText.y ));
1017 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout text Size(%f,%f) text Position(%f,%f) \n", remainingSpaceForText.width, remainingSpaceForText.height, labelPosition.x, labelPosition.y);
1019 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout text Size -- (%f,%f) text Position(%f,%f) \n", preSize.width, preSize.height, labelPosition.x, labelPosition.y);
1022 Property::Map textVisualTransform;
1023 textVisualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, preSize )
1024 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET, labelPosition )
1025 .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4( 1.0f, 1.0f, 1.0f,1.0f ) ) // Use absolute size
1026 .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
1027 .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, visualAnchorPoint );
1029 textVisual.SetTransformAndSize( textVisualTransform, size );
1033 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout selected (%s) \n", IsSelected()?"yes":"no" );
1035 DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout << \n");
1038 void Button::OnTap(Actor actor, const TapGesture& tap)
1040 // Prevents Parent getting a tap event
1043 void Button::SetUpTimer( float delay )
1045 mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
1046 mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot );
1047 mAutoRepeatingTimer.Start();
1050 bool Button::AutoRepeatingSlot()
1052 bool consumed = false;
1055 // Restart the autorepeat timer.
1056 SetUpTimer( mNextAutoRepeatingDelay );
1060 Toolkit::Button handle( GetOwner() );
1063 consumed = mReleasedSignal.Emit( handle );
1064 consumed = mClickedSignal.Emit( handle );
1065 consumed |= mPressedSignal.Emit( handle );
1071 void Button::Pressed()
1073 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Pressed\n" );
1075 if( mButtonState == UNSELECTED_STATE )
1077 ChangeState( SELECTED_STATE );
1078 OnPressed(); // Notifies the derived class the button has been pressed.
1082 void Button::Released()
1084 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Released\n" );
1086 if( mButtonState == SELECTED_STATE && !mTogglableButton )
1088 ChangeState( UNSELECTED_STATE );
1089 OnReleased(); // // Notifies the derived class the button has been released.
1091 mButtonPressedState = UNPRESSED;
1094 void Button::SelectRequiredVisual( Property::Index visualIndex )
1096 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SelectRequiredVisual index(%d) state(%d)\n", visualIndex, mButtonState );
1098 EnableVisual( visualIndex, true );
1101 void Button::RemoveVisual( Property::Index visualIndex )
1103 // Use OnButtonVisualRemoval if want button developer to have the option to override removal.
1104 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::RemoveVisual index(%d) state(%d)\n", visualIndex, mButtonState );
1106 Toolkit::Visual::Base visual = GetVisual( visualIndex );
1110 EnableVisual( visualIndex, false );
1114 void Button::OnButtonVisualRemoval( Property::Index visualIndex )
1116 // Derived Buttons can over ride this to prevent default removal.
1117 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnButtonVisualRemoval index(%d)\n", visualIndex );
1118 RemoveVisual( visualIndex );
1121 void Button::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
1123 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1125 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetProperty index[%d]\n", index );
1131 case Toolkit::Button::Property::DISABLED:
1133 GetImplementation( button ).SetDisabled( value.Get< bool >() );
1137 case Toolkit::Button::Property::AUTO_REPEATING:
1139 GetImplementation( button ).SetAutoRepeating( value.Get< bool >() );
1143 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1145 GetImplementation( button ).SetInitialAutoRepeatingDelay( value.Get< float >() );
1149 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1151 GetImplementation( button ).SetNextAutoRepeatingDelay( value.Get< float >() );
1155 case Toolkit::Button::Property::TOGGLABLE:
1157 GetImplementation( button ).SetTogglableButton( value.Get< bool >() );
1161 case Toolkit::Button::Property::SELECTED:
1163 GetImplementation( button ).SetSelected( value.Get< bool >() );
1167 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE: // Legacy Tizen 3.0
1169 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1172 case Toolkit::Button::Property::DISABLED_STATE_IMAGE: // Legacy Tizen 3.0
1174 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1177 case Toolkit::Button::Property::SELECTED_STATE_IMAGE: // Legacy Tizen 3.0
1179 GetImplementation( button ).CreateVisualsForComponent( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, value, DepthIndex::BACKGROUND );
1182 case Toolkit::DevelButton::Property::UNSELECTED_VISUAL:
1183 case Toolkit::DevelButton::Property::SELECTED_VISUAL:
1184 case Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL:
1185 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL:
1187 GetImplementation( button ).CreateVisualsForComponent( index, value, DepthIndex::CONTENT );
1191 case Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL:
1192 case Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL:
1193 case Toolkit::DevelButton::Property::DISABLED_SELECTED_BACKGROUND_VISUAL:
1194 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL:
1196 GetImplementation( button ).CreateVisualsForComponent( index , value, DepthIndex::BACKGROUND);
1200 case Toolkit::Button::Property::UNSELECTED_COLOR:
1202 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::UNSELECTED_COLOR instead use Button::Property::UNSELECTED_BACKGROUND_VISUAL\n", __FUNCTION__);
1203 GetImplementation( button ).SetColor( value.Get< Vector4 >(), Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1207 case Toolkit::Button::Property::SELECTED_COLOR:
1209 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::SELECTED_COLOR instead use Button::Property::SELECTED_BACKGROUND_VISUAL\n", __FUNCTION__);
1210 GetImplementation( button ).SetColor( value.Get< Vector4 >(), Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL );
1214 case Toolkit::Button::Property::LABEL_TEXT:
1216 DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::LABEL_TEXT instead use Button::Property::LABEL\n", __FUNCTION__);
1217 GetImplementation( button ).SetLabelText(value.Get< std::string >() );
1221 case Toolkit::Button::Property::LABEL:
1223 Property::Map outTextVisualProperties;
1224 std::string textString;
1226 if ( value.Get( textString ) )
1228 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetProperty Setting TextVisual with string[%s]\n", textString.c_str() );
1230 Property::Map setPropertyMap;
1231 setPropertyMap.Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT)
1232 .Add( Toolkit::TextVisual::Property::TEXT, textString );
1234 GetImplementation( button ).MergeWithExistingLabelProperties( setPropertyMap, outTextVisualProperties );
1238 // Get a Property::Map from the property if possible.
1239 Property::Map* setPropertyMap = value.GetMap();
1240 if( setPropertyMap )
1242 GetImplementation( button ).MergeWithExistingLabelProperties( *setPropertyMap, outTextVisualProperties );
1246 if( !outTextVisualProperties.Empty() )
1248 GetImplementation( button ).CreateVisualsForComponent( index, outTextVisualProperties, DepthIndex::CONTENT );
1249 GetImplementation( button ).RelayoutRequest();
1254 case Toolkit::DevelButton::Property::LABEL_RELATIVE_ALIGNMENT:
1256 Button::Align labelAlignment(END);
1257 Scripting::GetEnumeration< Button::Align> ( value.Get< std::string >().c_str(),
1258 ALIGNMENT_TABLE, ALIGNMENT_TABLE_COUNT,
1261 GetImplementation( button ).SetLabelAlignment( labelAlignment );
1262 GetImplementation( button ).RelayoutRequest();
1266 case Toolkit::DevelButton::Property::LABEL_PADDING:
1268 Vector4 padding ( value.Get< Vector4 >() );
1269 GetImplementation( button ).SetLabelPadding( Padding( padding.x, padding.y, padding.z, padding.w ) );
1273 case Toolkit::DevelButton::Property::VISUAL_PADDING:
1275 Vector4 padding ( value.Get< Vector4 >() );
1276 GetImplementation( button ).SetForegroundPadding( Padding( padding.x, padding.y, padding.z, padding.w ) );
1277 GetImplementation( button ).RelayoutRequest();
1284 Property::Value Button::GetProperty( BaseObject* object, Property::Index propertyIndex )
1286 Property::Value value;
1288 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1292 switch ( propertyIndex )
1294 case Toolkit::Button::Property::DISABLED:
1296 value = GetImplementation( button ).IsDisabled();
1300 case Toolkit::Button::Property::AUTO_REPEATING:
1302 value = GetImplementation( button ).mAutoRepeating;
1306 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1308 value = GetImplementation( button ).mInitialAutoRepeatingDelay;
1312 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1314 value = GetImplementation( button ).mNextAutoRepeatingDelay;
1318 case Toolkit::Button::Property::TOGGLABLE:
1320 value = GetImplementation( button ).mTogglableButton;
1324 case Toolkit::Button::Property::SELECTED:
1326 value = GetImplementation( button ).IsSelected();
1330 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1332 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1336 case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1338 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL );
1342 case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1344 value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL );
1348 case Toolkit::DevelButton::Property::UNSELECTED_VISUAL:
1349 case Toolkit::DevelButton::Property::SELECTED_VISUAL:
1350 case Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL:
1351 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL:
1352 case Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL:
1353 case Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL:
1354 case Toolkit::DevelButton::Property::DISABLED_SELECTED_BACKGROUND_VISUAL:
1355 case Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL:
1356 case Toolkit::Button::Property::LABEL:
1358 Property::Map visualProperty;
1359 if ( GetImplementation( button ).GetPropertyMapForVisual( propertyIndex, visualProperty ) )
1361 value = visualProperty;
1366 case Toolkit::Button::Property::UNSELECTED_COLOR:
1368 value = GetImplementation( button ).GetUnselectedColor();
1372 case Toolkit::Button::Property::SELECTED_COLOR:
1374 value = GetImplementation( button ).GetSelectedColor();
1378 case Toolkit::Button::Property::LABEL_TEXT:
1380 value = GetImplementation( button ).GetLabelText();
1384 case Toolkit::DevelButton::Property::LABEL_RELATIVE_ALIGNMENT:
1386 const char* alignment = Scripting::GetEnumerationName< Button::Align >( GetImplementation( button ).GetLabelAlignment(),
1387 ALIGNMENT_STRING_TABLE,
1388 ALIGNMENT_STRING_TABLE_COUNT );
1391 value = std::string( alignment );
1397 case Toolkit::DevelButton::Property::LABEL_PADDING:
1399 Padding padding = GetImplementation( button ).GetLabelPadding();
1400 value = Vector4( padding.x, padding.y, padding.top, padding.bottom);
1404 case Toolkit::DevelButton::Property::VISUAL_PADDING:
1406 Padding padding = GetImplementation( button ).GetForegroundPadding();
1407 value = Vector4( padding.x, padding.y, padding.top, padding.bottom);
1415 void Button::SetLabelPadding( const Padding& padding)
1417 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetLabelPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top );
1418 mLabelPadding = Padding( padding.left, padding.right, padding.bottom, padding.top );
1422 Padding Button::GetLabelPadding()
1424 return mLabelPadding;
1427 void Button::SetForegroundPadding( const Padding& padding)
1429 DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetForegroundPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top );
1430 mForegroundPadding = Padding( padding.left, padding.right, padding.bottom, padding.top );
1434 Padding Button::GetForegroundPadding()
1436 return mForegroundPadding;
1439 ////////////////////////////////////////////////////////////////////////
1440 // Legacy functions from Tizen 2.4 and 3.0
1442 // Legacy code needed whilst Color can be set by direct Property setting ( deprecated ) instead of setting a Visual
1443 void Button::SetColor( const Vector4& color, Property::Index visualIndex )
1445 if ( visualIndex == Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL )
1447 mSelectedColor = color;
1451 mUnselectedColor = color;
1455 map[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::COLOR;
1456 map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color;
1458 CreateVisualsForComponent( visualIndex, map, DepthIndex::BACKGROUND );
1461 const Vector4 Button::GetUnselectedColor() const
1463 return mUnselectedColor;
1466 const Vector4 Button::GetSelectedColor() const
1468 return mSelectedColor;
1471 void Button::SetAnimationTime( float animationTime )
1473 // Used by deprecated API
1474 mAnimationTime = animationTime;
1477 float Button::GetAnimationTime() const
1479 // Used by deprecated API
1480 return mAnimationTime;
1483 void Button::SetLabel( Actor label )
1487 Property::Value value ="";
1488 value = label.GetProperty(Toolkit::TextLabel::Property::TEXT);
1490 SetLabelText( value.Get<std::string>() );
1494 void Button::SetUnselectedImage( const std::string& filename )
1496 SetBackgroundImage( filename );
1499 void Button::SetBackgroundImage( const std::string& filename )
1501 if( !filename.empty() )
1503 CreateVisualsForComponent( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1507 UnregisterVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1511 void Button::SetSelectedImage( const std::string& filename )
1513 SetSelectedBackgroundImage( filename );
1516 void Button::SetSelectedBackgroundImage( const std::string& filename )
1518 if( !filename.empty() )
1520 CreateVisualsForComponent( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1524 UnregisterVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL );
1528 void Button::SetDisabledBackgroundImage( const std::string& filename )
1530 if( !filename.empty() )
1532 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND );
1536 void Button::SetDisabledImage( const std::string& filename )
1538 if( !filename.empty() )
1540 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL, filename, DepthIndex::CONTENT );
1544 void Button::SetDisabledSelectedImage( const std::string& filename )
1546 if( !filename.empty() )
1548 CreateVisualsForComponent( Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL, filename, DepthIndex::CONTENT );
1552 // Used by Deprecated Properties which don't use the Visual Property maps for setting and getting
1553 std::string Button::GetUrlForImageVisual( const Property::Index index ) const
1555 Toolkit::Visual::Base visual = GetVisual( index );
1560 Dali::Property::Map retreivedMap;
1561 visual.CreatePropertyMap( retreivedMap );
1562 Property::Value* value = retreivedMap.Find( Toolkit::ImageVisual::Property::URL, Property::STRING );
1565 result = value->Get<std::string>();
1572 // Below functions DEPRECATED_1_0.50 - Return empty Actors
1576 std::string GetUrlFromImage( Image& image )
1578 ResourceImage resourceImage = ResourceImage::DownCast( image );
1580 std::string imageUrl;
1582 if ( resourceImage )
1584 imageUrl = resourceImage.GetUrl();
1592 void Button::SetButtonImage( Image image )
1594 DALI_LOG_WARNING("Button::SetButtonImage @DEPRECATED_1_0.50\n");
1595 SetUnselectedImage( GetUrlFromImage( image ) );
1598 void Button::SetSelectedImage( Image image )
1600 DALI_LOG_WARNING("Button::SetSelectedImage @DEPRECATED_1_0.50\n");
1601 SetSelectedImage( GetUrlFromImage( image ) );
1604 Actor Button::GetButtonImage() const
1606 DALI_LOG_WARNING("Button::GetButtonImage @DEPRECATED_1_0.50\n");
1607 Actor imageView = Toolkit::ImageView::New( GetUrlForImageVisual( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL ) );
1612 Actor Button::GetSelectedImage() const
1614 DALI_LOG_WARNING("Button::GetSelectedImage @DEPRECATED_1_0.50\n");
1615 Actor imageView = Toolkit::ImageView::New( GetUrlForImageVisual( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL ) );
1620 } // namespace Internal
1622 } // namespace Toolkit