1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_FOCUS_FOCUS_NODE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_FOCUS_FOCUS_NODE_H
18 
19 #include <functional>
20 #include <list>
21 
22 #include "base/geometry/rect.h"
23 #include "base/memory/ace_type.h"
24 #include "base/utils/macros.h"
25 #include "base/utils/noncopyable.h"
26 #include "core/event/key_event.h"
27 
28 namespace OHOS::Ace {
29 
30 class FocusNode;
31 class FocusGroup;
32 class ClickInfo;
33 
34 using TabIndexNodeList = std::list<std::pair<int32_t, WeakPtr<FocusNode>>>;
35 constexpr int32_t DEFAULT_TAB_FOCUSED_INDEX = -2;
36 constexpr int32_t NONE_TAB_FOCUSED_INDEX = -1;
37 
38 class ACE_FORCE_EXPORT FocusNode : public virtual AceType {
39     DECLARE_ACE_TYPE(FocusNode, AceType);
40     ACE_DISALLOW_COPY_AND_MOVE(FocusNode);
41 
42 public:
43     explicit FocusNode(bool focusable = true) : focusable_(focusable) {}
44     ~FocusNode() override = default;
45 
46     bool HandleKeyEvent(const KeyEvent& keyEvent);
47     void CollectTabIndexNodes(TabIndexNodeList& tabIndexNodes);
48     bool GoToFocusByTabNodeIdx(TabIndexNodeList& tabIndexNodes, int32_t tabNodeIdx);
49     bool HandleFocusByTabIndex(const KeyEvent& event, const RefPtr<FocusGroup>& mainNode);
50     bool RequestFocusImmediately();
51     void UpdateAccessibilityFocusInfo();
52     // Use pipeline to request focus. In this case that node gets focus when the layout needs to be completed.
53     void RequestFocus();
54     void LostFocus(BlurReason reason = BlurReason::FOCUS_SWITCH);
55     void LostSelfFocus();
56 
IsFocusable()57     virtual bool IsFocusable() const
58     {
59         return enabled_ && show_ && focusable_ && parentFocusable_;
60     }
61 
62     virtual bool IsFocusableByTab() const;
63 
64     bool IsFocusableWholePath() const;
65 
AcceptFocusByRectOfLastFocus(const Rect & rect)66     virtual bool AcceptFocusByRectOfLastFocus(const Rect& rect)
67     {
68         return IsFocusable();
69     }
70 
71     void SetFocusable(bool focusable);
72 
IsParentFocusable()73     bool IsParentFocusable() const
74     {
75         return parentFocusable_;
76     }
77 
SetParentFocusable(bool parentFocusable)78     void SetParentFocusable(bool parentFocusable)
79     {
80         parentFocusable_ = parentFocusable;
81     }
82 
IsCurrentFocus()83     bool IsCurrentFocus() const
84     {
85         return currentFocus_;
86     }
87 
SetOnKeyCallback(std::function<bool (const KeyEvent &)> && onKeyCallback)88     void SetOnKeyCallback(std::function<bool(const KeyEvent&)>&& onKeyCallback)
89     {
90         onKeyCallback_ = std::move(onKeyCallback);
91     }
SetOnKeyCallback(std::function<void (const std::shared_ptr<KeyEventInfo> &)> && onKeyCallback)92     void SetOnKeyCallback(std::function<void(const std::shared_ptr<KeyEventInfo>&)>&& onKeyCallback)
93     {
94         onKeyEventCallback_ = std::move(onKeyCallback);
95     }
SetOnClickCallback(std::function<void ()> && onClickCallback)96     void SetOnClickCallback(std::function<void()>&& onClickCallback)
97     {
98         onClickCallback_ = std::move(onClickCallback);
99     }
SetOnClickCallback(std::function<void (const std::shared_ptr<ClickInfo> &)> && onClickCallback)100     void SetOnClickCallback(std::function<void(const std::shared_ptr<ClickInfo>&)>&& onClickCallback)
101     {
102         onClickEventCallback_ = std::move(onClickCallback);
103     }
SetOnFocusCallback(std::function<void ()> && onFocusCallback)104     void SetOnFocusCallback(std::function<void()>&& onFocusCallback)
105     {
106         onFocusCallback_ = std::move(onFocusCallback);
107     }
SetOnBlurCallback(std::function<void ()> && onBlurCallback)108     void SetOnBlurCallback(std::function<void()>&& onBlurCallback)
109     {
110         onBlurCallback_ = std::move(onBlurCallback);
111     }
SetFocusMoveCallback(std::function<void ()> && focusMoveCallback)112     void SetFocusMoveCallback(std::function<void()>&& focusMoveCallback)
113     {
114         focusMoveCallback_ = std::move(focusMoveCallback);
115     }
SetOnDeleteCallback(std::function<void ()> && onDeleteCallback)116     void SetOnDeleteCallback(std::function<void()>&& onDeleteCallback)
117     {
118         onDeleteCallback_ = std::move(onDeleteCallback);
119     }
120 
SetFocusIndex(int32_t focusIndex)121     void SetFocusIndex(int32_t focusIndex)
122     {
123         focusIndex_ = focusIndex;
124         autoFocusIndex_ = false;
125     }
126 
127     void RemoveSelf();
128 
GetParent()129     WeakPtr<FocusGroup> GetParent() const
130     {
131         return parent_;
132     }
SetParent(WeakPtr<FocusGroup> && parent)133     void SetParent(WeakPtr<FocusGroup>&& parent)
134     {
135         parent_ = std::move(parent);
136     }
137 
IsChild()138     virtual bool IsChild() const
139     {
140         return true;
141     }
142 
SetRect(const Rect & rect)143     void SetRect(const Rect& rect)
144     {
145         rectFromOrigin_ = rect;
146     }
GetRect()147     const Rect& GetRect() const
148     {
149         return rectFromOrigin_;
150     }
151 
CanShow()152     bool CanShow() const
153     {
154         return show_;
155     }
156     virtual void SetShow(bool show);
157 
IsEnabled()158     bool IsEnabled() const
159     {
160         return enabled_;
161     }
162     virtual void SetEnabled(bool enabled);
163 
164     virtual void DumpFocusTree(int32_t depth);
165 
166     virtual void DumpFocus();
167 
168     void RefreshFocus();
169 
170     virtual void RefreshParentFocusable(bool focusable);
171 
OnClick()172     virtual void OnClick()
173     {
174         if (onClickCallback_) {
175             onClickCallback_();
176         }
177     }
178 
179     virtual bool OnClick(const KeyEvent& event);
180 
GetTabIndex()181     int32_t GetTabIndex() const
182     {
183         return tabIndex_;
184     }
185 
SetTabIndex(int32_t tabIndex)186     void SetTabIndex(int32_t tabIndex)
187     {
188         tabIndex_ = tabIndex;
189     }
190 
GetInspectorKey()191     const std::string& GetInspectorKey() const
192     {
193         return inspectorKey_;
194     }
195 
SetInspectorKey(std::string & inspectorKey)196     void SetInspectorKey(std::string& inspectorKey)
197     {
198         inspectorKey_ = inspectorKey;
199     }
200 
201     RefPtr<FocusNode> GetChildDefaultFocusNode(bool isGetDefaultFocus = true);
202 
203     RefPtr<FocusNode> GetChildFocusNodeById(const std::string& id);
204 
205     bool RequestFocusImmediatelyById(const std::string& id);
206 
IsDefaultFocus()207     bool IsDefaultFocus() const
208     {
209         return isDefaultFocus_;
210     }
SetIsDefaultFocus(bool isDefaultFocus)211     void SetIsDefaultFocus(bool isDefaultFocus)
212     {
213         isDefaultFocus_ = isDefaultFocus;
214     }
215 
IsDefaultGroupFocus()216     bool IsDefaultGroupFocus() const
217     {
218         return isDefaultGroupFocus_;
219     }
SetIsDefaultGroupFocus(bool isDefaultGroupFocus)220     void SetIsDefaultGroupFocus(bool isDefaultGroupFocus)
221     {
222         isDefaultGroupFocus_ = isDefaultGroupFocus;
223     }
224 
225 protected:
226     virtual bool OnKeyEvent(const KeyEvent& keyEvent);
227 
OnFocus()228     virtual void OnFocus()
229     {
230         if (onFocusCallback_) {
231             onFocusCallback_();
232         }
233         if (onFocus_) {
234             onFocus_();
235         }
236     }
OnBlur()237     virtual void OnBlur()
238     {
239         OnBlur(blurReason_);
240         if (onBlurCallback_) {
241             onBlurCallback_();
242         }
243         if (onBlur_) {
244             onBlur_();
245         }
246     }
OnBlur(BlurReason reason)247     virtual void OnBlur(BlurReason reason) {}
OnFocusMove(KeyCode keyCode)248     virtual void OnFocusMove(KeyCode keyCode)
249     {
250         bool flag = keyCode == KeyCode::TV_CONTROL_UP || keyCode == KeyCode::TV_CONTROL_DOWN ||
251                     keyCode == KeyCode::TV_CONTROL_LEFT || keyCode == KeyCode::TV_CONTROL_RIGHT ||
252                     keyCode == KeyCode::KEY_TAB;
253         if (onFocusMove_ && flag) {
254             onFocusMove_((int)keyCode);
255         }
256     }
257 
HandleFocus()258     virtual void HandleFocus()
259     {
260         if ((!AceType::InstanceOf<FocusGroup>(this)) && focusMoveCallback_) {
261             focusMoveCallback_();
262         }
263         OnFocus();
264     }
265 
OnDeleteEvent()266     virtual void OnDeleteEvent()
267     {
268         if (onDeleteCallback_) {
269             onDeleteCallback_();
270         }
271     }
272 
IsDeleteDisabled()273     virtual bool IsDeleteDisabled()
274     {
275         return false;
276     }
277 
278     std::function<void(int)> onFocusMove_;
279     std::function<void()> onFocus_;
280     std::function<void()> onBlur_;
281     int32_t tabIndex_ = 0;
282     std::string inspectorKey_;
283     bool isFocusOnTouch_ = false;
284     bool isDefaultFocus_ = false;
285     bool isDefaultGroupFocus_ = false;
286     BlurReason blurReason_ = BlurReason::FOCUS_SWITCH;
287 
288 private:
289     static int32_t GenerateFocusIndex();
290 
291     WeakPtr<FocusGroup> parent_;
292 
293     std::function<void(std::shared_ptr<ClickInfo>&)> onClickEventCallback_;
294     std::function<bool(const KeyEvent&)> onKeyCallback_;
295     std::function<void(const std::shared_ptr<KeyEventInfo>&)> onKeyEventCallback_;
296     std::function<void()> onClickCallback_;
297     std::function<void()> onFocusCallback_;
298     std::function<void()> onBlurCallback_;
299     std::function<void()> focusMoveCallback_;
300     std::function<void()> onDeleteCallback_;
301 
302     int32_t focusIndex_ { GenerateFocusIndex() };
303     bool autoFocusIndex_ { true };
304 
305     bool focusable_ { true };
306     bool parentFocusable_ { true };
307     bool currentFocus_ { false };
308     bool show_ { true };
309     bool enabled_ { true };
310 
311     Rect rectFromOrigin_;
312 };
313 
314 class ACE_EXPORT FocusGroup : public FocusNode {
315     DECLARE_ACE_TYPE(FocusGroup, FocusNode);
316 
317 public:
FocusGroup()318     FocusGroup() : FocusNode(true) {}
319     ~FocusGroup() override = default;
320 
321     bool IsFocusable() const override;
322 
323     bool IsFocusableByTab() const override;
324 
325     void AddChild(const RefPtr<FocusNode>& focusNode);
326     void AddChild(const RefPtr<FocusNode>& focusNode, const RefPtr<FocusNode>& nextFocusNode);
327     void RemoveChild(const RefPtr<FocusNode>& focusNode);
328     void RebuildChild(std::list<RefPtr<FocusNode>>&& rebuildFocusNodes);
329 
330     void SwitchFocus(const RefPtr<FocusNode>& focusNode);
331     bool GoToNextFocus(bool reverse, const Rect& rect = Rect());
332 
333     int32_t GetFocusingTabNodeIdx(TabIndexNodeList& tabIndexNodes);
334 
GetChildrenList()335     const std::list<RefPtr<FocusNode>>& GetChildrenList() const
336     {
337         return focusNodes_;
338     }
339 
IsChild()340     bool IsChild() const override
341     {
342         return false;
343     }
344 
345     void DumpFocusTree(int32_t depth) override;
346 
347     void SetShow(bool show) override;
348 
349     void SetEnabled(bool enabled) override;
350 
351     void RefreshParentFocusable(bool focusable) override;
352 
SetIsGroupDefaultFocused(bool isGroupDefaultFocused)353     void SetIsGroupDefaultFocused(bool isGroupDefaultFocused)
354     {
355         isGroupDefaultFocused_ = isGroupDefaultFocused;
356     }
IsGroupDefaultFocused()357     bool IsGroupDefaultFocused() const
358     {
359         return isGroupDefaultFocused_;
360     }
361 
SetIsDefaultHasFocused(bool isDefaultHasFocused)362     void SetIsDefaultHasFocused(bool isDefaultHasFocused)
363     {
364         isDefaultHasFocused_ = isDefaultHasFocused;
365     }
IsDefaultHasFocused()366     bool IsDefaultHasFocused() const
367     {
368         return isDefaultHasFocused_;
369     }
370 
371 protected:
372     bool OnKeyEvent(const KeyEvent& keyEvent) override;
373     void OnFocus() override;
374     void OnBlur() override;
375 
376     bool TryRequestFocus(const RefPtr<FocusNode>& focusNode, const Rect& rect);
377     bool CalculateRect(const RefPtr<FocusNode>& node, Rect& rect);
378     bool AcceptFocusByRectOfLastFocus(const Rect& rect) override;
379 
380     virtual bool RequestNextFocus(bool vertical, bool reverse, const Rect& rect) = 0;
381 
382     std::list<RefPtr<FocusNode>> focusNodes_;
383     std::list<RefPtr<FocusNode>>::iterator itLastFocusNode_ { focusNodes_.end() };
384 
385 private:
386     bool CalculatePosition();
387     bool isDefaultHasFocused_ { false };
388     bool isGroupDefaultFocused_ { false };
389     bool isFirstFocusInPage_ { true };
390 };
391 
392 } // namespace OHOS::Ace
393 
394 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_FOCUS_FOCUS_NODE_H
395