Tizen 2.4.0 rev3 SDK Public Release
[framework/graphics/dali.git] / dali / public-api / animation / constraint.h
1 #ifndef __DALI_CONSTRAINT_H__
2 #define __DALI_CONSTRAINT_H__
3
4 /*
5  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/animation/constraint-source.h>
23 #include <dali/public-api/common/dali-vector.h>
24 #include <dali/public-api/object/base-handle.h>
25 #include <dali/public-api/object/property.h>
26 #include <dali/public-api/object/property-input.h>
27 #include <dali/public-api/signals/callback.h>
28
29 namespace Dali
30 {
31 /**
32  * @addtogroup dali_core_animation
33  * @{
34  */
35
36 class Handle;
37
38 namespace Internal DALI_INTERNAL
39 {
40 class ConstraintBase;
41 }
42
43 typedef Vector< PropertyInput* > PropertyInputContainer;  ///< Container for PropertyInput @since_tizen 2.4
44
45 /**
46  * @brief An abstract base class for Constraints.
47  *
48  * This can be used to constrain a property of an object, after animations have been applied.
49  * Constraints are applied in the following order:
50  *   - Constraints are applied to on-stage actors in a depth-first traversal.
51  *   - For each actor, the constraints are applied in the same order as the calls to Apply().
52  *   - Constraints are not applied to off-stage actors.
53  *
54  * Create a constraint using one of the New methods depending on the type of callback function used.
55  * Try to use a C function unless some data needs to be stored, otherwise functors and class methods
56  * are also supported.
57  *
58  * A constraint can be applied to an object in the following manner:
59  *
60  * @code
61  * Handle handle = CreateMyObject();
62  * Constraint constraint = Constraint::New< Vector3 >( handle, CONSTRAINING_PROPERTY_INDEX, &MyFunction );
63  * constraint.AddSource( LocalSource( INPUT_PROPERTY_INDEX ) );
64  * constraint.Apply();
65  * @endcode
66  * @since_tizen 2.4
67  */
68 class DALI_IMPORT_API Constraint : public BaseHandle
69 {
70 public:
71
72   /**
73    * @brief Template for the Function that is called by the Constraint system.
74    *
75    * Supports:
76    *  - C style functions
77    *  - Static member methods of an object
78    *  - Member functions of a particular class
79    *  - Functors of a particular class
80    *  - If a functor or method is provided, then a copy of the object is made.
81    *
82    * The expected signature of the callback should be:
83    * @code
84    *   void Function( P&, const PropertyInputContainer& );
85    * @endcode
86    *
87    * The P& parameter is an in,out parameter which stores the current value of the property. The callback
88    * should change this value to the desired one. The PropertyInputContainer is a const reference to the property inputs
89    * added to the Constraint in the order they were added via AddSource().
90    *
91    * @tparam  P  The property type to constrain.
92    * @since_tizen 2.4
93    */
94   template< typename P >
95   class DALI_INTERNAL Function : public CallbackBase
96   {
97   public:
98
99     /**
100      * @brief Constructor which connects to the provided C function (or a static member function).
101      *
102      * The expected signature of the function is:
103      * @code
104      *   void MyFunction( P&, const PropertyInputContainer& );
105      * @endcode
106      *
107      * @since_tizen 2.4
108      * @param[in]  function  The function to call.
109      */
110     Function( void( *function )( P&, const PropertyInputContainer& ) )
111     : CallbackBase( reinterpret_cast< CallbackBase::Function >( function ) ),
112       mCopyConstructorDispatcher( NULL )
113     {
114     }
115
116     /**
117      * @brief Constructor which copies a function object and connects to the functor of that object.
118      *
119      * The function object should have a functor with the following signature:
120      * @code
121      *   void operator()( P&, const PropertyInputContainer& );
122      * @endcode
123      *
124      * @since_tizen 2.4
125      * @param[in]  object  The object to copy.
126      *
127      * @tparam  T  The type of the object.
128      */
129     template< class T >
130     Function( const T& object )
131     : CallbackBase( reinterpret_cast< void* >( new T( object ) ), // copy the object
132                     NULL, // uses operator() instead of member function
133                     reinterpret_cast< CallbackBase::Dispatcher >( &FunctorDispatcher2< T, P&, const PropertyInputContainer& >::Dispatch ),
134                     reinterpret_cast< CallbackBase::Destructor >( &Destroyer< T >::Delete ) ),
135       mCopyConstructorDispatcher( reinterpret_cast< CopyConstructorDispatcher >( &ObjectCopyConstructorDispatcher< T >::Copy ) )
136     {
137     }
138
139     /**
140      * @brief Constructor which copies a function object and allows a connection to a member method.
141      *
142      * The object should have a method with the signature:
143      * @code
144      *   void MyObject::MyMethod( P&, const PropertyInputContainer& );
145      * @endcode
146      *
147      * @since_tizen 2.4
148      * @param[in]  object          The object to copy.
149      * @param[in]  memberFunction  The member function to call. This has to be a member of the same class.
150      *
151      * @tparam  T  The type of the object.
152      */
153     template< class T >
154     Function( const T& object, void ( T::*memberFunction ) ( P&, const PropertyInputContainer& ) )
155     : CallbackBase( reinterpret_cast< void* >( new T( object ) ), // copy the object
156                     reinterpret_cast< CallbackBase::MemberFunction >( memberFunction ),
157                     reinterpret_cast< CallbackBase::Dispatcher >( &Dispatcher2< T, P&, const PropertyInputContainer& >::Dispatch ),
158                     reinterpret_cast< CallbackBase::Destructor >( &Destroyer< T >::Delete ) ),
159       mCopyConstructorDispatcher( reinterpret_cast< CopyConstructorDispatcher >( &ObjectCopyConstructorDispatcher< T >::Copy ) )
160     {
161     }
162
163     /**
164      * @brief Clones the Function object.
165      *
166      * The object, if held by this object, is also copied.
167      *
168      * @since_tizen 2.4
169      * @return A pointer to a newly-allocation Function.
170      */
171     CallbackBase* Clone()
172     {
173       CallbackBase* callback = NULL;
174       if ( mImpl && mImpl->mObjectPointer && mCopyConstructorDispatcher )
175       {
176         callback = new Function( mCopyConstructorDispatcher( reinterpret_cast< UndefinedClass* >( mImpl->mObjectPointer ) ) /* Copy the object */,
177                                  mMemberFunction,
178                                  mImpl->mMemberFunctionDispatcher,
179                                  mImpl->mDestructorDispatcher,
180                                  mCopyConstructorDispatcher );
181       }
182       else
183       {
184         callback = new Function( mFunction );
185       }
186       return callback;
187     }
188
189   private:
190
191     /**
192      * @brief Must not be declared.
193      *
194      * This is used so that no optimisations are done by the compiler when using void*.
195      */
196     class UndefinedClass;
197
198     /**
199      * @brief Used to call the function to copy the stored object
200      * @since_tizen 2.4
201      */
202     typedef UndefinedClass* (*CopyConstructorDispatcher) ( UndefinedClass* object );
203
204     /**
205      * @brief Copies the actual object in Constraint::Function.
206      *
207      * @tparam  T  The type of the object.
208      * @since_tizen 2.4
209      */
210     template< class T >
211     struct ObjectCopyConstructorDispatcher
212     {
213       /**
214        * @brief Copy the object stored in Constraint::Function.
215        *
216        * @since_tizen 2.4
217        * @param[in]  object  The object to copy.
218        *
219        * @return Newly allocated clone of the object.
220        */
221       static UndefinedClass* Copy( const UndefinedClass* object )
222       {
223         T* copy = new T( *( reinterpret_cast< const T* >( object ) ) );
224         return reinterpret_cast< UndefinedClass* >( copy );
225       }
226     };
227
228     /**
229      * @brief Undefined copy constructor
230      * @since_tizen 2.4
231      */
232     Function( const Function& );
233
234     /**
235      * @brief Undefined assignment operator
236      * @since_tizen 2.4
237      */
238     Function& operator=( const Function& );
239
240     /**
241      * @brief Constructor used when copying the stored object.
242      *
243      * @since_tizen 2.4
244      * @param[in]  object                     A newly copied object
245      * @param[in]  memberFunction             The member function of the object.
246      * @param[in]  dispatcher                 Used to call the actual object.
247      * @param[in]  destructor                 Used to delete the owned object.
248      * @param[in]  copyConstructorDispatcher  Used to create a copy of the owned object.
249      */
250     Function( void* object,
251               CallbackBase::MemberFunction memberFunction,
252               CallbackBase::Dispatcher dispatcher,
253               CallbackBase::Destructor destructor,
254               CopyConstructorDispatcher copyConstructorDispatcher )
255     : CallbackBase( object, memberFunction, dispatcher, destructor ),
256       mCopyConstructorDispatcher( copyConstructorDispatcher )
257     {
258     }
259
260     /**
261      * @brief Constructor used when copying a simple stored function.
262      *
263      * @since_tizen 2.4
264      * @param[in]  function   The function to call.
265      */
266     Function( CallbackBase::Function function )
267     : CallbackBase( function ),
268       mCopyConstructorDispatcher( NULL )
269     {
270     }
271
272     // Data
273
274     CopyConstructorDispatcher mCopyConstructorDispatcher; ///< Function to call to copy the stored object
275   };
276
277   /**
278    * @brief The action that will happen when the constraint is removed.
279    *
280    * The final value may be "baked" i.e. saved permanently.
281    * Alternatively the constrained value may be discarded when the constraint is removed.
282    * @since_tizen 2.4
283    */
284   enum RemoveAction
285   {
286     Bake,   ///< When the constraint is fully-applied, the constrained value is saved. @since_tizen 2.4
287     Discard ///< When the constraint is removed, the constrained value is discarded. @since_tizen 2.4
288   };
289
290   static const RemoveAction  DEFAULT_REMOVE_ACTION;  ///< Bake
291
292   /**
293    * @brief Create an uninitialized Constraint; this can be initialized with Constraint::New().
294    *
295    * Calling member functions with an uninitialized Constraint handle is not allowed.
296    *
297    * @since_tizen 2.4
298    */
299   Constraint();
300
301   /**
302    * @brief Create a constraint which targets a property using a function or a static class member.
303    *
304    * The expected signature, for a Vector3 type for example, of the function is:
305    * @code
306    *   void MyFunction( Vector3&, const PropertyInputContainer& );
307    * @endcode
308    *
309    * Create the constraint with this function as follows:
310    *
311    * @code
312    *   Constraint constraint = Constraint::New< Vector3 >( handle, CONSTRAINING_PROPERTY_INDEX, &MyFunction );
313    * @endcode
314    *
315    * @since_tizen 2.4
316    * @param[in]  handle       The handle to the property-owning object.
317    * @param[in]  targetIndex  The index of the property to constrain.
318    * @param[in]  function     The function to call to set the constrained property value.
319    * @return The new constraint.
320    *
321    * @tparam P The type of the property to constrain.
322    */
323   template< class P >
324   static Constraint New( Handle handle, Property::Index targetIndex, void( *function )( P&, const PropertyInputContainer& ) )
325   {
326     CallbackBase* callback = new Constraint::Function< P >( function );
327     return New( handle, targetIndex, PropertyTypes::Get< P >(), callback );
328   }
329
330   /**
331    * @brief Create a constraint which targets a property using a functor object.
332    *
333    * The expected structure, for a Vector3 type for example, of the functor object is:
334    * @code
335    *   struct MyObject
336    *   {
337    *     void operator() ( Vector3&, const PropertyInputContainer& );
338    *   };
339    * @endcode
340    *
341    * Create the constraint with this object as follows:
342    *
343    * @code
344    *   Constraint constraint = Constraint::New< Vector3 >( handle, CONSTRAINING_PROPERTY_INDEX, MyObject() );
345    * @endcode
346    *
347    * @since_tizen 2.4
348    * @param[in]  handle       The handle to the property-owning object.
349    * @param[in]  targetIndex  The index of the property to constrain.
350    * @param[in]  object       The functor object whose functor is called to set the constrained property value.
351    * @return The new constraint.
352    *
353    * @tparam P The type of the property to constrain.
354    * @tparam T The type of the object.
355    */
356   template< class P, class T >
357   static Constraint New( Handle handle, Property::Index targetIndex, const T& object )
358   {
359     CallbackBase* function = new Constraint::Function< P >( object );
360     return New( handle, targetIndex, PropertyTypes::Get< P >(), function );
361   }
362
363   /**
364    * @brief Create a constraint which targets a property using an object method.
365    *
366    * The expected structure, for a Vector3 type for example, of the object is:
367    * @code
368    *   struct MyObject
369    *   {
370    *     void MyMethod( Vector3&, const PropertyInputContainer& );
371    *   };
372    * @endcode
373    *
374    * Create the constraint with this object as follows:
375    *
376    * @code
377    *   Constraint constraint = Constraint::New< Vector3 >( handle, CONSTRAINING_PROPERTY_INDEX, MyObject(), &MyObject::MyMethod );
378    * @endcode
379    *
380    * @since_tizen 2.4
381    * @param[in]  handle          The handle to the property-owning object.
382    * @param[in]  targetIndex     The index of the property to constrain.
383    * @param[in]  object          The object whose member function is called to set the constrained property value.
384    * @param[in]  memberFunction  The member function to call to set the constrained property value.
385    * @return The new constraint.
386    *
387    * @tparam P The type of the property to constrain.
388    * @tparam T The type of the object.
389    */
390   template< class P, class T >
391   static Constraint New( Handle handle, Property::Index targetIndex, const T& object, void ( T::*memberFunction ) ( P&, const PropertyInputContainer& ) )
392   {
393     CallbackBase* function = new Constraint::Function< P >( object, memberFunction );
394     return New( handle, targetIndex, PropertyTypes::Get< P >(), function );
395   }
396
397   /**
398    * @brief Creates a clones of this constraint for another object.
399    *
400    * @since_tizen 2.4
401    * @param[in]  handle  The handle to the property-owning object this constraint is to be cloned for.
402    *
403    * @return The new constraint.
404    */
405   Constraint Clone( Handle handle );
406
407   /**
408    * @brief Destructor
409    *
410    * This is non-virtual since derived Handle types must not contain data or virtual methods.
411    * @since_tizen 2.4
412    */
413   ~Constraint();
414
415   /**
416    * @brief This copy constructor is required for (smart) pointer semantics.
417    *
418    * @since_tizen 2.4
419    * @param [in]  constraint  A reference to the copied handle
420    */
421   Constraint( const Constraint& constraint );
422
423   /**
424    * @brief This assignment operator is required for (smart) pointer semantics.
425    *
426    * @since_tizen 2.4
427    * @param [in] rhs  A reference to the copied handle
428    * @return A reference to this
429    */
430   Constraint& operator=( const Constraint& rhs );
431
432   /**
433    * @brief Downcast a handle to Constraint handle.
434    *
435    * If handle points to a Constraint object the
436    * downcast produces valid handle. If not the returned handle is left uninitialized.
437    * @since_tizen 2.4
438    * @param[in] baseHandle BaseHandle to an object
439    * @return Handle to a Constraint object or an uninitialized handle
440    */
441   static Constraint DownCast( BaseHandle baseHandle );
442
443   /**
444    * @brief Adds a constraint source to the constraint
445    *
446    * @since_tizen 2.4
447    * @param[in] source The constraint source input to add
448    */
449   void AddSource( ConstraintSource source );
450
451   /**
452    * @brief Applies this constraint.
453    *
454    * @since_tizen 2.4
455    * @pre The constraint must be initialized
456    * @pre The target object must still be alive
457    * @pre The source inputs should not have been destroyed
458    */
459   void Apply();
460
461   /**
462    * @brief Removes this constraint.
463    * @since_tizen 2.4
464    */
465   void Remove();
466
467   /**
468    * @brief Retrieve the object which this constraint is targeting.
469    *
470    * @since_tizen 2.4
471    * @return The target object.
472    */
473   Handle GetTargetObject();
474
475   /**
476    * @brief Retrieve the property which this constraint is targeting.
477    *
478    * @since_tizen 2.4
479    * @return The target property.
480    */
481   Dali::Property::Index GetTargetProperty();
482
483   /**
484    * @brief Set whether the constraint will "bake" a value when fully-applied.
485    *
486    * Otherwise the constrained value will be discarded, when the constraint is removed.
487    * The default value is Constraint::Bake.
488    * @since_tizen 2.4
489    * @param[in] action The remove-action.
490    */
491   void SetRemoveAction( RemoveAction action );
492
493   /**
494    * @brief Query whether the constraint will "bake" a value when fully-applied.
495    *
496    * Otherwise the constrained value will be discarded, when the constraint is removed.
497    * @since_tizen 2.4
498    * @return The remove-action.
499    */
500   RemoveAction GetRemoveAction() const;
501
502   /**
503    * @brief Set a tag for the constraint so it can be identified later
504    *
505    * @since_tizen 2.4
506    * @param[in] tag An integer to identify the constraint
507    */
508   void SetTag( const unsigned int tag );
509
510   /**
511    * @brief Get the tag
512    *
513    * @since_tizen 2.4
514    * @return The tag
515    */
516   unsigned int GetTag() const;
517
518 public: // Not intended for use by Application developers
519
520   /**
521    * @brief This constructor is used by Constraint::New() methods
522    * @since_tizen 2.4
523    * @param [in] constraint A pointer to a newly allocated Dali resource
524    */
525   explicit DALI_INTERNAL Constraint( Internal::ConstraintBase* constraint );
526
527 private: // Not intended for use by Application developers
528
529   /**
530    * @brief Construct a new constraint which targets a property.
531    *
532    * @since_tizen 2.4
533    * @param[in]  handle       The handle to the property-owning object.
534    * @param[in]  targetIndex  The index of the property to constrain.
535    * @param[in]  targetType   Type The type of the constrained property.
536    * @param[in]  function     The constraint function.
537    * @return The new constraint.
538    */
539   static Constraint New( Handle handle, Property::Index targetIndex, Property::Type targetType, CallbackBase* function );
540 };
541
542 /**
543  * @}
544  */
545 } // namespace Dali
546
547 #endif // __DALI_CONSTRAINT_H__