• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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_STATE_STYLE_MANAGER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_STATE_STYLE_MANAGER_H
18 
19 #include <set>
20 
21 #include "base/geometry/ng/point_t.h"
22 #include "base/geometry/offset.h"
23 #include "base/memory/ace_type.h"
24 #include "base/memory/referenced.h"
25 #include "base/thread/cancelable_callback.h"
26 #include "core/components_ng/base/ui_node.h"
27 
28 namespace OHOS::Ace::NG {
29 
30 class FrameNode;
31 class TouchEventImpl;
32 class CustomNodeBase;
33 
34 using UIState = uint64_t;
35 inline constexpr UIState UI_STATE_NORMAL = 0;
36 inline constexpr UIState UI_STATE_PRESSED = 1;
37 inline constexpr UIState UI_STATE_FOCUSED = 1 << 1;
38 inline constexpr UIState UI_STATE_DISABLED = 1 << 2;
39 // used for radio, checkbox, switch.
40 inline constexpr UIState UI_STATE_SELECTED = 1 << 3;
41 inline constexpr UIState UI_STATE_UNKNOWN = 1 << 9;
42 
43 inline constexpr uint64_t EXCLUDE_INNER_FLAG_NONE = 0;
44 
45 // StateStyleManager is mainly used to manage the setting and refresh of state styles.
46 class StateStyleManager : public virtual AceType {
47     DECLARE_ACE_TYPE(StateStyleManager, AceType);
48 
49 public:
50     explicit StateStyleManager(WeakPtr<FrameNode> frameNode);
51     ~StateStyleManager() override;
52 
HasStateStyle(UIState state)53     bool HasStateStyle(UIState state) const
54     {
55         return (supportedStates_ & state) == state;
56     }
57 
GetCurrentUIState()58     UIState GetCurrentUIState() const
59     {
60         return currentState_;
61     }
62 
63     // this function should only be called by the frontend parsing layer to add a supported UI state.
AddSupportedState(UIState state)64     void AddSupportedState(UIState state)
65     {
66         supportedStates_ = supportedStates_ | state;
67         if (frontendSubscribers_ & UI_STATE_UNKNOWN) {
68             frontendSubscribers_ = frontendSubscribers_ | state;
69         }
70     }
71 
SetSupportedStates(UIState state)72     void SetSupportedStates(UIState state)
73     {
74         supportedStates_ = state;
75     }
76 
77     void AddSupportedUIStateWithCallback(
78         UIState state, std::function<void(uint64_t)>& callback, bool isInner, bool excludeInner = false);
79     void RemoveSupportedUIState(UIState state, bool isInner);
80 
GetUserSetStateStyle()81     bool GetUserSetStateStyle()
82     {
83         bool isSetState = true;
84 
85         if (innerStateStyleSubscribers_.first == UI_STATE_UNKNOWN &&
86             userStateStyleSubscribers_.first == UI_STATE_UNKNOWN && frontendSubscribers_ == UI_STATE_UNKNOWN) {
87             isSetState = false;
88         }
89         return isSetState;
90     }
91 
IsCurrentStateOn(UIState state)92     bool IsCurrentStateOn(UIState state) const
93     {
94         if (state == UI_STATE_NORMAL) {
95             return currentState_ == state;
96         }
97         return (currentState_ & state) == state;
98     }
99 
100     void SetCurrentUIState(UIState state, bool flag);
101 
SetScrollingFeatureForbidden(bool scrollingFeatureForbidden)102     void SetScrollingFeatureForbidden(bool scrollingFeatureForbidden)
103     {
104         scrollingFeatureForbidden_ = scrollingFeatureForbidden;
105     }
106 
GetScrollingFeatureForbidden()107     bool GetScrollingFeatureForbidden()
108     {
109         return scrollingFeatureForbidden_;
110     }
111 
UpdateCurrentUIState(UIState state)112     void UpdateCurrentUIState(UIState state)
113     {
114         if (!HasStateStyle(state)) {
115             return;
116         }
117         auto temp = currentState_ | state;
118         if (temp != currentState_) {
119             currentState_ = temp;
120             FireStateFunc(state, currentState_, false);
121         }
122     }
123 
ResetCurrentUIState(UIState state)124     void ResetCurrentUIState(UIState state)
125     {
126         if (!HasStateStyle(state)) {
127             return;
128         }
129         if ((currentState_ & state) != state) {
130             return;
131         }
132         auto temp = currentState_ ^ state;
133         if (temp != currentState_) {
134             currentState_ = temp;
135             FireStateFunc(state, currentState_, true);
136         }
137     }
138 
GetHasScrollingParent()139     bool GetHasScrollingParent() const
140     {
141         return hasScrollingParent_;
142     }
143 
144     const RefPtr<TouchEventImpl>& GetPressedListener();
145     void HandleTouchDown();
146     void HandleTouchUp();
147 
148     RefPtr<FrameNode> GetFrameNode() const;
149 
ClearStateStyleTask()150     void ClearStateStyleTask()
151     {
152         DeletePressStyleTask();
153         ResetPressedPendingState();
154     }
155 
156 private:
157     void HandleStateChangeInternal(
158         UIState handlingState, UIState currentState, bool isReset, bool skipFrontendForcibly = false);
159     void FireStateFunc(UIState handlingState, UIState currentState, bool isReset, bool skipFrontendForcibly = false);
160 
161     void PostListItemPressStyleTask(UIState state);
162     void PostPressStyleTask(uint32_t delayTime);
163     void PostPressCancelStyleTask(uint32_t delayTime);
164 
165     void HandleScrollingParent();
166 
DeletePressStyleTask()167     void DeletePressStyleTask()
168     {
169         if (pressStyleTask_) {
170             pressStyleTask_.Cancel();
171         }
172     }
173 
DeletePressCancelStyleTask()174     void DeletePressCancelStyleTask()
175     {
176         if (pressCancelStyleTask_) {
177             pressCancelStyleTask_.Cancel();
178         }
179     }
180 
IsPressedStatePending()181     bool IsPressedStatePending()
182     {
183         return pressedPendingState_;
184     }
185 
IsPressedCancelStatePending()186     bool IsPressedCancelStatePending()
187     {
188         return pressedCancelPendingState_;
189     }
190 
ResetPressedPendingState()191     void ResetPressedPendingState()
192     {
193         pressedPendingState_ = false;
194     }
195 
ResetPressedCancelPendingState()196     void ResetPressedCancelPendingState()
197     {
198         pressedCancelPendingState_ = false;
199     }
200 
PendingPressedState()201     void PendingPressedState()
202     {
203         pressedPendingState_ = true;
204     }
205 
PendingCancelPressedState()206     void PendingCancelPressedState()
207     {
208         pressedCancelPendingState_ = true;
209     }
210 
ResetPressedState()211     void ResetPressedState()
212     {
213         ResetCurrentUIState(UI_STATE_PRESSED);
214         DeletePressStyleTask();
215         ResetPressedPendingState();
216     }
217 
ResetPressedCancelState()218     void ResetPressedCancelState()
219     {
220         DeletePressCancelStyleTask();
221         ResetPressedCancelPendingState();
222     }
223 
224     bool IsOutOfPressedRegion(int32_t sourceType, const Offset& location) const;
225     bool IsOutOfPressedRegionWithoutClip(RefPtr<FrameNode> node, int32_t sourceType,
226         const Offset& location) const;
227     void Transform(PointF& localPointF, const WeakPtr<FrameNode>& node) const;
228     void CleanScrollingParentListener();
229 
230     void GetCustomNode(RefPtr<CustomNodeBase>& customNode, RefPtr<UINode> node);
231     bool GetCustomNodeFromSelf(RefPtr<UINode>& node, RefPtr<CustomNodeBase>& customNode, int32_t nodeId);
232     bool GetCustomNodeFromNavgation(RefPtr<UINode>& node, RefPtr<CustomNodeBase>& customNode, int32_t nodeId);
233     bool IsExcludeInner(UIState handlingState);
234 
235     WeakPtr<FrameNode> host_;
236     RefPtr<TouchEventImpl> pressedFunc_;
237 
238     UIState supportedStates_ = UI_STATE_NORMAL;
239     UIState currentState_ = UI_STATE_NORMAL;
240     // manages inner subscription UI state and callbacks.
241     std::pair<UIState, std::function<void(uint64_t)>> innerStateStyleSubscribers_ = { UI_STATE_UNKNOWN, nullptr };
242     // manages user subscription UI state and callbacks.
243     std::pair<UIState, std::function<void(uint64_t)>> userStateStyleSubscribers_ = { UI_STATE_UNKNOWN, nullptr };
244     // manages the flag that forbids the inner default state style handling for user subscriptions.
245     uint64_t userSubscribersExcludeConfigs_ = EXCLUDE_INNER_FLAG_NONE;
246     // tracks frontend UI state.
247     UIState frontendSubscribers_ = UI_STATE_UNKNOWN;
248 
249     std::set<int32_t> pointerId_;
250     CancelableCallback<void()> pressStyleTask_;
251     CancelableCallback<void()> pressCancelStyleTask_;
252     bool pressedPendingState_ = false;
253     bool pressedCancelPendingState_ = false;
254     bool hasScrollingParent_ = false;
255     bool scrollingFeatureForbidden_ = false;
256     bool isFastScrolling_ = false;
257 
258     ACE_DISALLOW_COPY_AND_MOVE(StateStyleManager);
259 };
260 
261 } // namespace OHOS::Ace::NG
262 
263 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_STATE_STYLE_MANAGER_H