From: Ferran Sole Date: Mon, 13 Apr 2015 15:02:37 +0000 (+0100) Subject: Added PathConstrainer and LinearConstrainer support to builder X-Git-Tag: accepted/tizen/common/20150529.134100~31^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=ff26956b1702af9d1ffff11d93cc118f6db5c4ba;hp=--cc Added PathConstrainer and LinearConstrainer support to builder constrainers are defined like this "constrainers": { "constrainer0": { "type":"PathConstrainer", "points":[[100.0, 500.0, 0.0],[400.0, 500.0, 0.0]] , "control-points":[[200.0, 100.0, 0.0],[300.0, 100.0, 0.0]], "forward":[1.0,0.0,0.0] }, "constrainer1": { "type":"LinearConstrainer", "values":[0,400,200,0], "progress":[0.0,0.25,0.75,1.0] } } And they can be applied or remove using signals like this: ... "signals": [ { "name": "on-stage", "action": "applyConstraint", "constrainer": "constrainer0", "properties": [ { "target":"targetActor", "targetProperty":"position", "source":"sourceActor", "sourceProperty":"position-y", "range":[-120.0,300.0] }, { "target":"targetActor", "targetProperty":"orientation", "source":"sourceActor", "sourceProperty":"position-y", "range":[-120.0,300.0] } ] }, ... { "name": "touched", "action": "removeConstraints", "constrainer": "constrainer0", "properties": [ { "target":"targetActor" } ] } Change-Id: I182c5ac2ad53f36fcb17bdcde6c47b9facf12bf0 --- ff26956b1702af9d1ffff11d93cc118f6db5c4ba diff --git a/dali-toolkit/internal/builder/builder-impl.cpp b/dali-toolkit/internal/builder/builder-impl.cpp index fd58ec3..b103bf3 100644 --- a/dali-toolkit/internal/builder/builder-impl.cpp +++ b/dali-toolkit/internal/builder/builder-impl.cpp @@ -815,6 +815,212 @@ Path Builder::GetPath( const std::string& name ) return ret; } +PathConstrainer Builder::GetPathConstrainer( const std::string& name ) +{ + DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded"); + + //Search the pathConstrainer in the LUT + size_t count( mPathConstrainerLut.size() ); + for( size_t i(0); i!=count; ++i ) + { + if( mPathConstrainerLut[i].name == name ) + { + //PathConstrainer has already been created + return mPathConstrainerLut[i].pathConstrainer; + } + } + + //Create a new PathConstrainer + PathConstrainer ret; + if( OptionalChild constrainers = IsChild( *mParser.GetRoot(), "constrainers") ) + { + if( OptionalChild pathConstrainer = IsChild( *constrainers, name ) ) + { + OptionalString constrainerType(IsString(IsChild(*pathConstrainer, "type"))); + if(!constrainerType) + { + DALI_SCRIPT_WARNING("Constrainer type not specified for constrainer '%s'\n", name.c_str() ); + } + else if( *constrainerType == "PathConstrainer") + { + //points property + if( OptionalChild pointsProperty = IsChild( *pathConstrainer, "points") ) + { + Dali::Property::Value points(Property::ARRAY); + if( SetPropertyFromNode( *pointsProperty, Property::ARRAY, points ) ) + { + ret = PathConstrainer::New(); + ret.SetProperty( PathConstrainer::Property::POINTS, points); + + //control-points property + if( OptionalChild pointsProperty = IsChild( *pathConstrainer, "control-points") ) + { + Dali::Property::Value points(Property::ARRAY); + if( SetPropertyFromNode( *pointsProperty, Property::ARRAY, points ) ) + { + ret.SetProperty( PathConstrainer::Property::CONTROL_POINTS, points); + } + + //Forward vector + OptionalVector3 forward( IsVector3( IsChild(*pathConstrainer, "forward" ) ) ); + if( forward ) + { + ret.SetProperty( PathConstrainer::Property::FORWARD, *forward); + } + + //Add the new constrainer to the vector of PathConstrainer + PathConstrainerEntry entry = {name,ret}; + mPathConstrainerLut.push_back( entry ); + } + else + { + //Control points not specified + DALI_SCRIPT_WARNING("Control points not specified for pathConstrainer '%s'\n", name.c_str() ); + } + } + } + else + { + //Interpolation points not specified + DALI_SCRIPT_WARNING("Interpolation points not specified for pathConstrainer '%s'\n", name.c_str() ); + } + } + else + { + DALI_SCRIPT_WARNING("Constrainer '%s' is not a PathConstrainer\n", name.c_str() ); + } + } + } + + return ret; +} + +bool Builder::IsPathConstrainer( const std::string& name ) +{ + size_t count( mPathConstrainerLut.size() ); + for( size_t i(0); i!=count; ++i ) + { + if( mPathConstrainerLut[i].name == name ) + { + return true; + } + } + + if( OptionalChild constrainers = IsChild( *mParser.GetRoot(), "constrainers") ) + { + if( OptionalChild constrainer = IsChild( *constrainers, name ) ) + { + OptionalString constrainerType(IsString(IsChild(*constrainer, "type"))); + if(!constrainerType) + { + return false; + } + else + { + return *constrainerType == "PathConstrainer"; + } + } + } + return false; +} + +Dali::LinearConstrainer Builder::GetLinearConstrainer( const std::string& name ) +{ + DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded"); + + //Search the LinearConstrainer in the LUT + size_t count( mLinearConstrainerLut.size() ); + for( size_t i(0); i!=count; ++i ) + { + if( mLinearConstrainerLut[i].name == name ) + { + //LinearConstrainer has already been created + return mLinearConstrainerLut[i].linearConstrainer; + } + } + + //Create a new LinearConstrainer + LinearConstrainer ret; + if( OptionalChild constrainers = IsChild( *mParser.GetRoot(), "constrainers") ) + { + if( OptionalChild linearConstrainer = IsChild( *constrainers, name ) ) + { + OptionalString constrainerType(IsString(IsChild(*linearConstrainer, "type"))); + if(!constrainerType) + { + DALI_SCRIPT_WARNING("Constrainer type not specified for constrainer '%s'\n", name.c_str() ); + } + else if( *constrainerType == "LinearConstrainer") + { + //points property + if( OptionalChild pointsProperty = IsChild( *linearConstrainer, "value") ) + { + Dali::Property::Value points(Property::ARRAY); + if( SetPropertyFromNode( *pointsProperty, Property::ARRAY, points ) ) + { + ret = Dali::LinearConstrainer::New(); + ret.SetProperty( LinearConstrainer::Property::VALUE, points); + + //control-points property + if( OptionalChild pointsProperty = IsChild( *linearConstrainer, "progress") ) + { + Dali::Property::Value points(Property::ARRAY); + if( SetPropertyFromNode( *pointsProperty, Property::ARRAY, points ) ) + { + ret.SetProperty( LinearConstrainer::Property::PROGRESS, points); + } + } + //Add the new constrainer to vector of LinearConstrainer + LinearConstrainerEntry entry = {name,ret}; + mLinearConstrainerLut.push_back( entry ); + } + } + else + { + //Interpolation points not specified + DALI_SCRIPT_WARNING("Values not specified for LinearConstrainer '%s'\n", name.c_str() ); + } + } + else + { + DALI_SCRIPT_WARNING("Constrainer '%s' is not a LinearConstrainer\n", name.c_str() ); + } + } + } + + return ret; +} + +bool Builder::IsLinearConstrainer( const std::string& name ) +{ + //Search the LinearConstrainer in the LUT + size_t count( mLinearConstrainerLut.size() ); + for( size_t i(0); i!=count; ++i ) + { + if( mLinearConstrainerLut[i].name == name ) + { + return true; + } + } + + if( OptionalChild constrainers = IsChild( *mParser.GetRoot(), "constrainers") ) + { + if( OptionalChild constrainer = IsChild( *constrainers, name ) ) + { + OptionalString constrainerType(IsString(IsChild(*constrainer, "type"))); + if(!constrainerType) + { + return false; + } + else + { + return *constrainerType == "LinearConstrainer"; + } + } + } + return false; +} + Toolkit::Builder::BuilderSignalType& Builder::QuitSignal() { return mQuitSignal; diff --git a/dali-toolkit/internal/builder/builder-impl.h b/dali-toolkit/internal/builder/builder-impl.h index 4fb7aba..af1c85c 100644 --- a/dali-toolkit/internal/builder/builder-impl.h +++ b/dali-toolkit/internal/builder/builder-impl.h @@ -186,6 +186,33 @@ public: * @copydoc Toolkit::Builder::GetPath */ Path GetPath( const std::string &name ); + + /** + * @copydoc Toolkit::Builder::GetPathConstrainer + */ + Dali::PathConstrainer GetPathConstrainer( const std::string& name ); + + /* + * Check if a given constrainer is of type PathConstrainer + * @param[in] name The name of the constrainer + * @return True if constainer is of type PathConstrainer, False otherwise + * + */ + bool IsPathConstrainer( const std::string& name ); + + /** + * @copydoc Toolkit::Builder::GetLinearConstrainer + */ + Dali::LinearConstrainer GetLinearConstrainer( const std::string& name ); + + /* + * Check if a given constrainer is of type LinearConstrainer + * @param[in] name The name of the constrainer + * @return True if constainer is of type LinearConstrainer, False otherwise + * + */ + bool IsLinearConstrainer( const std::string& name ); + /** * @copydoc Toolkit::Builder::QuitSignal */ @@ -219,6 +246,14 @@ private: typedef std::map PathLut; PathLut mPathLut; + typedef struct{ std::string name; Dali::PathConstrainer pathConstrainer; } PathConstrainerEntry; + typedef std::vector PathConstrainerLut; + PathConstrainerLut mPathConstrainerLut; + + typedef struct{ std::string name; Dali::LinearConstrainer linearConstrainer; } LinearConstrainerEntry; + typedef std::vector LinearConstrainerLut; + LinearConstrainerLut mLinearConstrainerLut; + SlotDelegate mSlotDelegate; Property::Map mReplacementMap; diff --git a/dali-toolkit/internal/builder/builder-signals.cpp b/dali-toolkit/internal/builder/builder-signals.cpp index f832721..804deb3 100644 --- a/dali-toolkit/internal/builder/builder-signals.cpp +++ b/dali-toolkit/internal/builder/builder-signals.cpp @@ -18,9 +18,11 @@ // EXTERNAL INCLUDES #include #include +#include #include #include #include +#include // INTERNAL INCLUDES #include @@ -142,6 +144,182 @@ struct DelayedAnimationPlay }; }; +// Delay a pathConstrainer apply +struct DelayedConstrainerApply +{ + std::string constrainerName; + + std::vector targetActorNames; + std::vector sourceActorNames; + std::vector targetPropertyNames; + std::vector sourcePropertyNames; + std::vector ranges; + std::vector wrapRanges; + + Dali::IntrusivePtr builder; + + /* + * Helper function to get the parameters to apply each constraint + * @param[in] i i-essim element + * @param[out] tagetActor Target actor for the constraint + * @param[out] tagetPropertyIndex Target property index for the constraint + * @param[out] sourceActor Source actor for the constraint + * @param[out] sourcePropertyIndex Source property index for the constraint + */ + bool GetApplyParameters( size_t i, + Actor& targetActor, Property::Index& targetPropertyIndex, + Actor& sourceActor, Property::Index& sourcePropertyIndex) + { + + targetActor = Stage::GetCurrent().GetRootLayer().FindChildByName(targetActorNames[i]); + targetPropertyIndex = Property::INVALID_INDEX; + if(targetActor) + { + targetPropertyIndex = targetActor.GetPropertyIndex(targetPropertyNames[i]); + if( targetPropertyIndex == Property::INVALID_INDEX ) + { + DALI_SCRIPT_WARNING("Property '%s' not founded in actor '%s'\n", targetPropertyNames[i].c_str(), targetActorNames[i].c_str() ); + return false; + } + } + else + { + DALI_SCRIPT_WARNING("Actor '%s' not founded\n", targetActorNames[i].c_str() ); + return false; + } + + + sourceActor = Stage::GetCurrent().GetRootLayer().FindChildByName(sourceActorNames[i]); + sourcePropertyIndex = Property::INVALID_INDEX; + if(sourceActor) + { + sourcePropertyIndex = sourceActor.GetPropertyIndex(sourcePropertyNames[i]); + if( sourcePropertyIndex == Property::INVALID_INDEX ) + { + DALI_SCRIPT_WARNING("Property '%s' not founded in actor '%s'\n", sourcePropertyNames[i].c_str(), sourceActorNames[i].c_str() ); + return false; + } + } + else + { + DALI_SCRIPT_WARNING("Actor '%s' not founded\n", targetActorNames[i].c_str() ); + return false; + } + return true; + } + + void operator()(void) + { + Actor sourceActor, targetActor; + Property::Index targetPropertyIndex(Property::INVALID_INDEX); + Property::Index sourcePropertyIndex(Property::INVALID_INDEX); + size_t actorCount( targetActorNames.size() ); + if( builder.Get()->IsPathConstrainer( constrainerName )) + { + PathConstrainer constrainer = builder.Get()->GetPathConstrainer(constrainerName); + if( constrainer ) + { + for(size_t i(0); iIsLinearConstrainer( constrainerName ) ) + { + Dali::LinearConstrainer constrainer( builder.Get()->GetLinearConstrainer(constrainerName)); + if( constrainer ) + { + for(size_t i(0); i targetActorNames; + Dali::IntrusivePtr builder; + + void operator()(void) + { + size_t actorCount( targetActorNames.size() ); + if( builder.Get()->IsPathConstrainer( constrainerName )) + { + PathConstrainer constrainer = builder.Get()->GetPathConstrainer(constrainerName); + if( constrainer ) + { + for(size_t i(0); iIsLinearConstrainer( constrainerName )) + { + LinearConstrainer constrainer = builder.Get()->GetLinearConstrainer(constrainerName); + if( constrainer ) + { + for(size_t i(0); i GetAction(const TreeNode &root, const TreeNode &chi DALI_SCRIPT_WARNING("Cannot find animations section\n"); } } + else if("applyConstraint" == *actionName ) + { + OptionalString constrainerName = IsString( IsChild(child, "constrainer") ); + if( !constrainerName ) + { + DALI_SCRIPT_WARNING("Need to specify a constrainer\n"); + } + else + { + DelayedConstrainerApply action; + action.constrainerName = *constrainerName; + action.builder = builder; + OptionalChild propertiesNode = IsChild(child, "properties"); + if(propertiesNode) + { + const TreeNode::ConstIterator endIter = (*propertiesNode).CEnd(); + for( TreeNode::ConstIterator iter = (*propertiesNode).CBegin(); endIter != iter; ++iter ) + { + const TreeNode::KeyNodePair& pKeyChild = *iter; + OptionalString sourceActorName(IsString(IsChild(pKeyChild.second, "source"))); + if(!sourceActorName) + { + DALI_SCRIPT_WARNING("Need to specify source actor to apply the constraint\n"); + continue; + } + OptionalString sourcePropertyName( IsString( IsChild(pKeyChild.second, "sourceProperty" ) ) ); + if(!sourcePropertyName) + { + DALI_SCRIPT_WARNING("Need to specify source property to apply the constraint\n"); + continue; + } + + OptionalString targetActorName(IsString(IsChild(pKeyChild.second, "target"))); + if(!targetActorName) + { + DALI_SCRIPT_WARNING("Need to specify target actor to apply the constraint\n"); + continue; + } + + OptionalString targetPropertyName( IsString( IsChild(pKeyChild.second, "targetProperty" ) ) ); + if(!targetPropertyName) + { + DALI_SCRIPT_WARNING("Need to specify target property name to apply the constraint\n"); + continue; + } + + OptionalVector2 range(IsVector2(IsChild(pKeyChild.second, "range"))); + if(!range) + { + DALI_SCRIPT_WARNING("Constrainer range not specified\n"); + continue; + } + + Vector2 wrap(-std::numeric_limits::max(), std::numeric_limits::max()); + OptionalVector2 wrapRange(IsVector2(IsChild(pKeyChild.second, "wrap"))); + if(wrapRange) + { + wrap = *wrapRange; + } + + action.sourceActorNames.push_back(*sourceActorName); + action.sourcePropertyNames.push_back(*sourcePropertyName); + action.targetActorNames.push_back(*targetActorName); + action.targetPropertyNames.push_back(*targetPropertyName); + action.ranges.push_back(*range); + action.wrapRanges.push_back(wrap); + } + + callback = action; + } + } + + + } + else if("removeConstraints" == *actionName ) + { + OptionalString constrainerName = IsString( IsChild(child, "constrainer") ); + if( !constrainerName ) + { + DALI_SCRIPT_WARNING("Need to specify a constrainer\n"); + } + else + { + + DelayedConstrainerRemove action; + action.constrainerName = *constrainerName; + action.builder = builder; + OptionalChild propertiesNode = IsChild(child, "properties"); + if(propertiesNode) + { + const TreeNode::ConstIterator endIter = (*propertiesNode).CEnd(); + for( TreeNode::ConstIterator iter = (*propertiesNode).CBegin(); endIter != iter; ++iter ) + { + const TreeNode::KeyNodePair& pKeyChild = *iter; + OptionalString targetActorName(IsString(IsChild(pKeyChild.second, "target"))); + if(targetActorName) + { + action.targetActorNames.push_back(*targetActorName); + } + else + { + DALI_SCRIPT_WARNING("Need to specify target actor to remove the constraint\n"); + continue; + } + } + } + callback = action; + } + } else { // no named actor; presume self diff --git a/dali-toolkit/public-api/builder/builder.cpp b/dali-toolkit/public-api/builder/builder.cpp index 3ab0ba8..f89b622 100644 --- a/dali-toolkit/public-api/builder/builder.cpp +++ b/dali-toolkit/public-api/builder/builder.cpp @@ -149,6 +149,16 @@ Path Builder::GetPath( const std::string &name ) return GetImpl(*this).GetPath( name ); } +PathConstrainer Builder::GetPathConstrainer( const std::string& pathConstrainerName ) +{ + return GetImpl(*this).GetPathConstrainer( pathConstrainerName ); +} + +LinearConstrainer Builder::GetLinearConstrainer( const std::string& linearConstrainerName ) +{ + return GetImpl(*this).GetLinearConstrainer( linearConstrainerName ); +} + Builder::BuilderSignalType& Builder::QuitSignal() { return GetImpl( *this ).QuitSignal(); diff --git a/dali-toolkit/public-api/builder/builder.h b/dali-toolkit/public-api/builder/builder.h index a975014..51dd743 100644 --- a/dali-toolkit/public-api/builder/builder.h +++ b/dali-toolkit/public-api/builder/builder.h @@ -21,6 +21,8 @@ // EXTERNAL INCLUDES #include #include +#include +#include #include #include @@ -408,6 +410,30 @@ class DALI_IMPORT_API Builder : public BaseHandle */ Path GetPath( const std::string &name ); + /** + * Get or create a PathConstrainer from the set of known PathConstrainers + * e.g. + * PathConstrainer a = builder.GetPathConstrainer( "my-path-constrainer"); + * + * @pre The Builder has been initialized. + * @pre The pathConstrainerName exists in the Constrainers section of the data representation + * @param pathConstrainerName The name of the PathConstrainer + * @returns A handle to a PathConstrainer if found, otherwise empty + */ + PathConstrainer GetPathConstrainer( const std::string& pathConstrainerName ); + + /** + * Get or create a LinearConstrainer from the set of known LinearConstrainers + * e.g. + * LinearConstrainer a = builder.GetLinearConstrainer( "my-linear-constrainer"); + * + * @pre The Builder has been initialized. + * @pre The linearConstrainerName exists in the Constrainers section of the data representation + * @param linearConstrainerName The name of the LinearConstrainer + * @returns A handle to a LinearConstrainer if found, otherwise empty + */ + LinearConstrainer GetLinearConstrainer( const std::string& linearConstrainerName ); + // Signals /**