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