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 mOffstageWeight( Dali::ActiveConstraint::DEFAULT_WEIGHT ),
83 mAlphaFunction( Dali::Constraint::DEFAULT_ALPHA_FUNCTION ),
84 mRemoveAction( Dali::Constraint::DEFAULT_REMOVE_ACTION ),
91 ActiveConstraintBase::~ActiveConstraintBase()
93 // Disconnect from internal animation signals
95 if ( mApplyAnimation )
97 GetImplementation(mApplyAnimation).SetFinishedCallback( NULL, NULL );
100 if( mRemoveAnimation )
102 GetImplementation(mRemoveAnimation).SetFinishedCallback( NULL, NULL );
106 void ActiveConstraintBase::FirstApply( ProxyObject& parent, TimePeriod applyTime, ActiveConstraintCallbackType* callback )
108 // Notify derived classes
109 OnFirstApply( parent );
111 if ( applyTime.durationSeconds > 0.0f )
113 DALI_ASSERT_DEBUG( !mApplyAnimation );
118 // Automatically animate (increase) the weight, until the constraint is fully applied
119 mApplyAnimation = Dali::Animation::New( applyTime.delaySeconds + applyTime.durationSeconds );
120 Dali::ActiveConstraint self( this );
121 mApplyAnimation.AnimateTo( Property( self, Dali::ActiveConstraint::WEIGHT ), Dali::ActiveConstraint::FINAL_WEIGHT, mAlphaFunction, applyTime );
122 mApplyAnimation.Play();
124 // Chain "Finish" to "Applied" signal
125 GetImplementation(mApplyAnimation).SetFinishedCallback( &ActiveConstraintBase::FirstApplyFinished, this );
129 void ActiveConstraintBase::BeginRemove()
131 // Notify derived classes
134 // Remove gradually by animating weight down to zero
135 if ( mRemoveTime.durationSeconds > 0.0f )
137 // Stop baking behaviour from interfering with remove animation
138 if ( mSceneGraphConstraint )
140 // Immediately remove from scene-graph
141 SetRemoveActionMessage( mEventToUpdate, *mSceneGraphConstraint, Dali::Constraint::Discard );
144 // Interrupt ongoing apply-animations
145 if ( mApplyAnimation )
147 mApplyAnimation.Stop();
150 // Reduce the weight to zero
151 mRemoveAnimation = Dali::Animation::New( mRemoveTime.delaySeconds + mRemoveTime.durationSeconds );
152 Dali::ActiveConstraint self( this );
153 mRemoveAnimation.AnimateTo( Property( self, Dali::ActiveConstraint::WEIGHT ), 0.0f, mAlphaFunction, mRemoveTime );
154 mRemoveAnimation.Play();
156 // Finish removal when animation ends
157 GetImplementation(mRemoveAnimation).SetFinishedCallback( &ActiveConstraintBase::OnRemoveFinished, this );
161 OnRemoveFinished( this );
165 bool ActiveConstraintBase::IsRemoving()
167 return mRemoveAnimation;
170 ProxyObject* ActiveConstraintBase::GetParent()
175 bool ActiveConstraintBase::Supports( Capability capability ) const
177 return false; // switch-off support for dynamic properties
180 Dali::Handle ActiveConstraintBase::GetTargetObject()
182 return Dali::Handle( mTargetProxy );
185 Property::Index ActiveConstraintBase::GetTargetProperty()
187 return mTargetPropertyIndex;
190 void ActiveConstraintBase::SetWeight( float weight )
192 if ( mSceneGraphConstraint )
194 BakeWeightMessage( mEventToUpdate, *mSceneGraphConstraint, weight );
198 mOffstageWeight = weight;
202 float ActiveConstraintBase::GetCurrentWeight() const
204 float currentWeight( mOffstageWeight );
206 if ( mSceneGraphConstraint )
208 currentWeight = mSceneGraphConstraint->GetWeight( mEventToUpdate.GetEventBufferIndex() );
211 return currentWeight;
214 ActiveConstraintSignalV2& ActiveConstraintBase::AppliedSignal()
216 return mAppliedSignal;
219 bool ActiveConstraintBase::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
221 bool connected( true );
222 ActiveConstraintBase* constraint = dynamic_cast<ActiveConstraintBase*>(object);
224 if ( Dali::ActiveConstraint::SIGNAL_APPLIED == signalName )
226 constraint->AppliedSignal().Connect( tracker, functor );
230 // signalName does not match any signal
237 void ActiveConstraintBase::SetRemoveTime( TimePeriod removeTime )
239 mRemoveTime = removeTime;
242 TimePeriod ActiveConstraintBase::GetRemoveTime() const
247 void ActiveConstraintBase::SetAlphaFunction( AlphaFunction alphaFunc )
249 mAlphaFunction = alphaFunc;
252 AlphaFunction ActiveConstraintBase::GetAlphaFunction() const
254 return mAlphaFunction;
257 void ActiveConstraintBase::SetRemoveAction( ActiveConstraintBase::RemoveAction action )
259 mRemoveAction = action;
262 ActiveConstraintBase::RemoveAction ActiveConstraintBase::GetRemoveAction() const
264 return mRemoveAction;
267 void ActiveConstraintBase::SetTag(const unsigned int tag)
272 unsigned int ActiveConstraintBase::GetTag() const
278 bool ActiveConstraintBase::IsSceneObjectRemovable() const
280 return true; // The constraint removed when target SceneGraph::PropertyOwner is destroyed
283 unsigned int ActiveConstraintBase::GetDefaultPropertyCount() const
285 return DEFAULT_PROPERTY_COUNT;
288 void ActiveConstraintBase::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
290 indices.reserve( DEFAULT_PROPERTY_COUNT );
292 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
294 indices.push_back( i );
298 const std::string& ActiveConstraintBase::GetDefaultPropertyName( Property::Index index ) const
300 if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
302 return DEFAULT_PROPERTY_NAMES[index];
306 // index out of range..return empty string
307 static const std::string INVALID_PROPERTY_NAME;
308 return INVALID_PROPERTY_NAME;
312 Property::Index ActiveConstraintBase::GetDefaultPropertyIndex( const std::string& name ) const
314 Property::Index index = Property::INVALID_INDEX;
316 // Only one name to compare with...
317 if ( name == DEFAULT_PROPERTY_NAMES[0] )
325 bool ActiveConstraintBase::IsDefaultPropertyWritable( Property::Index index ) const
327 return true; // All default properties are currently writable
330 bool ActiveConstraintBase::IsDefaultPropertyAnimatable( Property::Index index ) const
332 return true; // All default properties are currently animatable
335 bool ActiveConstraintBase::IsDefaultPropertyAConstraintInput( Property::Index index ) const
337 return true; // All default properties can currently be used as a constraint input
340 Property::Type ActiveConstraintBase::GetDefaultPropertyType( Property::Index index ) const
342 if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
344 return DEFAULT_PROPERTY_TYPES[index];
348 // Index out-of-range
349 return Property::NONE;
353 void ActiveConstraintBase::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
357 case Dali::ActiveConstraint::WEIGHT:
359 SetWeight( propertyValue.Get<float>() );
365 DALI_ASSERT_ALWAYS( false && "ActiveConstraint property out of bounds" ); // should not come here
371 void ActiveConstraintBase::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
373 DALI_ASSERT_ALWAYS( false && "ActiveConstraintBase does not have custom properties"); // should not come here
376 Property::Value ActiveConstraintBase::GetDefaultProperty( Property::Index index ) const
378 Property::Value value;
382 case Dali::ActiveConstraint::WEIGHT:
384 value = GetCurrentWeight();
390 DALI_ASSERT_ALWAYS( false && "ActiveConstraint property out of bounds" ); // should not come here
398 void ActiveConstraintBase::InstallSceneObjectProperty( SceneGraph::PropertyBase& newProperty, const std::string& name, unsigned int index )
400 DALI_ASSERT_ALWAYS( false && "ActiveConstraintBase does not have custom properties" ); // should not come here
403 const SceneGraph::PropertyOwner* ActiveConstraintBase::GetSceneObject() const
405 return mSceneGraphConstraint;
408 const SceneGraph::PropertyBase* ActiveConstraintBase::GetSceneObjectAnimatableProperty( Property::Index index ) const
410 DALI_ASSERT_DEBUG( 0 == index ); // only 1 property supported
412 // This method should only return a property which is part of the scene-graph
413 if ( !mSceneGraphConstraint )
418 return &mSceneGraphConstraint->mWeight;
421 const PropertyInputImpl* ActiveConstraintBase::GetSceneObjectInputProperty( Property::Index index ) const
423 DALI_ASSERT_DEBUG( 0 == index ); // only 1 property supported
425 // This method should only return a property which is part of the scene-graph
426 if ( !mSceneGraphConstraint )
431 return &mSceneGraphConstraint->mWeight;
434 void ActiveConstraintBase::FirstApplyFinished( Object* object )
436 ActiveConstraintBase& self = dynamic_cast<ActiveConstraintBase&>( *object );
438 // This is necessary when the constraint was not added to scene-graph during the animation
439 self.SetWeight( Dali::ActiveConstraint::FINAL_WEIGHT );
441 // The animation is no longer needed
442 GetImplementation(self.mApplyAnimation).SetFinishedCallback( NULL, NULL );
443 self.mApplyAnimation.Reset();
445 // Chain "Finish" to "Applied" signal
447 if ( !self.mAppliedSignal.Empty() )
449 Dali::ActiveConstraint handle( &self );
451 self.mAppliedSignal.Emit( handle );
454 // WARNING - this constraint may now have been deleted; don't do anything else here
457 void ActiveConstraintBase::OnRemoveFinished( Object* object )
459 ActiveConstraintBase& self = dynamic_cast<ActiveConstraintBase&>( *object );
461 const SceneGraph::PropertyOwner* propertyOwner = self.mTargetProxy ? self.mTargetProxy->GetSceneObject() : NULL;
463 if ( propertyOwner &&
464 self.mSceneGraphConstraint )
466 // Notify base class that the scene-graph constraint is being removed
467 self.OnSceneObjectRemove();
469 // Remove from scene-graph
470 RemoveConstraintMessage( self.mEventToUpdate, *propertyOwner, *(self.mSceneGraphConstraint) );
472 // mSceneGraphConstraint will be deleted in update-thread, remove dangling pointer
473 self.mSceneGraphConstraint = NULL;
476 // The animation is no longer needed
477 self.mRemoveAnimation.Reset();
480 } // namespace Internal