1 /* 2 * Copyright (c) 2024 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_MANAGER_FOCUS_FOCUS_MANAGER_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_FOCUS_FOCUS_MANAGER_H 18 19 #include <list> 20 #include <optional> 21 22 #include "base/error/error_code.h" 23 #include "base/memory/ace_type.h" 24 #include "base/memory/referenced.h" 25 #include "base/utils/listener.h" 26 #include "core/components_ng/manager/focus/focus_view.h" 27 28 namespace OHOS::Ace::NG { 29 30 class PipelineContext; 31 32 using FocusViewMap = std::unordered_map<int32_t, std::pair<WeakPtr<FocusView>, std::list<WeakPtr<FocusView>>>>; 33 using RequestFocusCallback = std::function<void(NG::RequestFocusResult result)>; 34 using FocusHubScopeMap = std::unordered_map<std::string, std::pair<WeakPtr<FocusHub>, std::list<WeakPtr<FocusHub>>>>; 35 using FocusChangeCallback = std::function<void(const WeakPtr<FocusHub>& last, 36 const RefPtr<FocusHub>& current, FocusReason focusReason)>; 37 using FocusActiveChangeCallback = std::function<void(bool isFocusActive)>; 38 39 enum class FocusActiveReason : int32_t { 40 POINTER_EVENT = 0, 41 KEYBOARD_EVENT = 1, 42 USE_API = 2, 43 }; 44 45 enum class FocusViewStackState : int32_t { 46 IDLE = 0, 47 SHOW = 1, 48 CLOSE = 2, 49 }; 50 51 enum class KeyProcessingMode : int32_t { 52 FOCUS_NAVIGATION = 0, 53 ANCESTOR_EVENT = 1, 54 }; 55 56 class FocusManager : public virtual AceType { 57 DECLARE_ACE_TYPE(FocusManager, AceType); 58 59 public: 60 class FocusGuard { 61 public: 62 explicit FocusGuard(const RefPtr<FocusHub>& focushub, SwitchingStartReason reason); 63 FocusGuard() = delete; 64 ~FocusGuard(); 65 void CreateFocusGuard(const RefPtr<FocusHub>& focushub, const RefPtr<FocusManager>& focusManager, 66 SwitchingStartReason reason); 67 private: 68 RefPtr<FocusManager> focusMng_; 69 }; 70 friend FocusGuard; 71 72 explicit FocusManager(const RefPtr<PipelineContext>& pipeline); 73 ~FocusManager() override = default; 74 75 void FocusViewShow(const RefPtr<FocusView>& focusView, bool isTriggerByStep = false); 76 void FocusViewHide(const RefPtr<FocusView>& focusView); 77 void FocusViewClose(const RefPtr<FocusView>& focusView, bool isDetachFromTree = false); 78 79 void FlushFocusView(); 80 81 void DumpFocusManager(); 82 GetLastFocusView()83 WeakPtr<FocusView> GetLastFocusView() const 84 { 85 return lastFocusView_; 86 } 87 GetWeakFocusViewList()88 const std::list<WeakPtr<FocusView>>& GetWeakFocusViewList() const 89 { 90 return focusViewStack_; 91 } 92 SetRequestFocusCallback(const RequestFocusCallback & callback)93 void SetRequestFocusCallback(const RequestFocusCallback& callback) 94 { 95 requestCallback_ = std::move(callback); 96 } 97 ResetRequestFocusCallback()98 void ResetRequestFocusCallback() 99 { 100 requestCallback_ = nullptr; 101 } 102 TriggerRequestFocusCallback(NG::RequestFocusResult result)103 void TriggerRequestFocusCallback(NG::RequestFocusResult result) 104 { 105 if (requestCallback_) { 106 requestCallback_(result); 107 requestCallback_ = nullptr; 108 } 109 } 110 SetRequestFocusResult(const int32_t requestFocusResult)111 void SetRequestFocusResult(const int32_t requestFocusResult) 112 { 113 requestFocusResult_ = requestFocusResult; 114 } 115 GetRequestFocusResult()116 int32_t GetRequestFocusResult() 117 { 118 return requestFocusResult_; 119 } 120 ResetRequestFocusResult()121 void ResetRequestFocusResult() 122 { 123 requestFocusResult_ = ERROR_CODE_NO_ERROR; 124 } 125 SetLastFocusStateNode(const RefPtr<FocusHub> & node)126 void SetLastFocusStateNode(const RefPtr<FocusHub>& node) 127 { 128 lastFocusStateNode_ = AceType::WeakClaim(AceType::RawPtr(node)); 129 if (isNeedTriggerScroll_.has_value()) { 130 isNeedTriggerScroll_ = true; 131 } 132 } GetLastFocusStateNode()133 RefPtr<FocusHub> GetLastFocusStateNode() const 134 { 135 return lastFocusStateNode_.Upgrade(); 136 } 137 SetNeedTriggerScroll(std::optional<bool> isNeedTriggerScroll)138 void SetNeedTriggerScroll(std::optional<bool> isNeedTriggerScroll) 139 { 140 isNeedTriggerScroll_ = isNeedTriggerScroll; 141 } 142 GetNeedTriggerScroll()143 bool GetNeedTriggerScroll() const 144 { 145 return isNeedTriggerScroll_.value_or(false); 146 } 147 SetIsAutoFocusTransfer(bool isAutoFocusTransfer)148 void SetIsAutoFocusTransfer(bool isAutoFocusTransfer) 149 { 150 isAutoFocusTransfer_ = isAutoFocusTransfer; 151 } 152 IsAutoFocusTransfer()153 bool IsAutoFocusTransfer() const 154 { 155 return isAutoFocusTransfer_; 156 } 157 158 bool RearrangeViewStack(); 159 SetFocusViewStackState(FocusViewStackState focusViewStackState)160 void SetFocusViewStackState(FocusViewStackState focusViewStackState) 161 { 162 focusViewStackState_ = focusViewStackState; 163 } 164 SetKeyProcessingMode(KeyProcessingMode keyProcessingMode)165 void SetKeyProcessingMode(KeyProcessingMode keyProcessingMode) 166 { 167 keyProcessingMode_ = keyProcessingMode; 168 } 169 GetKeyProcessingMode()170 KeyProcessingMode GetKeyProcessingMode() const 171 { 172 return keyProcessingMode_; 173 } 174 175 bool SetFocusViewRootScope(const RefPtr<FocusView>& focusView); 176 177 void PaintFocusState(); 178 179 bool AddFocusScope(const std::string& focusScopeId, const RefPtr<FocusHub>& scopeFocusHub); 180 void RemoveFocusScope(const std::string& focusScopeId); 181 void AddScopePriorityNode(const std::string& focusScopeId, const RefPtr<FocusHub>& priorFocusHub, bool pushFront); 182 void RemoveScopePriorityNode(const std::string& focusScopeId, const RefPtr<FocusHub>& priorFocusHub); 183 std::optional<std::list<WeakPtr<FocusHub>>*> GetFocusScopePriorityList(const std::string& focusScopeId); 184 185 void UpdateCurrentFocus(const RefPtr<FocusHub>& current, SwitchingUpdateReason reason); 186 RefPtr<FocusHub> GetCurrentFocus(); UpdateSwitchingEndReason(SwitchingEndReason reason)187 void UpdateSwitchingEndReason(SwitchingEndReason reason) 188 { 189 if (isSwitchingFocus_.value_or(false)) { 190 endReason_ = reason; 191 } 192 } 193 int32_t AddFocusListener(FocusChangeCallback&& callback); 194 void RemoveFocusListener(int32_t id); 195 int32_t AddFocusActiveChangeListener(const FocusActiveChangeCallback& callback); 196 void RemoveFocusActiveChangeListener(int32_t handler); 197 void TriggerFocusActiveChangeCallback(bool isFocusActive); 198 void FocusSwitchingStart(const RefPtr<FocusHub>& focusHub, SwitchingStartReason reason); 199 void FocusSwitchingEnd(SwitchingEndReason reason = SwitchingEndReason::FOCUS_GUARD_DESTROY); 200 void WindowFocusMoveStart(); 201 void WindowFocusMoveEnd(); 202 void WindowFocus(bool isFocus); GetCurrentFocusEvent()203 std::optional<FocusEvent> GetCurrentFocusEvent() 204 { 205 return currentFocusEvent_; 206 } 207 SetCurrentFocusEvent(const FocusEvent & event)208 void SetCurrentFocusEvent(const FocusEvent& event) 209 { 210 currentFocusEvent_.reset(); 211 currentFocusEvent_.emplace(event); 212 } 213 ResetCurrentFocusEvent()214 void ResetCurrentFocusEvent() 215 { 216 currentFocusEvent_.reset(); 217 } 218 219 static RefPtr<FocusManager> GetFocusManager(RefPtr<FrameNode>& node); 220 221 private: 222 void GetFocusViewMap(FocusViewMap& focusViewMap); 223 void ReportFocusSwitching(FocusReason focusReason); 224 225 std::list<WeakPtr<FocusView>> focusViewStack_; 226 WeakPtr<FocusView> lastFocusView_; 227 const WeakPtr<PipelineContext> pipeline_; 228 229 RequestFocusCallback requestCallback_; 230 231 WeakPtr<FocusHub> lastFocusStateNode_; 232 WeakPtr<FocusHub> currentFocus_; 233 /** 234 * In the case of a scrollable component's sliding state, this variable will be set to nullopt to prevent the 235 * ScrollBy animation triggered by FireFocusScroll from interrupting the sliding animation of the component. 236 * In the SetLastFocusStateNode method, this variable will not be set to true until it has value. 237 */ 238 std::optional<bool> isNeedTriggerScroll_ = false; 239 FocusHubScopeMap focusHubScopeMap_; 240 241 std::map<int32_t, FocusChangeCallback> listeners_; 242 ValueListenable<bool> focusActiveChangeCallback_; 243 int32_t nextListenerHdl_ = -1; 244 std::optional<bool> isSwitchingFocus_; 245 bool isSwitchingWindow_ = false; 246 RefPtr<FocusHub> switchingFocus_; 247 248 std::optional<SwitchingStartReason> startReason_; 249 std::optional<SwitchingEndReason> endReason_; 250 std::optional<SwitchingUpdateReason> updateReason_; 251 252 bool isAutoFocusTransfer_ = true; 253 FocusViewStackState focusViewStackState_ = FocusViewStackState::IDLE; 254 255 int32_t requestFocusResult_ = ERROR_CODE_NO_ERROR; 256 std::optional<FocusEvent> currentFocusEvent_; 257 KeyProcessingMode keyProcessingMode_ = KeyProcessingMode::FOCUS_NAVIGATION; 258 ACE_DISALLOW_COPY_AND_MOVE(FocusManager); 259 }; 260 } // namespace OHOS::Ace::NG 261 262 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_FOCUS_FOCUS_MANAGER_H 263