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