2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://floralicense.org/license/
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 #include <dali/internal/event/animation/active-constraint-base.h>
21 #include <dali/public-api/animation/active-constraint.h>
22 #include <dali/public-api/object/handle.h>
23 #include <dali/public-api/object/type-registry.h>
24 #include <dali/internal/common/event-to-update.h>
25 #include <dali/internal/event/animation/animation-impl.h>
26 #include <dali/internal/update/common/animatable-property.h>
27 #include <dali/internal/update/animation/scene-graph-constraint-base.h>
28 #include <dali/internal/update/common/property-owner-messages.h>
30 using Dali::Internal::SceneGraph::AnimatableProperty;
35 const Property::Index ActiveConstraint::WEIGHT = 0;
40 namespace // unnamed namespace
45 // not directly creatable
49 TypeRegistration mType( typeid(Dali::ActiveConstraint), typeid(Dali::Handle), Create );
51 SignalConnectorType signalConnector1( mType, Dali::ActiveConstraint::SIGNAL_APPLIED, &ActiveConstraintBase::DoConnectSignal );
56 namespace // unnamed namespace
60 * We want to discourage the use of property strings (minimize string comparisons),
61 * particularly for the default properties.
63 const std::string DEFAULT_PROPERTY_NAMES[] =
67 const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_NAMES ) / sizeof( std::string );
69 const Property::Type DEFAULT_PROPERTY_TYPES[DEFAULT_PROPERTY_COUNT] =
71 Property::FLOAT // WEIGHT
74 } // unnamed namespace
76 ActiveConstraintBase::ActiveConstraintBase( EventToUpdate& eventToUpdate, Property::Index targetPropertyIndex )
77 : mEventToUpdate( eventToUpdate ),
78 mTargetPropertyIndex( targetPropertyIndex ),
80 mSceneGraphConstraint( NULL ),
81 mCustomWeight( NULL ),
82 mOffstageWeight( Dali::ActiveConstraint::DEFAULT_WEIGHT ),
84 mAlphaFunction( Dali::Constraint::DEFAULT_ALPHA_FUNCTION ),
85 mRemoveAction( Dali::Constraint::DEFAULT_REMOVE_ACTION ),
92 ActiveConstraintBase::~ActiveConstraintBase()
94 // Disconnect from internal animation signals
96 if ( mApplyAnimation )
98 GetImplementation(mApplyAnimation).SetFinishedCallback( NULL, NULL );
101 if( mRemoveAnimation )
103 GetImplementation(mRemoveAnimation).SetFinishedCallback( NULL, NULL );
107 void ActiveConstraintBase::SetCustomWeightObject( ProxyObject& weightObject, Property::Index weightIndex )
109 const SceneGraph::PropertyBase* base = weightObject.GetSceneObjectAnimatableProperty( weightIndex );
110 const SceneGraph::AnimatableProperty<float>* sceneProperty = dynamic_cast< const SceneGraph::AnimatableProperty<float>* >( base );
114 mCustomWeight = sceneProperty;
116 OnCustomWeightSet( weightObject );
120 void ActiveConstraintBase::FirstApply( ProxyObject& parent, TimePeriod applyTime )
122 // Notify derived classes
123 OnFirstApply( parent );
125 if ( applyTime.durationSeconds > 0.0f )
127 DALI_ASSERT_DEBUG( !mApplyAnimation );
132 // Automatically animate (increase) the weight, until the constraint is fully applied
133 mApplyAnimation = Dali::Animation::New( applyTime.delaySeconds + applyTime.durationSeconds );
134 Dali::ActiveConstraint self( this );
135 mApplyAnimation.AnimateTo( Property( self, Dali::ActiveConstraint::WEIGHT ), Dali::ActiveConstraint::FINAL_WEIGHT, mAlphaFunction, applyTime );
136 mApplyAnimation.Play();
138 // Chain "Finish" to "Applied" signal
139 GetImplementation(mApplyAnimation).SetFinishedCallback( &ActiveConstraintBase::FirstApplyFinished, this );
143 void ActiveConstraintBase::BeginRemove()
145 // Notify derived classes
148 // Remove gradually by animating weight down to zero
149 if ( mRemoveTime.durationSeconds > 0.0f )
151 // Stop baking behaviour from interfering with remove animation
152 if ( mSceneGraphConstraint )
154 // Immediately remove from scene-graph
155 SetRemoveActionMessage( mEventToUpdate, *mSceneGraphConstraint, Dali::Constraint::Discard );
158 // Interrupt ongoing apply-animations
159 if ( mApplyAnimation )
161 mApplyAnimation.Stop();
164 // Reduce the weight to zero
165 mRemoveAnimation = Dali::Animation::New( mRemoveTime.delaySeconds + mRemoveTime.durationSeconds );
166 Dali::ActiveConstraint self( this );
167 mRemoveAnimation.AnimateTo( Property( self, Dali::ActiveConstraint::WEIGHT ), 0.0f, mAlphaFunction, mRemoveTime );
168 mRemoveAnimation.Play();
170 // Finish removal when animation ends
171 GetImplementation(mRemoveAnimation).SetFinishedCallback( &ActiveConstraintBase::OnRemoveFinished, this );
175 OnRemoveFinished( this );
179 bool ActiveConstraintBase::IsRemoving()
181 return mRemoveAnimation;
184 ProxyObject* ActiveConstraintBase::GetParent()
189 bool ActiveConstraintBase::Supports( Capability capability ) const
191 return false; // switch-off support for dynamic properties
194 Dali::Handle ActiveConstraintBase::GetTargetObject()
196 return Dali::Handle( mTargetProxy );
199 Property::Index ActiveConstraintBase::GetTargetProperty()
201 return mTargetPropertyIndex;
204 void ActiveConstraintBase::SetWeight( float weight )
206 if ( mSceneGraphConstraint )
208 BakeWeightMessage( mEventToUpdate, *mSceneGraphConstraint, weight );
212 mOffstageWeight = weight;
216 float ActiveConstraintBase::GetCurrentWeight() const
218 float currentWeight( mOffstageWeight );
220 if ( mSceneGraphConstraint )
222 currentWeight = mSceneGraphConstraint->GetWeight( mEventToUpdate.GetEventBufferIndex() );
225 return currentWeight;
228 ActiveConstraintSignalV2& ActiveConstraintBase::AppliedSignal()
230 return mAppliedSignal;
233 bool ActiveConstraintBase::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
235 bool connected( true );
236 ActiveConstraintBase* constraint = dynamic_cast<ActiveConstraintBase*>(object);
238 if ( Dali::ActiveConstraint::SIGNAL_APPLIED == signalName )
240 constraint->AppliedSignal().Connect( tracker, functor );
244 // signalName does not match any signal
251 void ActiveConstraintBase::SetRemoveTime( TimePeriod removeTime )
253 mRemoveTime = removeTime;
256 TimePeriod ActiveConstraintBase::GetRemoveTime() const
261 void ActiveConstraintBase::SetAlphaFunction( AlphaFunction alphaFunc )
263 mAlphaFunction = alphaFunc;
266 AlphaFunction ActiveConstraintBase::GetAlphaFunction() const
268 return mAlphaFunction;
271 void ActiveConstraintBase::SetRemoveAction( ActiveConstraintBase::RemoveAction action )
273 mRemoveAction = action;
276 ActiveConstraintBase::RemoveAction ActiveConstraintBase::GetRemoveAction() const
278 return mRemoveAction;
281 void ActiveConstraintBase::SetTag(const unsigned int tag)
286 unsigned int ActiveConstraintBase::GetTag() const
292 bool ActiveConstraintBase::IsSceneObjectRemovable() const
294 return true; // The constraint removed when target SceneGraph::PropertyOwner is destroyed
297 unsigned int ActiveConstraintBase::GetDefaultPropertyCount() const
299 return DEFAULT_PROPERTY_COUNT;
302 void ActiveConstraintBase::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
304 indices.reserve( DEFAULT_PROPERTY_COUNT );
306 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
308 indices.push_back( i );
312 const std::string& ActiveConstraintBase::GetDefaultPropertyName( Property::Index index ) const
314 if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
316 return DEFAULT_PROPERTY_NAMES[index];
320 // index out of range..return empty string
321 static const std::string INVALID_PROPERTY_NAME;
322 return INVALID_PROPERTY_NAME;
326 Property::Index ActiveConstraintBase::GetDefaultPropertyIndex( const std::string& name ) const
328 Property::Index index = Property::INVALID_INDEX;
330 // Only one name to compare with...
331 if ( name == DEFAULT_PROPERTY_NAMES[0] )
339 bool ActiveConstraintBase::IsDefaultPropertyWritable( Property::Index index ) const
341 return true; // All default properties are currently writable
344 bool ActiveConstraintBase::IsDefaultPropertyAnimatable( Property::Index index ) const
346 return true; // All default properties are currently animatable
349 bool ActiveConstraintBase::IsDefaultPropertyAConstraintInput( Property::Index index ) const
351 return true; // All default properties can currently be used as a constraint input
354 Property::Type ActiveConstraintBase::GetDefaultPropertyType( Property::Index index ) const
356 if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
358 return DEFAULT_PROPERTY_TYPES[index];
362 // Index out-of-range
363 return Property::NONE;
367 void ActiveConstraintBase::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
371 case Dali::ActiveConstraint::WEIGHT:
373 SetWeight( propertyValue.Get<float>() );
379 DALI_ASSERT_ALWAYS( false && "ActiveConstraint property out of bounds" ); // should not come here
385 void ActiveConstraintBase::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
387 DALI_ASSERT_ALWAYS( false && "ActiveConstraintBase does not have custom properties"); // should not come here
390 Property::Value ActiveConstraintBase::GetDefaultProperty( Property::Index index ) const
392 Property::Value value;
396 case Dali::ActiveConstraint::WEIGHT:
398 value = GetCurrentWeight();
404 DALI_ASSERT_ALWAYS( false && "ActiveConstraint property out of bounds" ); // should not come here
412 void ActiveConstraintBase::InstallSceneObjectProperty( SceneGraph::PropertyBase& newProperty, const std::string& name, unsigned int index )
414 DALI_ASSERT_ALWAYS( false && "ActiveConstraintBase does not have custom properties" ); // should not come here
417 const SceneGraph::PropertyOwner* ActiveConstraintBase::GetSceneObject() const
419 return mSceneGraphConstraint;
422 const SceneGraph::PropertyBase* ActiveConstraintBase::GetSceneObjectAnimatableProperty( Property::Index index ) const
424 DALI_ASSERT_DEBUG( 0 == index ); // only 1 property supported
426 // This method should only return a property which is part of the scene-graph
427 if ( !mSceneGraphConstraint )
432 return &mSceneGraphConstraint->mWeight;
435 const PropertyInputImpl* ActiveConstraintBase::GetSceneObjectInputProperty( Property::Index index ) const
437 DALI_ASSERT_DEBUG( 0 == index ); // only 1 property supported
439 // This method should only return a property which is part of the scene-graph
440 if ( !mSceneGraphConstraint )
445 return &mSceneGraphConstraint->mWeight;
448 void ActiveConstraintBase::FirstApplyFinished( Object* object )
450 ActiveConstraintBase& self = dynamic_cast<ActiveConstraintBase&>( *object );
452 // This is necessary when the constraint was not added to scene-graph during the animation
453 self.SetWeight( Dali::ActiveConstraint::FINAL_WEIGHT );
455 // The animation is no longer needed
456 GetImplementation(self.mApplyAnimation).SetFinishedCallback( NULL, NULL );
457 self.mApplyAnimation.Reset();
459 // Chain "Finish" to "Applied" signal
461 if ( !self.mAppliedSignal.Empty() )
463 Dali::ActiveConstraint handle( &self );
465 self.mAppliedSignal.Emit( handle );
468 // WARNING - this constraint may now have been deleted; don't do anything else here
471 void ActiveConstraintBase::OnRemoveFinished( Object* object )
473 ActiveConstraintBase& self = dynamic_cast<ActiveConstraintBase&>( *object );
475 const SceneGraph::PropertyOwner* propertyOwner = self.mTargetProxy ? self.mTargetProxy->GetSceneObject() : NULL;
477 if ( propertyOwner &&
478 self.mSceneGraphConstraint )
480 // Notify base class that the scene-graph constraint is being removed
481 self.OnSceneObjectRemove();
483 // Remove from scene-graph
484 RemoveConstraintMessage( self.mEventToUpdate, *propertyOwner, *(self.mSceneGraphConstraint) );
486 // mSceneGraphConstraint will be deleted in update-thread, remove dangling pointer
487 self.mSceneGraphConstraint = NULL;
490 // The animation is no longer needed
491 self.mRemoveAnimation.Reset();
494 } // namespace Internal