Merge "DALi Version 1.9.30" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / focus-manager / keyboard-focus-manager-impl.h
1 #ifndef DALI_TOOLKIT_INTERNAL_KEYBOARD_FOCUS_MANAGER_H
2 #define DALI_TOOLKIT_INTERNAL_KEYBOARD_FOCUS_MANAGER_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/object/base-object.h>
23 #include <dali/public-api/object/weak-handle.h>
24 #include <dali/public-api/common/vector-wrapper.h>
25
26 // INTERNAL INCLUDES
27 #include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
28 #include <dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.h>
29 #include <dali/devel-api/adaptor-framework/window-devel.h>
30
31 namespace Dali
32 {
33
34 namespace Integration
35 {
36
37 class SceneHolder;
38
39 } // namespace Integration
40
41 namespace Toolkit
42 {
43
44 namespace Internal
45 {
46
47 /**
48  * @copydoc Toolkit::KeyboardFocusManager
49  */
50 class KeyboardFocusManager : public Dali::BaseObject, public ConnectionTracker
51 {
52 public:
53
54   typedef Toolkit::DevelKeyboardFocusManager::CustomAlgorithmInterface CustomAlgorithmInterface;
55
56   enum FocusIndicatorState
57   {
58     UNKNOWN = -1,   ///< Unknown state
59     HIDE = 0,          ///< FocusIndicator is hidden
60     SHOW = 1,          ///< FocusIndicator is shown
61   };
62
63   enum EnableFocusedIndicatorState
64   {
65     DISABLE = 0,          ///< FocusIndicator is disable
66     ENABLE = 1,          ///< FocusIndicator is enable
67   };
68
69   enum FocusedIndicatorModeState
70   {
71     NONE = 0,          ///< Set nothing
72     ALWAYS_SHOW = 1,          ///< FocusIndicator is always shown
73   };
74
75   /**
76    * @copydoc Toolkit::KeyboardFocusManager::Get
77    */
78   static Toolkit::KeyboardFocusManager Get();
79
80   /**
81    * Construct a new KeyboardFocusManager.
82    */
83   KeyboardFocusManager();
84
85   /**
86    * @copydoc Toolkit::KeyboardFocusManager::SetCurrentFocusActor
87    */
88   bool SetCurrentFocusActor(Actor actor);
89
90   /**
91    * @copydoc Toolkit::KeyboardFocusManager::GetCurrentFocusActor
92    */
93   Actor GetCurrentFocusActor();
94
95   /**
96    * @copydoc Toolkit::KeyboardFocusManager::MoveFocus
97    */
98   bool MoveFocus(Toolkit::Control::KeyboardFocus::Direction direction);
99
100   /**
101    * @copydoc Toolkit::KeyboardFocusManager::ClearFocus
102    */
103   void ClearFocus();
104
105   /**
106    * @copydoc Toolkit::KeyboardFocusManager::SetAsFocusGroup
107    */
108   void SetAsFocusGroup(Actor actor, bool isFocusGroup);
109
110   /**
111    * @copydoc Toolkit::KeyboardFocusManager::IsFocusGroup
112    */
113   bool IsFocusGroup(Actor actor) const;
114
115   /**
116    * @copydoc Toolkit::KeyboardFocusManager::GetFocusGroup
117    */
118   Actor GetFocusGroup(Actor actor);
119
120   /**
121    * @copydoc Toolkit::KeyboardFocusManager::SetFocusGroupLoop
122    */
123   void SetFocusGroupLoop(bool enabled);
124
125   /**
126    * @copydoc Toolkit::KeyboardFocusManager::GetFocusGroupLoop
127    */
128   bool GetFocusGroupLoop() const;
129
130   /**
131    * @copydoc Toolkit::KeyboardFocusManager::SetFocusIndicatorActor
132    */
133   void SetFocusIndicatorActor(Actor indicator);
134
135   /**
136    * @copydoc Toolkit::KeyboardFocusManager::GetFocusIndicatorActor
137    */
138   Actor GetFocusIndicatorActor();
139
140   /**
141    * Move current focus to backward
142    */
143   void MoveFocusBackward();
144
145   /**
146    * @copydoc Toolkit::DevelKeyboardFocusManager::SetCustomAlgorithm
147    */
148   void SetCustomAlgorithm(CustomAlgorithmInterface& interface);
149
150   /**
151    * @copydoc Toolkit::DevelKeyboardFocusManager::UseFocusIndicator
152    */
153   void EnableFocusIndicator(bool enable);
154
155   /**
156    * @copydoc Toolkit::DevelKeyboardFocusManager::UseFocusIndicator
157    */
158   bool IsFocusIndicatorEnabled() const;
159
160 public:
161
162   /**
163    * @copydoc Toolkit::KeyboardFocusManager::PreFocusChangeSignal()
164    */
165   Toolkit::KeyboardFocusManager::PreFocusChangeSignalType& PreFocusChangeSignal();
166
167   /**
168    * @copydoc Toolkit::KeyboardFocusManager::FocusChangedSignal()
169    */
170   Toolkit::KeyboardFocusManager::FocusChangedSignalType& FocusChangedSignal();
171
172   /**
173    * @copydoc Toolkit::KeyboardFocusManager::FocusGroupChangedSignal()
174    */
175   Toolkit::KeyboardFocusManager::FocusGroupChangedSignalType& FocusGroupChangedSignal();
176
177   /**
178    * @copydoc Toolkit::KeyboardFocusManager::FocusedActorEnterKeySignal()
179    */
180   Toolkit::KeyboardFocusManager::FocusedActorEnterKeySignalType& FocusedActorEnterKeySignal();
181
182   /**
183    * Connects a callback function with the object's signals.
184    * @param[in] object The object providing the signal.
185    * @param[in] tracker Used to disconnect the signal.
186    * @param[in] signalName The signal to connect to.
187    * @param[in] functor A newly allocated FunctorDelegate.
188    * @return True if the signal was connected.
189    * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
190    */
191   static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor );
192
193 protected:
194
195   /**
196    * Destructor
197    */
198   virtual ~KeyboardFocusManager();
199
200 private:
201
202   typedef std::vector< WeakHandle< Actor > > FocusStack; ///< Define Dali::Vector< Dali::BaseObject* > as FocusStack to contain focus history
203   typedef FocusStack::iterator FocusStackIterator; ///< Define FocusStack::Iterator as FocusStackIterator to navigate FocusStack
204
205   /**
206    * This will be called when the adaptor is initialized
207    */
208   void OnAdaptorInit();
209
210   /**
211    * This will be called when a new scene holder is created
212    * @param sceneHolder The new scene holder
213    */
214   void OnSceneHolderCreated( Dali::Integration::SceneHolder& sceneHolder );
215
216   /**
217    * Get configuration from StyleManager.
218    */
219   void GetConfigurationFromStyleManger();
220
221   /**
222    * Get the focus group of current focused actor.
223    * @pre The FocusManager has been initialized.
224    * @return A handle to the parent of the current focused actor which is a focus group,
225    * or an empty handle if no actor is focused.
226    */
227   Actor GetCurrentFocusGroup();
228
229   /**
230    * Move the focus to the specified actor and send notification for the focus change.
231    * @param actor The actor to be queried
232    * @return Whether the focus is successful or not
233    */
234   bool DoSetCurrentFocusActor(Actor actor);
235
236   /**
237    * Move the focus to the next actor towards the specified direction within the layout control
238    * @param control The layout control to move the focus in
239    * @param actor The current focused actor
240    * @param direction The direction of focus movement
241    * @return Whether the focus is successful or not
242    */
243   bool DoMoveFocusWithinLayoutControl(Toolkit::Control control, Actor actor, Toolkit::Control::KeyboardFocus::Direction direction);
244
245   /**
246    * Move the focus to the first focusable actor in the next focus group in the forward
247    * or backward direction. The "Tab" key changes the focus group in the forward direction
248    * and the "Shift-Tab" key changes it in the backward direction.
249    * @param forward Whether the direction of focus group change is forward or backward
250    * @return Whether the focus group change is successful or not
251    */
252   bool DoMoveFocusToNextFocusGroup(bool forward);
253
254   /**
255    * Enter has been pressed on the actor. If the actor is control, call the OnKeybaordEnter virtual function.
256    * This function will emit FocusedActorEnterKeySignal.
257    * @param actor The actor to notify
258    */
259   void DoKeyboardEnter( Actor actor );
260
261   /**
262    * Check whether the actor is a layout control that supports two dimensional keyboard navigation.
263    * The layout control needs to internally set the focus order for the child actor and be able to
264    * tell KeyboardFocusmanager the next focusable actor in the given direction.
265    * @pre The KeyboardFocusManager has been initialized.
266    * @pre The Actor has been initialized.
267    * @param actor The actor to be checked.
268    * @return Whether the actor is a layout control or not.
269    */
270   bool IsLayoutControl(Actor actor) const;
271
272   /**
273    * Returns the closest ancestor of the given actor that is a layout control.
274    * @param actor The actor to be checked for its parent layout control
275    * @return The parent layout control the given actor belongs to or an empty handle if the given actor doesn't belong to a layout control
276    */
277  Toolkit::Control GetParentLayoutControl(Actor actor) const;
278
279   /**
280    * Callback for the key event when no actor in the stage has gained the key input focus
281    * @param[in] event The KeyEvent event.
282    */
283   void OnKeyEvent( const KeyEvent& event );
284
285   /**
286    * Callback for the touch event when the screen is touched and when the touch ends
287    * (i.e. the down & up touch events only).
288    * @param[in] touch The touch information
289    */
290   void OnTouch( const TouchEvent& touch );
291
292   /**
293    * Called when the window focus is changed.
294    * @param[in] window The window whose focus is changed
295    * @param[in] focusIn Whether the focus is in/out
296    */
297   void OnWindowFocusChanged( Window window, bool focusIn );
298
299   /**
300    * Get the focus Actor from current window
301    */
302   Actor GetFocusActorFromCurrentWindow();
303
304 private:
305
306   // Undefined
307   KeyboardFocusManager(const KeyboardFocusManager&);
308
309   KeyboardFocusManager& operator=(const KeyboardFocusManager& rhs);
310
311 private:
312
313   Toolkit::KeyboardFocusManager::PreFocusChangeSignalType mPreFocusChangeSignal; ///< The signal to notify the focus will be changed
314   Toolkit::KeyboardFocusManager::FocusChangedSignalType mFocusChangedSignal; ///< The signal to notify the focus change
315   Toolkit::KeyboardFocusManager::FocusGroupChangedSignalType mFocusGroupChangedSignal; ///< The signal to notify the focus group change
316   Toolkit::KeyboardFocusManager::FocusedActorEnterKeySignalType mFocusedActorEnterKeySignal; ///< The signal to notify that enter has been pressed on the focused actor
317
318   WeakHandle< Actor > mCurrentFocusActor; ///< A weak handle to the current focused actor
319
320   Actor mFocusIndicatorActor; ///< The focus indicator actor shared by all the keyboard focusable actors for highlight
321
322   FocusStack mFocusHistory; ///< Stack to contain pre-focused actor's BaseObject*
323
324   SlotDelegate< KeyboardFocusManager > mSlotDelegate;
325
326   CustomAlgorithmInterface* mCustomAlgorithmInterface; ///< The user's (application / toolkit) implementation of CustomAlgorithmInterface
327
328   typedef std::vector< std::pair< WeakHandle< Layer >, WeakHandle< Actor > > > FocusActorContainer;
329
330   FocusActorContainer mCurrentFocusActors; ///< A container of focused actors
331
332   WeakHandle< Layer > mCurrentFocusedWindow; ///< A weak handle to the current focused window's root layer
333
334   FocusIndicatorState mIsFocusIndicatorShown; ///< Whether indicator should be shown / hidden when getting focus. It could be enabled when keyboard focus feature is enabled and navigation keys or 'Tab' key are pressed.
335
336   EnableFocusedIndicatorState mEnableFocusIndicator;  ///< Whether use focus indicator
337
338   FocusedIndicatorModeState mAlwaysShowIndicator; ///< Whether always show indicator. If true, the indicator would be directly shown when focused
339
340   bool mFocusGroupLoopEnabled:1; ///< Whether the focus movement is looped within the same focus group
341
342   bool mIsWaitingKeyboardFocusChangeCommit:1; /// A flag to indicate PreFocusChangeSignal emitted but the proposed focus actor is not commited by the application yet.
343
344   bool mClearFocusOnTouch:1; ///< Whether clear focus on touch.
345 };
346
347 } // namespace Internal
348
349 inline Internal::KeyboardFocusManager& GetImpl(Dali::Toolkit::KeyboardFocusManager& obj)
350 {
351   DALI_ASSERT_ALWAYS(obj);
352
353   Dali::BaseObject& handle = obj.GetBaseObject();
354
355   return static_cast<Internal::KeyboardFocusManager&>(handle);
356 }
357
358 inline const Internal::KeyboardFocusManager& GetImpl(const Dali::Toolkit::KeyboardFocusManager& obj)
359 {
360   DALI_ASSERT_ALWAYS(obj);
361
362   const Dali::BaseObject& handle = obj.GetBaseObject();
363
364   return static_cast<const Internal::KeyboardFocusManager&>(handle);
365 }
366
367 } // namespace Toolkit
368
369 } // namespace Dali
370
371 #endif // DALI_TOOLKIT_INTERNAL_KEYBOARD_FOCUS_MANAGER_H