• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_EXPORT FocusNode : public virtual AceType {
39     DECLARE_ACE_TYPE(FocusNode, AceType);
40     ACE_DISALLOW_COPY_AND_MOVE(FocusNode);
41 
42 public:
focusable_(focusable)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         LOGD("FocusNode::OnFocus: Node(%{public}s) on focus", AceType::TypeName(this));
231         if (onFocusCallback_) {
232             onFocusCallback_();
233         }
234         if (onFocus_) {
235             onFocus_();
236         }
237     }
OnBlur()238     virtual void OnBlur()
239     {
240         LOGD("FocusNode::OnBlur: Node(%{public}s) on blur", AceType::TypeName(this));
241         OnBlur(blurReason_);
242         if (onBlurCallback_) {
243             onBlurCallback_();
244         }
245         if (onBlur_) {
246             onBlur_();
247         }
248     }
OnBlur(BlurReason reason)249     virtual void OnBlur(BlurReason reason)
250     {
251         LOGD("FocusNode: (%{public}s) 's blur reason is %{public}d", AceType::TypeName(this), reason);
252     }
OnFocusMove(KeyCode keyCode)253     virtual void OnFocusMove(KeyCode keyCode)
254     {
255         bool flag = keyCode == KeyCode::TV_CONTROL_UP || keyCode == KeyCode::TV_CONTROL_DOWN ||
256                     keyCode == KeyCode::TV_CONTROL_LEFT || keyCode == KeyCode::TV_CONTROL_RIGHT ||
257                     keyCode == KeyCode::KEY_TAB;
258         if (onFocusMove_ && flag) {
259             onFocusMove_((int)keyCode);
260         }
261     }
262 
HandleFocus()263     virtual void HandleFocus()
264     {
265         if ((!AceType::InstanceOf<FocusGroup>(this)) && focusMoveCallback_) {
266             focusMoveCallback_();
267         }
268         OnFocus();
269     }
270 
OnDeleteEvent()271     virtual void OnDeleteEvent()
272     {
273         if (onDeleteCallback_) {
274             onDeleteCallback_();
275         }
276     }
277 
IsDeleteDisabled()278     virtual bool IsDeleteDisabled()
279     {
280         return false;
281     }
282 
283     std::function<void(int)> onFocusMove_;
284     std::function<void()> onFocus_;
285     std::function<void()> onBlur_;
286     int32_t tabIndex_ = 0;
287     std::string inspectorKey_;
288     bool isFocusOnTouch_ = false;
289     bool isDefaultFocus_ = false;
290     bool isDefaultGroupFocus_ = false;
291     BlurReason blurReason_ = BlurReason::FOCUS_SWITCH;
292 
293 private:
294     static int32_t GenerateFocusIndex();
295 
296     WeakPtr<FocusGroup> parent_;
297 
298     std::function<void(std::shared_ptr<ClickInfo>&)> onClickEventCallback_;
299     std::function<bool(const KeyEvent&)> onKeyCallback_;
300     std::function<void(const std::shared_ptr<KeyEventInfo>&)> onKeyEventCallback_;
301     std::function<void()> onClickCallback_;
302     std::function<void()> onFocusCallback_;
303     std::function<void()> onBlurCallback_;
304     std::function<void()> focusMoveCallback_;
305     std::function<void()> onDeleteCallback_;
306 
307     int32_t focusIndex_ { GenerateFocusIndex() };
308     bool autoFocusIndex_ { true };
309 
310     bool focusable_ { true };
311     bool parentFocusable_ { true };
312     bool currentFocus_ { false };
313     bool show_ { true };
314     bool enabled_ { true };
315 
316     Rect rectFromOrigin_;
317 };
318 
319 class ACE_EXPORT FocusGroup : public FocusNode {
320     DECLARE_ACE_TYPE(FocusGroup, FocusNode);
321 
322 public:
FocusGroup()323     FocusGroup() : FocusNode(true) {}
324     ~FocusGroup() override = default;
325 
326     bool IsFocusable() const override;
327 
328     bool IsFocusableByTab() const override;
329 
330     void AddChild(const RefPtr<FocusNode>& focusNode);
331     void AddChild(const RefPtr<FocusNode>& focusNode, const RefPtr<FocusNode>& nextFocusNode);
332     void RemoveChild(const RefPtr<FocusNode>& focusNode);
333     void RebuildChild(std::list<RefPtr<FocusNode>>&& rebuildFocusNodes);
334 
335     void SwitchFocus(const RefPtr<FocusNode>& focusNode);
336     bool GoToNextFocus(bool reverse, const Rect& rect = Rect());
337 
338     int32_t GetFocusingTabNodeIdx(TabIndexNodeList& tabIndexNodes);
339 
GetChildrenList()340     const std::list<RefPtr<FocusNode>>& GetChildrenList() const
341     {
342         return focusNodes_;
343     }
344 
IsChild()345     bool IsChild() const override
346     {
347         return false;
348     }
349 
350     void DumpFocusTree(int32_t depth) override;
351 
352     void SetShow(bool show) override;
353 
354     void SetEnabled(bool enabled) override;
355 
356     void RefreshParentFocusable(bool focusable) override;
357 
SetIsGroupDefaultFocused(bool isGroupDefaultFocused)358     void SetIsGroupDefaultFocused(bool isGroupDefaultFocused)
359     {
360         isGroupDefaultFocused_ = isGroupDefaultFocused;
361     }
IsGroupDefaultFocused()362     bool IsGroupDefaultFocused() const
363     {
364         return isGroupDefaultFocused_;
365     }
366 
SetIsDefaultHasFocused(bool isDefaultHasFocused)367     void SetIsDefaultHasFocused(bool isDefaultHasFocused)
368     {
369         isDefaultHasFocused_ = isDefaultHasFocused;
370     }
IsDefaultHasFocused()371     bool IsDefaultHasFocused() const
372     {
373         return isDefaultHasFocused_;
374     }
375 
376 protected:
377     bool OnKeyEvent(const KeyEvent& keyEvent) override;
378     void OnFocus() override;
379     void OnBlur() override;
380 
381     bool TryRequestFocus(const RefPtr<FocusNode>& focusNode, const Rect& rect);
382     bool CalculateRect(const RefPtr<FocusNode>& node, Rect& rect);
383     bool AcceptFocusByRectOfLastFocus(const Rect& rect) override;
384 
385     virtual bool RequestNextFocus(bool vertical, bool reverse, const Rect& rect) = 0;
386 
387     std::list<RefPtr<FocusNode>> focusNodes_;
388     std::list<RefPtr<FocusNode>>::iterator itLastFocusNode_ { focusNodes_.end() };
389 
390 private:
391     bool CalculatePosition();
392     bool isDefaultHasFocused_ { false };
393     bool isGroupDefaultFocused_ { false };
394     bool isFirstFocusInPage_ { true };
395 };
396 
397 } // namespace OHOS::Ace
398 
399 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_FOCUS_FOCUS_NODE_H
400