b8b562148741ecda56649a19392afed810b0d2de
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / public-api / controls / control.h
1 #ifndef DALI_TOOLKIT_CONTROL_H
2 #define DALI_TOOLKIT_CONTROL_H
3
4 /*
5  * Copyright (c) 2020 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 <dali/public-api/actors/custom-actor.h>
23 #include <dali-toolkit/public-api/dali-toolkit-common.h>
24 #include <dali/public-api/events/long-press-gesture-detector.h>
25 #include <dali/public-api/events/pan-gesture-detector.h>
26 #include <dali/public-api/events/pinch-gesture-detector.h>
27 #include <dali/public-api/events/tap-gesture-detector.h>
28 #include <dali/public-api/events/tap-gesture-detector.h>
29
30 // INTERNAL INCLUDES
31 #include <dali-toolkit/public-api/visuals/visual-properties.h>
32
33 namespace Dali
34 {
35
36 namespace Toolkit
37 {
38
39 //Forward declarations.
40
41 namespace Internal
42 {
43 class Control;
44 }
45 /**
46  * @addtogroup dali_toolkit_controls
47  * @{
48  */
49
50 /**
51  * @brief Control is the base class for all controls.
52  *
53  * The implementation of the control must be supplied; see Internal::Control for more details.
54  * @SINCE_1_0.0
55  * @see Internal::Control
56  *
57  * Signals
58  * | %Signal Name           | Method                                              |
59  * |------------------------|-----------------------------------------------------|
60  * | keyEvent               | @ref KeyEventSignal()                               |
61  * | keyInputFocusGained    | @ref KeyInputFocusGainedSignal()                    |
62  * | keyInputFocusLost      | @ref KeyInputFocusLostSignal()                      |
63  * | resourceReady          | @ref ResourceReadySignal()                          |
64  * | tapped                 | @ref GetTapGestureDetector().DetectedSignal()       |
65  * | panned                 | @ref GetPanGestureDetector().DetectedSignal()       |
66  * | pinched                | @ref GetPinchGestureDetector().DetectedSignal()     |
67  * | longPressed            | @ref GetLongPressGestureDetector().DetectedSignal() |
68  *
69  * Actions
70  * | %Action Name           | %Control method called                             |
71  * |------------------------|----------------------------------------------------|
72  * | accessibilityActivated | %OnAccessibilityActivated()                        |
73  */
74 class DALI_TOOLKIT_API Control : public CustomActor
75 {
76 public:
77
78   /**
79    * @brief Enumeration for the start and end property ranges for control.
80    * @SINCE_1_0.0
81    */
82   enum PropertyRange
83   {
84     PROPERTY_START_INDEX = PROPERTY_REGISTRATION_START_INDEX,        ///< Start index is used by the property registration macro. @SINCE_1_0.0
85     CONTROL_PROPERTY_START_INDEX = PROPERTY_START_INDEX,             ///< Start index of Control properties. @SINCE_1_0.0
86     CONTROL_PROPERTY_END_INDEX = CONTROL_PROPERTY_START_INDEX + 1000 ///< Reserving 1000 property indices. @SINCE_1_0.0
87   };
88
89   /**
90    * @brief Enumeration for the instance of properties belonging to the Control class.
91    * @SINCE_1_0.0
92    */
93   struct Property
94   {
95     /**
96      * @brief Enumeration for the instance of properties belonging to the Control class.
97      * @SINCE_1_0.0
98      */
99     enum
100     {
101       /**
102        * @brief The name of the style to be applied to the control.
103        * @details Name "styleName", type Property::STRING.
104        * @see Toolkit::Control::SetStyleName()
105        * @SINCE_1_0.0
106        */
107       STYLE_NAME = PROPERTY_START_INDEX,
108
109       /**
110        * @brief Receives key events to the control.
111        * @details Name "keyInputFocus", type Property::BOOLEAN.
112        * @see Toolkit::Control::SetKeyInputFocus()
113        * @SINCE_1_0.0
114        */
115       KEY_INPUT_FOCUS,
116
117       /**
118        * @brief The background of the control.
119        *
120        * @details Name "background", type Property::MAP or std::string for URL or Property::VECTOR4 for Color.
121        * @SINCE_1_1.3
122        */
123       BACKGROUND,
124
125       /**
126        * @brief The outer space around the control.
127        * @details Name "margin", type Property::EXTENTS.
128        * @SINCE_1_2.62
129        * @note Margin property is to be supported by Layout algorithms and containers in future.
130        */
131       MARGIN,
132
133       /**
134        * @brief The inner space of the control.
135        * @details Name "padding", type Property::EXTENTS.
136        * @SINCE_1_2.62
137        */
138       PADDING
139     };
140   };
141
142   /**
143    * @brief Describes the direction to move the keyboard focus towards.
144    * @SINCE_1_0.0
145    */
146   struct KeyboardFocus
147   {
148     /**
149      * @brief Keyboard focus direction.
150      * @SINCE_1_0.0
151      */
152     enum Direction
153     {
154       LEFT,   ///< Move keyboard focus towards the left direction @SINCE_1_0.0
155       RIGHT,  ///< Move keyboard focus towards the right direction @SINCE_1_0.0
156       UP,     ///< Move keyboard focus towards the up direction @SINCE_1_0.0
157       DOWN,    ///< Move keyboard focus towards the down direction @SINCE_1_0.0
158       PAGE_UP,     ///< Move keyboard focus towards the previous page direction @SINCE_1_2.14
159       PAGE_DOWN    ///< Move keyboard focus towards the next page direction @SINCE_1_2.14
160     };
161   };
162
163   // Typedefs
164
165   /// @brief Key Event signal type. @SINCE_1_0.0
166   typedef Signal<bool ( Control, const KeyEvent& ) > KeyEventSignalType;
167
168   /// @brief Key InputFocusType signal type. @SINCE_1_0.0
169   typedef Signal<void ( Control ) > KeyInputFocusSignalType;
170
171   /// @brief ResourceReady signal type. @SINCE_1_2.60
172   typedef Signal<void ( Control ) > ResourceReadySignalType;
173
174 public: // Creation & Destruction
175
176   /**
177    * @brief Creates a new instance of a Control.
178    *
179    * @SINCE_1_0.0
180    * @return A handle to a new Control
181    */
182   static Control New();
183
184   /**
185    * @brief Creates an uninitialized Control handle.
186    *
187    * Only derived versions can be instantiated.  Calling member
188    * functions with an uninitialized Dali::Object is not allowed.
189    * @SINCE_1_0.0
190    */
191   Control();
192
193   /**
194    * @brief Copy constructor.
195    *
196    * Creates another handle that points to the same real object.
197    * @SINCE_1_0.0
198    * @param[in] uiControl Handle to copy
199    */
200   Control(const Control& uiControl);
201
202   /**
203    * @brief Dali::Control is intended as a base class.
204    *
205    * This is non-virtual since derived Handle types must not contain data or virtual methods.
206    * @SINCE_1_0.0
207    */
208   ~Control();
209
210 public: // operators
211
212   /**
213    * @brief Assignment operator.
214    *
215    * Changes this handle to point to another real object.
216    * @SINCE_1_0.0
217    * @param[in] handle Object to assign this to
218    * @return Reference to this
219    */
220   Control& operator=( const Control& handle );
221
222 public:
223
224   /**
225    * @brief Downcasts a handle to Control handle.
226    *
227    * If handle points to a Control, the downcast produces valid handle.
228    * If not, the returned handle is left uninitialized.
229    *
230    * @SINCE_1_0.0
231    * @param[in] handle Handle to an object
232    * @return A handle to a Control or an uninitialized handle
233    */
234   static Control DownCast( BaseHandle handle );
235
236   // Key Input
237
238   /**
239    * @brief This sets the control to receive key events.
240    *
241    * The key event can originate from a virtual or physical keyboard.
242    * @SINCE_1_0.0
243    * @pre The Control has been initialized.
244    * @pre The Control should be on the stage before setting keyboard focus.
245    */
246   void SetKeyInputFocus();
247
248   /**
249    * @brief Quries whether the control has key input focus.
250    *
251    * @SINCE_1_0.0
252    * @return true if this control has keyboard input focus
253    * @pre The Control has been initialized.
254    * @pre The Control should be on the stage before setting keyboard focus.
255    * @note The control can be set to have the focus and still not receive all the key events if another control has over ridden it.
256    * As the key input focus mechanism works like a stack, the top most control receives all the key events, and passes on the
257    * unhandled events to the controls below in the stack. A control in the stack will regain key input focus when there are no more
258    * controls above it in the focus stack.
259    * To query for the control which is on top of the focus stack use Dali::Toolkit::KeyInputFocusManager::GetCurrentKeyboardFocusActor().
260    */
261   bool HasKeyInputFocus();
262
263   /**
264    * @brief Once an actor is Set to receive key input focus this function is called to stop it receiving key events.
265    *
266    * A check is performed to ensure it was previously set, if this check fails then nothing is done.
267    * @SINCE_1_0.0
268    * @pre The Actor has been initialized.
269    */
270   void ClearKeyInputFocus();
271
272   // Gesture Detection
273
274   /**
275    * @brief Retrieves the pinch gesture detector of the control.
276    *
277    * @SINCE_1_0.0
278    * @return The pinch gesture detector
279    * @note Will return an empty handle if the control does not handle the gesture itself.
280    */
281   PinchGestureDetector GetPinchGestureDetector() const;
282
283   /**
284    * @brief Retrieves the pan gesture detector of the control.
285    *
286    * @SINCE_1_0.0
287    * @return The pan gesture detector
288    * @note Will return an empty handle if the control does not handle the gesture itself.
289    */
290   PanGestureDetector GetPanGestureDetector() const;
291
292   /**
293    * @brief Retrieves the tap gesture detector of the control.
294    *
295    * @SINCE_1_0.0
296    * @return The tap gesture detector
297    * @note Will return an empty handle if the control does not handle the gesture itself.
298    */
299   TapGestureDetector GetTapGestureDetector() const;
300
301   /**
302    * @brief Retrieves the long press gesture detector of the control.
303    *
304    * @SINCE_1_0.0
305    * @return The long press gesture detector
306    * @note Will return an empty handle if the control does not handle the gesture itself.
307    */
308   LongPressGestureDetector GetLongPressGestureDetector() const;
309
310   // Styling
311
312   /**
313    * @brief Sets the name of the style to be applied to the control.
314    *
315    * @SINCE_1_0.0
316    * @param[in] styleName A string matching a style described in a stylesheet
317    */
318   void SetStyleName( const std::string& styleName );
319
320   /**
321    * @brief Retrieves the name of the style to be applied to the control (if any).
322    * @SINCE_1_0.0
323    * @return A string matching a style, or an empty string
324    */
325   const std::string& GetStyleName() const;
326
327   // Background
328
329   /**
330    * @brief Sets the background color of the control.
331    *
332    * @SINCE_1_0.0
333    * @param[in] color The required background color of the control
334    *
335    * @note If SetBackgroundImage is called later, this background color is removed.
336    *
337    * @note The background color fully blends with the actor color.
338    */
339   void SetBackgroundColor( const Vector4& color );
340
341   /**
342    * @brief Clears the background.
343    * @SINCE_1_0.0
344    */
345   void ClearBackground();
346
347   // Resources
348
349   /**
350    * @brief Query if all resources required by a control are loaded and ready.
351    *
352    * Most resources are only loaded when the control is placed on stage.
353    * @SINCE_1_2.60
354    * @return true if the resources are loaded and ready, false otherwise
355    */
356   bool IsResourceReady() const;
357
358   /**
359    * @brief Get the loading state of the visual resource.
360    *
361    * @SINCE_1_3_5
362    * @param[in] index The Property index of the visual
363    * @return Return the loading status (PREPARING, READY and FAILED) of visual resource
364    */
365   Visual::ResourceStatus GetVisualResourceStatus( const Dali::Property::Index index );
366
367   // Signals
368
369   /**
370    * @brief This signal is emitted when key event is received.
371    *
372    * A callback of the following type may be connected:
373    * @code
374    *   bool YourCallbackName(Control control, const KeyEvent& event);
375    * @endcode
376    * The return value of True, indicates that the event should be consumed.
377    * Otherwise the signal will be emitted on the next parent of the actor.
378    * @SINCE_1_0.0
379    * @return The signal to connect to
380    * @pre The Control has been initialized.
381    */
382   KeyEventSignalType& KeyEventSignal();
383
384   /**
385    * @brief This signal is emitted when the control gets Key Input Focus.
386    *
387    * A callback of the following type may be connected:
388    * @code
389    *   bool YourCallbackName( Control control );
390    * @endcode
391    * The return value of True, indicates that the event should be consumed.
392    * Otherwise the signal will be emitted on the next parent of the actor.
393    * @SINCE_1_0.0
394    * @return The signal to connect to
395    * @pre The Control has been initialized.
396    */
397   KeyInputFocusSignalType& KeyInputFocusGainedSignal();
398
399   /**
400    * @brief This signal is emitted when the control loses Key Input Focus.
401    *
402    * This could be due to it being gained by another Control or Actor or just cleared from
403    * this control as no longer required.
404    *
405    * A callback of the following type may be connected:
406    * @code
407    *   bool YourCallbackName( Control control );
408    * @endcode
409    * The return value of True, indicates that the event should be consumed.
410    * Otherwise the signal will be emitted on the next parent of the actor.
411    * @SINCE_1_0.0
412    * @return The signal to connect to
413    * @pre The Control has been initialized.
414    */
415   KeyInputFocusSignalType& KeyInputFocusLostSignal();
416
417   /**
418    * @brief This signal is emitted after all resources required by a control are loaded and ready.
419    *
420    * Most resources are only loaded when the control is placed on stage.
421    *
422    * If resources are shared between ImageViews, they are cached.
423    * In this case, the ResourceReady signal may be sent before there is an object to connect to.
424    * To protect against this, IsResourceReady() can be checked first.
425    *
426    * @code
427    *    auto newControl = Control::New();
428    *    newControl.SetResource( resourceUrl );
429    *    if ( newControl.IsResourceReady() )
430    *    {
431    *       // do something
432    *    }
433    *    else
434    *    {
435    *      newControl.ResourceReadySignal.Connect( .... )
436    *    }
437    * @endcode
438    *
439    * A callback of the following type may be connected:
440    * @code
441    *   void YourCallbackName( Control control );
442    * @endcode
443    *
444    * @SINCE_1_2.60
445    * @return The signal to connect to
446    * @note A RelayoutRequest is queued by Control before this signal is emitted
447    */
448   ResourceReadySignalType& ResourceReadySignal();
449
450 public: // Intended for control developers
451
452   /**
453    * @brief Creates an initialized Control.
454    *
455    * @SINCE_1_0.0
456    * @param[in] implementation The implementation for this control
457    * @return A handle to a newly allocated Dali resource
458    * @note Should NOT be called to create a handle from the implementation. As stated, this allocates a NEW Dali resource.
459    */
460   explicit Control(Internal::Control& implementation);
461
462   /**
463    * @brief This constructor is used by CustomActor within Dali core to create additional Control handles
464    * using an Internal CustomActor pointer.
465    *
466    * @SINCE_1_0.0
467    * @param[in] internal A pointer to a newly allocated Dali resource
468    */
469   explicit Control(Dali::Internal::CustomActor* internal);
470
471 public: // Templates for Deriving Classes
472
473   /**
474    * @brief Template to allow deriving controls to DownCast handles to deriving handle classes.
475    *
476    * @tparam     T      The handle class
477    * @tparam     I      The implementation class
478    * @SINCE_1_0.0
479    * @param[in] handle Handle to an object
480    * @return Handle to a class T or an uninitialized handle
481    * @see DownCast(BaseHandle)
482    */
483   template<typename T, typename I>
484   DALI_INTERNAL static T DownCast( BaseHandle handle )
485   {
486     T result;
487
488     CustomActor custom = Dali::CustomActor::DownCast( handle );
489     if ( custom )
490     {
491       CustomActorImpl& customImpl = custom.GetImplementation();
492
493       I* impl = dynamic_cast<I*>(&customImpl);
494
495       if (impl)
496       {
497         result = T(customImpl.GetOwner());
498       }
499     }
500
501     return result;
502   }
503
504   /**
505    * @brief Template to allow deriving controls to verify whether the Internal::CustomActor* is actually an
506    * implementation of their class.
507    *
508    * @tparam     I       The implementation class
509    * @SINCE_1_0.0
510    * @param[in] internal Pointer to the Internal::CustomActor
511    */
512   template<typename I>
513   DALI_INTERNAL void VerifyCustomActorPointer(Dali::Internal::CustomActor* internal)
514   {
515     // Can have a NULL pointer so we only need to check if the internal implementation is our class
516     // when there is a value.
517     if (internal)
518     {
519       DALI_ASSERT_DEBUG(dynamic_cast<I*>(&CustomActor(internal).GetImplementation()));
520     }
521   }
522
523 };
524
525 /**
526  * @}
527  */
528 } // namespace Toolkit
529
530 } // namespace Dali
531
532 #endif // DALI_TOOLKIT_CONTROL_H