a9c1a00122b6fd93193ba954b1f7a49774d48296
[platform/core/uifw/dali-core.git] / dali / public-api / actors / custom-actor-impl.h
1 #ifndef __DALI_CUSTOM_ACTOR_IMPL_H__
2 #define __DALI_CUSTOM_ACTOR_IMPL_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/object/property.h>
23 #include <dali/public-api/object/ref-object.h>
24 #include <dali/public-api/actors/actor-enumerations.h>
25 #include <dali/public-api/math/compile-time-math.h>
26
27 namespace Dali
28 {
29 /**
30  * @addtogroup dali_core_actors
31  * @{
32  */
33
34 namespace Internal DALI_INTERNAL
35 {
36 class CustomActor;
37 }
38
39 class Actor;
40 class Animation;
41 class CustomActor;
42 class CustomActorImpl;
43 class RelayoutContainer;
44 struct KeyEvent;
45 struct TouchEvent;
46 struct HoverEvent;
47 struct WheelEvent;
48 struct Vector2;
49 struct Vector3;
50
51 /**
52  * @brief Pointer to Dali::CustomActorImpl object.
53  * @SINCE_1_0.0
54  */
55 typedef IntrusivePtr<CustomActorImpl> CustomActorImplPtr;
56
57 /**
58  * @brief CustomActorImpl is an abstract base class for custom control implementations.
59  *
60  * This provides a series of pure virtual methods, which are called when actor-specific events occur.
61  * And CustomActorImpl is typically owned by a single CustomActor instance; see also CustomActor::CustomActor( CustomActorImpl &implementation ).
62  * @SINCE_1_0.0
63  */
64 class DALI_IMPORT_API CustomActorImpl : public Dali::RefObject
65 {
66 public:
67
68   class Extension; ///< Forward declare future extension interface
69
70   /**
71    * @brief Virtual destructor
72    * @SINCE_1_0.0
73    */
74   virtual ~CustomActorImpl();
75
76   /**
77    * @brief Used by derived CustomActorImpl instances, to access the public Actor interface.
78    *
79    * @SINCE_1_0.0
80    * @return A pointer to self, or an uninitialized pointer if the CustomActorImpl is not owned.
81    */
82   CustomActor Self() const;
83
84   /**
85    * @brief Called after the actor has been connected to the stage.
86    *
87    * When an actor is connected, it will be directly or indirectly parented to the root Actor.
88    * @SINCE_1_0.0
89    * @param[in] depth The depth in the hierarchy for the actor
90    *
91    * @note The root Actor is provided automatically by Dali::Stage, and is always considered to be connected.
92    * When the parent of a set of actors is connected to the stage, then all of the children
93    * will received this callback.
94    * For the following actor tree, the callback order will be A, B, D, E, C, and finally F.
95    *
96    * @code
97    *
98    *       A (parent)
99    *      / \
100    *     B   C
101    *    / \   \
102    *   D   E   F
103    *
104    * @endcode
105    * @param[in] depth The depth in the hierarchy for the actor
106    */
107   virtual void OnStageConnection( int depth ) = 0;
108
109   /**
110    * @brief Called after the actor has been disconnected from Stage.
111    *
112    * If an actor is disconnected it either has no parent, or is parented to a disconnected actor.
113    *
114    * @SINCE_1_0.0
115    * @note When the parent of a set of actors is disconnected to the stage, then all of the children
116    * will received this callback, starting with the leaf actors.
117    * For the following actor tree, the callback order will be D, E, B, F, C, and finally A.
118    *
119    * @code
120    *
121    *       A (parent)
122    *      / \
123    *     B   C
124    *    / \   \
125    *   D   E   F
126    *
127    * @endcode
128    */
129   virtual void OnStageDisconnection() = 0;
130
131   /**
132    * @brief Called after a child has been added to the owning actor.
133    *
134    * @SINCE_1_0.0
135    * @param[in] child The child which has been added
136    */
137   virtual void OnChildAdd(Actor& child) = 0;
138
139   /**
140    * @brief Called after the owning actor has attempted to remove a child( regardless of whether it succeeded or not ).
141    *
142    * @SINCE_1_0.0
143    * @param[in] child The child being removed
144    */
145   virtual void OnChildRemove(Actor& child) = 0;
146
147   /**
148    * @brief Called when the owning actor property is set.
149    *
150    * @SINCE_1_0.0
151    * @param[in] index The Property index that was set
152    * @param[in] propertyValue The value to set
153    */
154   virtual void OnPropertySet( Property::Index index, Property::Value propertyValue );
155
156   /**
157    * @brief Called when the owning actor's size is set e.g. using Actor::SetSize().
158    *
159    * @SINCE_1_0.0
160    * @param[in] targetSize The target size. Note that this target size may not match the size returned via @ref Actor::GetTargetSize.
161    */
162   virtual void OnSizeSet(const Vector3& targetSize) = 0;
163
164   /**
165    * @brief Called when the owning actor's size is animated e.g. using Animation::AnimateTo( Property( actor, Actor::Property::SIZE ), ... ).
166    *
167    * @SINCE_1_0.0
168    * @param[in] animation The object which is animating the owning actor.
169    * @param[in] targetSize The target size. Note that this target size may not match the size returned via @ref Actor::GetTargetSize.
170    */
171   virtual void OnSizeAnimation(Animation& animation, const Vector3& targetSize) = 0;
172
173   /**
174    * @DEPRECATED_1_1.37 Connect to TouchSignal() instead.
175    *
176    * @brief Called after a touch-event is received by the owning actor.
177    *
178    * @SINCE_1_0.0
179    * @param[in] event The touch event
180    * @return True if the event should be consumed.
181    * @note CustomActorImpl::REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomActorImpl::CustomActorImpl( ActorFlags flags ).
182    */
183   virtual bool OnTouchEvent(const TouchEvent& event) = 0;
184
185   /**
186    * @brief Called after a hover-event is received by the owning actor.
187    *
188    * @SINCE_1_0.0
189    * @param[in] event The hover event
190    * @return True if the event should be consumed.
191    * @note CustomActorImpl::REQUIRES_HOVER_EVENTS must be enabled during construction. See CustomActorImpl::CustomActorImpl( ActorFlags flags ).
192    */
193   virtual bool OnHoverEvent(const HoverEvent& event) = 0;
194
195   /**
196    * @brief Called after a key-event is received by the actor that has had its focus set.
197    *
198    * @SINCE_1_0.0
199    * @param[in] event the Key Event
200    * @return True if the event should be consumed.
201    */
202   virtual bool OnKeyEvent(const KeyEvent& event) = 0;
203
204   /**
205    * @brief Called after a wheel-event is received by the owning actor.
206    *
207    * @SINCE_1_0.0
208    * @param[in] event The wheel event
209    * @return True if the event should be consumed.
210    * @note CustomActorImpl::REQUIRES_WHEEL_EVENTS must be enabled during construction. See CustomActorImpl::CustomActorImpl( ActorFlags flags ).
211    */
212   virtual bool OnWheelEvent(const WheelEvent& event) = 0;
213
214   /**
215    * @brief Called after the size negotiation has been finished for this control.
216    *
217    * The control is expected to assign this given size to itself/its children.
218    *
219    * Should be overridden by derived classes if they need to layout
220    * actors differently after certain operations like add or remove
221    * actors, resize or after changing specific properties.
222    *
223    * @SINCE_1_0.0
224    * @param[in]      size       The allocated size.
225    * @param[in,out]  container  The control should add actors to this container that it is not able
226    *                            to allocate a size for.
227    * @note  As this function is called from inside the size negotiation algorithm, you cannot
228    * call RequestRelayout (the call would just be ignored).
229    */
230   virtual void OnRelayout( const Vector2& size, RelayoutContainer& container ) = 0;
231
232   /**
233    * @brief Notification for deriving classes
234    *
235    * @SINCE_1_0.0
236    * @param[in] policy The policy being set
237    * @param[in] dimension The dimension the policy is being set for
238    */
239   virtual void OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension ) = 0;
240
241   /**
242    * @brief Return the natural size of the actor.
243    *
244    * @SINCE_1_0.0
245    * @return The actor's natural size
246    */
247   virtual Vector3 GetNaturalSize() = 0;
248
249   /**
250    * @brief Calculate the size for a child.
251    *
252    * @SINCE_1_0.0
253    * @param[in] child The child actor to calculate the size for
254    * @param[in] dimension The dimension to calculate the size for. E.g. width or height.
255    * @return Return the calculated size for the given dimension.
256    */
257   virtual float CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension ) = 0;
258
259   /**
260    * @brief This method is called during size negotiation when a height is required for a given width.
261    *
262    * Derived classes should override this if they wish to customize the height returned.
263    *
264    * @SINCE_1_0.0
265    * @param width Width to use.
266    * @return The height based on the width.
267    */
268   virtual float GetHeightForWidth( float width ) = 0;
269
270   /**
271    * @brief This method is called during size negotiation when a width is required for a given height.
272    *
273    * Derived classes should override this if they wish to customize the width returned.
274    *
275    * @SINCE_1_0.0
276    * @param height Height to use.
277    * @return The width based on the width.
278    */
279   virtual float GetWidthForHeight( float height ) = 0;
280
281   /**
282    * @brief Determine if this actor is dependent on it's children for relayout.
283    *
284    * @SINCE_1_0.0
285    * @param dimension The dimension(s) to check for
286    * @return Return if the actor is dependent on it's children.
287    */
288   virtual bool RelayoutDependentOnChildren( Dimension::Type dimension = Dimension::ALL_DIMENSIONS ) = 0;
289
290   /**
291    * @brief Virtual method to notify deriving classes that relayout dependencies have been
292    * met and the size for this object is about to be calculated for the given dimension
293    *
294    * @SINCE_1_0.0
295    * @param dimension The dimension that is about to be calculated
296    */
297   virtual void OnCalculateRelayoutSize( Dimension::Type dimension ) = 0;
298
299   /**
300    * @brief Virtual method to notify deriving classes that the size for a dimension
301    * has just been negotiated
302    *
303    * @SINCE_1_0.0
304    * @param[in] size The new size for the given dimension
305    * @param[in] dimension The dimension that was just negotiated
306    */
307   virtual void OnLayoutNegotiated( float size, Dimension::Type dimension ) = 0;
308
309   /**
310    * @brief Retrieve the extension for this control.
311    *
312    * @SINCE_1_0.0
313    * @return The extension if available, NULL otherwise
314    */
315   virtual Extension* GetExtension()
316   {
317     return NULL;
318   }
319
320 protected: // For derived classes
321
322   /**
323    * @brief Flags for the constructor
324    * @SINCE_1_0.0
325    */
326   enum ActorFlags
327   {
328     ACTOR_BEHAVIOUR_NONE          = 0,
329     DISABLE_SIZE_NEGOTIATION      = 1 << 0,     ///< True if control does not need size negotiation, i.e. it can be skipped in the algorithm @SINCE_1_0.0
330     REQUIRES_TOUCH_EVENTS         = 1 << 1,     ///< True if the OnTouchEvent() callback is required. @SINCE_1_0.0
331     REQUIRES_HOVER_EVENTS         = 1 << 2,     ///< True if the OnHoverEvent() callback is required. @SINCE_1_0.0
332     REQUIRES_WHEEL_EVENTS   = 1 << 3,     ///< True if the OnWheelEvent() callback is required. @SINCE_1_0.0
333
334     LAST_ACTOR_FLAG                             ///< Special marker for last actor flag @SINCE_1_0.0
335   };
336
337   static const int ACTOR_FLAG_COUNT = Log< LAST_ACTOR_FLAG - 1 >::value + 1;      ///< Value for deriving classes to continue on the flag enum
338
339   /**
340    * @brief Create a CustomActorImpl.
341    * @SINCE_1_0.0
342    * @param[in] flags Bitfield of ActorFlags to define behaviour
343    */
344   CustomActorImpl( ActorFlags flags );
345
346   // Size negotiation helpers
347
348   /**
349    * @brief Request a relayout, which means performing a size negotiation on this actor, its parent and children (and potentially whole scene).
350    *
351    * This method can also be called from a derived class every time it needs a different size.
352    * At the end of event processing, the relayout process starts and
353    * all controls which requested Relayout will have their sizes (re)negotiated.
354    *
355    * @SINCE_1_0.0
356    * @note RelayoutRequest() can be called multiple times; the size negotiation is still
357    * only performed once, i.e. there is no need to keep track of this in the calling side.
358    */
359   void RelayoutRequest();
360
361   /**
362    * @brief Provides the Actor implementation of GetHeightForWidth.
363    * @SINCE_1_0.0
364    * @param width Width to use.
365    * @return The height based on the width.
366    */
367   float GetHeightForWidthBase( float width );
368
369   /**
370    * @brief Provides the Actor implementation of GetWidthForHeight.
371    * @SINCE_1_0.0
372    * @param height Height to use.
373    * @return The width based on the height.
374    */
375   float GetWidthForHeightBase( float height );
376
377   /**
378    * @brief Calculate the size for a child using the base actor object.
379    *
380    * @SINCE_1_0.0
381    * @param[in] child The child actor to calculate the size for
382    * @param[in] dimension The dimension to calculate the size for. E.g. width or height
383    * @return Return the calculated size for the given dimension. If more than one dimension is requested, just return the first one found.
384    */
385   float CalculateChildSizeBase( const Dali::Actor& child, Dimension::Type dimension );
386
387   /**
388    * @brief Determine if this actor is dependent on it's children for relayout from the base class.
389    *
390    * @SINCE_1_0.0
391    * @param dimension The dimension(s) to check for
392    * @return Return if the actor is dependent on it's children.
393    */
394   bool RelayoutDependentOnChildrenBase( Dimension::Type dimension = Dimension::ALL_DIMENSIONS );
395
396 public: // Not intended for application developers
397
398   /**
399    * @brief Initialize a CustomActor.
400    * @SINCE_1_0.0
401    * @param[in] owner The owning object
402    * @pre The CustomActorImpl is not already owned.
403    * @note Called when ownership of the CustomActorImpl is passed to a CustomActor.
404    */
405   void Initialize(Internal::CustomActor& owner);
406
407   /**
408    * @brief Get the owner.
409    *
410    * This method is needed when creating additional handle objects to existing objects.
411    * Owner is the Dali::Internal::CustomActor that owns the implementation of the custom actor
412    * inside core. Creation of a handle to Dali public API Actor requires this pointer.
413    * @SINCE_1_0.0
414    * @return A pointer to the Actor implementation that owns this custom actor implementation
415    */
416   Internal::CustomActor* GetOwner() const;
417
418   /**
419    * @brief Returns whether the OnTouchEvent() callback is required.
420    * @SINCE_1_0.0
421    * @return True if the OnTouchEvent() callback is required.
422    * @note Called when ownership of the CustomActorImpl is passed to a CustomActor.
423    */
424   bool RequiresTouchEvents() const;
425
426   /**
427    * @brief Returns whether the OnHoverEvent() callback is required.
428    * @SINCE_1_0.0
429    * @return True if the OnHoverEvent() callback is required.
430    * @note Called when ownership of the CustomActorImpl is passed to a CustomActor.
431    */
432   bool RequiresHoverEvents() const;
433
434   /**
435    * @brief Returns whether the OnWheelEvent() callback is required.
436    * @SINCE_1_0.0
437    * @return True if the OnWheelEvent() callback is required.
438    * @note Called when ownership of the CustomActorImpl is passed to a CustomActor.
439    */
440   bool RequiresWheelEvents() const;
441
442   /**
443    * @brief Returns whether relayout is enabled.
444    * @SINCE_1_0.0
445    * @return Return true if relayout is enabled on the custom actor.
446    * @note Called when ownership of the CustomActorImpl is passed to a CustomActor.
447    */
448   bool IsRelayoutEnabled() const;
449
450 private:
451
452   Internal::CustomActor* mOwner;        ///< Internal owner of this custom actor implementation
453   ActorFlags mFlags :ACTOR_FLAG_COUNT;  ///< ActorFlags flags to determine behaviour
454 };
455
456 /**
457  * @}
458  */
459 } // namespace Dali
460
461 #endif // __DALI_CUSTOM_ACTOR_IMPL_H__