• 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_COMPONENTS_NG_EVENT_FOCUS_HUB_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_FOCUS_HUB_H
18 
19 #include "focus_event_handler.h"
20 #include "core/components_ng/base/geometry_node.h"
21 #include "core/components_ng/event/focus_box.h"
22 #include "core/components_ng/event/touch_event.h"
23 #include "core/event/key_event.h"
24 #include "core/gestures/gesture_event.h"
25 
26 namespace OHOS::Ace::NG {
27 
28 class FocusView;
29 class FocusManager;
30 
31 using TabIndexNodeList = std::list<std::pair<int32_t, WeakPtr<FocusHub>>>;
32 using OnGetNextFocusNodeFunc = std::function<RefPtr<FocusHub>(FocusReason, FocusIntension)>;
33 constexpr int32_t DEFAULT_TAB_FOCUSED_INDEX = -2;
34 constexpr int32_t NONE_TAB_FOCUSED_INDEX = -1;
35 constexpr int32_t MASK_FOCUS_STEP_VERTICAL = 0x01;
36 constexpr int32_t MASK_FOCUS_STEP_FORWARD = 0x10;
37 constexpr int32_t MASK_FOCUS_STEP_TAB = 0x5;
38 
39 enum class FocusNodeType : int32_t {
40     DEFAULT = 0,
41     GROUP_DEFAULT = 1,
42 };
43 enum class ScopeType : int32_t {
44     OTHERS = 0,
45     FLEX = 1,
46     PROJECT_AREA = 2,
47 };
48 enum class FocusStep : int32_t {
49     NONE = 0x0,
50     LEFT = 0x1,
51     UP = 0x2,
52     RIGHT = 0x11,
53     DOWN = 0x12,
54     LEFT_END = 0x3,
55     UP_END = 0x4,
56     RIGHT_END = 0X13,
57     DOWN_END = 0x14,
58     SHIFT_TAB = 0x5,
59     TAB = 0x15,
60 };
61 enum class RequestFocusResult : int32_t {
62     DEFAULT = 0,
63     NON_FOCUSABLE = 1,
64     NON_FOCUSABLE_ANCESTOR = 2,
65     NON_EXIST = 3,
66     NON_FOCUSABLE_BY_TAB = 4,
67 };
68 enum class SwitchingStartReason : int32_t {
69     DEFAULT = 0,
70     WINDOW_FOCUS = 1,
71     REQUEST_FOCUS = 2,
72     LOST_FOCUS_TO_VIEW_ROOT = 3,
73     REMOVE_SELF = 4,
74     REMOVE_CHILD = 5,
75     LOST_FOCUS_TO_TABSTOP = 6,
76 };
77 enum class SwitchingEndReason : int32_t {
78     DEFAULT = 0,
79     FOCUS_GUARD_DESTROY = 1,
80     DEPENDENCE_SELF = 2,
81     NO_FOCUSABLE_CHILD = 3,
82     NODE_FOCUS = 4,
83     TAB_STOP = 5,
84 };
85 enum class SwitchingUpdateReason : int32_t {
86     DEFAULT = 0,
87     SWITCH_FOCUS = 1,
88     ON_FOCUS_NODE = 2,
89 };
90 
91 using GetNextFocusNodeFunc = std::function<bool(FocusStep, const WeakPtr<FocusHub>&, WeakPtr<FocusHub>&)>;
92 
93 enum class FocusStyleType : int32_t {
94     NONE = -1,
95     INNER_BORDER = 0,
96     OUTER_BORDER = 1,
97     CUSTOM_BORDER = 2,
98     CUSTOM_REGION = 3,
99     FORCE_BORDER = 4,
100     FORCE_NONE = 5,
101 };
102 
103 enum class FocusDependence : int32_t {
104     CHILD = 0,
105     SELF = 1,
106     AUTO = 2,
107 };
108 
109 enum class FocusPriority : int32_t {
110     AUTO = 0,
111     PRIOR = 2000,
112     PREVIOUS = 3000,
113 };
114 
115 class ACE_EXPORT FocusPaintParam : public virtual AceType {
116     DECLARE_ACE_TYPE(FocusPaintParam, AceType)
117 
118 public:
119     FocusPaintParam() = default;
120     ~FocusPaintParam() override = default;
121 
HasPaintRect()122     bool HasPaintRect() const
123     {
124         return paintRect.has_value();
125     }
GetPaintRect()126     const RoundRect& GetPaintRect() const
127     {
128         return paintRect.value();
129     }
130 
HasPaintColor()131     bool HasPaintColor() const
132     {
133         return paintColor.has_value();
134     }
GetPaintColor()135     const Color& GetPaintColor() const
136     {
137         return paintColor.value();
138     }
139 
HasPaintWidth()140     bool HasPaintWidth() const
141     {
142         return paintWidth.has_value();
143     }
GetPaintWidth()144     const Dimension& GetPaintWidth() const
145     {
146         return paintWidth.value();
147     }
148 
HasFocusPadding()149     bool HasFocusPadding() const
150     {
151         return focusPadding.has_value();
152     }
GetFocusPadding()153     const Dimension& GetFocusPadding() const
154     {
155         return focusPadding.value();
156     }
SetPaintRect(const RoundRect & rect)157     void SetPaintRect(const RoundRect& rect)
158     {
159         paintRect = rect;
160     }
SetPaintColor(const Color & color)161     void SetPaintColor(const Color& color)
162     {
163         paintColor = color;
164     }
SetPaintWidth(const Dimension & width)165     void SetPaintWidth(const Dimension& width)
166     {
167         paintWidth = width;
168     }
SetFocusPadding(const Dimension & padding)169     void SetFocusPadding(const Dimension& padding)
170     {
171         focusPadding = padding;
172     }
173 
174 private:
175     std::optional<RoundRect> paintRect;
176     std::optional<Color> paintColor;
177     std::optional<Dimension> paintWidth;
178     std::optional<Dimension> focusPadding;
179 };
180 
181 class ACE_EXPORT FocusPattern : public virtual AceType {
182     DECLARE_ACE_TYPE(FocusPattern, AceType)
183 
184 public:
185     FocusPattern() = default;
FocusPattern(FocusType focusType,bool focusable)186     FocusPattern(FocusType focusType, bool focusable) : focusType_(focusType), focusable_(focusable) {}
FocusPattern(FocusType focusType,bool focusable,FocusStyleType styleType)187     FocusPattern(FocusType focusType, bool focusable, FocusStyleType styleType)
188         : focusType_(focusType), focusable_(focusable), styleType_(styleType)
189     {}
FocusPattern(FocusType focusType,bool focusable,FocusStyleType styleType,const FocusPaintParam & paintParams)190     FocusPattern(FocusType focusType, bool focusable, FocusStyleType styleType, const FocusPaintParam& paintParams)
191         : focusType_(focusType), focusable_(focusable), styleType_(styleType)
192     {
193         if (!paintParams_) {
194             paintParams_ = std::make_unique<FocusPaintParam>();
195         }
196         if (paintParams.HasPaintRect()) {
197             paintParams_->SetPaintRect(paintParams.GetPaintRect());
198         }
199         if (paintParams.HasPaintColor()) {
200             paintParams_->SetPaintColor(paintParams.GetPaintColor());
201         }
202         if (paintParams.HasPaintWidth()) {
203             paintParams_->SetPaintWidth(paintParams.GetPaintWidth());
204         }
205         if (paintParams.HasFocusPadding()) {
206             paintParams_->SetFocusPadding(paintParams.GetFocusPadding());
207         }
208     }
FocusPattern(const FocusPattern & focusPattern)209     FocusPattern(const FocusPattern& focusPattern)
210     {
211         focusType_ = focusPattern.GetFocusType();
212         focusable_ = focusPattern.GetFocusable();
213         styleType_ = focusPattern.GetStyleType();
214         if (focusPattern.GetFocusPaintParams()) {
215             SetFocusPaintParams(*focusPattern.GetFocusPaintParams());
216         }
217         isFocusActiveWhenFocused_ = focusPattern.GetIsFocusActiveWhenFocused();
218     }
219     ~FocusPattern() override = default;
220 
GetFocusType()221     FocusType GetFocusType() const
222     {
223         return focusType_;
224     }
SetFocusType(FocusType type)225     void SetFocusType(FocusType type)
226     {
227         focusType_ = type;
228     }
229 
GetFocusable()230     bool GetFocusable() const
231     {
232         return focusable_;
233     }
SetFocusable(bool focusable)234     void SetFocusable(bool focusable)
235     {
236         focusable_ = focusable;
237     }
238 
GetStyleType()239     FocusStyleType GetStyleType() const
240     {
241         return styleType_;
242     }
SetStyleType(FocusStyleType styleType)243     void SetStyleType(FocusStyleType styleType)
244     {
245         styleType_ = styleType;
246     }
247 
GetFocusPaintParams()248     const std::unique_ptr<FocusPaintParam>& GetFocusPaintParams() const
249     {
250         return paintParams_;
251     }
SetFocusPaintParams(const FocusPaintParam & paintParams)252     void SetFocusPaintParams(const FocusPaintParam& paintParams)
253     {
254         if (!paintParams_) {
255             paintParams_ = std::make_unique<FocusPaintParam>();
256         }
257         if (paintParams.HasPaintRect()) {
258             paintParams_->SetPaintRect(paintParams.GetPaintRect());
259         }
260         if (paintParams.HasPaintColor()) {
261             paintParams_->SetPaintColor(paintParams.GetPaintColor());
262         }
263         if (paintParams.HasPaintWidth()) {
264             paintParams_->SetPaintWidth(paintParams.GetPaintWidth());
265         }
266         if (paintParams.HasFocusPadding()) {
267             paintParams_->SetFocusPadding(paintParams.GetFocusPadding());
268         }
269     }
270 
GetIsFocusActiveWhenFocused()271     bool GetIsFocusActiveWhenFocused() const
272     {
273         return isFocusActiveWhenFocused_;
274     }
SetIsFocusActiveWhenFocused(bool value)275     void SetIsFocusActiveWhenFocused(bool value)
276     {
277         isFocusActiveWhenFocused_ = value;
278     }
279 
280 private:
281     FocusType focusType_ = FocusType::DISABLE;
282     bool focusable_ = false;
283     FocusStyleType styleType_ = FocusStyleType::NONE;
284     std::unique_ptr<FocusPaintParam> paintParams_ = nullptr;
285     bool isFocusActiveWhenFocused_ = false;
286 };
287 
288 enum class ScopeFocusDirection {
289     VERTICAL = 0,
290     HORIZONTAL,
291     UNIVERSAL,
292 };
293 
294 struct ScopeFocusAlgorithm final {
295     ScopeFocusAlgorithm() = default;
ScopeFocusAlgorithmfinal296     ScopeFocusAlgorithm(bool isVertical, bool isLeftToRight, ScopeType scopeType)
297         : isVertical(isVertical), isLeftToRight(isLeftToRight), scopeType(scopeType)
298     {}
ScopeFocusAlgorithmfinal299     ScopeFocusAlgorithm(bool isVertical, bool isLeftToRight, ScopeType scopeType, GetNextFocusNodeFunc&& function)
300         : isVertical(isVertical), isLeftToRight(isLeftToRight), scopeType(scopeType),
301           getNextFocusNode(std::move(function))
302     {}
ScopeFocusAlgorithmfinal303     ScopeFocusAlgorithm(ScopeFocusDirection direction, bool isVertical, bool isLeftToRight, ScopeType scopeType)
304         : direction(direction), isVertical(isVertical), isLeftToRight(isLeftToRight), scopeType(scopeType)
305     {}
ScopeFocusAlgorithmfinal306     ScopeFocusAlgorithm(ScopeFocusDirection direction, bool isVertical, bool isLeftToRight, ScopeType scopeType,
307         GetNextFocusNodeFunc&& function)
308         : direction(direction), isVertical(isVertical), isLeftToRight(isLeftToRight), scopeType(scopeType),
309           getNextFocusNode(std::move(function))
310     {}
311     ~ScopeFocusAlgorithm() = default;
312 
313     // isVertical will be deleted
314     ScopeFocusDirection direction { ScopeFocusDirection::VERTICAL };
315     bool isVertical { true };
316     bool isLeftToRight { true };
317     ScopeType scopeType { ScopeType::OTHERS };
318     GetNextFocusNodeFunc getNextFocusNode;
319 };
320 
321 class ACE_EXPORT FocusHub : public virtual FocusEventHandler, public virtual FocusState {
DECLARE_ACE_TYPE(FocusHub,FocusEventHandler,FocusState)322     DECLARE_ACE_TYPE(FocusHub, FocusEventHandler, FocusState)
323 public:
324     explicit FocusHub(const WeakPtr<EventHub>& eventHub, FocusType type = FocusType::DISABLE, bool focusable = false)
325         : FocusState(eventHub, type), FocusEventHandler(), focusable_(focusable)
326     {}
FocusHub(const WeakPtr<EventHub> & eventHub,const FocusPattern & focusPattern)327     explicit FocusHub(const WeakPtr<EventHub>& eventHub, const FocusPattern& focusPattern)
328         : FocusState(eventHub), FocusEventHandler()
329     {
330         focusable_ = focusPattern.GetFocusable();
331         focusType_ = focusPattern.GetFocusType();
332         focusStyleType_ = focusPattern.GetStyleType();
333         if (focusPattern.GetFocusPaintParams()) {
334             SetFocusPaintParamsPtr(focusPattern.GetFocusPaintParams());
335         }
336         isFocusActiveWhenFocused_ = focusPattern.GetIsFocusActiveWhenFocused();
337     }
338     ~FocusHub() override = default;
339 
340     static constexpr int32_t SCROLL_TO_HEAD = -1;
341     static constexpr int32_t SCROLL_TO_TAIL = -2;
342 
SetFocusStyleType(FocusStyleType type)343     void SetFocusStyleType(FocusStyleType type)
344     {
345         focusStyleType_ = type;
346     }
GetFocusStyleType()347     FocusStyleType GetFocusStyleType() const
348     {
349         return focusStyleType_;
350     }
351 
GetBlurReason()352     BlurReason GetBlurReason() const
353     {
354         return blurReason_;
355     }
356 
SetFocusPaintParamsPtr(const std::unique_ptr<FocusPaintParam> & paramsPtr)357     void SetFocusPaintParamsPtr(const std::unique_ptr<FocusPaintParam>& paramsPtr)
358     {
359         CHECK_NULL_VOID(paramsPtr);
360         if (!focusPaintParamsPtr_) {
361             focusPaintParamsPtr_ = std::make_unique<FocusPaintParam>();
362         }
363         if (paramsPtr->HasPaintRect()) {
364             focusPaintParamsPtr_->SetPaintRect(paramsPtr->GetPaintRect());
365         }
366         if (paramsPtr->HasPaintColor()) {
367             focusPaintParamsPtr_->SetPaintColor(paramsPtr->GetPaintColor());
368         }
369         if (paramsPtr->HasPaintWidth()) {
370             focusPaintParamsPtr_->SetPaintWidth(paramsPtr->GetPaintWidth());
371         }
372         if (paramsPtr->HasFocusPadding()) {
373             focusPaintParamsPtr_->SetFocusPadding(paramsPtr->GetFocusPadding());
374         }
375     }
376 
HasPaintRect()377     bool HasPaintRect() const
378     {
379         return focusPaintParamsPtr_ ? focusPaintParamsPtr_->HasPaintRect() : false;
380     }
GetPaintRect()381     RoundRect GetPaintRect() const
382     {
383         CHECK_NULL_RETURN(focusPaintParamsPtr_, RoundRect());
384         return focusPaintParamsPtr_->GetPaintRect();
385     }
386 
HasPaintColor()387     bool HasPaintColor() const
388     {
389         return focusPaintParamsPtr_ ? focusPaintParamsPtr_->HasPaintColor() : false;
390     }
GetPaintColor()391     const Color& GetPaintColor() const
392     {
393         CHECK_NULL_RETURN(focusPaintParamsPtr_, Color::TRANSPARENT);
394         return focusPaintParamsPtr_->GetPaintColor();
395     }
396 
HasPaintWidth()397     bool HasPaintWidth() const
398     {
399         return focusPaintParamsPtr_ ? focusPaintParamsPtr_->HasPaintWidth() : false;
400     }
GetPaintWidth()401     Dimension GetPaintWidth() const
402     {
403         CHECK_NULL_RETURN(focusPaintParamsPtr_, Dimension());
404         return focusPaintParamsPtr_->GetPaintWidth();
405     }
406 
HasFocusPadding()407     bool HasFocusPadding() const
408     {
409         return focusPaintParamsPtr_ ? focusPaintParamsPtr_->HasFocusPadding() : false;
410     }
411 
HasBackwardFocusMovement()412     bool HasBackwardFocusMovement() const
413     {
414         return hasBackwardMovement_;
415     }
416 
HasForwardFocusMovement()417     bool HasForwardFocusMovement() const
418     {
419         return hasForwardMovement_;
420     }
421 
ClearFocusMovementFlags()422     void ClearFocusMovementFlags()
423     {
424         hasBackwardMovement_ = false;
425         hasForwardMovement_ = false;
426     }
427 
428     bool HasBackwardFocusMovementInChildren();
429     bool HasForwardFocusMovementInChildren();
430     void ClearFocusMovementFlagsInChildren();
431 
GetFocusPadding()432     Dimension GetFocusPadding() const
433     {
434         CHECK_NULL_RETURN(focusPaintParamsPtr_, Dimension());
435         return focusPaintParamsPtr_->GetFocusPadding();
436     }
SetPaintRect(const RoundRect & rect)437     void SetPaintRect(const RoundRect& rect)
438     {
439         if (!focusPaintParamsPtr_) {
440             focusPaintParamsPtr_ = std::make_unique<FocusPaintParam>();
441         }
442         CHECK_NULL_VOID(focusPaintParamsPtr_);
443         focusPaintParamsPtr_->SetPaintRect(rect);
444     }
SetPaintColor(const Color & color)445     void SetPaintColor(const Color& color)
446     {
447         if (!focusPaintParamsPtr_) {
448             focusPaintParamsPtr_ = std::make_unique<FocusPaintParam>();
449         }
450         CHECK_NULL_VOID(focusPaintParamsPtr_);
451         focusPaintParamsPtr_->SetPaintColor(color);
452     }
SetPaintWidth(const Dimension & width)453     void SetPaintWidth(const Dimension& width)
454     {
455         if (!focusPaintParamsPtr_) {
456             focusPaintParamsPtr_ = std::make_unique<FocusPaintParam>();
457         }
458         CHECK_NULL_VOID(focusPaintParamsPtr_);
459         focusPaintParamsPtr_->SetPaintWidth(width);
460     }
SetFocusPadding(const Dimension & padding)461     void SetFocusPadding(const Dimension& padding)
462     {
463         if (!focusPaintParamsPtr_) {
464             focusPaintParamsPtr_ = std::make_unique<FocusPaintParam>();
465         }
466         CHECK_NULL_VOID(focusPaintParamsPtr_);
467         focusPaintParamsPtr_->SetFocusPadding(padding);
468     }
469 
470     RefPtr<FocusManager> GetFocusManager() const;
471     RefPtr<FocusHub> GetParentFocusHub() const;
472     RefPtr<FocusHub> GetRootFocusHub();
473     RefPtr<FocusHub> GetFocusLeaf();
474 
475     bool HandleEvent(const NonPointerEvent& event);
476     bool HandleFocusTravel(const FocusEvent& event) override;
477     bool HandleFocusNavigation(const FocusEvent& event);
478     bool RequestFocusImmediately(FocusReason reason = FocusReason::DEFAULT);
479     void RequestFocus() const;
480     void SwitchFocus(const RefPtr<FocusHub>& focusNode, FocusReason focusReason = FocusReason::DEFAULT);
481 
482     static void LostFocusToViewRoot();
483     void LostFocusToTabStop(const RefPtr<FocusHub>& focusNode);
484 
485     bool IsViewRootScope();
486     void LostFocus(BlurReason reason = BlurReason::FOCUS_SWITCH);
487     void LostSelfFocus();
488     void RemoveSelf(BlurReason reason = BlurReason::FRAME_DESTROY);
489     void RemoveChild(const RefPtr<FocusHub>& focusNode, BlurReason reason = BlurReason::FRAME_DESTROY);
490     bool GoToNextFocusLinear(FocusStep step, const RectF& rect = RectF());
491     bool TryRequestFocus(const RefPtr<FocusHub>& focusNode, const RectF& rect, FocusStep step = FocusStep::NONE);
InheritFocus()492     void InheritFocus()
493     {
494         OnFocusScope(true);
495     }
496 
497     void CollectTabIndexNodes(TabIndexNodeList& tabIndexNodes);
498     bool GoToFocusByTabNodeIdx(TabIndexNodeList& tabIndexNodes, int32_t tabNodeIdx);
499     bool HandleFocusByTabIndex(const KeyEvent& event);
500     RefPtr<FocusHub> GetChildFocusNodeByType(FocusNodeType nodeType = FocusNodeType::DEFAULT);
501     RefPtr<FocusHub> GetChildFocusNodeById(const std::string& id);
502     bool TriggerFocusScroll();
503     int32_t GetFocusingTabNodeIdx(TabIndexNodeList& tabIndexNodes) const;
504     bool RequestFocusImmediatelyById(const std::string& id, bool isSyncRequest = false);
505     RefPtr<FocusView> GetFirstChildFocusView();
506 
507     bool IsFocusableByTab();
508     bool IsFocusableNodeByTab();
509     bool IsFocusableScopeByTab();
510 
511     bool IsFocusableWholePath();
512     bool IsSelfFocusableWholePath();
513     bool IsOnRootTree() const;
514 
515     bool IsFocusable();
516     bool IsFocusableNode();
517     bool IsFocusableScope();
518 
519     bool IsSyncRequestFocusable();
520     bool IsSyncRequestFocusableNode();
521     bool IsSyncRequestFocusableScope();
522 
IsParentFocusable()523     bool IsParentFocusable() const
524     {
525         return parentFocusable_;
526     }
527     void SetParentFocusable(bool parentFocusable);
528 
529     void SetFocusable(bool focusable, bool isExplicit = true);
530 
GetFocusable()531     bool GetFocusable() const
532     {
533         return focusable_;
534     }
535 
536     void SetShow(bool show);
537     void SetEnabled(bool enabled);
538 
539     bool IsShow() const;
540 
541     bool IsEnabled() const;
542 
543     bool IsCurrentFocusWholePath();
544 
545     bool HasFocusedChild();
546 
SetOnFocusInternal(OnFocusFunc && onFocusInternal)547     void SetOnFocusInternal(OnFocusFunc&& onFocusInternal)
548     {
549         onFocusInternal_ = std::move(onFocusInternal);
550     }
SetOnBlurInternal(OnBlurFunc && onBlurInternal)551     void SetOnBlurInternal(OnBlurFunc&& onBlurInternal)
552     {
553         onBlurInternal_ = std::move(onBlurInternal);
554     }
SetOnBlurReasonInternal(OnBlurReasonFunc && onBlurReasonInternal)555     void SetOnBlurReasonInternal(OnBlurReasonFunc&& onBlurReasonInternal)
556     {
557         onBlurReasonInternal_ = std::move(onBlurReasonInternal);
558     }
SetOnPreFocusCallback(OnPreFocusFunc && onPreFocusCallback)559     void SetOnPreFocusCallback(OnPreFocusFunc&& onPreFocusCallback)
560     {
561         onPreFocusCallback_ = std::move(onPreFocusCallback);
562     }
563 
SetOnGetNextFocusNodeFunc(OnGetNextFocusNodeFunc && onGetNextFocusNodeFunc)564     void SetOnGetNextFocusNodeFunc(OnGetNextFocusNodeFunc&& onGetNextFocusNodeFunc)
565     {
566         onGetNextFocusNodeFunc_ = std::move(onGetNextFocusNodeFunc);
567     }
568 
IsAllowedLoop()569     bool IsAllowedLoop()
570     {
571         return allowedLoop_;
572     }
SetAllowedLoop(bool allowedLoop)573     void SetAllowedLoop(bool allowedLoop)
574     {
575         allowedLoop_ = allowedLoop;
576     }
577 
SetOnClearFocusStateInternal(OnClearFocusStateFunc && onClearFocusCallback)578     void SetOnClearFocusStateInternal(OnClearFocusStateFunc&& onClearFocusCallback)
579     {
580         onClearFocusStateCallback_ = std::move(onClearFocusCallback);
581     }
582 
SetOnPaintFocusStateInternal(OnPaintFocusStateFunc && onPaintFocusCallback)583     void SetOnPaintFocusStateInternal(OnPaintFocusStateFunc&& onPaintFocusCallback)
584     {
585         onPaintFocusStateCallback_ = std::move(onPaintFocusCallback);
586     }
587 
588     std::list<RefPtr<FocusHub>>::iterator FlushChildrenFocusHub(std::list<RefPtr<FocusHub>>& focusNodes);
589     /* Manipulation on node-tree is forbidden in operation. */
590     template<bool isReverse = false>
591     bool AnyChildFocusHub(const std::function<bool(const RefPtr<FocusHub>&)>& operation);
592     bool AnyChildFocusHub(bool isReverse, const std::function<bool(const RefPtr<FocusHub>&)>& operation);
593     template<bool isReverse = false>
594     void AllChildFocusHub(const std::function<void(const RefPtr<FocusHub>&)>& operation);
595 
IsChild()596     bool IsChild() const
597     {
598         return focusType_ == FocusType::NODE;
599     }
600 
SetRect(const RectF & rect)601     void SetRect(const RectF& rect)
602     {
603         rectFromOrigin_ = rect;
604     }
GetRect()605     const RectF& GetRect() const
606     {
607         return rectFromOrigin_;
608     }
609 
610     void DumpFocusTree(int32_t depth);
611     void DumpFocusNodeTree(int32_t depth);
612     void DumpFocusScopeTree(int32_t depth);
613     void DumpFocusUie();
614     void DumpFocusUieInJson(std::unique_ptr<JsonValue>& json);
615 
SetFocusType(FocusType type)616     void SetFocusType(FocusType type)
617     {
618         if (focusType_ != type && type == FocusType::DISABLE) {
619             RemoveSelf(BlurReason::FOCUS_SWITCH);
620         }
621         focusType_ = type;
622 
623         if (IsImplicitFocusableScope() && focusDepend_ == FocusDependence::CHILD) {
624             focusDepend_ = FocusDependence::AUTO;
625         }
626     }
GetFocusType()627     FocusType GetFocusType() const
628     {
629         return focusType_;
630     }
631 
GetTabIndex()632     int32_t GetTabIndex() const
633     {
634         return focusCallbackEvents_ ? focusCallbackEvents_->tabIndex_ : 0;
635     }
SetTabIndex(int32_t tabIndex)636     void SetTabIndex(int32_t tabIndex)
637     {
638         if (!focusCallbackEvents_) {
639             focusCallbackEvents_ = MakeRefPtr<FocusCallbackEvents>();
640         }
641         focusCallbackEvents_->tabIndex_ = tabIndex;
642     }
643 
IsDefaultFocus()644     bool IsDefaultFocus() const
645     {
646         return focusCallbackEvents_ ? focusCallbackEvents_->isDefaultFocus_ : false;
647     }
648 
SetIsDefaultFocus(bool isDefaultFocus)649     void SetIsDefaultFocus(bool isDefaultFocus)
650     {
651         if (!focusCallbackEvents_) {
652             focusCallbackEvents_ = MakeRefPtr<FocusCallbackEvents>();
653         }
654         focusCallbackEvents_->isDefaultFocus_ = isDefaultFocus;
655     }
656 
IsDefaultGroupFocus()657     bool IsDefaultGroupFocus() const
658     {
659         return focusCallbackEvents_ ? focusCallbackEvents_->isDefaultGroupFocus_ : false;
660     }
661 
SetIsDefaultGroupFocus(bool isDefaultGroupFocus)662     void SetIsDefaultGroupFocus(bool isDefaultGroupFocus)
663     {
664         if (!focusCallbackEvents_) {
665             focusCallbackEvents_ = MakeRefPtr<FocusCallbackEvents>();
666         }
667         focusCallbackEvents_->isDefaultGroupFocus_ = isDefaultGroupFocus;
668     }
669 
GetDefaultFocusNode()670     WeakPtr<FocusHub> GetDefaultFocusNode() const
671     {
672         return focusCallbackEvents_ ? focusCallbackEvents_->defaultFocusNode_ : nullptr;
673     }
674 
SetDefaultFocusNode(const WeakPtr<FocusHub> & node)675     void SetDefaultFocusNode(const WeakPtr<FocusHub>& node)
676     {
677         if (!focusCallbackEvents_) {
678             focusCallbackEvents_ = MakeRefPtr<FocusCallbackEvents>();
679         }
680         focusCallbackEvents_->defaultFocusNode_ = node;
681     }
682 
IsFocusOnTouch()683     std::optional<bool> IsFocusOnTouch() const
684     {
685         return focusCallbackEvents_ ? focusCallbackEvents_->isFocusOnTouch_ : std::nullopt;
686     }
687 
688     void SetIsFocusOnTouch(bool isFocusOnTouch);
689 
SetIsDefaultHasFocused(bool isDefaultHasFocused)690     void SetIsDefaultHasFocused(bool isDefaultHasFocused)
691     {
692         if (!focusCallbackEvents_) {
693             focusCallbackEvents_ = MakeRefPtr<FocusCallbackEvents>();
694         }
695         focusCallbackEvents_->isDefaultHasFocused_ = isDefaultHasFocused;
696     }
697 
IsDefaultHasFocused()698     bool IsDefaultHasFocused() const
699     {
700         return focusCallbackEvents_ ? focusCallbackEvents_->isDefaultHasFocused_ : false;
701     }
702 
SetIsDefaultGroupHasFocused(bool isDefaultGroupHasFocused)703     void SetIsDefaultGroupHasFocused(bool isDefaultGroupHasFocused)
704     {
705         if (!focusCallbackEvents_) {
706             focusCallbackEvents_ = MakeRefPtr<FocusCallbackEvents>();
707         }
708         focusCallbackEvents_->isDefaultGroupHasFocused_ = isDefaultGroupHasFocused;
709     }
710 
IsDefaultGroupHasFocused()711     bool IsDefaultGroupHasFocused() const
712     {
713         return focusCallbackEvents_ ? focusCallbackEvents_->isDefaultGroupHasFocused_ : false;
714     }
715 
IsImplicitFocusableScope()716     bool IsImplicitFocusableScope() const
717     {
718         return (focusType_ == FocusType::SCOPE) && focusable_ && implicitFocusable_;
719     }
720 
721     std::optional<std::string> GetInspectorKey() const;
722 
723     bool PaintFocusState(bool isNeedStateStyles = true);
724     bool PaintAllFocusState();
725     bool PaintInnerFocusState(const RoundRect& paintRect, bool forceUpdate = false);
726     void ClearFocusState(bool isNeedStateStyles = true);
727     void ClearAllFocusState();
728 
SetInnerFocusPaintRectCallback(const std::function<void (RoundRect &)> & callback)729     void SetInnerFocusPaintRectCallback(const std::function<void(RoundRect&)>& callback)
730     {
731         getInnerFocusRectFunc_ = callback;
732     }
733 
SetIsFocusUnit(bool isFocusUnit)734     void SetIsFocusUnit(bool isFocusUnit)
735     {
736         isFocusUnit_ = isFocusUnit;
737     }
738 
GetFocusDependence()739     FocusDependence GetFocusDependence() const
740     {
741         return focusDepend_;
742     }
SetFocusDependence(FocusDependence focusDepend)743     void SetFocusDependence(FocusDependence focusDepend)
744     {
745         focusDepend_ = focusDepend;
746     }
747 
GetFocusableCount()748     size_t GetFocusableCount()
749     {
750         size_t count = 0;
751         AllChildFocusHub([&count](const RefPtr<FocusHub>& child) {
752             if (child->IsFocusable()) {
753                 count++;
754             }
755         });
756         return count;
757     }
758 
SetIsFocusActiveWhenFocused(bool value)759     void SetIsFocusActiveWhenFocused(bool value)
760     {
761         isFocusActiveWhenFocused_ = value;
762     }
GetIsFocusActiveWhenFocused()763     bool GetIsFocusActiveWhenFocused() const
764     {
765         return isFocusActiveWhenFocused_;
766     }
767 
IsFocusStepVertical(FocusStep step)768     static inline bool IsFocusStepVertical(FocusStep step)
769     {
770         return (static_cast<uint32_t>(step) & MASK_FOCUS_STEP_VERTICAL) == 0;
771     }
772 
773     static inline bool IsFocusStepForward(FocusStep step, bool isRtl = false)
774     {
775         bool isForward = (static_cast<uint32_t>(step) & MASK_FOCUS_STEP_FORWARD) != 0;
776         if (isRtl && (step == FocusStep::RIGHT || step == FocusStep::LEFT)) {
777             isForward = !isForward;
778         }
779         return isForward;
780     }
781 
IsFocusStepTab(FocusStep step)782     static inline bool IsFocusStepTab(FocusStep step)
783     {
784         return (static_cast<uint32_t>(step) & MASK_FOCUS_STEP_TAB) == MASK_FOCUS_STEP_TAB;
785     }
786 
787     static inline FocusStep GetRealFocusStepByTab(FocusStep moveStep, bool isRtl = false)
788     {
789         if (isRtl) {
790             return moveStep == FocusStep::TAB ? FocusStep::LEFT : FocusStep::RIGHT;
791         } else {
792             return moveStep == FocusStep::TAB ? FocusStep::RIGHT : FocusStep::LEFT;
793         }
794     }
795 
796     static double GetProjectAreaOnRect(const RectF& rect, const RectF& projectRect, FocusStep step);
797 
798     void SetFocusScopeId(const std::string& focusScopeId, bool isGroup, bool arrowKeyStepOut = true);
799     void SetFocusScopePriority(const std::string& focusScopeId, const uint32_t focusPriority);
800     void RemoveFocusScopeIdAndPriority();
801     bool AcceptFocusOfPriorityChild();
802     bool SetLastWeakFocusNodeToPreviousNode();
803     void SetLastWeakFocusToPreviousInFocusView();
GetIsFocusGroup()804     bool GetIsFocusGroup() const
805     {
806         return isGroup_;
807     }
808 
GetIsFocusScope()809     bool GetIsFocusScope() const
810     {
811         return isFocusScope_;
812     }
813 
GetFocusScopeId()814     std::string GetFocusScopeId() const
815     {
816         return focusScopeId_;
817     }
818 
GetFocusBox()819     FocusBox& GetFocusBox()
820     {
821         return box_;
822     }
823 
GetFocusPriority()824     FocusPriority GetFocusPriority() const
825     {
826         return focusPriority_;
827     }
828 
829     static void ToJsonValue(
830         const RefPtr<FocusHub>& hub, std::unique_ptr<JsonValue>& json, const InspectorFilter& filter);
831 
832     bool FocusToHeadOrTailChild(bool isHead);
833 
834     WeakPtr<FocusHub> GetUnfocusableParentFocusNode();
835 
GetOnGetNextFocusNodeFunc()836     OnGetNextFocusNodeFunc GetOnGetNextFocusNodeFunc()
837     {
838         return onGetNextFocusNodeFunc_;
839     }
840 
841 protected:
842     bool RequestNextFocusOfKeyTab(const FocusEvent& event);
843     bool RequestNextFocusOfKeyEnter();
844     bool RequestNextFocusOfKeyEsc();
845 
846     bool AcceptFocusOfSpecifyChild(FocusStep step);
847     bool AcceptFocusOfLastFocus();
848     bool AcceptFocusByRectOfLastFocus(const RectF& rect);
849     bool AcceptFocusByRectOfLastFocusNode(const RectF& rect);
850     bool AcceptFocusByRectOfLastFocusFlex(const RectF& rect);
851 
852     bool CalculateRect(const RefPtr<FocusHub>& childNode, RectF& rect) const;
853     bool RequestNextFocus(FocusStep moveStep);
854 
855     void OnFocus();
856     void OnFocusNode();
857     void OnFocusScope(bool currentHasFocused = false);
858     void OnBlur();
859     void OnBlurNode();
860     void OnBlurScope();
861 
HandleFocus()862     void HandleFocus()
863     {
864         // Need update: void RenderNode::MoveWhenOutOfViewPort(bool hasEffect)
865         OnFocus();
866     }
867 
868 private:
869     friend class FocusView;
870     friend class FocusManager;
871 
872     bool CalculatePosition();
873 
874     bool IsLeafFocusScope();
875 
876     void ClearLastFocusNode();
877 
878     void SetScopeFocusAlgorithm();
879 
880     void SetLastFocusNodeIndex(const RefPtr<FocusHub>& focusNode);
881 
882     void ScrollToLastFocusIndex() const;
883 
884     void CheckFocusStateStyle(bool onFocus);
885     bool HasFocusStateStyle();
886 
887     bool IsNeedPaintFocusState();
888 
889     bool ScrollByOffset();
890     bool ScrollByOffsetToParent(const RefPtr<FrameNode>& parentFrameNode) const;
891 
892     RefPtr<FocusHub> GetNearestNodeByProjectArea(const std::list<RefPtr<FocusHub>>& allNodes, FocusStep step);
893 
894     bool UpdateFocusView();
895 
896     bool IsFocusAbleChildOf(const RefPtr<FocusHub>& parentFocusHub);
897     WeakPtr<FocusHub> GetChildPriorfocusNode(const std::string& focusScopeId);
898     bool RequestFocusByPriorityInScope();
899     bool IsInFocusGroup();
900     bool IsNestingFocusGroup();
901     void SetLastWeakFocusNodeWholeScope(const std::string& focusScopeId);
902 
903     void RaiseZIndex(); // Recover z-index in ClearFocusState
904 
905     bool RequestFocusImmediatelyInner(FocusReason reason = FocusReason::DEFAULT);
906     bool RequestNextFocusByKey(const FocusEvent& event);
907 
908     // donot move focus before detach if has focus view child
909     bool SkipFocusMoveBeforeRemove() const;
910 
911     bool IsArrowKeyStepOut(FocusStep moveStep);
912 
913     OnFocusFunc onFocusInternal_;
914     OnBlurFunc onBlurInternal_;
915     OnBlurReasonFunc onBlurReasonInternal_;
916     OnPreFocusFunc onPreFocusCallback_;
917     OnClearFocusStateFunc onClearFocusStateCallback_;
918     OnPaintFocusStateFunc onPaintFocusStateCallback_;
919     OnGetNextFocusNodeFunc onGetNextFocusNodeFunc_;
920 
921     RefPtr<TouchEventImpl> focusOnTouchListener_;
922 
923     int32_t lastFocusNodeIndex_ { -1 };
924     int32_t lastTabIndexNodeId_ { DEFAULT_TAB_FOCUSED_INDEX };
925 
926     bool focusable_ { true };
927     bool isFocusableExplicit_ { false };
928     bool implicitFocusable_ { false };
929     bool parentFocusable_ { true };
930     bool isFocusUnit_ { false };
931     bool hasForwardMovement_ { false };
932     bool hasBackwardMovement_ { false };
933     bool isFocusActiveWhenFocused_ { false };
934     bool isRaisedZIndex_ { false };
935     bool allowedLoop_ { true };
936 
937     FocusStyleType focusStyleType_ = FocusStyleType::NONE;
938     std::unique_ptr<FocusPaintParam> focusPaintParamsPtr_;
939     std::function<void(RoundRect&)> getInnerFocusRectFunc_;
940     FocusBox box_;
941 
942     RectF rectFromOrigin_;
943     ScopeFocusAlgorithm focusAlgorithm_;
944     BlurReason blurReason_ = BlurReason::FOCUS_SWITCH;
945     FocusReason focusReason_ = FocusReason::DEFAULT;
946     FocusDependence focusDepend_ = FocusDependence::CHILD;
947 
948     std::string focusScopeId_;
949     bool isFocusScope_ { false };
950     bool isGroup_ { false };
951     FocusPriority focusPriority_ = FocusPriority::AUTO;
952     bool arrowKeyStepOut_ { true };
953     bool isSwitchByEnter_ { false };
954     bool isCustomFocusTravel_ = false;
955     WeakPtr<FocusHub> nextFocusTravelNode_;
956 };
957 } // namespace OHOS::Ace::NG
958 
959 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_FOCUS_HUB_H
960