[Tizen] 1. Implement FocusFinder
[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   /**
161    * @copydoc Toolkit::DevelKeyboardFocusManager::EnableDefaultAlgorithm
162    */
163   void EnableDefaultAlgorithm(bool enable);
164
165   /**
166    * @copydoc Toolkit::DevelKeyboardFocusManager::IsDefaultAlgorithmEnabled
167    */
168   bool IsDefaultAlgorithmEnabled() const;
169
170 public:
171
172   /**
173    * @copydoc Toolkit::KeyboardFocusManager::PreFocusChangeSignal()
174    */
175   Toolkit::KeyboardFocusManager::PreFocusChangeSignalType& PreFocusChangeSignal();
176
177   /**
178    * @copydoc Toolkit::KeyboardFocusManager::FocusChangedSignal()
179    */
180   Toolkit::KeyboardFocusManager::FocusChangedSignalType& FocusChangedSignal();
181
182   /**
183    * @copydoc Toolkit::KeyboardFocusManager::FocusGroupChangedSignal()
184    */
185   Toolkit::KeyboardFocusManager::FocusGroupChangedSignalType& FocusGroupChangedSignal();
186
187   /**
188    * @copydoc Toolkit::KeyboardFocusManager::FocusedActorEnterKeySignal()
189    */
190   Toolkit::KeyboardFocusManager::FocusedActorEnterKeySignalType& FocusedActorEnterKeySignal();
191
192   /**
193    * Connects a callback function with the object's signals.
194    * @param[in] object The object providing the signal.
195    * @param[in] tracker Used to disconnect the signal.
196    * @param[in] signalName The signal to connect to.
197    * @param[in] functor A newly allocated FunctorDelegate.
198    * @return True if the signal was connected.
199    * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
200    */
201   static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor );
202
203 protected:
204
205   /**
206    * Destructor
207    */
208   virtual ~KeyboardFocusManager();
209
210 private:
211
212   typedef std::vector< WeakHandle< Actor > > FocusStack; ///< Define Dali::Vector< Dali::BaseObject* > as FocusStack to contain focus history
213   typedef FocusStack::iterator FocusStackIterator; ///< Define FocusStack::Iterator as FocusStackIterator to navigate FocusStack
214
215   /**
216    * This will be called when the adaptor is initialized
217    */
218   void OnAdaptorInit();
219
220   /**
221    * This will be called when a new scene holder is created
222    * @param sceneHolder The new scene holder
223    */
224   void OnSceneHolderCreated( Dali::Integration::SceneHolder& sceneHolder );
225
226   /**
227    * Get configuration from StyleManager.
228    */
229   void GetConfigurationFromStyleManger();
230
231   /**
232    * Get the focus group of current focused actor.
233    * @pre The FocusManager has been initialized.
234    * @return A handle to the parent of the current focused actor which is a focus group,
235    * or an empty handle if no actor is focused.
236    */
237   Actor GetCurrentFocusGroup();
238
239   /**
240    * Move the focus to the specified actor and send notification for the focus change.
241    * @param actor The actor to be queried
242    * @return Whether the focus is successful or not
243    */
244   bool DoSetCurrentFocusActor(Actor actor);
245
246   /**
247    * Move the focus to the next actor towards the specified direction within the layout control
248    * @param control The layout control to move the focus in
249    * @param actor The current focused actor
250    * @param direction The direction of focus movement
251    * @return Whether the focus is successful or not
252    */
253   bool DoMoveFocusWithinLayoutControl(Toolkit::Control control, Actor actor, Toolkit::Control::KeyboardFocus::Direction direction);
254
255   /**
256    * Move the focus to the first focusable actor in the next focus group in the forward
257    * or backward direction. The "Tab" key changes the focus group in the forward direction
258    * and the "Shift-Tab" key changes it in the backward direction.
259    * @param forward Whether the direction of focus group change is forward or backward
260    * @return Whether the focus group change is successful or not
261    */
262   bool DoMoveFocusToNextFocusGroup(bool forward);
263
264   /**
265    * Enter has been pressed on the actor. If the actor is control, call the OnKeybaordEnter virtual function.
266    * This function will emit FocusedActorEnterKeySignal.
267    * @param actor The actor to notify
268    */
269   void DoKeyboardEnter( Actor actor );
270
271   /**
272    * Check whether the actor is a layout control that supports two dimensional keyboard navigation.
273    * The layout control needs to internally set the focus order for the child actor and be able to
274    * tell KeyboardFocusmanager the next focusable actor in the given direction.
275    * @pre The KeyboardFocusManager has been initialized.
276    * @pre The Actor has been initialized.
277    * @param actor The actor to be checked.
278    * @return Whether the actor is a layout control or not.
279    */
280   bool IsLayoutControl(Actor actor) const;
281
282   /**
283    * Returns the closest ancestor of the given actor that is a layout control.
284    * @param actor The actor to be checked for its parent layout control
285    * @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
286    */
287  Toolkit::Control GetParentLayoutControl(Actor actor) const;
288
289   /**
290    * Callback for the key event when no actor in the stage has gained the key input focus
291    * @param[in] event The KeyEvent event.
292    */
293   void OnKeyEvent( const KeyEvent& event );
294
295   /**
296    * Callback for the touch event when the screen is touched and when the touch ends
297    * (i.e. the down & up touch events only).
298    * @param[in] touch The touch information
299    */
300   void OnTouch( const TouchEvent& touch );
301
302   /**
303    * Called when the window focus is changed.
304    * @param[in] window The window whose focus is changed
305    * @param[in] focusIn Whether the focus is in/out
306    */
307   void OnWindowFocusChanged( Window window, bool focusIn );
308
309   /**
310    * Get the focus Actor from current window
311    */
312   Actor GetFocusActorFromCurrentWindow();
313
314 private:
315
316   // Undefined
317   KeyboardFocusManager(const KeyboardFocusManager&);
318
319   KeyboardFocusManager& operator=(const KeyboardFocusManager& rhs);
320
321 private:
322
323   Toolkit::KeyboardFocusManager::PreFocusChangeSignalType mPreFocusChangeSignal; ///< The signal to notify the focus will be changed
324   Toolkit::KeyboardFocusManager::FocusChangedSignalType mFocusChangedSignal; ///< The signal to notify the focus change
325   Toolkit::KeyboardFocusManager::FocusGroupChangedSignalType mFocusGroupChangedSignal; ///< The signal to notify the focus group change
326   Toolkit::KeyboardFocusManager::FocusedActorEnterKeySignalType mFocusedActorEnterKeySignal; ///< The signal to notify that enter has been pressed on the focused actor
327
328   WeakHandle< Actor > mCurrentFocusActor; ///< A weak handle to the current focused actor
329
330   Actor mFocusIndicatorActor; ///< The focus indicator actor shared by all the keyboard focusable actors for highlight
331
332   FocusStack mFocusHistory; ///< Stack to contain pre-focused actor's BaseObject*
333
334   SlotDelegate< KeyboardFocusManager > mSlotDelegate;
335
336   CustomAlgorithmInterface* mCustomAlgorithmInterface; ///< The user's (application / toolkit) implementation of CustomAlgorithmInterface
337
338   typedef std::vector< std::pair< WeakHandle< Layer >, WeakHandle< Actor > > > FocusActorContainer;
339
340   FocusActorContainer mCurrentFocusActors; ///< A container of focused actors
341
342   WeakHandle< Layer > mCurrentFocusedWindow; ///< A weak handle to the current focused window's root layer
343
344   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.
345
346   EnableFocusedIndicatorState mEnableFocusIndicator;  ///< Whether use focus indicator
347
348   FocusedIndicatorModeState mAlwaysShowIndicator; ///< Whether always show indicator. If true, the indicator would be directly shown when focused
349
350   bool mFocusGroupLoopEnabled:1; ///< Whether the focus movement is looped within the same focus group
351
352   bool mIsWaitingKeyboardFocusChangeCommit:1; /// A flag to indicate PreFocusChangeSignal emitted but the proposed focus actor is not commited by the application yet.
353
354   bool mClearFocusOnTouch:1; ///< Whether clear focus on touch.
355
356   bool mEnableDefaultAlgorithm : 1; ///< Whether use default algorithm focus
357 };
358
359 } // namespace Internal
360
361 inline Internal::KeyboardFocusManager& GetImpl(Dali::Toolkit::KeyboardFocusManager& obj)
362 {
363   DALI_ASSERT_ALWAYS(obj);
364
365   Dali::BaseObject& handle = obj.GetBaseObject();
366
367   return static_cast<Internal::KeyboardFocusManager&>(handle);
368 }
369
370 inline const Internal::KeyboardFocusManager& GetImpl(const Dali::Toolkit::KeyboardFocusManager& obj)
371 {
372   DALI_ASSERT_ALWAYS(obj);
373
374   const Dali::BaseObject& handle = obj.GetBaseObject();
375
376   return static_cast<const Internal::KeyboardFocusManager&>(handle);
377 }
378
379 } // namespace Toolkit
380
381 } // namespace Dali
382
383 #endif // DALI_TOOLKIT_INTERNAL_KEYBOARD_FOCUS_MANAGER_H