* @note The constraint will be copied by the Actor. This means that modifying the apply-time etc.
* of the constraint, will not affect actors which are already being constrained.
* @pre The Actor has been initialized.
- * @param[in] constraint The constraint to add.
+ * @param[in] constraint The constraint to apply.
* @return The active-constraint being applied to the actor.
*/
ActiveConstraint ApplyConstraint( Constraint constraint );
/**
+ * @brief Constrain one of the properties of an Actor, using a custom weight property.
+ *
+ * This overload is intended to allow a single weight property to be shared by many constraints
+ * e.g. call WeightObject::New() once, and pass the return value into every call to ApplyConstraint().
+ * @pre The Actor has been initialized.
+ * @param[in] constraint The constraint to apply.
+ * @param[in] weightObject An object which is expected to have a float property named "weight".
+ * @return The active-constraint being applied to the actor.
+ */
+ ActiveConstraint ApplyConstraint( Constraint constraint, Constrainable weightObject );
+
+ /**
* @brief Remove one constraint from an Object.
*
* @pre The Object has been intialized.
void RemoveConstraints();
/**
- * @brief Remove all the constraint from the Object with a matching tag.
- *
- * @pre The Object has been intialized.
- * @param[in] tag The tag of the constraints which will be removed
- */
+ * @brief Remove all the constraint from the Object with a matching tag.
+ *
+ * @pre The Object has been intialized.
+ * @param[in] tag The tag of the constraints which will be removed
+ */
void RemoveConstraints( unsigned int tag );
public:
-
/**
* @brief This constructor is used by Dali New() methods.
*
explicit DALI_INTERNAL Constrainable(Dali::Internal::Object* handle);
};
+namespace WeightObject
+{
+
+extern const Property::Index WEIGHT; ///< name "weight", type FLOAT
+
+/**
+ * @brief Convenience function to create an object with a custom "weight" property.
+ *
+ * @return A handle to a newly allocated object.
+ */
+Constrainable New();
+
+} // namespace WeightObject
+
} // namespace Dali
/**
mTargetPropertyIndex( targetPropertyIndex ),
mTargetProxy( NULL ),
mSceneGraphConstraint( NULL ),
+ mCustomWeight( NULL ),
mOffstageWeight( Dali::ActiveConstraint::DEFAULT_WEIGHT ),
mRemoveTime( 0.0f ),
mAlphaFunction( Dali::Constraint::DEFAULT_ALPHA_FUNCTION ),
}
}
-void ActiveConstraintBase::FirstApply( ProxyObject& parent, TimePeriod applyTime, ActiveConstraintCallbackType* callback )
+void ActiveConstraintBase::SetCustomWeightObject( ProxyObject& weightObject, Property::Index weightIndex )
+{
+ const SceneGraph::PropertyBase* base = weightObject.GetSceneObjectAnimatableProperty( weightIndex );
+ const SceneGraph::AnimatableProperty<float>* sceneProperty = dynamic_cast< const SceneGraph::AnimatableProperty<float>* >( base );
+
+ if( sceneProperty )
+ {
+ mCustomWeight = sceneProperty;
+
+ OnCustomWeightSet( weightObject );
+ }
+}
+
+void ActiveConstraintBase::FirstApply( ProxyObject& parent, TimePeriod applyTime )
{
// Notify derived classes
OnFirstApply( parent );
namespace SceneGraph
{
class ConstraintBase;
+
+template <typename T>
+class AnimatableProperty;
}
/**
virtual ActiveConstraintBase* Clone() = 0;
/**
+ * Set a custom "weight" property.
+ * @param[in] weightObject An object with a "weight" float property.
+ * @param[in] weightIndex The index of the weight property.
+ */
+ void SetCustomWeightObject( ProxyObject& weightObject, Property::Index weightIndex );
+
+ /**
* Called when the ActiveConstraint is first applied.
* @pre The active-constraint does not already have a parent.
* @param[in] parent The parent object.
* @param[in] applyTime The apply-time for this constraint.
- * @param[in] callback A pointer to a callback for the applied signal, or NULL.
*/
- void FirstApply( ProxyObject& parent, TimePeriod applyTime, ActiveConstraintCallbackType* callback );
+ void FirstApply( ProxyObject& parent, TimePeriod applyTime );
/**
* Called when the ActiveConstraint is removed.
// To be implemented in derived classes
/**
+ * Used to observe the lifetime of an object with custom "weight" property
+ * @param [in] weightObject The object.
+ */
+ virtual void OnCustomWeightSet( ProxyObject& weightObject ) = 0;
+
+ /**
* Set the parent of the active-constraint; called during OnFirstApply().
* @param [in] parent The parent object.
*/
const SceneGraph::ConstraintBase* mSceneGraphConstraint;
+ const SceneGraph::AnimatableProperty<float>* mCustomWeight;
+
float mOffstageWeight;
TimePeriod mRemoveTime;
}
/**
+ * @copydoc ActiveConstraintBase::OnCustomWeightSet()
+ */
+ virtual void OnCustomWeightSet( ProxyObject& weightObject )
+ {
+ ObserveProxy( weightObject );
+ }
+
+ /**
* @copydoc ActiveConstraintBase::OnFirstApply()
*/
virtual void OnFirstApply( ProxyObject& parent )
SceneGraph::ConstraintBase* sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty,
propertyOwners,
func,
- mInterpolatorFunction );
+ mInterpolatorFunction,
+ mCustomWeight );
DALI_ASSERT_DEBUG( NULL != sceneGraphConstraint );
sceneGraphConstraint->SetInitialWeight( mOffstageWeight );
sceneGraphConstraint->SetRemoveAction( mRemoveAction );
}
/**
+ * @copydoc ActiveConstraintBase::OnCustomWeightSet()
+ */
+ virtual void OnCustomWeightSet( ProxyObject& weightObject )
+ {
+ ObserveProxy( weightObject );
+ }
+
+ /**
* @copydoc ActiveConstraintBase::OnFirstApply()
*/
virtual void OnFirstApply( ProxyObject& parent )
sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty,
propertyOwners,
func,
- mInterpolatorFunction );
+ mInterpolatorFunction,
+ mCustomWeight );
}
else
{
if ( 0 == componentIndex )
{
typedef SceneGraph::Constraint< float, PropertyComponentAccessorX<Vector3> > SceneGraphConstraint;
- sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction );
+ sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction, mCustomWeight );
}
else if ( 1 == componentIndex )
{
typedef SceneGraph::Constraint< float, PropertyComponentAccessorY<Vector3> > SceneGraphConstraint;
- sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction );
+ sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction, mCustomWeight );
}
else if ( 2 == componentIndex )
{
typedef SceneGraph::Constraint< float, PropertyComponentAccessorZ<Vector3> > SceneGraphConstraint;
- sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction );
+ sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction, mCustomWeight );
}
}
else if ( PropertyTypes::Get< Vector4 >() == targetProperty->GetType() )
if ( 0 == componentIndex )
{
typedef SceneGraph::Constraint< float, PropertyComponentAccessorX<Vector4> > SceneGraphConstraint;
- sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction );
+ sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction, mCustomWeight );
}
else if ( 1 == componentIndex )
{
typedef SceneGraph::Constraint< float, PropertyComponentAccessorY<Vector4> > SceneGraphConstraint;
- sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction );
+ sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction, mCustomWeight );
}
else if ( 2 == componentIndex )
{
typedef SceneGraph::Constraint< float, PropertyComponentAccessorZ<Vector4> > SceneGraphConstraint;
- sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction );
+ sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction, mCustomWeight );
}
else if ( 3 == componentIndex )
{
typedef SceneGraph::Constraint< float, PropertyComponentAccessorW<Vector4> > SceneGraphConstraint;
- sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction );
+ sceneGraphConstraint = SceneGraphConstraint::New( *targetProperty, propertyOwners, func, mInterpolatorFunction, mCustomWeight );
}
}
}
Dali::ActiveConstraint ProxyObject::ApplyConstraint( Constraint& constraint )
{
- return Dali::ActiveConstraint(DoApplyConstraint( constraint, NULL/*callback is optional*/ ));
+ return Dali::ActiveConstraint( DoApplyConstraint( constraint, Dali::Constrainable() ) );
}
-Dali::ActiveConstraint ProxyObject::ApplyConstraint( Constraint& constraint, ActiveConstraintCallbackType callback )
+Dali::ActiveConstraint ProxyObject::ApplyConstraint( Constraint& constraint, Dali::Constrainable weightObject )
{
- return Dali::ActiveConstraint(DoApplyConstraint( constraint, &callback ));
+ return Dali::ActiveConstraint( DoApplyConstraint( constraint, weightObject ) );
}
-ActiveConstraintBase* ProxyObject::DoApplyConstraint( Constraint& constraint, ActiveConstraintCallbackType* callback )
+ActiveConstraintBase* ProxyObject::DoApplyConstraint( Constraint& constraint, Dali::Constrainable weightObject )
{
ActiveConstraintBase* activeConstraintImpl = constraint.CreateActiveConstraint();
DALI_ASSERT_DEBUG( NULL != activeConstraintImpl );
Dali::ActiveConstraint activeConstraint( activeConstraintImpl );
+ if( weightObject )
+ {
+ ProxyObject& weightObjectImpl = GetImplementation( weightObject );
+ Property::Index weightIndex = weightObjectImpl.GetPropertyIndex( "weight" );
+
+ if( Property::INVALID_INDEX != weightIndex )
+ {
+ activeConstraintImpl->SetCustomWeightObject( weightObjectImpl, weightIndex );
+ }
+ }
+
if( !mConstraints )
{
mConstraints = new ActiveConstraintContainer;
}
mConstraints->push_back( activeConstraint );
- activeConstraintImpl->FirstApply( *this, constraint.GetApplyTime(), callback );
+ activeConstraintImpl->FirstApply( *this, constraint.GetApplyTime() );
return activeConstraintImpl;
}
/**
* Apply a constraint to a ProxyObject.
* @param[in] constraint The constraint to apply.
- * @param[in] callback This method will be called at the end of the constraint apply-time.
+ * @param[in] weightObject An object with a "weight" float property.
*/
- Dali::ActiveConstraint ApplyConstraint( Constraint& constraint, ActiveConstraintCallbackType callback );
+ Dali::ActiveConstraint ApplyConstraint( Constraint& constraint, Dali::Constrainable weightObject );
/**
* Remove one constraint from a ProxyObject.
/**
* Helper for ApplyConstraint overloads.
+ * @param[in] constraint The constraint to apply.
+ * @param[in] weightObject An object with a "weight" float property, or an empty handle.
* @return The new active-constraint which is owned by ProxyObject.
*/
- ActiveConstraintBase* DoApplyConstraint( Constraint& constraint, ActiveConstraintCallbackType* callback );
+ ActiveConstraintBase* DoApplyConstraint( Constraint& constraint, Dali::Constrainable weightObject );
/**
* Helper to delete removed constraints
* @param[in] ownerSet A set of property owners; func is connected to the properties provided by these objects.
* @param[in] func The function to calculate the final constrained value.
* @param[in] interpolator The function to interpolate between start & final value.
+ * @param[in] customWeight A custom weight property, or NULL if the constraint is using its own.
* @return A smart-pointer to a newly allocated constraint.
*/
static ConstraintBase* New( const PropertyBase& targetProperty,
PropertyOwnerSet& ownerSet,
ConstraintFunctionPtr func,
- InterpolatorFunc interpolator )
+ InterpolatorFunc interpolator,
+ const AnimatableProperty<float>* customWeight )
{
// Scene-graph thread can edit these objects
PropertyBase& property = const_cast< PropertyBase& >( targetProperty );
return new Constraint< PropertyType, PropertyAccessorType >( property,
ownerSet,
func,
- interpolator );
+ interpolator,
+ customWeight );
}
/**
if ( ! mTargetProperty.IsClean() ||
mFunc->InputsChanged() ||
- ! mWeight.IsClean() )
+ ! mWeightInput->IsClean() )
{
return true;
}
const PropertyType& current = mTargetProperty.Get( updateBufferIndex );
// FINAL_WEIGHT means the constraint is fully-applied, unless weight is still being animated
- if ( ! mWeight.IsClean() ||
- ! Equals( Dali::ActiveConstraint::FINAL_WEIGHT, mWeight[updateBufferIndex] ) )
+ if ( ! mWeightInput->IsClean() ||
+ ! Equals( Dali::ActiveConstraint::FINAL_WEIGHT, (*mWeightInput)[updateBufferIndex] ) )
{
// Constraint is not fully-applied; interpolation between start & final values
mTargetProperty.Set( updateBufferIndex,
- mInterpolator( current, mFunc->Apply( updateBufferIndex, current ), mWeight[updateBufferIndex] ) );
+ mInterpolator( current, mFunc->Apply( updateBufferIndex, current ), (*mWeightInput)[updateBufferIndex] ) );
}
else
{
Constraint( PropertyBase& targetProperty,
PropertyOwnerSet& ownerSet,
ConstraintFunctionPtr func,
- InterpolatorFunc interpolator )
+ InterpolatorFunc interpolator,
+ const AnimatableProperty<float>* customWeight )
: ConstraintBase( ownerSet ),
mTargetProperty( &targetProperty ),
mFunc( func ),
- mInterpolator( interpolator )
+ mInterpolator( interpolator ),
+ mWeightInput( customWeight ? customWeight : &mWeight)
{
}
ConstraintFunctionPtr mFunc;
InterpolatorFunc mInterpolator;
+
+ const AnimatableProperty<float>* mWeightInput;
};
} // namespace SceneGraph
// limitations under the License.
//
+// CLASS HEADER
#include <dali/public-api/object/constrainable.h>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/object/property-index.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/animation/active-constraint.h>
#include <dali/internal/event/common/proxy-object.h>
ActiveConstraint Constrainable::ApplyConstraint( Constraint constraint )
{
- return GetImplementation(*this).ApplyConstraint(GetImplementation(constraint));
+ return GetImplementation(*this).ApplyConstraint( GetImplementation( constraint ) );
+}
+
+ActiveConstraint Constrainable::ApplyConstraint( Constraint constraint, Constrainable weightObject )
+{
+ return GetImplementation(*this).ApplyConstraint( GetImplementation( constraint ), weightObject );
}
void Constrainable::RemoveConstraint(ActiveConstraint activeConstraint)
GetImplementation(*this).RemoveConstraints( tag );
}
+namespace WeightObject
+{
+
+const Property::Index WEIGHT = PROPERTY_CUSTOM_START_INDEX;
+
+Constrainable New()
+{
+ Constrainable handle = Constrainable::New();
+
+ handle.RegisterProperty( "weight", 0.0f );
+
+ return handle;
+}
+} // namespace WeightObject
-} // Dali
+} // namespace Dali