License conversion from Flora to Apache 2.0
[platform/core/uifw/dali-toolkit.git] / capi / dali-toolkit / public-api / controls / control-impl.h
1 #ifndef __DALI_TOOLKIT_CONTROL_IMPL_H__
2 #define __DALI_TOOLKIT_CONTROL_IMPL_H__
3
4 /*
5  * Copyright (c) 2014 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 /**
22  * @addtogroup CAPI_DALI_TOOLKIT_CONTROLS_MODULE
23  * @{
24  */
25
26 // INTERNAL INCLUDES
27 #include <dali-toolkit/public-api/controls/control.h>
28
29 namespace Dali DALI_IMPORT_API
30 {
31
32 namespace Toolkit
33 {
34
35 namespace Internal DALI_INTERNAL
36 {
37 class StyleChangeProcessor;
38 class RelayoutControllerImpl;
39 class KeyInputFocusManager;
40 }
41
42 typedef std::pair< Actor, Vector2 > ActorSizePair; ///< Pair of actor and size
43 typedef std::vector< ActorSizePair > ActorSizeContainer; ///< Container of actors and their sizes
44
45 /**
46  * @brief This is the internal base class for all controls.
47  *
48  * It will provide some common functionality required by all controls.
49  * Implements ConnectionTrackerInterface so that signals (typically connected to member functions) will
50  * be disconnected automatically when the control is destroyed.
51  */
52 class ControlImpl : public CustomActorImpl, public ConnectionTrackerInterface
53 {
54 public:
55
56   // Properties
57   enum
58   {
59     CONTROL_PROPERTY_START_INDEX = PROPERTY_REGISTRATION_START_INDEX,
60     CONTROL_PROPERTY_END_INDEX = CONTROL_PROPERTY_START_INDEX + 1000 ///< Reserving 1000 property indices
61   };
62
63   // Creation
64
65   /**
66    * @brief Create a new ControlImpl instance that does not require touch by default.
67    *
68    * If touch is required then the user can connect to this class' touch signal.
69    * @return A handle to the ConntrolImpl instance.
70    */
71   static Control New();
72
73   // Destruction
74
75   /**
76    * @brief Virtual destructor.
77    */
78   virtual ~ControlImpl();
79
80   // Actions
81
82   /**
83    * @brief This method should be overridden by deriving classes when they wish to be notified when they
84    * are activated.
85    */
86   virtual void OnActivated() { }
87
88   /**
89    * @brief This method should be overridden by deriving classes when they wish to respond the accessibility
90    * pan gesture.
91    *
92    * @param[in] gesture The pan gesture.
93    * @return true if the pan gesture has been consumed by this control
94    */
95   virtual bool OnAccessibilityPan(PanGesture gesture);
96
97   /**
98    * @brief This method should be overridden by deriving classes when they wish to respond
99    * the accessibility up and down action (i.e. value change of slider control).
100    *
101    * @param[in] isIncrease Whether the value should be increased or decreased
102    * @return true if the value changed action has been consumed by this control
103    */
104   virtual bool OnAccessibilityValueChange(bool isIncrease);
105
106   /**
107    * @brief Sets whether this control supports two dimensional
108    * keyboard navigation (i.e. whether it knows how to handle the
109    * keyboardn focus movement between its child actors).
110    *
111    * The control doesn't support it by default.
112    * @param[in] isSupported Whether this control supports two dimensional keyboard navigation.
113    */
114   void SetKeyboardNavigationSupport(bool isSupported);
115
116   /**
117    * @brief Gets whether this control supports two dimensional keyboard navigation.
118    *
119    * @return true if this control supports two dimensional keyboard navigation.
120    */
121   bool IsKeyboardNavigationSupported();
122
123   /**
124    * @brief Sets whether this control is a focus group for keyboard navigation.
125    *
126    * (i.e. the scope of keyboard focus movement
127    * can be limitied to its child actors). The control is not a focus group by default.
128    * @param[in] isFocusGroup Whether this control is set as a focus group for keyboard navigation.
129    */
130   void SetAsKeyboardFocusGroup(bool isFocusGroup);
131
132   /**
133    * @brief Gets whether this control is a focus group for keyboard navigation.
134    *
135    * @return true if this control is set as a focus group for keyboard navigation.
136    */
137   bool IsKeyboardFocusGroup();
138
139   /**
140    * @brief Gets the next keyboard focusable actor in this control towards the given direction.
141    *
142    * A control needs to override this function in order to support two dimensional keyboard navigation.
143    * @param[in] currentFocusedActor The current focused actor.
144    * @param[in] direction The direction to move the focus towards.
145    * @param[in] loopEnabled Whether the focus movement should be looped within the control.
146    * @return the next keyboard focusable actor in this control or an empty handle if no actor can be focused.
147    */
148   virtual Actor GetNextKeyboardFocusableActor(Actor currentFocusedActor, Control::KeyboardFocusNavigationDirection direction, bool loopEnabled);
149
150   /**
151    * @brief Informs this control that its chosen focusable actor will be focused.
152    *
153    * This allows the application to preform any actions if wishes
154    * before the focus is actually moved to the chosen actor.
155    *
156    * @param[in] commitedFocusableActor The commited focusable actor.
157    */
158   virtual void OnKeyboardFocusChangeCommitted(Actor commitedFocusableActor) { }
159
160   /**
161    * @brief Performs actions as requested using the action name.
162    *
163    * @param[in] object The object on which to perform the action.
164    * @param[in] actionName The action to perform.
165    * @param[in] attributes The attributes with which to perfrom this action.
166    * @return true if action has been accepted by this control
167    */
168   static bool DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes);
169
170   /**
171    * @brief If deriving classes wish to fine tune pinch gesture
172    * detection then they can access the gesture detector through this
173    * API and modify the detection.
174    *
175    * @return The pinch gesture detector.
176    * @pre Pinch detection should have been enabled via EnableGestureDetection().
177    * @see EnableGestureDetection
178    */
179   PinchGestureDetector GetPinchGestureDetector() const;
180
181   /**
182    * @brief If deriving classes wish to fine tune pan gesture
183    * detection then they can access the gesture detector through this
184    * API and modify the detection.
185    *
186    * @return The pan gesture detector.
187    * @pre Pan detection should have been enabled via EnableGestureDetection().
188    * @see EnableGestureDetection
189    */
190   PanGestureDetector GetPanGestureDetector() const;
191
192   /**
193    * @brief If deriving classes wish to fine tune tap gesture
194    * detection then they can access the gesture detector through this
195    * API and modify the detection.
196    *
197    * @return The tap gesture detector.
198    * @pre Tap detection should have been enabled via EnableGestureDetection().
199    * @see EnableGestureDetection
200    */
201   TapGestureDetector GetTapGestureDetector() const;
202
203   /**
204    * @brief If deriving classes wish to fine tune long press gesture
205    * detection then they can access the gesture detector through this
206    * API and modify the detection.
207    *
208    * @return The long press gesture detector.
209    * @pre Long press detection should have been enabled via EnableGestureDetection().
210    * @see EnableGestureDetection
211    */
212   LongPressGestureDetector GetLongPressGestureDetector() const;
213
214   // Background
215
216   /**
217    * @copydoc Dali::Toolkit::Control::SetBackgroundColor
218    */
219   void SetBackgroundColor( const Vector4& color );
220
221   /**
222    * @copydoc Dali::Toolkit::Control::GetBackgroundColor
223    */
224   Vector4 GetBackgroundColor() const;
225
226   /**
227    * @copydoc Dali::Toolkit::Control::SetBackground
228    */
229   void SetBackground( Image image );
230
231   /**
232    * @copydoc Dali::Toolkit::Control::ClearBackground
233    */
234   void ClearBackground();
235
236   /**
237    * @copydoc Dali::Toolkit::Control::GetBackgroundActor
238    */
239   Actor GetBackgroundActor() const;
240
241 public:
242
243   /**
244    * @copydoc Dali::Toolkit::Control::KeyEventSignal()
245    */
246   Toolkit::Control::KeyEventSignalV2& KeyEventSignal();
247
248 protected:
249
250   // Construction
251
252   /**
253    * @brief Second phase initialization.
254    */
255   void Initialize();
256
257   // Gesture Detection
258
259   /**
260    * @brief Allows deriving classes to enable any of the gesture detectors that are available.
261    *
262    * Gesture detection can be enabled one at a time or in bitwise format as shown:
263    * @code
264    * EnableGestureDetection(Gesture::Type(Gesture::Pinch | Gesture::Tap | Gesture::Pan));
265    * @endcode
266    * @param[in]  type  The gesture type(s) to enable.
267    */
268   void EnableGestureDetection(Gesture::Type type);
269
270   /**
271    * @brief Allows deriving classes to disable any of the gesture detectors.
272    *
273    * Like EnableGestureDetection, this can also be called using bitwise or.
274    * @param[in]  type  The gesture type(s) to disable.
275    * @see EnableGetureDetection
276    */
277   void DisableGestureDetection(Gesture::Type type);
278
279 private: // For derived classes to override
280
281   /**
282    * @brief This method is called after the Control has been initialized.
283    *
284    * Derived classes should do any second phase initialization by
285    * overriding this method.
286    */
287   virtual void OnInitialize() { }
288
289   /**
290    * @brief This method should be overridden by deriving classes when
291    * they wish to be notified when the style changes.
292    *
293    * @param[in] change  Information denoting what has changed.
294    */
295   virtual void OnStyleChange(StyleChange change) { }
296
297   /**
298    * @brief Called whenever a pinch gesture is detected on this control.
299    *
300    * This can be overridden by deriving classes when pinch detection
301    * is enabled.  The default behaviour is to scale the control by the
302    * pinch scale.
303    *
304    * @note If overridden, then the default behaviour will not occur.
305    * @note Pinch detection should be enabled via EnableGestureDetection().
306    * @param[in]  pinch  The pinch gesture.
307    * @see EnableGestureDetection
308    */
309   virtual void OnPinch(PinchGesture pinch);
310
311   /**
312    * @brief Called whenever a pan gesture is detected on this control.
313    *
314    * This should be overridden by deriving classes when pan detection
315    * is enabled.
316    *
317    * @note There is no default behaviour with panning.
318    * @note Pan detection should be enabled via EnableGestureDetection().
319    * @param[in]  pan  The pan gesture.
320    * @see EnableGestureDetection
321    */
322   virtual void OnPan(PanGesture pan) { }
323
324   /**
325    * @brief Called whenever a tap gesture is detected on this control.
326    *
327    * This should be overridden by deriving classes when tap detection
328    * is enabled.
329    *
330    * @note There is no default behaviour with a tap.
331    * @note Tap detection should be enabled via EnableGestureDetection().
332    * @param[in]  tap  The tap gesture.
333    * @see EnableGestureDetection
334    */
335   virtual void OnTap(TapGesture tap) { }
336
337   /**
338    * @brief Called whenever a long press gesture is detected on this control.
339    *
340    * This should be overridden by deriving classes when long press
341    * detection is enabled.
342    *
343    * @note There is no default behaviour associated with a long press.
344    * @note Long press detection should be enabled via EnableGestureDetection().
345    * @param[in]  longPress  The long press gesture.
346    * @see EnableGestureDetection
347    */
348   virtual void OnLongPress(LongPressGesture longPress) { }
349
350   /**
351    * @brief Called whenever the control is added to the stage.
352    *
353    * Could be overridden by derived classes.
354    */
355   virtual void OnControlStageConnection() { }
356
357   /**
358    * @brief Called whenever the control is removed from the stage.
359    *
360    * Could be overridden by derived classes.
361    */
362   virtual void OnControlStageDisconnection() { }
363
364   /**
365    * @brief Called whenever an Actor is added to the control.
366    *
367    * Could be overridden by derived classes.
368    *
369    * @param[in] child The added actor.
370    */
371   virtual void OnControlChildAdd( Actor& child ) { }
372
373   /**
374    * @brief Called whenever an Actor is removed from the control.
375    *
376    * Could be overridden by derived classes.
377    *
378    * @param[in] child The removed actor.
379    */
380   virtual void OnControlChildRemove( Actor& child ) { }
381
382   /**
383    * @brief Called whenever the Control's size is set.
384    *
385    * Could be overridden by derived classes.
386    *
387    * @param[in] size The new size.
388    */
389   virtual void OnControlSizeSet( const Vector3& size ) { }
390
391   /**
392    * @brief Called after the Dali::Stage::SignalMessageQueueFlushed()
393    * signal is emitted if this control requested to be relaid-out.
394    *
395    * Should be overridden by derived classes if they need to layout
396    * actors differently after certain operations like add or remove
397    * actors, resize or after changing especific properties.
398    *
399    * @param[in]      size       The allocated size.
400    * @param[in,out]  container  The control should add actors to this container that it is not able
401    *                            to allocate a size for.
402    */
403   virtual void OnRelaidOut( Vector2 size, ActorSizeContainer& container );
404
405 private: // From CustomActorImpl, derived classes can override these.
406
407   /**
408    * @brief Sends a request to relayout this control.
409    *
410    * The control will be relaid out after the
411    * Dali::Stage::SignalMessageQueueFlushed() signal is emitted.
412    *
413    * It calls OnControlStageConnection() to notify derived classes.
414    *
415    * @see Dali::CustomActorImpl::OnStageConnection()
416    */
417   virtual void OnStageConnection();
418
419   /**
420    * @brief Calls OnControlStageDisconnection() to notify derived classed.
421    *
422    * @see Dali::CustomActorImpl::OnStageDisconnection()
423    */
424   virtual void OnStageDisconnection();
425
426   /**
427    * @brief Sends a request to relayout this control.
428    *
429    * The control will be relaid out after the
430    * Dali::Stage::SignalMessageQueueFlushed() signal is emitted.  It
431    * calls OnControlChildAdd() to notify derived classes.
432    *
433    * @note This method shouldn't be overridden by derived classes.
434    *
435    * @param[in] child The added actor.
436    *
437    * @see Dali::CustomActorImpl::OnChildAdd(Actor&)
438    */
439   virtual void OnChildAdd(Actor& child);
440
441   /**
442    * @brief Sends a request to relayout this control.
443    *
444    * The control will be relaid out after the
445    * Dali::Stage::SignalMessageQueueFlushed() signal is emitted.  It
446    * calls OnControlChildRemove() to notify derived classes.
447    *
448    * @note This method shouldn't be overridden by derived classes.
449    *
450    * @param[in] child The removed actor.
451    *
452    * @see Dali::CustomActorImpl::OnChildRemove(Actor&)
453    */
454   virtual void OnChildRemove(Actor& child);
455
456   /**
457    * @brief It stores the size set by size negotiation and relayout.
458    *
459    * It also keeps a backup of the size set through the Actor's API used in the size negotiation.
460    * It calls the OnControlSizeSet() to notify derived classes.
461    *
462    * @param[in] targetSize The new size.
463    *
464    * @see Dali::CustomActorImpl::OnSizeSet(const Vector3&)
465    */
466   virtual void OnSizeSet(const Vector3& targetSize);
467
468   /**
469    * @copydoc Dali::CustomActorImpl::OnSizeAnimation(Animation&, const Vector3&)
470    */
471   virtual void OnSizeAnimation(Animation& animation, const Vector3& targetSize);
472
473   /**
474    * @copydoc Dali::CustomActorImpl::OnTouchEvent(const TouchEvent&)
475    */
476   virtual bool OnTouchEvent(const TouchEvent& event);
477
478   /**
479    * @copydoc Dali::CustomActorImpl::OnKeyEvent(const KeyEvent&)
480    */
481   virtual bool OnKeyEvent(const KeyEvent& event);
482
483   /**
484    * @copydoc Dali::CustomActorImpl::OnMouseWheelEvent(const MouseWheelEvent&)
485    */
486   virtual bool OnMouseWheelEvent(const MouseWheelEvent& event);
487
488   /**
489    * @copydoc Dali::CustomActorImpl::OnKeyInputFocusGained()
490    */
491   virtual void OnKeyInputFocusGained();
492
493   /**
494    * @copydoc Dali::CustomActorImpl::OnKeyInputFocusLost()
495    */
496   virtual void OnKeyInputFocusLost();
497
498   /**
499    * @copydoc Dali::CustomActorImpl::GetChildByAlias(const std::string& actorAlias)
500    */
501   virtual Actor GetChildByAlias(const std::string& actorAlias);
502
503 private:
504
505   /**
506    * @brief Perform the activated action.
507    *
508    * @param[in] attributes The attributes to perfrom this action.
509    */
510   void DoActivatedAction(const PropertyValueContainer& attributes);
511
512 protected: // Construction
513
514   /**
515    * @brief Create a ControlImpl.
516    *
517    * @param[in] requiresTouchEvents True if the OnTouchEvent() callback is required.
518    */
519   ControlImpl(bool requiresTouchEvents);
520
521 public:
522
523   // Size negotiation
524
525   /**
526    * @copydoc Control::SetSizePolicy()
527    */
528   void SetSizePolicy( Control::SizePolicy widthPolicy, Control::SizePolicy heightPolicy );
529
530   /**
531    * @copydoc Control::GetSizePolicy()
532    */
533   void GetSizePolicy( Control::SizePolicy& widthPolicy, Control::SizePolicy& heightPolicy ) const;
534
535   /**
536    * @copydoc Control::SetMinimumSize()
537    */
538   void SetMinimumSize( const Vector3& size );
539
540   /**
541    * @copydoc Control::GetMinimumSize()
542    */
543   const Vector3& GetMinimumSize() const;
544
545   /**
546    * @copydoc Control::SetMaximumSize()
547    */
548   void SetMaximumSize( const Vector3& size );
549
550   /**
551    * @copydoc Control::GetMaximumSize()
552    */
553   const Vector3& GetMaximumSize() const;
554
555   /**
556    * @copydoc Control::GetNaturalSize()
557    */
558   virtual Vector3 GetNaturalSize();
559
560   /**
561    * @copydoc Control::GetHeightForWidth()
562    */
563   virtual float GetHeightForWidth( float width );
564
565   /**
566    * @copydoc Control::GetWidthForHeight()
567    */
568   virtual float GetWidthForHeight( float height );
569
570   /**
571    * @brief Retrieves the current Control's size.
572    *
573    * @return The control's size.
574    */
575   const Vector3& GetControlSize() const;
576
577   /**
578    * @brief Retrieves the Control's size set by the Application / Control.
579    *
580    * @return The control's size.
581    */
582   const Vector3& GetSizeSet() const;
583
584   //KeyInput
585
586   /**
587    * @copydoc Control::SetKeyInputFocus()
588    */
589   void SetKeyInputFocus();
590
591   /**
592    * @copydoc Control::HasKeyInputFocus()
593    */
594   bool HasKeyInputFocus();
595
596   /**
597    * @copydoc Control::ClearKeyInputFocus()
598    */
599   void ClearKeyInputFocus();
600
601   /**
602    * @copydoc ConnectionTrackerInterface::SignalConnected
603    */
604   virtual void SignalConnected( SlotObserver* slotObserver, CallbackBase* callback );
605
606   /**
607    * @copydoc ConnectionTrackerInterface::SignalDisconnected
608    */
609   virtual void SignalDisconnected( SlotObserver* slotObserver, CallbackBase* callback );
610
611   /**
612    * @copydoc ConnectionTrackerInterface::GetConnectionCount
613    */
614   virtual std::size_t GetConnectionCount() const;
615
616 protected:
617
618   /**
619    * @brief Sends a request to be relaid-out.
620    *
621    * This method is called from OnStageConnection(), OnChildAdd(),
622    * OnChildRemove(), SetSizePolicy(), SetMinimumSize() and
623    * SetMaximumSize().
624    *
625    * This method could also be called from derived classes every time
626    * a control's poperty change and it needs to be relaid-out.  After
627    * the Dali::Stage::SignalMessageQueueFlushed() is emitted a
628    * relayout process starts and all controls which called this method
629    * will be relaid-out.
630    *
631    * @note RelayoutRequest() only sends a request per Control before
632    * the Dali::Stage::SignalMessageQueueFlushed() signal is
633    * emitted. That means a control will be relaid-out only once, even
634    * if more than one request is sent between two consecutive signals.
635    */
636   void RelayoutRequest();
637
638   /**
639    * @brief Helper method for controls to Relayout their children if
640    * they do not know whether that child is a control or not.
641    *
642    * @param[in]      actor      The actor to relayout.
643    * @param[in]      size       The size to allocate to the actor.
644    * @param[in,out]  container  The container that holds actors that have not been allocated a size yet.
645    */
646   static void Relayout( Actor actor, Vector2 size, ActorSizeContainer& container );
647
648 private: // Used by the RelayoutController
649
650   /**
651    * @brief Called by the RelayoutController to negotiate the size of a control.
652    *
653    * The size allocated by the the algorithm is passed in which the
654    * control must adhere to.  A container is passed in as well which
655    * the control should populate with actors it has not / or does not
656    * need to handle in its size negotiation.
657    *
658    * @param[in]      size       The allocated size.
659    * @param[in,out]  container  The container that holds actors that are fed back into the
660    *                            RelayoutController algorithm.
661    */
662   void NegotiateSize( Vector2 size, ActorSizeContainer& container );
663
664 private:
665
666   /**
667    * @brief Called by NegotiateSize when the size to allocate to the control has been calculated.
668    *
669    * It calls the OnRelaidOut() method which can be overridden by derived classes.
670    *
671    * @param[in]      size       The allocated size.
672    * @param[in,out]  container  The control should add actors to this container that it is not able
673    *                            to allocate a size for.
674    */
675   void Relayout( Vector2 size, ActorSizeContainer& container );
676
677   /**
678    * @brief Used by the KeyInputFocusManager to emit key event signals.
679    *
680    * @param[in] event The key event.
681    * @return True if the event was consumed.
682    */
683   bool EmitKeyEventSignal(const KeyEvent& event);
684
685
686
687 private:
688
689   // Undefined
690   ControlImpl(const ControlImpl&);
691   ControlImpl& operator=(const ControlImpl&);
692
693   class Impl;
694   Impl *mImpl;
695
696   friend class Internal::StyleChangeProcessor;
697   friend class Internal::RelayoutControllerImpl;   ///< Relayout controller needs to call Relayout() which is private.
698   friend class Internal::KeyInputFocusManager;     ///< KeyInputFocusManager needs to call which is private.
699 };
700
701 } // namespace Toolkit
702
703 } // namespace Dali
704
705 /**
706  * @}
707  */
708 #endif // __DALI_TOOLKIT_CONTROL_IMPL_H__