X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Fbuttons%2Fbutton-impl.cpp;h=61a57058525a829d495075269638efc4fea54c2e;hp=4072f4320dd1473eacc5d66ba7ba060d3b1be196;hb=abbf60ed35112186269d2fe93b949eb8abd4283d;hpb=394b478479627e640973168935bc0045c584b752 diff --git a/dali-toolkit/internal/controls/buttons/button-impl.cpp b/dali-toolkit/internal/controls/buttons/button-impl.cpp index 4072f43..61a5705 100644 --- a/dali-toolkit/internal/controls/buttons/button-impl.cpp +++ b/dali-toolkit/internal/controls/buttons/button-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,38 +20,30 @@ // EXTERNAL INCLUDES #include // for strcmp -#include +#include +#include +#include +#include #include -#include -#include +#include +#include #include // INTERNAL INCLUDES #include +#include +#include +#include +#include +#include +#include +#include +#include -/** - * Button states and contents - * (3) mSelectedContent - * (2) mUnselectedContent (2) mSelectedBackgroundContent - * (1) mBackgroundContent (1) mBackgroundContent - * < unselected > ----------------------- < selected > - * | OnSelect() | - * | OnDisabled() | OnDisabled() - * | | - * < disabled > < disabled-selected > - * (2) mDisabledContent (2) mDisabledSelectedContent - * (1) mDisabledBackgroundContent (1) mDisabledBackgroundContent - * - * The drawing order of child actors is as follows. - * - * Top mLabel - * | mUnselectedContent / mSelectedContent / mDisabledContent / mDisabledSelectedContent - * | mSelectedBackgroundContent - * Bottom mBackgroundContent / mDisabledBackgroundContent - * - * Some of contents may be missed. - * And 2 images - fade-in image and fade-out image - in the same layer can be shown during the transition animation. Fade-in image should be above fade-out image. - */ + +#if defined(DEBUG_ENABLED) + Debug::Filter* gLogButtonFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_BUTTON_CONTROL"); +#endif namespace Dali { @@ -72,46 +64,82 @@ BaseHandle Create() } // Setup properties, signals and actions using the type-registry. -DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Button, Toolkit::Control, Create ); - -DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabled", BOOLEAN, DISABLED ) -DALI_PROPERTY_REGISTRATION( Toolkit, Button, "auto-repeating", BOOLEAN, AUTO_REPEATING ) -DALI_PROPERTY_REGISTRATION( Toolkit, Button, "initial-auto-repeating-delay", FLOAT, INITIAL_AUTO_REPEATING_DELAY ) -DALI_PROPERTY_REGISTRATION( Toolkit, Button, "next-auto-repeating-delay", FLOAT, NEXT_AUTO_REPEATING_DELAY ) -DALI_PROPERTY_REGISTRATION( Toolkit, Button, "togglable", BOOLEAN, TOGGLABLE ) -DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selected", BOOLEAN, SELECTED ) -DALI_PROPERTY_REGISTRATION( Toolkit, Button, "normal-state-actor", MAP, NORMAL_STATE_ACTOR ) -DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selected-state-actor", MAP, SELECTED_STATE_ACTOR ) -DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabled-state-actor", MAP, DISABLED_STATE_ACTOR ) -DALI_PROPERTY_REGISTRATION( Toolkit, Button, "label-actor", MAP, LABEL_ACTOR ) - +DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Button, Toolkit::Control, Create ) + +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabled", BOOLEAN, DISABLED ) +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "autoRepeating", BOOLEAN, AUTO_REPEATING ) +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "initialAutoRepeatingDelay", FLOAT, INITIAL_AUTO_REPEATING_DELAY ) +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "nextAutoRepeatingDelay", FLOAT, NEXT_AUTO_REPEATING_DELAY ) +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "togglable", BOOLEAN, TOGGLABLE ) +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selected", BOOLEAN, SELECTED ) +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedStateImage", MAP, UNSELECTED_STATE_IMAGE ) // Deprecated property +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedStateImage", MAP, SELECTED_STATE_IMAGE ) // Deprecated property +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledStateImage", MAP, DISABLED_STATE_IMAGE ) // Deprecated property +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedColor", VECTOR4, UNSELECTED_COLOR ) // Deprecated property +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedColor", VECTOR4, SELECTED_COLOR ) // Deprecated property +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "label", MAP, LABEL ) +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "labelText", STRING, LABEL_TEXT ) // Deprecated property +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedVisual", MAP, UNSELECTED_VISUAL ) +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedVisual", MAP, SELECTED_VISUAL ) +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledSelectedVisual", MAP, DISABLED_SELECTED_VISUAL ) +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledUnselectedVisual", MAP, DISABLED_UNSELECTED_VISUAL ) +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedBackgroundVisual", MAP, UNSELECTED_BACKGROUND_VISUAL ) +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedBackgroundVisual", MAP, SELECTED_BACKGROUND_VISUAL ) +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledUnselectedBackgroundVisual", MAP, DISABLED_UNSELECTED_BACKGROUND_VISUAL ) +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledSelectedBackgroundVisual", MAP, DISABLED_SELECTED_BACKGROUND_VISUAL ) +DALI_PROPERTY_REGISTRATION( Toolkit, Button, "labelRelativeAlignment", STRING, LABEL_RELATIVE_ALIGNMENT ) + +// Signals: DALI_SIGNAL_REGISTRATION( Toolkit, Button, "pressed", SIGNAL_PRESSED ) DALI_SIGNAL_REGISTRATION( Toolkit, Button, "released", SIGNAL_RELEASED ) DALI_SIGNAL_REGISTRATION( Toolkit, Button, "clicked", SIGNAL_CLICKED ) -DALI_SIGNAL_REGISTRATION( Toolkit, Button, "state-changed", SIGNAL_STATE_CHANGED ) +DALI_SIGNAL_REGISTRATION( Toolkit, Button, "stateChanged", SIGNAL_STATE_CHANGED ) -DALI_ACTION_REGISTRATION( Toolkit, Button, "button-click", ACTION_BUTTON_CLICK ) +// Actions: +DALI_ACTION_REGISTRATION( Toolkit, Button, "buttonClick", ACTION_BUTTON_CLICK ) DALI_TYPE_REGISTRATION_END() -const unsigned int INITIAL_AUTOREPEATING_DELAY( 0.15f ); -const unsigned int NEXT_AUTOREPEATING_DELAY( 0.05f ); +DALI_ENUM_TO_STRING_TABLE_BEGIN( ALIGNMENT ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, BEGIN ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, END ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, TOP ) +DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Internal::Button, BOTTOM ) +DALI_ENUM_TO_STRING_TABLE_END( ALIGNMENT ) + +const Scripting::StringEnum ALIGNMENT_STRING_TABLE[] = +{ + { "BEGIN", Button::BEGIN }, + { "END", Button::END }, + { "TOP", Button::TOP }, + { "BOTTOM", Button::BOTTOM }, +}; + +const unsigned int ALIGNMENT_STRING_TABLE_COUNT = sizeof( ALIGNMENT_STRING_TABLE ) / sizeof( ALIGNMENT_STRING_TABLE[0] ); + +const Property::Index GET_VISUAL_INDEX_FOR_STATE[][Button::STATE_COUNT] = +{ + { Toolkit::Button::Property::UNSELECTED_BACKGROUND_VISUAL, Toolkit::Button::Property::UNSELECTED_VISUAL }, + { Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL, Toolkit::Button::Property::SELECTED_VISUAL }, + { Toolkit::Button::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, Toolkit::Button::Property::DISABLED_UNSELECTED_VISUAL }, + { Toolkit::Button::Property::DISABLED_SELECTED_BACKGROUND_VISUAL, Toolkit::Button::Property::DISABLED_SELECTED_VISUAL } +}; } // unnamed namespace Button::Button() -: Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS | REQUIRES_STYLE_CHANGE_SIGNALS ) ), +: Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ), mAutoRepeatingTimer(), - mDisabled( false ), + mTextLabelAlignment( END ), mAutoRepeating( false ), mTogglableButton( false ), - mSelected( false ), - mInitialAutoRepeatingDelay( INITIAL_AUTOREPEATING_DELAY ), - mNextAutoRepeatingDelay( NEXT_AUTOREPEATING_DELAY ), + mInitialAutoRepeatingDelay( 0.0f ), + mNextAutoRepeatingDelay( 0.0f ), mAnimationTime( 0.0f ), - mClickActionPerforming( false ), - mState( ButtonUp ), - mPaintState( UnselectedState ) + mButtonPressedState( UNPRESSED ), + mButtonState( UNSELECTED_STATE ), + mPreviousButtonState( mButtonState ), + mClickActionPerforming( false ) { } @@ -119,114 +147,6 @@ Button::~Button() { } -void Button::SetDisabled( bool disabled ) -{ - if( disabled == mDisabled ) - { - return; - } - - StopTransitionAnimation(); - - mDisabled = disabled; - - // Notifies the derived class the button has been disabled. - OnDisabled(); - - switch( mPaintState ) - { - case UnselectedState: - { - //Layer Order - //(3) mDisabledContent (Inserted) - //(4) mUnselectedContent - //(2) mDisabledBackgroundContent (Inserted) - //(1) mBackgroundContent - - TransitionInBetween( mUnselectedContent, mLabel, mDisabledContent ); - TransitionInAbove( mBackgroundContent, mDisabledBackgroundContent ); - - TransitionOut( mUnselectedContent ); - TransitionOut( mSelectedContent ); - TransitionOut( mBackgroundContent ); - TransitionOut( mSelectedBackgroundContent ); - TransitionOut( mDisabledSelectedContent ); - - mPaintState = DisabledUnselectedState; - break; - } - case SelectedState: - { - //Layer Order - //(5) mDisabledSelectedContent (Inserted) - //(4) mSelectedContent - //(3) mDisabledBackgroundContent (Inserted) - //(2) mSelectedBackgroundContent - //(1) mBackgroundContent - - TransitionInBetween( mSelectedContent, mLabel, mDisabledSelectedContent ); - TransitionInAbove( mSelectedBackgroundContent, mDisabledBackgroundContent ); - - TransitionOut( mUnselectedContent ); - TransitionOut( mSelectedContent ); - TransitionOut( mBackgroundContent ); - TransitionOut( mSelectedBackgroundContent ); - TransitionOut( mDisabledContent ); - - mPaintState = DisabledSelectedState; - break; - } - case DisabledUnselectedState: - { - //Layer Order - //(3) mUnselectedContent (Inserted) - //(4) mDisabledContent - //(2) mBackgroundContent (Inserted) - //(1) mDisabledBackgroundContent - - TransitionInBetween( mDisabledContent, mLabel, mUnselectedContent ); - TransitionInAbove( mDisabledBackgroundContent, mBackgroundContent ); - - TransitionOut( mSelectedContent ); - TransitionOut( mSelectedBackgroundContent ); - TransitionOut( mDisabledContent ); - TransitionOut( mDisabledSelectedContent ); - TransitionOut( mDisabledBackgroundContent ); - - mPaintState = UnselectedState; - break; - } - case DisabledSelectedState: - { - //Layer Order - //(4) mSelectedContent (Inserted) - //(5) mDisabledSelectedContent - //(3) mSelectedBackgroundContent (Inserted) - //(2) mBackgroundContent (Inserted) - //(1) mDisabledBackgroundContent - - TransitionInBetween( mDisabledSelectedContent, mLabel, mSelectedContent ); - TransitionInAbove( mDisabledBackgroundContent, mSelectedBackgroundContent ); - TransitionInAbove( mDisabledBackgroundContent, mBackgroundContent ); - - TransitionOut( mUnselectedContent ); - TransitionOut( mDisabledContent ); - TransitionOut( mDisabledSelectedContent ); - TransitionOut( mDisabledBackgroundContent ); - - mPaintState = SelectedState; - break; - } - } - - StartTransitionAnimation(); -} - -bool Button::IsDisabled() const -{ - return mDisabled; -} - void Button::SetAutoRepeating( bool autoRepeating ) { mAutoRepeating = autoRepeating; @@ -236,10 +156,9 @@ void Button::SetAutoRepeating( bool autoRepeating ) { mTogglableButton = false; - if( mSelected ) + if( IsSelected() ) { - // Emit a signal is not wanted, only change the appearance. - SetSelected( false, false ); + SetSelected( false ); } } } @@ -251,7 +170,7 @@ bool Button::IsAutoRepeating() const void Button::SetInitialAutoRepeatingDelay( float initialAutoRepeatingDelay ) { - DALI_ASSERT_ALWAYS( initialAutoRepeatingDelay > 0.f ); + DALI_ASSERT_DEBUG( initialAutoRepeatingDelay > 0.f ); mInitialAutoRepeatingDelay = initialAutoRepeatingDelay; } @@ -262,7 +181,7 @@ float Button::GetInitialAutoRepeatingDelay() const void Button::SetNextAutoRepeatingDelay( float nextAutoRepeatingDelay ) { - DALI_ASSERT_ALWAYS( nextAutoRepeatingDelay > 0.f ); + DALI_ASSERT_DEBUG( nextAutoRepeatingDelay > 0.f ); mNextAutoRepeatingDelay = nextAutoRepeatingDelay; } @@ -275,7 +194,7 @@ void Button::SetTogglableButton( bool togglable ) { mTogglableButton = togglable; - // A togglable button can't be an autorepeating button. + // A toggle button can't be an autorepeating button. if( togglable ) { mAutoRepeating = false; @@ -289,353 +208,239 @@ bool Button::IsTogglableButton() const void Button::SetSelected( bool selected ) { - if( !mDisabled && mTogglableButton && ( selected != mSelected ) ) + if( mTogglableButton ) { - SetSelected( selected, true ); + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetSelected (%s)\n", (selected?"true":"false") ); + + if ( selected && ( mButtonState != SELECTED_STATE ) ) + { + ChangeState( SELECTED_STATE ); + } + else if ( !selected && ( mButtonState != UNSELECTED_STATE ) ) + { + ChangeState( UNSELECTED_STATE ); + } } } -void Button::SetSelected( bool selected, bool emitSignal ) +void Button::SetDisabled( bool disabled ) { - StopTransitionAnimation(); - - mSelected = selected; + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetDisabled(%s) state(%d)\n", (disabled)?"disabled":"active", mButtonState ); - // Notifies the derived class the button has been selected. - OnSelected(); - - switch( mPaintState ) + if ( disabled ) { - case UnselectedState: - { - //Layer Order - //(3) mSelectedContent (Inserted) - //(4) mUnselectedContent - //(2) mSelectedBackgroundContent (Inserted) - //(1) mBackgroundContent - - TransitionInBetween( mUnselectedContent, mLabel, mSelectedContent ); - TransitionInAbove( mBackgroundContent, mSelectedBackgroundContent ); - TransitionInAtIndex( 0, mBackgroundContent ); - - TransitionOut( mUnselectedContent ); - TransitionOut( mDisabledContent ); - TransitionOut( mDisabledSelectedContent ); - TransitionOut( mDisabledBackgroundContent ); - - mPaintState = SelectedState; - break; - } - case SelectedState: + if ( mButtonState == SELECTED_STATE ) { - //Layer Order - //(3) mUnselectedContent (Inserted) - //(2) mSelectedContent - //(1) mBackgroundContent - - TransitionInBetween( mSelectedContent, mLabel, mUnselectedContent ); - TransitionInAtIndex( 0, mBackgroundContent ); - - TransitionOut( mSelectedContent ); - TransitionOut( mSelectedBackgroundContent ); - TransitionOut( mDisabledContent ); - TransitionOut( mDisabledSelectedContent ); - TransitionOut( mDisabledBackgroundContent ); - - mPaintState = UnselectedState; - break; + ChangeState( DISABLED_SELECTED_STATE ); } - case DisabledUnselectedState: - case DisabledSelectedState: + else if ( mButtonState == UNSELECTED_STATE ) { - DALI_ASSERT_DEBUG( 0 && "Shouldn't be able to change paint state if the button is disabled." ); - break; + ChangeState( DISABLED_UNSELECTED_STATE ); } } - - StartTransitionAnimation(); - - if( emitSignal ) - { - Toolkit::Button handle( GetOwner() ); - - // Emit signal. - mStateChangedSignal.Emit( handle ); - } - - RelayoutRequest(); -} - -bool Button::IsSelected() const -{ - return mTogglableButton && mSelected; -} - -void Button::SetAnimationTime( float animationTime ) -{ - mAnimationTime = animationTime; -} - -float Button::GetAnimationTime() const -{ - return mAnimationTime; -} - -void Button::SetLabel( const std::string& label ) -{ - Toolkit::TextLabel textLabel = Toolkit::TextLabel::New( label ); - SetLabel( textLabel ); -} - -void Button::SetLabel( Actor label ) -{ - if( mLabel != label ) + else { - if( mLabel && mLabel.GetParent() ) + if ( mButtonState == DISABLED_SELECTED_STATE ) { - mLabel.GetParent().Remove( mLabel ); + ChangeState( SELECTED_STATE ); + } + else if ( mButtonState == DISABLED_UNSELECTED_STATE ) + { + ChangeState( UNSELECTED_STATE ); } - - mLabel = label; - mLabel.SetPosition( 0.f, 0.f ); - - // label should be the top of the button - Self().Add( mLabel ); - - OnLabelSet(); - - RelayoutRequest(); } } -Actor Button::GetLabel() const -{ - return mLabel; -} - -Actor& Button::GetLabel() +bool Button::IsDisabled() const { - return mLabel; + return ( mButtonState == DISABLED_SELECTED_STATE || mButtonState == DISABLED_UNSELECTED_STATE ) ; } -void Button::SetButtonImage( Actor image ) +bool Button::ValidateState( State requestedState ) { - StopTransitionAnimation(); - - if( mUnselectedContent && mUnselectedContent.GetParent() ) - { - Self().Remove( mUnselectedContent ); - } - - mUnselectedContent = image; - if( mUnselectedContent ) - { - mUnselectedContent.SetAnchorPoint( AnchorPoint::TOP_LEFT ); - mUnselectedContent.SetParentOrigin( ParentOrigin::TOP_LEFT ); - mUnselectedContent.SetPosition( 0.f, 0.f ); - } - ResetImageLayers(); - OnButtonImageSet(); + /* Below tables shows allowed state transitions + * Match rows in first column to following columns, if true then transition allowed. + * eg UNSELECTED_STATE to DISABLED_UNSELECTED_STATE is true so state transition allowed. + * + to| UNSELECTED_STATE | SELECTED_STATE | DISABLED_UNSELECTED_STATE | DISABLED_SELECTED_STATE |*/ + /* from*/ + bool transitionTable[4][4] = { /* UNSELECTED_STATE*/ { false, true, true, false }, + /* SELECTED_STATE*/ { true, false, false, true }, + /* DISABLED_UNSELECTED_STATE*/{ true, true, false, false }, + /* DISABLED_SELECTED_STATE*/ { false, true, false, false } + }; - RelayoutRequest(); -} - -Actor Button::GetButtonImage() const -{ - return mUnselectedContent; -} + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ValidateState ReuestedState:%d, CurrentState:%d, result:%s\n", + requestedState, mButtonState, (transitionTable[mButtonState][requestedState])?"change-accepted":"change-denied"); -Actor& Button::GetButtonImage() -{ - return mUnselectedContent; + return transitionTable[mButtonState][requestedState]; } -void Button::SetSelectedImage( Actor image ) +void Button::PerformFunctionOnVisualsInState( void(Button::*functionPtr)( Property::Index visualIndex), State state ) { - StopTransitionAnimation(); - - if( mSelectedContent && mSelectedContent.GetParent() ) - { - Self().Remove( mSelectedContent ); - } + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::PerformFunctionOnVisualsInState BACKROUND visual(%d) for state (%d)\n", + GET_VISUAL_INDEX_FOR_STATE[state][BACKGROUND], state ); + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::PerformFunctionOnVisualsInState FOREGROUND visuals(%d) for state (%d)\n", + GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND], state ); - mSelectedContent = image; - if( mSelectedContent ) - { - mSelectedContent.SetAnchorPoint( AnchorPoint::TOP_LEFT ); - mSelectedContent.SetParentOrigin( ParentOrigin::TOP_LEFT ); - mSelectedContent.SetPosition( 0.f, 0.f ); - } - ResetImageLayers(); - OnSelectedImageSet(); + (this->*functionPtr)( GET_VISUAL_INDEX_FOR_STATE[state][BACKGROUND] ); + (this->*functionPtr)( GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND] ); RelayoutRequest(); } -Actor Button::GetSelectedImage() const -{ - return mSelectedContent; -} - -Actor& Button::GetSelectedImage() +void Button::ChangeState( State requestedState ) { - return mSelectedContent; -} - -void Button::SetBackgroundImage( Actor image ) -{ - StopTransitionAnimation(); + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ChangeState ReuestedState(%d)\n", requestedState ); - if( mBackgroundContent && mBackgroundContent.GetParent() ) + // Validate State before changing + if ( !ValidateState( requestedState )) { - Self().Remove( mBackgroundContent ); + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::ChangeState ReuestedState(%d) not validated\n", requestedState ); + return; } - mBackgroundContent = image; - if( mBackgroundContent ) + // If not on stage the button could have still been set to selected so update state/ + mPreviousButtonState = mButtonState; // Store previous state for visual removal (used when animations ended) + mButtonState = requestedState; // Update current state + + if ( Self().OnStage() ) { - mBackgroundContent.SetAnchorPoint( AnchorPoint::TOP_LEFT ); - mBackgroundContent.SetParentOrigin( ParentOrigin::TOP_LEFT ); - mBackgroundContent.SetPosition( 0.f, 0.f ); + OnStateChange( mButtonState ); // Notify derived buttons + PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState ); + // If animation supported then visual removal should be performed after any transition animation has completed. + PerformFunctionOnVisualsInState( &Button::OnButtonVisualRemoval, mPreviousButtonState ); // Derived button can override OnButtonVisualRemoval } - ResetImageLayers(); - OnBackgroundImageSet(); - RelayoutRequest(); + Toolkit::Button handle( GetOwner() ); + // Emit signal. + mStateChangedSignal.Emit( handle ); } -Actor Button::GetBackgroundImage() const +bool Button::IsSelected() const { - return mBackgroundContent; + bool selected = ( mButtonState == SELECTED_STATE ) || ( mButtonState == DISABLED_SELECTED_STATE ); + return mTogglableButton && selected; } -Actor& Button::GetBackgroundImage() +void Button::SetLabelText( const std::string& label ) { - return mBackgroundContent; + Property::Map labelProperty; + labelProperty.Insert( "text", label ); + SetupLabel( labelProperty ); } -void Button::SetSelectedBackgroundImage( Actor image ) +std::string Button::GetLabelText() const { - StopTransitionAnimation(); - - if( mSelectedBackgroundContent && mSelectedBackgroundContent.GetParent() ) + Toolkit::TextLabel label = Dali::Toolkit::TextLabel::DownCast( mLabel ); + if( label ) { - Self().Remove( mSelectedBackgroundContent ); + return label.GetProperty( Dali::Toolkit::TextLabel::Property::TEXT ); } - - mSelectedBackgroundContent = image; - if( mSelectedBackgroundContent ) - { - mSelectedBackgroundContent.SetAnchorPoint( AnchorPoint::TOP_LEFT ); - mSelectedBackgroundContent.SetParentOrigin( ParentOrigin::TOP_LEFT ); - mSelectedBackgroundContent.SetPosition( 0.f, 0.f ); - } - ResetImageLayers(); - OnSelectedBackgroundImageSet(); - - RelayoutRequest(); -} - -Actor Button::GetSelectedBackgroundImage() const -{ - return mSelectedBackgroundContent; + return std::string(); } -Actor& Button::GetSelectedBackgroundImage() +void Button::SetupLabel( const Property::Map& properties ) { - return mSelectedBackgroundContent; -} - -void Button::SetDisabledImage( Actor image ) -{ - StopTransitionAnimation(); + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "SetupLabel\n"); - if( mDisabledContent && mDisabledContent.GetParent() ) + // If we don't have a label yet, create one. + if( !mLabel ) { - Self().Remove( mDisabledContent ); + // If we don't have a label, create one and set it up. + // Note: The label text is set from the passed in property map after creation. + mLabel = Toolkit::TextLabel::New(); + mLabel.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" ); + mLabel.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" ); + mLabel.SetParentOrigin( ParentOrigin::TOP_LEFT ); + mLabel.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + + // todo DEBUG + mLabel.SetProperty( Toolkit::Control::Property::BACKGROUND, Dali::Property::Map() + .Add( Toolkit::Visual::Property::TYPE, Dali::Toolkit::Visual::COLOR ) + .Add( Toolkit::ColorVisual::Property::MIX_COLOR, Color::RED ) + ); + + ResizePolicy::Type policy = Self().GetResizePolicy( Dimension::ALL_DIMENSIONS ); + if ( policy == ResizePolicy::USE_NATURAL_SIZE || policy == ResizePolicy::FIT_TO_CHILDREN ) + { + mLabel.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS ); + } + else + { + // todo Can't set Text Label to USE_ASSIGNED_SIZE as causes a relayout in it whilst doing a relayout = error + //mLabel.SetResizePolicy(ResizePolicy::USE_ASSIGNED_SIZE, Dimension::ALL_DIMENSIONS ); + } + Self().Add( mLabel ); } - mDisabledContent = image; - if( mDisabledContent ) + // Set any properties specified for the label by iterating through all property key-value pairs. + for( unsigned int i = 0, mapCount = properties.Count(); i < mapCount; ++i ) { - mDisabledContent.SetAnchorPoint( AnchorPoint::TOP_LEFT ); - mDisabledContent.SetParentOrigin( ParentOrigin::TOP_LEFT ); - mDisabledContent.SetPosition( 0.f, 0.f ); + const StringValuePair& propertyPair( properties.GetPair( i ) ); + + // Convert the property string to a property index. + Property::Index setPropertyIndex = mLabel.GetPropertyIndex( propertyPair.first ); + if( setPropertyIndex != Property::INVALID_INDEX ) + { + // If the conversion worked, we have a valid property index, + // Set the property to the new value. + mLabel.SetProperty( setPropertyIndex, propertyPair.second ); + } } - ResetImageLayers(); - OnDisabledImageSet(); + RelayoutRequest(); } -Actor Button::GetDisabledImage() const +void Button::SetLabelAlignment( Button::Align labelAlignment) { - return mDisabledContent; + mTextLabelAlignment = labelAlignment; + RelayoutRequest(); } -Actor& Button::GetDisabledImage() +Button::Align Button::GetLabelAlignment() { - return mDisabledContent; + return mTextLabelAlignment; } -void Button::SetDisabledSelectedImage( Actor image ) +void Button::CreateVisualsForComponent( Property::Index index, const Property::Value& value, const float visualDepth ) { - StopTransitionAnimation(); + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent index(%d)\n", index ); + Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get(); + Toolkit::Visual::Base buttonVisual; - if( mDisabledSelectedContent && mDisabledSelectedContent.GetParent() ) + std::string imageUrl; + if( value.Get( imageUrl ) ) { - Self().Remove( mDisabledSelectedContent ); + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent Using image URL(%d)\n", index ); + if ( !imageUrl.empty() ) + { + buttonVisual = visualFactory.CreateVisual( imageUrl, ImageDimensions() ); + } } - - mDisabledSelectedContent = image; - if( mDisabledSelectedContent ) + else { - mDisabledSelectedContent.SetAnchorPoint( AnchorPoint::TOP_LEFT ); - mDisabledSelectedContent.SetParentOrigin( ParentOrigin::TOP_LEFT ); - mDisabledSelectedContent.SetPosition( 0.f, 0.f ); + // if its not a string then get a Property::Map from the property if possible. + Property::Map *map = value.GetMap(); + if( map && !map->Empty() ) // Empty map results in current visual removal. + { + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "CreateVisualsForComponent Using Map(%d)\n", index ); + buttonVisual = visualFactory.CreateVisual( *map ); + } } - ResetImageLayers(); - OnDisabledSelectedImageSet(); -} - -Actor Button::GetDisabledSelectedImage() const -{ - return mDisabledSelectedContent; -} - -Actor& Button::GetDisabledSelectedImage() -{ - return mDisabledSelectedContent; -} - -void Button::SetDisabledBackgroundImage( Actor image ) -{ - StopTransitionAnimation(); - - if( mDisabledBackgroundContent && mDisabledBackgroundContent.GetParent() ) + if ( buttonVisual ) { - Self().Remove( mDisabledBackgroundContent ); + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "RegisterVisual index(%d)\n", index ); + buttonVisual.SetDepthIndex( visualDepth ); + // Background Visuals take full size of control + RegisterVisual( index, buttonVisual, false ); } - - mDisabledBackgroundContent = image; - if( mDisabledBackgroundContent ) + else { - mDisabledBackgroundContent.SetAnchorPoint( AnchorPoint::TOP_LEFT ); - mDisabledBackgroundContent.SetParentOrigin( ParentOrigin::TOP_LEFT ); - mDisabledBackgroundContent.SetPosition( 0.f, 0.f ); + UnregisterVisual( index ); + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "Button visual not created or empty map provided (clearing visual).(%d)\n", index); } - ResetImageLayers(); - OnDisabledBackgroundImageSet(); -} - -Actor Button::GetDisabledBackgroundImage() const -{ - return mDisabledBackgroundContent; -} - -Actor& Button::GetDisabledBackgroundImage() -{ - return mDisabledBackgroundContent; } bool Button::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes ) @@ -646,7 +451,7 @@ bool Button::DoAction( BaseObject* object, const std::string& actionName, const Toolkit::Button button = Toolkit::Button::DownCast( handle ); - DALI_ASSERT_ALWAYS( button ); + DALI_ASSERT_DEBUG( button ); if( 0 == strcmp( actionName.c_str(), ACTION_BUTTON_CLICK ) ) { @@ -663,9 +468,12 @@ bool Button::DoClickAction( const Property::Map& attributes ) if( !mClickActionPerforming ) { mClickActionPerforming = true; - OnButtonDown(); - mState = ButtonDown; - OnButtonUp(); + ButtonDown(); + if ( !mTogglableButton ) + { + mButtonPressedState = DEPRESSED; + } + ButtonUp(); mClickActionPerforming = false; return true; @@ -674,84 +482,92 @@ bool Button::DoClickAction( const Property::Map& attributes ) return false; } -void Button::OnButtonStageDisconnection() +void Button::ButtonDown() { - if( ButtonDown == mState ) + if( mTogglableButton ) { - if( !mTogglableButton ) + if ( mButtonState != SELECTED_STATE ) { - Released(); - - if( mAutoRepeating ) - { - mAutoRepeatingTimer.Reset(); - } + SetSelected( true ); + mButtonPressedState = TOGGLE_DEPRESSED; + } + else + { + mButtonPressedState = DEPRESSED; } } -} - -void Button::OnButtonDown() -{ - if( !mTogglableButton ) + else { - Toolkit::Button handle( GetOwner() ); - Pressed(); - + mButtonPressedState = DEPRESSED; if( mAutoRepeating ) { - SetUpTimer( mInitialAutoRepeatingDelay ); + SetUpTimer( mInitialAutoRepeatingDelay ); } - - //Emit signal. - mPressedSignal.Emit( handle ); } + + // The pressed signal should be emitted regardless of toggle mode. + Toolkit::Button handle( GetOwner() ); + mPressedSignal.Emit( handle ); } -void Button::OnButtonUp() +void Button::ButtonUp() { - if( ButtonDown == mState ) + if( DEPRESSED == mButtonPressedState ) { - if( mTogglableButton ) + bool validButtonAction = false; + + if( mTogglableButton ) // Button up will change state { - SetSelected( !mSelected ); + OnToggleReleased(); // Derived toggle buttons can override this to provide custom behaviour } else { - Released(); - + Released(); // Button up will result in unselected state if( mAutoRepeating ) { mAutoRepeatingTimer.Reset(); } + validButtonAction = true; + } + if ( validButtonAction ) + { + // The clicked and released signals should be emitted regardless of toggle mode. Toolkit::Button handle( GetOwner() ); - - //Emit signal. mReleasedSignal.Emit( handle ); mClickedSignal.Emit( handle ); } } } +bool Button::OnToggleReleased() +{ + SetSelected( !IsSelected() ); + mButtonPressedState = UNPRESSED; + return true; +} + + void Button::OnTouchPointLeave() { - if( ButtonDown == mState ) + if( DEPRESSED == mButtonPressedState ) { if( !mTogglableButton ) { - Toolkit::Button handle( GetOwner() ); - Released(); if( mAutoRepeating ) { mAutoRepeatingTimer.Reset(); } - - //Emit signal. - mReleasedSignal.Emit( handle ); } + + mButtonPressedState = UNPRESSED; + + // The released signal should be emitted regardless of toggle mode. + Toolkit::Button handle( GetOwner() ); + mReleasedSignal.Emit( handle ); } } @@ -812,435 +628,425 @@ bool Button::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tr return connected; } -bool Button::OnTouchEvent(const TouchEvent& event) +void Button::OnInitialize() +{ + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnInitialize\n" ); + + Actor self = Self(); + + mTapDetector = TapGestureDetector::New(); + mTapDetector.Attach( self ); + mTapDetector.DetectedSignal().Connect(this, &Button::OnTap); + + self.SetKeyboardFocusable( true ); + + self.TouchSignal().Connect( this, &Button::OnTouch ); +} + +bool Button::OnAccessibilityActivated() +{ + return OnKeyboardEnter(); +} + +bool Button::OnTouch( Actor actor, const TouchData& touch ) { + // Only events are processed when the button is not disabled and the touch event has only // one touch point. - if( ( !mDisabled ) && ( 1 == event.GetPointCount() ) ) + + if( !IsDisabled() && ( 1 == touch.GetPointCount() ) ) { - switch( event.GetPoint(0).state ) + switch( touch.GetState( 0 ) ) { - case TouchPoint::Down: + case PointState::DOWN: { - OnButtonDown(); // Notification for derived classes. - - // Sets the button state to ButtonDown. - mState = ButtonDown; + ButtonDown(); break; } - case TouchPoint::Up: + case PointState::UP: { - OnButtonUp(); // Notification for derived classes. - - // Sets the button state to ButtonUp. - mState = ButtonUp; + ButtonUp(); break; } - case TouchPoint::Interrupted: + case PointState::INTERRUPTED: { - OnTouchPointInterrupted(); // Notification for derived classes. - - // Sets the button state to the default (ButtonUp). - mState = ButtonUp; + OnTouchPointInterrupted(); break; } - case TouchPoint::Leave: + case PointState::LEAVE: { - OnTouchPointLeave(); // Notification for derived classes. - - // Sets the button state to the default (ButtonUp). - mState = ButtonUp; + OnTouchPointLeave(); break; } - case TouchPoint::Motion: - case TouchPoint::Stationary: // FALLTHROUGH + case PointState::MOTION: + case PointState::STATIONARY: // FALLTHROUGH { // Nothing to do break; } - default: - { - DALI_ASSERT_ALWAYS( !"Point status unhandled." ); - break; - } } } - else if( 1 < event.GetPointCount() ) + else if( 1 < touch.GetPointCount() ) { OnTouchPointLeave(); // Notification for derived classes. - // Sets the button state to the default (ButtonUp). - mState = ButtonUp; + // Sets the button state to the default + mButtonPressedState = UNPRESSED; } return false; } -void Button::OnInitialize() +bool Button::OnKeyboardEnter() { - Actor self = Self(); - - mTapDetector = TapGestureDetector::New(); - mTapDetector.Attach( self ); - mTapDetector.DetectedSignal().Connect(this, &Button::OnTap); - - OnButtonInitialize(); + // When the enter key is pressed, or button is activated, the click action is performed. + Property::Map attributes; + bool ret = DoClickAction( attributes ); - self.SetKeyboardFocusable( true ); + return ret; } -bool Button::OnAccessibilityActivated() +void Button::OnStageDisconnection() { - return OnKeyboardEnter(); -} + if( DEPRESSED == mButtonPressedState ) + { + if( !mTogglableButton ) + { + Released(); -bool Button::OnKeyboardEnter() -{ - // When the enter key is pressed, or button is activated, the click action is performed. - Property::Map attributes; - bool ret = DoClickAction( attributes ); + if( mAutoRepeating ) + { + mAutoRepeatingTimer.Reset(); + } + } + } - return ret; -} + mButtonPressedState = UNPRESSED; -void Button::OnControlStageDisconnection() -{ - OnButtonStageDisconnection(); // Notification for derived classes. - mState = ButtonUp; + Control::OnStageDisconnection(); // Visuals will be set off stage } -void Button::OnTap(Actor actor, const TapGesture& tap) +void Button::OnStageConnection( int depth ) { - // Do nothing. -} + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnStageConnection ptr(%p) \n", this ); + PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState ); + Control::OnStageConnection( depth ); // Enabled visuals will be put on stage -void Button::SetUpTimer( float delay ) -{ - mAutoRepeatingTimer = Dali::Timer::New( static_cast( 1000.f * delay ) ); - mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot ); - mAutoRepeatingTimer.Start(); } -bool Button::AutoRepeatingSlot() +Vector3 Button::GetNaturalSize() { - bool consumed = false; - if( !mDisabled ) - { - // Restart the autorepeat timer. - SetUpTimer( mNextAutoRepeatingDelay ); + Vector3 size = Vector3::ZERO; - Pressed(); + bool horizontalAlignment = mTextLabelAlignment == BEGIN || mTextLabelAlignment == END; // label and visual side by side - Toolkit::Button handle( GetOwner() ); + // Get natural size of foreground ( largest of the possible visuals ) + Size largestForegroundVisual; + Size labelSize; - //Emit signal. - consumed = mReleasedSignal.Emit( handle ); - consumed |= mClickedSignal.Emit( handle ); - consumed |= mPressedSignal.Emit( handle ); - } - - return consumed; -} - -void Button::Pressed() -{ - if( mPaintState == UnselectedState ) + for ( int state = Button::UNSELECTED_STATE; state < Button::STATE_COUNT; state++) { - StopTransitionAnimation(); - - // Notifies the derived class the button has been pressed. - OnPressed(); - - //Layer Order - //(4) mSelectedContent (Inserted) - //(3) mUnselectedContent - //(2) mSelectedBackgroundContent (Inserted) - //(1) mBackgroundContent - - TransitionInBetween( mUnselectedContent, mLabel, mSelectedContent ); - TransitionInAbove( mBackgroundContent, mSelectedBackgroundContent ); - TransitionInAtIndex( 0, mBackgroundContent ); - - TransitionOut( mUnselectedContent ); - TransitionOut( mDisabledContent ); - TransitionOut( mDisabledSelectedContent ); - TransitionOut( mDisabledBackgroundContent ); - - mPaintState = SelectedState; - - StartTransitionAnimation(); + Toolkit::Visual::Base visual = GetVisual( GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND] ); + Size visualSize; + if ( visual ) + { + visual.GetNaturalSize( visualSize ); + largestForegroundVisual.width = std::max(largestForegroundVisual.width, visualSize.width ); + largestForegroundVisual.height = std::max(largestForegroundVisual.height, visualSize.height ); + } } -} -void Button::Released() -{ - if( mPaintState == SelectedState ) + // Get horizontal padding total + if ( largestForegroundVisual.width > 0 ) // if visual exists { - StopTransitionAnimation(); - - // Notifies the derived class the button has been released. - OnReleased(); + size.width += largestForegroundVisual.width + mForegroundPadding.left + mForegroundPadding.right; + } + // Get vertical padding total + if ( largestForegroundVisual.height > 0 ) + { + size.height += largestForegroundVisual.height + mForegroundPadding.top + mForegroundPadding.bottom; + } - //Layer Order - //(3) mUnselectedContent (Inserted) - //(2) mSelectedContent - //(1) mBackgroundContent + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize visual Size(%f,%f)\n", + largestForegroundVisual.width, largestForegroundVisual.height ); - TransitionInBetween( mSelectedContent, mLabel, mUnselectedContent ); - TransitionInAtIndex( 0, mBackgroundContent ); + // Get natural size of label + if ( mLabel ) + { + labelSize = Vector2( mLabel.GetNaturalSize()); - TransitionOut( mSelectedContent ); - TransitionOut( mSelectedBackgroundContent ); - TransitionOut( mDisabledContent ); - TransitionOut( mDisabledSelectedContent ); - TransitionOut( mDisabledBackgroundContent ); + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize labelSize(%f,%f) padding(%f,%f)\n", + labelSize.width, labelSize.height, mLabelPadding.left + mLabelPadding.right, mLabelPadding.top + mLabelPadding.bottom); - mPaintState = UnselectedState; + labelSize.width += mLabelPadding.left + mLabelPadding.right; + labelSize.height += mLabelPadding.top + mLabelPadding.bottom; - StartTransitionAnimation(); + // Add label size to height or width depending on alignment position + if ( horizontalAlignment ) + { + size.width += labelSize.width; + size.height = std::max(size.height, labelSize.height ); + } + else + { + size.height += labelSize.height; + size.width = std::max(size.width, labelSize.width ); + } } -} -Button::ButtonState Button::GetState() -{ - return mState; -} - -Button::PaintState Button::GetPaintState() -{ - return mPaintState; -} - -bool Button::InsertButtonImage( unsigned int index, Actor& actor ) -{ - if( actor ) + if( size.width < 1 && size.height < 1 ) { - Self().Insert( index, actor ); - PrepareForTranstionOut( actor ); - return true; + // if no image or label then use Control's natural size + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize Using control natural size\n"); + size = Control::GetNaturalSize(); } - return false; -} + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "Button GetNaturalSize (%f,%f)\n", size.width, size.height ); -void Button::RemoveButtonImage( Actor& actor ) -{ - if( actor ) - { - if( actor.GetParent() ) - { - Self().Remove( actor ); - } - PrepareForTranstionIn( actor ); - } + return size; } -unsigned int Button::FindChildIndex( Actor& actor ) +void Button::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension ) { - Actor self = Self(); - unsigned int childrenNum = self.GetChildCount(); + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnSetResizePolicy\n"); - for( unsigned int i = 0; i < childrenNum; i++ ) + if ( policy != ResizePolicy::USE_NATURAL_SIZE || policy != ResizePolicy::FIT_TO_CHILDREN ) { - Actor child = self.GetChildAt( i ); - if( child == actor ) + if ( mLabel ) { - return i; + // todo Can't set Text Label to USE_ASSIGNED_SIZE as causes a relayout in it whilst doing a relayout = error + //mLabel.SetResizePolicy(ResizePolicy::USE_ASSIGNED_SIZE, Dimension::ALL_DIMENSIONS ); } } - return childrenNum; + RelayoutRequest(); } -void Button::TransitionInBetween( Actor childLower, Actor childUpper, Actor actor ) +void Button::OnRelayout( const Vector2& size, RelayoutContainer& container ) { - unsigned int index = childLower ? FindChildIndex( childLower ) + 1 : FindChildIndex( childUpper ); - TransitionInAtIndex( index, actor ); -} + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout targetSize(%f,%f) ptr(%p) state[%d]\n", size.width, size.height, this, mButtonState ); -void Button::TransitionInAbove( Actor child, Actor actor ) -{ - unsigned int index = child ? FindChildIndex( child ) + 1 : 0; - TransitionInAtIndex( index, actor ); -} + Toolkit::Visual::Base currentVisual = GetVisual( GET_VISUAL_INDEX_FOR_STATE[mButtonState][FOREGROUND] ); -void Button::TransitionInAtIndex( unsigned int index, Actor actor ) -{ - if( actor ) + Toolkit::Visual::Base currentBackGroundVisual = GetVisual( GET_VISUAL_INDEX_FOR_STATE[mButtonState][BACKGROUND] ); + + // Sizes and padding set to zero, if not present then values will no effect calculations. + Vector2 visualPosition = Vector2::ZERO; + Vector2 labelPosition = Vector2::ZERO; + Size visualSize = Size::ZERO; + Padding foregroundVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f ); + Padding labelVisualPadding = Padding(0.0f, 0.0f, 0.0f, 0.0f ); + + if ( mLabel ) { - if( !actor.GetParent() ) - { - Self().Insert( index, actor ); - } + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Label padding setting padding:%f,%f,%f,%f\n", mLabelPadding.y, mLabelPadding.x, mLabelPadding.width,mLabelPadding.height ); + labelVisualPadding = mLabelPadding; + } - OnTransitionIn( actor ); + if ( currentVisual ) + { + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Foreground Visual setting padding:%f,%f,%f,%f\n", mForegroundPadding.y, mForegroundPadding.x, mForegroundPadding.width,mForegroundPadding.height ); + currentVisual.GetNaturalSize( visualSize ); + foregroundVisualPadding = mForegroundPadding; } -} -void Button::TransitionOut( Actor actor ) -{ - OnTransitionOut( actor ); -} + Toolkit::Align::Type visualAnchorPoint = Toolkit::Align::TOP_BEGIN; -void Button::ResetImageLayers() -{ - //ensure that all layers are in the correct order and state according to the paint state + Vector2 visualAndPaddingSize = Vector2( ( foregroundVisualPadding.x + visualSize.width + foregroundVisualPadding.y ), + ( foregroundVisualPadding.width + visualSize.height + foregroundVisualPadding.height )); + + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout visualAndPaddingSize(%f,%f)\n", visualAndPaddingSize.width, visualAndPaddingSize.height); - int index = 0; - switch( mPaintState ) + switch ( mTextLabelAlignment ) { - case UnselectedState: + case BEGIN : { - //Layer Order - //(2) mUnselectedContent - //(1) mBackgroundContent + visualAnchorPoint = Toolkit::Align::TOP_END; + visualPosition.x = foregroundVisualPadding.right; + visualPosition.y = foregroundVisualPadding.top; - RemoveButtonImage( mSelectedContent ); - RemoveButtonImage( mSelectedBackgroundContent ); - RemoveButtonImage( mDisabledContent ); - RemoveButtonImage( mDisabledSelectedContent ); - RemoveButtonImage( mDisabledBackgroundContent ); - - if( InsertButtonImage( index, mBackgroundContent ) ) - { - ++index; - } - if( InsertButtonImage( index, mUnselectedContent ) ) - { - ++index; - } + labelPosition.x = labelVisualPadding.x; + labelPosition.y = labelVisualPadding.top; break; } - case SelectedState: + case END : { - //Layer Order - //(3) mSelectedContent - //(2) mSelectedBackgroundContent - //(1) mBackgroundContent + visualAnchorPoint = Toolkit::Align::TOP_BEGIN; + visualPosition.x = foregroundVisualPadding.left; + visualPosition.y = foregroundVisualPadding.top; - RemoveButtonImage( mUnselectedContent ); - RemoveButtonImage( mDisabledContent ); - RemoveButtonImage( mDisabledSelectedContent ); - RemoveButtonImage( mDisabledBackgroundContent ); - - if( InsertButtonImage( index, mBackgroundContent ) ) - { - ++index; - } - if( InsertButtonImage( index, mSelectedBackgroundContent ) ) - { - ++index; - } - if( InsertButtonImage( index, mSelectedContent ) ) - { - ++index; - } + labelPosition.x = visualAndPaddingSize.width + labelVisualPadding.x; + labelPosition.y = labelVisualPadding.top; break; } - case DisabledUnselectedState: + case TOP : { - //Layer Order - //(2) mDisabledContent - //(1) mDisabledBackgroundContent - - RemoveButtonImage( mUnselectedContent ); - RemoveButtonImage( mBackgroundContent ); - RemoveButtonImage( mSelectedContent ); - RemoveButtonImage( mDisabledSelectedContent ); - RemoveButtonImage( mSelectedBackgroundContent ); + visualAnchorPoint = Toolkit::Align::BOTTOM_END; + visualPosition.x = foregroundVisualPadding.left; + visualPosition.y = foregroundVisualPadding.bottom; - if( InsertButtonImage( index, mDisabledBackgroundContent ? mDisabledBackgroundContent : mBackgroundContent ) ) - { - ++index; - } - if( InsertButtonImage( index, mDisabledContent ? mDisabledContent : mUnselectedContent ) ) - { - ++index; - } + labelPosition.x = labelVisualPadding.left; + labelPosition.y = labelVisualPadding.top; break; } - case DisabledSelectedState: + case BOTTOM : { - //Layer Order - // (2) mDisabledSelectedContent - // (1) mDisabledBackgroundContent + visualAnchorPoint = Toolkit::Align::TOP_END; + visualPosition.x = foregroundVisualPadding.left; + visualPosition.y = foregroundVisualPadding.top; - RemoveButtonImage( mUnselectedContent ); - RemoveButtonImage( mSelectedContent ); - RemoveButtonImage( mBackgroundContent ); - RemoveButtonImage( mSelectedBackgroundContent ); - RemoveButtonImage( mDisabledContent ); + labelPosition.x = labelVisualPadding.left; + labelPosition.y = visualAndPaddingSize.height + labelVisualPadding.top; + break; + } + } - if( mDisabledBackgroundContent ) - { - if( InsertButtonImage( index, mDisabledBackgroundContent) ) - { - ++index; - } - } - else - { - if( InsertButtonImage( index, mBackgroundContent ) ) - { - ++index; - } - if( InsertButtonImage( index, mSelectedBackgroundContent ) ) - { - ++index; - } - } + if ( currentBackGroundVisual ) + { + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual bakcground size to(%f,%f)\n", size.width, size.height); - if( InsertButtonImage( index, mDisabledSelectedContent ? mDisabledSelectedContent : mSelectedContent) ) - { - ++index; - } - break; + Property::Map visualTransform; + + visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, size ) + .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4( 0.0f, 0.0f, 1.0f, 1.0f) ); // Use relative size + + currentBackGroundVisual.SetTransformAndSize( visualTransform, size ); + } + + if ( currentVisual ) + { + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Setting visual size to(%f,%f)\n", visualSize.width, visualSize.height); + + currentVisual.SetProperty( Toolkit::Visual::DevelProperty::TRANSFORM, + Dali::Property::Map() + .Add( Toolkit::Visual::DevelProperty::Transform::Property::SIZE, visualSize ) + .Add( Toolkit::Visual::DevelProperty::Transform::Property::OFFSET, visualPosition ) + .Add( Toolkit::Visual::DevelProperty::Transform::Property::OFFSET_SIZE_MODE, Vector4(1.0f, 1.0f, 1.0f,1.0f) ) + .Add( Toolkit::Visual::DevelProperty::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN ) + .Add( Toolkit::Visual::DevelProperty::Transform::Property::ANCHOR_POINT, visualAnchorPoint ) + ); + } + + if ( mLabel ) + { + // When Text visual size can be set, determine the size here. + // Text Visual should take all space available after foreground visual size and all padding is considered. + // Remaining Space priority, Foreground padding, foreground visual, Text padding then Text visual. + + Size remainingSpaceForText = Size::ZERO; + remainingSpaceForText.width = size.width - visualAndPaddingSize.width - labelVisualPadding.x - labelVisualPadding.y; + remainingSpaceForText.height = size.height - visualAndPaddingSize.height - labelVisualPadding.width - labelVisualPadding.height; + + if ( !currentVisual ) + { + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout Only Text\n"); + + // Center Text if no foreground visual + Size labelNaturalSize = Vector2( mLabel.GetNaturalSize() ); + + // A Text visual will take up all the remainingSpaceForText, for now TextLabel natural size needed for positioning. + labelPosition.x = labelVisualPadding.left + remainingSpaceForText.width*0.5 - labelNaturalSize.width *0.5; + labelPosition.y = labelVisualPadding.height + remainingSpaceForText.height*0.5 - labelNaturalSize.height *0.5; } + + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout text Size(%f,%f) text Position(%f,%f) \n", remainingSpaceForText.width, remainingSpaceForText.height, labelPosition.x, labelPosition.y); + + mLabel.SetPosition( labelPosition.x, labelPosition.y ); + container.Add( mLabel, remainingSpaceForText ); // Currently a TextLabel is used and size can not be set here. } + + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnRelayout << \n"); +} + +void Button::OnTap(Actor actor, const TapGesture& tap) +{ + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "OnTap\n" ); } -void Button::StartTransitionAnimation() +void Button::SetUpTimer( float delay ) { - if( mTransitionAnimation ) + mAutoRepeatingTimer = Dali::Timer::New( static_cast( 1000.f * delay ) ); + mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot ); + mAutoRepeatingTimer.Start(); +} + +bool Button::AutoRepeatingSlot() +{ + bool consumed = false; + if( !IsDisabled() ) { - mTransitionAnimation.Play(); - } - else + // Restart the autorepeat timer. + SetUpTimer( mNextAutoRepeatingDelay ); + + Pressed(); + + Toolkit::Button handle( GetOwner() ); + + //Emit signal. + consumed = mReleasedSignal.Emit( handle ); + consumed = mClickedSignal.Emit( handle ); + consumed |= mPressedSignal.Emit( handle ); + } + + return consumed; +} + +void Button::Pressed() +{ + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Pressed\n" ); + + if( mButtonState == UNSELECTED_STATE ) { - ResetImageLayers(); + ChangeState( SELECTED_STATE ); + OnPressed(); // Notifies the derived class the button has been pressed. } } -void Button::StopTransitionAnimation() +void Button::Released() { - if( mTransitionAnimation ) + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::Released\n" ); + + if( mButtonState == SELECTED_STATE && !mTogglableButton ) { - mTransitionAnimation.Clear(); - mTransitionAnimation.Reset(); + ChangeState( UNSELECTED_STATE ); + OnReleased(); // // Notifies the derived class the button has been released. } + mButtonPressedState = UNPRESSED; +} + +void Button::SelectRequiredVisual( Property::Index visualIndex ) +{ + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SelectRequiredVisual index(%d) state(%d)\n", visualIndex, mButtonState ); + + EnableVisual( visualIndex, true ); } -Dali::Animation Button::GetTransitionAnimation() +void Button::RemoveVisual( Property::Index visualIndex ) { - if( !mTransitionAnimation ) + // Use OnButtonVisualRemoval if want button developer to have the option to override removal. + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::RemoveVisual index(%d) state(%d)\n", visualIndex, mButtonState ); + + Toolkit::Visual::Base visual = GetVisual( visualIndex ); + + if( visual ) { - mTransitionAnimation = Dali::Animation::New( GetAnimationTime() ); - mTransitionAnimation.FinishedSignal().Connect( this, &Button::TransitionAnimationFinished ); + EnableVisual( visualIndex, false ); } - - return mTransitionAnimation; } -void Button::TransitionAnimationFinished( Dali::Animation& source ) +void Button::OnButtonVisualRemoval( Property::Index visualIndex ) { - StopTransitionAnimation(); - ResetImageLayers(); + // Derived Buttons can over ride this to prevent default removal. + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnButtonVisualRemoval index(%d)\n", visualIndex ); + RemoveVisual( visualIndex ); } void Button::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value ) { Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) ); + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetProperty index[%d]\n", index ); + if ( button ) { switch ( index ) @@ -1281,27 +1087,81 @@ void Button::SetProperty( BaseObject* object, Property::Index index, const Prope break; } - case Toolkit::Button::Property::NORMAL_STATE_ACTOR: + case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE: // Legacy Tizen 3.0 + { + GetImplementation( button ).CreateVisualsForComponent( Toolkit::Button::Property::UNSELECTED_VISUAL, value, DepthIndex::CONTENT ); + break; + } + case Toolkit::Button::Property::DISABLED_STATE_IMAGE: // Legacy Tizen 3.0 + { + GetImplementation( button ).CreateVisualsForComponent( Toolkit::Button::Property::DISABLED_UNSELECTED_VISUAL, value, DepthIndex::CONTENT ); + break; + } + case Toolkit::Button::Property::SELECTED_STATE_IMAGE: // Legacy Tizen 3.0 + { + GetImplementation( button ).CreateVisualsForComponent( Toolkit::Button::Property::SELECTED_VISUAL, value, DepthIndex::CONTENT ); + break; + } + case Toolkit::Button::Property::UNSELECTED_VISUAL: + case Toolkit::Button::Property::SELECTED_VISUAL: + case Toolkit::Button::Property::DISABLED_SELECTED_VISUAL: + case Toolkit::Button::Property::DISABLED_UNSELECTED_VISUAL: + { + GetImplementation( button ).CreateVisualsForComponent( index, value, DepthIndex::CONTENT ); + break; + } + + case Toolkit::Button::Property::UNSELECTED_BACKGROUND_VISUAL: + case Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL: + case Toolkit::Button::Property::DISABLED_SELECTED_BACKGROUND_VISUAL: + case Toolkit::Button::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL: + { + GetImplementation( button ).CreateVisualsForComponent( index , value, DepthIndex::BACKGROUND); + break; + } + + case Toolkit::Button::Property::UNSELECTED_COLOR: { - GetImplementation( button ).SetButtonImage( Scripting::NewActor( value.Get< Property::Map >() ) ); + DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::UNSELECTED_COLOR instead use Button::Property::UNSELECTED_BACKGROUND_VISUAL\n", __FUNCTION__); + GetImplementation( button ).SetColor( value.Get< Vector4 >(), Toolkit::Button::Property::UNSELECTED_BACKGROUND_VISUAL ); break; } - case Toolkit::Button::Property::SELECTED_STATE_ACTOR: + case Toolkit::Button::Property::SELECTED_COLOR: { - GetImplementation( button ).SetSelectedImage( Scripting::NewActor( value.Get< Property::Map >() ) ); + DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::SELECTED_COLOR instead use Button::Property::SELECTED_BACKGROUND_VISUAL\n", __FUNCTION__); + GetImplementation( button ).SetColor( value.Get< Vector4 >(), Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL ); break; } - case Toolkit::Button::Property::DISABLED_STATE_ACTOR: + case Toolkit::Button::Property::LABEL_TEXT: { - GetImplementation( button ).SetDisabledImage( Scripting::NewActor( value.Get< Property::Map >() ) ); + DALI_LOG_WARNING("[%s] Using deprecated Property Button::Property::LABEL_TEXT instead use Button::Property::LABEL\n", __FUNCTION__); + Property::Map labelTextProperty; + labelTextProperty.Insert( "text", value.Get< std::string >() ); + GetImplementation( button ).SetupLabel( labelTextProperty ); + break; + } + + case Toolkit::Button::Property::LABEL: + { + // Get a Property::Map from the property if possible. + Property::Map setPropertyMap; + if( value.Get( setPropertyMap ) ) + { + GetImplementation( button ).SetupLabel( setPropertyMap ); + } break; } - case Toolkit::Button::Property::LABEL_ACTOR: + case Toolkit::Button::Property::LABEL_RELATIVE_ALIGNMENT: { - GetImplementation( button ).SetLabel( Scripting::NewActor( value.Get< Property::Map >() ) ); + Button::Align labelAlignment(END); + Scripting::GetEnumeration< Button::Align> ( value.Get< std::string >().c_str(), + ALIGNMENT_TABLE, ALIGNMENT_TABLE_COUNT, + labelAlignment ); + + GetImplementation( button ).SetLabelAlignment( labelAlignment ); break; } } @@ -1320,7 +1180,7 @@ Property::Value Button::GetProperty( BaseObject* object, Property::Index propert { case Toolkit::Button::Property::DISABLED: { - value = GetImplementation( button ).mDisabled; + value = GetImplementation( button ).IsDisabled(); break; } @@ -1350,39 +1210,69 @@ Property::Value Button::GetProperty( BaseObject* object, Property::Index propert case Toolkit::Button::Property::SELECTED: { - value = GetImplementation( button ).mSelected; + value = GetImplementation( button ).IsSelected(); + break; + } + + case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE: + { + value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::Button::Property::UNSELECTED_VISUAL ); + break; + } + + case Toolkit::Button::Property::SELECTED_STATE_IMAGE: + { + value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::Button::Property::SELECTED_VISUAL ); + break; + } + + case Toolkit::Button::Property::DISABLED_STATE_IMAGE: + { + value = GetImplementation( button ).GetUrlForImageVisual( Toolkit::Button::Property::DISABLED_UNSELECTED_VISUAL ); + break; + } + + case Toolkit::Button::Property::UNSELECTED_COLOR: + { + value = GetImplementation( button ).GetUnselectedColor(); + break; + } + + case Toolkit::Button::Property::SELECTED_COLOR: + { + value = GetImplementation( button ).GetSelectedColor(); break; } - case Toolkit::Button::Property::NORMAL_STATE_ACTOR: + case Toolkit::Button::Property::LABEL_TEXT: { - Property::Map map; - Scripting::CreatePropertyMap( GetImplementation( button ).mUnselectedContent, map ); - value = map; + value = GetImplementation( button ).GetLabelText(); break; } - case Toolkit::Button::Property::SELECTED_STATE_ACTOR: + case Toolkit::Button::Property::LABEL: { - Property::Map map; - Scripting::CreatePropertyMap( GetImplementation( button ).mSelectedContent, map ); - value = map; + Property::Map emptyMap; + value = emptyMap; break; } - case Toolkit::Button::Property::DISABLED_STATE_ACTOR: + case Toolkit::Button::Property::LABEL_STRUT_LENGTH: { - Property::Map map; - Scripting::CreatePropertyMap( GetImplementation( button ).mDisabledContent, map ); - value = map; + value = GetImplementation( button ).GetLabelStrutLength(); break; } - case Toolkit::Button::Property::LABEL_ACTOR: + case Toolkit::Button::Property::LABEL_RELATIVE_ALIGNMENT: { - Property::Map map; - Scripting::CreatePropertyMap( GetImplementation( button ).mLabel, map ); - value = map; + const char* alignment = Scripting::GetEnumerationName< Button::Align >( GetImplementation( button ).GetLabelAlignment(), + ALIGNMENT_STRING_TABLE, + ALIGNMENT_STRING_TABLE_COUNT ); + if( alignment ) + { + value = std::string( alignment ); + } + break; } } @@ -1391,6 +1281,174 @@ Property::Value Button::GetProperty( BaseObject* object, Property::Index propert return value; } +void Button::SetLabelPadding( const Padding& padding) +{ + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetLabelPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top ); + mLabelPadding = Padding( padding.left, padding.right, padding.bottom, padding.top ); + RelayoutRequest(); +} + +Padding Button::GetLabelPadding() +{ + return mLabelPadding; +} + +void Button::SetForegroundPadding( const Padding& padding) +{ + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetForegroundPadding padding(%f,%f,%f,%f)\n", padding.left, padding.right, padding.bottom, padding.top ); + mForegroundPadding = Padding( padding.left, padding.right, padding.bottom, padding.top ); + RelayoutRequest(); +} + +Padding Button::GetForegroundPadding() +{ + return mForegroundPadding; +} + +//////////////////////////////////////////////////////////////////////// +// Legacy functions from Tizen 2.4 and 3.0 + +// Legacy code needed whilst Color can be set by direct Property setting ( deprecated ) instead of setting a Visual +void Button::SetColor( const Vector4& color, Property::Index visualIndex ) +{ + if ( visualIndex == Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL ) + { + mSelectedColor = color; + } + else + { + mUnselectedColor = color; + } + + Property::Map map; + map[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::COLOR; + map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color; + + CreateVisualsForComponent( visualIndex, map, DepthIndex::BACKGROUND ); +} + +const Vector4 Button::GetUnselectedColor() const +{ + return mUnselectedColor; +} + +const Vector4 Button::GetSelectedColor() const +{ + return mSelectedColor; +} + +void Button::SetAnimationTime( float animationTime ) +{ + // Used by depreciated API + mAnimationTime = animationTime; +} + +float Button::GetAnimationTime() const +{ + // Used by depreciated API + return mAnimationTime; +} + +void Button::SetLabel( Actor label ) +{ + if ( label ) + { + Property::Value value =""; + value = label.GetProperty(Toolkit::TextLabel::Property::TEXT); + + SetLabelText( value.Get() ); + } +} + +void Button::SetUnselectedImage( const std::string& filename ) +{ + if( !filename.empty() ) + { + CreateVisualsForComponent( Toolkit::Button::Property::UNSELECTED_VISUAL, filename, DepthIndex::CONTENT ); + } +} + +void Button::SetBackgroundImage( const std::string& filename ) +{ + if( !filename.empty() ) + { + CreateVisualsForComponent( Toolkit::Button::Property::UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND ); + } +} + +void Button::SetSelectedImage( const std::string& filename ) +{ + if( !filename.empty() ) + { + CreateVisualsForComponent( Toolkit::Button::Property::SELECTED_VISUAL, filename, DepthIndex::CONTENT ); + } +} + +void Button::SetSelectedBackgroundImage( const std::string& filename ) +{ + if( !filename.empty() ) + { + CreateVisualsForComponent( Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND ); + } +} + +void Button::SetDisabledBackgroundImage( const std::string& filename ) +{ + if( !filename.empty() ) + { + CreateVisualsForComponent( Toolkit::Button::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, filename, DepthIndex::BACKGROUND ); + } +} + +void Button::SetDisabledImage( const std::string& filename ) +{ + if( !filename.empty() ) + { + CreateVisualsForComponent( Toolkit::Button::Property::DISABLED_UNSELECTED_VISUAL, filename, DepthIndex::CONTENT ); + } +} + +void Button::SetDisabledSelectedImage( const std::string& filename ) +{ + if( !filename.empty() ) + { + CreateVisualsForComponent( Toolkit::Button::Property::DISABLED_SELECTED_VISUAL, filename, DepthIndex::CONTENT ); + } +} + +std::string Button::GetUrlForImageVisual( Property::Index index ) +{ + Toolkit::Visual::Base visual = GetVisual( index ); + std::string result; + + if ( visual ) + { + Dali::Property::Map retreivedMap; + visual.CreatePropertyMap( retreivedMap ); + Property::Value* value = retreivedMap.Find( Toolkit::ImageVisual::Property::URL, Property::STRING ); + if ( value ) + { + result = value->Get(); + } + } + + return result; +} + +// Below functions DEPRECATED_1_0.50 - Return empty Actors + +Actor Button::GetButtonImage() const +{ + DALI_LOG_WARNING("Button::GetButtonImage @DEPRECATED_1_0.50 Returning empty Actor \n"); + return Actor();; +} + +Actor Button::GetSelectedImage() const +{ + DALI_LOG_WARNING("Button::GetSelectedImage @DEPRECATED_1_0.50 Returning empty Actor \n"); + return Actor(); +} + } // namespace Internal } // namespace Toolkit