X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Fpublic-api%2Fcontrols%2Fcontrol-impl.cpp;h=fffbe6962a4516972ff6482fc990c736007e04ea;hp=18dd3fde2aa4006842c9f4130cc7f9e73e369451;hb=9795d65d103bdf0524aa92e96475019eff2705f3;hpb=edd703ba97ff54cc54f6e8734ba23a9bfbe63c7e diff --git a/dali-toolkit/public-api/controls/control-impl.cpp b/dali-toolkit/public-api/controls/control-impl.cpp index 18dd3fd..fffbe69 100644 --- a/dali-toolkit/public-api/controls/control-impl.cpp +++ b/dali-toolkit/public-api/controls/control-impl.cpp @@ -40,8 +40,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -58,6 +60,22 @@ namespace Dali namespace Toolkit { +namespace Internal +{ + +extern const Dali::Scripting::StringEnum ControlStateTable[]; +extern const unsigned int ControlStateTableCount; + + +// Not static or anonymous - shared with other translation units +const Scripting::StringEnum ControlStateTable[] = { + { "NORMAL", Toolkit::DevelControl::NORMAL }, + { "FOCUSED", Toolkit::DevelControl::FOCUSED }, + { "DISABLED", Toolkit::DevelControl::DISABLED }, +}; const unsigned int ControlStateTableCount = sizeof( ControlStateTable ) / sizeof( ControlStateTable[0] ); + +} // Internal namespace + namespace { @@ -121,17 +139,6 @@ Toolkit::Visual::Base GetVisualByName( return visualHandle; } -void SetDefaultTransform( Property::Map& propertyMap ) -{ - propertyMap.Clear(); - propertyMap - .Add( Toolkit::DevelVisual::Transform::Property::OFFSET, Vector2(0.0f, 0.0f) ) - .Add( Toolkit::DevelVisual::Transform::Property::SIZE, Vector2(1.0f, 1.0f) ) - .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::CENTER ) - .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, Toolkit::Align::CENTER ) - .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4::ZERO ); -} - /** * Creates control through type registry */ @@ -257,6 +264,12 @@ public: // Construction & Destruction Impl(Control& controlImpl) : mControlImpl( controlImpl ), + mState( Toolkit::DevelControl::NORMAL ), + mSubStateName(""), + mLeftFocusableActorId( -1 ), + mRightFocusableActorId( -1 ), + mUpFocusableActorId( -1 ), + mDownFocusableActorId( -1 ), mStyleName(""), mBackgroundColor(Color::TRANSPARENT), mStartingPinchScale( NULL ), @@ -323,6 +336,83 @@ public: break; } + case Toolkit::DevelControl::Property::STATE: + { + bool withTransitions=true; + const Property::Value* valuePtr=&value; + Property::Map* map = value.GetMap(); + if(map) + { + Property::Value* value2 = map->Find("withTransitions"); + if( value2 ) + { + withTransitions = value2->Get(); + } + + valuePtr = map->Find("state"); + } + + if( valuePtr ) + { + Toolkit::DevelControl::State state( controlImpl.mImpl->mState ); + if( Scripting::GetEnumerationProperty< Toolkit::DevelControl::State >( *valuePtr, ControlStateTable, ControlStateTableCount, state ) ) + { + controlImpl.mImpl->SetState( state, withTransitions ); + } + } + } + break; + + case Toolkit::DevelControl::Property::SUB_STATE: + { + std::string subState; + if( value.Get( subState ) ) + { + controlImpl.mImpl->SetSubState( subState ); + } + } + break; + + case Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID: + { + int focusId; + if( value.Get( focusId ) ) + { + controlImpl.mImpl->mLeftFocusableActorId = focusId; + } + } + break; + + case Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID: + { + int focusId; + if( value.Get( focusId ) ) + { + controlImpl.mImpl->mRightFocusableActorId = focusId; + } + } + break; + + case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID: + { + int focusId; + if( value.Get( focusId ) ) + { + controlImpl.mImpl->mUpFocusableActorId = focusId; + } + } + break; + + case Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID: + { + int focusId; + if( value.Get( focusId ) ) + { + controlImpl.mImpl->mDownFocusableActorId = focusId; + } + } + break; + case Toolkit::Control::Property::BACKGROUND_COLOR: { DALI_LOG_WARNING( "BACKGROUND_COLOR property is deprecated. Use BACKGROUND property instead\n" ); @@ -362,6 +452,7 @@ public: case Toolkit::Control::Property::BACKGROUND: { std::string url; + Vector4 color; const Property::Map* map = value.GetMap(); if( map && !map->Empty() ) { @@ -377,6 +468,10 @@ public: visual.SetDepthIndex( DepthIndex::BACKGROUND ); } } + else if( value.Get( color ) ) + { + controlImpl.SetBackgroundColor(color); + } else { // The background is an empty property map, so we should clear the background @@ -422,6 +517,42 @@ public: break; } + case Toolkit::DevelControl::Property::STATE: + { + value = controlImpl.mImpl->mState; + break; + } + + case Toolkit::DevelControl::Property::SUB_STATE: + { + value = controlImpl.mImpl->mSubStateName; + break; + } + + case Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID: + { + value = controlImpl.mImpl->mLeftFocusableActorId; + break; + } + + case Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID: + { + value = controlImpl.mImpl->mRightFocusableActorId; + break; + } + + case Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID: + { + value = controlImpl.mImpl->mUpFocusableActorId; + break; + } + + case Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID: + { + value = controlImpl.mImpl->mDownFocusableActorId; + break; + } + case Toolkit::Control::Property::BACKGROUND_COLOR: { DALI_LOG_WARNING( "BACKGROUND_COLOR property is deprecated. Use BACKGROUND property instead\n" ); @@ -478,9 +609,306 @@ public: return value; } + + void CopyInstancedProperties( RegisteredVisualContainer& visuals, Dictionary& instancedProperties ) + { + for(RegisteredVisualContainer::Iterator iter = visuals.Begin(); iter!= visuals.End(); iter++) + { + if( (*iter)->visual ) + { + Property::Map instanceMap; + Toolkit::GetImplementation((*iter)->visual).CreateInstancePropertyMap(instanceMap); + instancedProperties.Add( (*iter)->visual.GetName(), instanceMap ); + } + } + } + + template + void Remove( Dictionary& keyValues, const std::string& name ) + { + keyValues.Remove(name); + } + + void Remove( DictionaryKeys& keys, const std::string& name ) + { + DictionaryKeys::iterator iter = std::find( keys.begin(), keys.end(), name ); + if( iter != keys.end()) + { + keys.erase(iter); + } + } + + void FindChangableVisuals( Dictionary& stateVisualsToAdd, + Dictionary& stateVisualsToChange, + DictionaryKeys& stateVisualsToRemove) + { + DictionaryKeys copyOfStateVisualsToRemove = stateVisualsToRemove; + + for( DictionaryKeys::iterator iter = copyOfStateVisualsToRemove.begin(); + iter != copyOfStateVisualsToRemove.end(); ++iter ) + { + const std::string& visualName = (*iter); + Property::Map* toMap = stateVisualsToAdd.Find( visualName ); + if( toMap ) + { + stateVisualsToChange.Add( visualName, *toMap ); + stateVisualsToAdd.Remove( visualName ); + Remove( stateVisualsToRemove, visualName ); + } + } + } + + void RemoveVisual( RegisteredVisualContainer& visuals, const std::string& visualName ) + { + Actor self( mControlImpl.Self() ); + + for ( RegisteredVisualContainer::Iterator visualIter = visuals.Begin(); + visualIter != visuals.End(); ++visualIter ) + { + Toolkit::Visual::Base visual = (*visualIter)->visual; + if( visual && visual.GetName() == visualName ) + { + Toolkit::GetImplementation(visual).SetOffStage( self ); + (*visualIter)->visual.Reset(); + visuals.Erase( visualIter ); + break; + } + } + } + + void RemoveVisuals( RegisteredVisualContainer& visuals, DictionaryKeys& removeVisuals ) + { + Actor self( mControlImpl.Self() ); + for( DictionaryKeys::iterator iter = removeVisuals.begin(); iter != removeVisuals.end(); ++iter ) + { + const std::string visualName = *iter; + RemoveVisual( visuals, visualName ); + } + } + + Toolkit::DevelVisual::Type GetVisualTypeFromMap( const Property::Map& map ) + { + Property::Value* typeValue = map.Find( Toolkit::DevelVisual::Property::TYPE, VISUAL_TYPE ); + Toolkit::DevelVisual::Type type = Toolkit::DevelVisual::IMAGE; + if( typeValue ) + { + Scripting::GetEnumerationProperty( *typeValue, VISUAL_TYPE_TABLE, VISUAL_TYPE_TABLE_COUNT, type ); + } + return type; + } + + /** + * Go through the list of visuals that are common to both states. + * If they are different types, or are both image types with different + * URLs, then the existing visual needs moving and the new visual creating + */ + void RecreateChangedVisuals( Dictionary& stateVisualsToChange, + Dictionary& instancedProperties ) + { + Dali::CustomActor handle( mControlImpl.GetOwner() ); + for( Dictionary::iterator iter = stateVisualsToChange.Begin(); + iter != stateVisualsToChange.End(); ++iter ) + { + const std::string& visualName = (*iter).key; + const Property::Map& toMap = (*iter).entry; + + // is it a candidate for re-creation? + bool recreate = false; + + Toolkit::Visual::Base visual = GetVisualByName( mVisuals, visualName ); + if( visual ) + { + Property::Map fromMap; + visual.CreatePropertyMap( fromMap ); + + Toolkit::DevelVisual::Type fromType = GetVisualTypeFromMap( fromMap ); + Toolkit::DevelVisual::Type toType = GetVisualTypeFromMap( toMap ); + + if( fromType != toType ) + { + recreate = true; + } + else + { + if( fromType == Toolkit::DevelVisual::IMAGE || fromType == Toolkit::DevelVisual::N_PATCH + || fromType == Toolkit::DevelVisual::SVG || fromType == Toolkit::DevelVisual::ANIMATED_IMAGE ) + { + Property::Value* fromUrl = fromMap.Find( Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME ); + Property::Value* toUrl = toMap.Find( Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME ); + + if( fromUrl && toUrl ) + { + std::string fromUrlString; + std::string toUrlString; + fromUrl->Get(fromUrlString); + toUrl->Get(toUrlString); + + if( fromUrlString != toUrlString ) + { + recreate = true; + } + } + } + } + + const Property::Map* instancedMap = instancedProperties.FindConst( visualName ); + if( recreate || instancedMap ) + { + RemoveVisual( mVisuals, visualName ); + Style::ApplyVisual( handle, visualName, toMap, instancedMap ); + } + else + { + // @todo check to see if we can apply toMap without recreating the visual + // e.g. by setting only animatable properties + // For now, recreate all visuals, but merge in instance data. + RemoveVisual( mVisuals, visualName ); + Style::ApplyVisual( handle, visualName, toMap, instancedMap ); + } + } + } + } + + void ReplaceStateVisualsAndProperties( const StylePtr oldState, const StylePtr newState, const std::string& subState ) + { + // Collect all old visual names + DictionaryKeys stateVisualsToRemove; + if( oldState ) + { + oldState->visuals.GetKeys( stateVisualsToRemove ); + if( ! subState.empty() ) + { + const StylePtr* oldSubState = oldState->subStates.FindConst(subState); + if( oldSubState ) + { + DictionaryKeys subStateVisualsToRemove; + (*oldSubState)->visuals.GetKeys( subStateVisualsToRemove ); + Merge( stateVisualsToRemove, subStateVisualsToRemove ); + } + } + } + + // Collect all new visual properties + Dictionary stateVisualsToAdd; + if( newState ) + { + stateVisualsToAdd = newState->visuals; + if( ! subState.empty() ) + { + const StylePtr* newSubState = newState->subStates.FindConst(subState); + if( newSubState ) + { + stateVisualsToAdd.Merge( (*newSubState)->visuals ); + } + } + } + + // If a name is in both add/remove, move it to change list. + Dictionary stateVisualsToChange; + FindChangableVisuals( stateVisualsToAdd, stateVisualsToChange, stateVisualsToRemove); + + // Copy instanced properties (e.g. text label) of current visuals + Dictionary instancedProperties; + CopyInstancedProperties( mVisuals, instancedProperties ); + + // For each visual in remove list, remove from mVisuals + RemoveVisuals( mVisuals, stateVisualsToRemove ); + + // For each visual in add list, create and add to mVisuals + Dali::CustomActor handle( mControlImpl.GetOwner() ); + Style::ApplyVisuals( handle, stateVisualsToAdd, instancedProperties ); + + // For each visual in change list, if it requires a new visual, + // remove old visual, create and add to mVisuals + RecreateChangedVisuals( stateVisualsToChange, instancedProperties ); + } + + void SetState( DevelControl::State newState, bool withTransitions=true ) + { + DevelControl::State oldState = mState; + Dali::CustomActor handle( mControlImpl.GetOwner() ); + DALI_LOG_INFO(gLogFilter, Debug::Concise, "Control::Impl::SetState: %s\n", + (mState == DevelControl::NORMAL ? "NORMAL" :( + mState == DevelControl::FOCUSED ?"FOCUSED" : ( + mState == DevelControl::DISABLED?"DISABLED":"NONE" )))); + + if( mState != newState ) + { + // If mState was Disabled, and new state is Focused, should probably + // store that fact, e.g. in another property that FocusManager can access. + mState = newState; + + // Trigger state change and transitions + // Apply new style, if stylemanager is available + Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get(); + if( styleManager ) + { + const StylePtr stylePtr = GetImpl( styleManager ).GetRecordedStyle( Toolkit::Control( mControlImpl.GetOwner() ) ); + + if( stylePtr ) + { + std::string oldStateName = Scripting::GetEnumerationName< Toolkit::DevelControl::State >( oldState, ControlStateTable, ControlStateTableCount ); + std::string newStateName = Scripting::GetEnumerationName< Toolkit::DevelControl::State >( newState, ControlStateTable, ControlStateTableCount ); + + const StylePtr* newStateStyle = stylePtr->subStates.Find( newStateName ); + const StylePtr* oldStateStyle = stylePtr->subStates.Find( oldStateName ); + if( oldStateStyle && newStateStyle ) + { + // Only change if both state styles exist + ReplaceStateVisualsAndProperties( *oldStateStyle, *newStateStyle, mSubStateName ); + } + } + } + } + } + + void SetSubState( const std::string& subStateName, bool withTransitions=true ) + { + if( mSubStateName != subStateName ) + { + // Get existing sub-state visuals, and unregister them + Dali::CustomActor handle( mControlImpl.GetOwner() ); + + Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get(); + if( styleManager ) + { + const StylePtr stylePtr = GetImpl( styleManager ).GetRecordedStyle( Toolkit::Control( mControlImpl.GetOwner() ) ); + if( stylePtr ) + { + // Stringify state + std::string stateName = Scripting::GetEnumerationName< Toolkit::DevelControl::State >( mState, ControlStateTable, ControlStateTableCount ); + + const StylePtr* state = stylePtr->subStates.Find( stateName ); + if( state ) + { + StylePtr stateStyle(*state); + + const StylePtr* newStateStyle = stateStyle->subStates.Find( subStateName ); + const StylePtr* oldStateStyle = stateStyle->subStates.Find( mSubStateName ); + if( oldStateStyle && newStateStyle ) + { + std::string empty; + ReplaceStateVisualsAndProperties( *oldStateStyle, *newStateStyle, empty ); + } + } + } + } + + mSubStateName = subStateName; + } + } + // Data Control& mControlImpl; + DevelControl::State mState; + std::string mSubStateName; + + int mLeftFocusableActorId; ///< Actor ID of Left focusable control. + int mRightFocusableActorId; ///< Actor ID of Right focusable control. + int mUpFocusableActorId; ///< Actor ID of Up focusable control. + int mDownFocusableActorId; ///< Actor ID of Down focusable control. + RegisteredVisualContainer mVisuals; // Stores visuals needed by the control, non trivial type so std::vector used. std::string mStyleName; Vector4 mBackgroundColor; ///< The color of the background visual @@ -509,15 +937,27 @@ public: static const PropertyRegistration PROPERTY_4; static const PropertyRegistration PROPERTY_5; static const PropertyRegistration PROPERTY_6; + static const PropertyRegistration PROPERTY_7; + static const PropertyRegistration PROPERTY_8; + static const PropertyRegistration PROPERTY_9; + static const PropertyRegistration PROPERTY_10; + static const PropertyRegistration PROPERTY_11; + static const PropertyRegistration PROPERTY_12; }; // Properties registered without macro to use specific member variables. -const PropertyRegistration Control::Impl::PROPERTY_1( typeRegistration, "styleName", Toolkit::Control::Property::STYLE_NAME, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_2( typeRegistration, "backgroundColor", Toolkit::Control::Property::BACKGROUND_COLOR, Property::VECTOR4, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_3( typeRegistration, "backgroundImage", Toolkit::Control::Property::BACKGROUND_IMAGE, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_4( typeRegistration, "keyInputFocus", Toolkit::Control::Property::KEY_INPUT_FOCUS, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_5( typeRegistration, "background", Toolkit::Control::Property::BACKGROUND, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_6( typeRegistration, "tooltip", Toolkit::DevelControl::Property::TOOLTIP, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); +const PropertyRegistration Control::Impl::PROPERTY_1( typeRegistration, "styleName", Toolkit::Control::Property::STYLE_NAME, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); +const PropertyRegistration Control::Impl::PROPERTY_2( typeRegistration, "backgroundColor", Toolkit::Control::Property::BACKGROUND_COLOR, Property::VECTOR4, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); +const PropertyRegistration Control::Impl::PROPERTY_3( typeRegistration, "backgroundImage", Toolkit::Control::Property::BACKGROUND_IMAGE, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); +const PropertyRegistration Control::Impl::PROPERTY_4( typeRegistration, "keyInputFocus", Toolkit::Control::Property::KEY_INPUT_FOCUS, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); +const PropertyRegistration Control::Impl::PROPERTY_5( typeRegistration, "background", Toolkit::Control::Property::BACKGROUND, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); +const PropertyRegistration Control::Impl::PROPERTY_6( typeRegistration, "tooltip", Toolkit::DevelControl::Property::TOOLTIP, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); +const PropertyRegistration Control::Impl::PROPERTY_7( typeRegistration, "state", Toolkit::DevelControl::Property::STATE, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); +const PropertyRegistration Control::Impl::PROPERTY_8( typeRegistration, "subState", Toolkit::DevelControl::Property::SUB_STATE, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); +const PropertyRegistration Control::Impl::PROPERTY_9( typeRegistration, "leftFocusableActorId", Toolkit::DevelControl::Property::LEFT_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); +const PropertyRegistration Control::Impl::PROPERTY_10( typeRegistration, "rightFocusableActorId", Toolkit::DevelControl::Property::RIGHT_FOCUSABLE_ACTOR_ID,Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); +const PropertyRegistration Control::Impl::PROPERTY_11( typeRegistration, "upFocusableActorId", Toolkit::DevelControl::Property::UP_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); +const PropertyRegistration Control::Impl::PROPERTY_12( typeRegistration, "downFocusableActorId", Toolkit::DevelControl::Property::DOWN_FOCUSABLE_ACTOR_ID, Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); Toolkit::Control Control::New() { @@ -702,7 +1142,11 @@ bool Control::HasKeyInputFocus() bool result = false; if( Self().OnStage() ) { - result = Toolkit::KeyInputFocusManager::Get().IsKeyboardListener(Toolkit::Control::DownCast(Self())); + Toolkit::Control control = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl(); + if( Self() == control ) + { + result = true; + } } return result; } @@ -1060,8 +1504,8 @@ void Control::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Ty if( styleManager && change == StyleChange::THEME_CHANGE ) { GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) ); + RelayoutRequest(); } - RelayoutRequest(); } void Control::OnPinch(const PinchGesture& pinch) @@ -1212,9 +1656,7 @@ void Control::OnSizeSet(const Vector3& targetSize) if( visual ) { Vector2 size( targetSize ); - Property::Map transformMap; - SetDefaultTransform( transformMap ); - visual.SetTransformAndSize( transformMap, size ); + visual.SetTransformAndSize( Property::Map(), size ); // Send an empty map as we do not want to modify the visual's set transform } } @@ -1253,10 +1695,7 @@ void Control::OnRelayout( const Vector2& size, RelayoutContainer& container ) Toolkit::Visual::Base visual = GetVisual( Toolkit::Control::Property::BACKGROUND ); if( visual ) { - Vector2 controlSize( size ); - Property::Map transformMap; - SetDefaultTransform( transformMap ); - visual.SetTransformAndSize( transformMap, controlSize ); + visual.SetTransformAndSize( Property::Map(), size ); // Send an empty map as we do not want to modify the visual's set transform } }