• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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_PATTERNS_SCROLL_BAR_SCROLL_BAR_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_BAR_SCROLL_BAR_PATTERN_H
18 
19 #include "base/geometry/axis.h"
20 #include "base/utils/utils.h"
21 #include "core/common/container.h"
22 #include "core/components/common/layout/constants.h"
23 #include "core/components_ng/pattern/pattern.h"
24 #include "core/components_ng/pattern/scroll/inner/scroll_bar.h"
25 #include "core/components_ng/pattern/scroll/scroll_event_hub.h"
26 #include "core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.h"
27 #include "core/components_ng/pattern/scroll_bar/scroll_bar_accessibility_property.h"
28 #include "core/components_ng/pattern/scroll_bar/scroll_bar_layout_algorithm.h"
29 #include "core/components_ng/pattern/scroll_bar/scroll_bar_layout_property.h"
30 #include "core/components_ng/pattern/scroll_bar/scroll_bar_paint_method.h"
31 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
32 #include "core/components_ng/render/animation_utils.h"
33 
34 namespace OHOS::Ace::NG {
35 
36 class ScrollBarPattern : public Pattern {
37     DECLARE_ACE_TYPE(ScrollBarPattern, Pattern);
38 
39 public:
40     ScrollBarPattern() = default;
~ScrollBarPattern()41     ~ScrollBarPattern() override
42     {
43         if (scrollBarProxy_) {
44             scrollBarProxy_->UnRegisterScrollBar(AceType::WeakClaim(this));
45         }
46         scrollBarProxy_ = nullptr;
47         scrollableEvent_ = nullptr;
48         disappearAnimation_ = nullptr;
49     }
50 
IsAtomicNode()51     bool IsAtomicNode() const override
52     {
53         return false;
54     }
55 
CreateLayoutProperty()56     RefPtr<LayoutProperty> CreateLayoutProperty() override
57     {
58         return MakeRefPtr<ScrollBarLayoutProperty>();
59     }
60 
CreateAccessibilityProperty()61     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
62     {
63         return MakeRefPtr<ScrollBarAccessibilityProperty>();
64     }
65 
CreateLayoutAlgorithm()66     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
67     {
68         auto layoutAlgorithm = MakeRefPtr<ScrollBarLayoutAlgorithm>(currentOffset_);
69         return layoutAlgorithm;
70     }
71 
CreateEventHub()72     RefPtr<EventHub> CreateEventHub() override
73     {
74         return MakeRefPtr<ScrollEventHub>();
75     }
76 
GetCurrentPosition()77     float GetCurrentPosition() const
78     {
79         return currentOffset_;
80     }
81 
SetCurrentPosition(float currentOffset)82     void SetCurrentPosition(float currentOffset)
83     {
84         currentOffset_ = currentOffset;
85     }
86 
GetAxis()87     Axis GetAxis() const
88     {
89         return axis_;
90     }
91 
GetScrollableDistance()92     float GetScrollableDistance() const
93     {
94         return scrollableDistance_;
95     }
96 
SetScrollBarProxy(const RefPtr<ScrollBarProxy> & scrollBarProxy)97     void SetScrollBarProxy(const RefPtr<ScrollBarProxy>& scrollBarProxy)
98     {
99         scrollBarProxy_ = scrollBarProxy;
100     }
101 
GetDisplayMode()102     const DisplayMode& GetDisplayMode() const
103     {
104         return displayMode_;
105     }
106 
GetControlDistance()107     float GetControlDistance() const
108     {
109         return controlDistance_;
110     }
111 
SetControlDistance(float controlDistance)112     void SetControlDistance(float controlDistance)
113     {
114         controlDistanceChanged_ = Positive(controlDistance_) ? !Positive(controlDistance) : Positive(controlDistance);
115         controlDistance_ = controlDistance;
116     }
117 
GetScrollableNodeOffset()118     float GetScrollableNodeOffset() const
119     {
120         return scrollableNodeOffset_;
121     }
122 
SetScrollableNodeOffset(float scrollableNodeOffset)123     void SetScrollableNodeOffset(float scrollableNodeOffset)
124     {
125         scrollableNodeOffset_ = scrollableNodeOffset;
126     }
127 
128     bool IsAtTop() const;
129     bool IsAtBottom() const;
130     bool UpdateCurrentOffset(float offset, int32_t source);
131 
132     /**
133      * @brief Stops the motion animator of the scroll bar.
134      */
StopMotion()135     inline void StopMotion()
136     {
137         if (frictionController_ && frictionController_->IsRunning()) {
138             frictionController_->Stop();
139         }
140     }
141     // disappear Animator
142     void StartDisappearAnimator();
143     void StopDisappearAnimator();
144     void SetOpacity(uint8_t value);
145     void SendAccessibilityEvent(AccessibilityEventType eventType);
146 
SetChildOffset(float childOffset)147     void SetChildOffset(float childOffset)
148     {
149         childOffset_ = childOffset;
150     };
151 
GetChildOffset()152     float GetChildOffset() const
153     {
154         return childOffset_;
155     };
156 
SetChildRect(const RectF & rect)157     void SetChildRect(const RectF& rect)
158     {
159         childRect_ = rect;
160     }
161 
SetDisappearAnimation(const std::shared_ptr<AnimationUtils::Animation> & disappearAnimation)162     void SetDisappearAnimation(const std::shared_ptr<AnimationUtils::Animation>& disappearAnimation)
163     {
164         disappearAnimation_ = disappearAnimation;
165     }
166 
167     void OnCollectTouchTarget(const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl,
168         TouchTestResult& result, const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent,
169         ResponseLinkResult& responseLinkResult);
170 
GetMainOffset(const Offset & offset)171     float GetMainOffset(const Offset& offset) const
172     {
173         return axis_ == Axis::HORIZONTAL ? offset.GetX() : offset.GetY();
174     }
175 
SetDragStartPosition(float position)176     void SetDragStartPosition(float position)
177     {
178         dragStartPosition_ = position;
179     }
180 
SetDragEndPosition(float position)181     void SetDragEndPosition(float position)
182     {
183         dragEndPosition_ = position;
184     }
185 
GetDragOffset()186     float GetDragOffset()
187     {
188         return dragEndPosition_ - dragStartPosition_;
189     }
190 
191     void SetScrollBar(DisplayMode displayMode);
192     void UpdateScrollBarOffset();
193     void HandleScrollBarOutBoundary(float scrollBarOutBoundaryExtent);
194     void UpdateScrollBarRegion(float offset, float estimatedHeight, Size viewPort, Offset viewOffset);
195     void RegisterScrollBarEventTask();
196     bool UpdateScrollBarDisplay();
197     bool IsReverse() const;
198     void SetReverse(bool reverse);
199 
GetGestureHub()200     RefPtr<GestureEventHub> GetGestureHub()
201     {
202         auto host = GetHost();
203         CHECK_NULL_RETURN(host, nullptr);
204         auto hub = host->GetEventHub<EventHub>();
205         CHECK_NULL_RETURN(hub, nullptr);
206         return hub->GetOrCreateGestureEventHub();
207     }
208 
GetInputHub()209     RefPtr<InputEventHub> GetInputHub()
210     {
211         auto host = GetHost();
212         CHECK_NULL_RETURN(host, nullptr);
213         auto hub = host->GetEventHub<EventHub>();
214         CHECK_NULL_RETURN(hub, nullptr);
215         return hub->GetOrCreateInputEventHub();
216     }
217 
CreateScrollBarOverlayModifier()218     void CreateScrollBarOverlayModifier()
219     {
220         CHECK_NULL_VOID(scrollBar_ && scrollBar_->NeedPaint());
221         CHECK_NULL_VOID(!scrollBarOverlayModifier_);
222         scrollBarOverlayModifier_ = AceType::MakeRefPtr<ScrollBarOverlayModifier>();
223         scrollBarOverlayModifier_->SetRect(scrollBar_->GetActiveRect());
224         scrollBarOverlayModifier_->SetPositionMode(scrollBar_->GetPositionMode());
225     }
226 
CreateNodePaintMethod()227     RefPtr<NodePaintMethod> CreateNodePaintMethod() override
228     {
229         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
230             auto paint = MakeRefPtr<ScrollBarPaintMethod>(hasChild_);
231             paint->SetScrollBar(scrollBar_);
232             if (!HasChild()) {
233                 auto activeRect = scrollBar_->GetActiveRect();
234                 auto offset = activeRect.GetOffset();
235                 auto offsetF = OffsetF(offset.GetX(), offset.GetY());
236                 auto size = activeRect.GetSize();
237                 auto sizeF = SizeF(size.Width(), size.Height());
238                 childRect_ = RectF(offsetF, sizeF);
239             }
240             CreateScrollBarOverlayModifier();
241             paint->SetScrollBarOverlayModifier(scrollBarOverlayModifier_);
242             return paint;
243         } else {
244             return Pattern::CreateNodePaintMethod();
245         }
246     }
247 
SetChild(bool hasChild)248     void SetChild(bool hasChild)
249     {
250         hasChild_ = hasChild;
251     }
252 
SetPreFrameChildState(bool preFrameChildState)253     void SetPreFrameChildState(bool preFrameChildState)
254     {
255         preFrameChildState_ = preFrameChildState;
256     }
257 
GetPreFrameChildState()258     bool GetPreFrameChildState()
259     {
260         return preFrameChildState_;
261     }
262 
HasChild()263     bool HasChild()
264     {
265         return hasChild_;
266     }
267 
CheckChildState()268     bool CheckChildState()
269     {
270         auto currentChildState = HasChild();
271         auto preChildState = GetPreFrameChildState();
272         if (preChildState != currentChildState) {
273             SetPreFrameChildState(currentChildState);
274             return true;
275         }
276         return false;
277     }
278 
279     void AddScrollBarLayoutInfo();
280 
281     void GetAxisDumpInfo();
282 
283     void GetDisplayModeDumpInfo();
284 
285     void GetPanDirectionDumpInfo();
286 
287     void DumpAdvanceInfo() override;
288 
SetScrollEnabled(bool enabled)289     void SetScrollEnabled(bool enabled)
290     {
291         CHECK_NULL_VOID(scrollableEvent_);
292         scrollableEvent_->SetEnabled(enabled);
293         if (!enabled) {
294             scrollableEvent_->SetAxis(Axis::NONE);
295         } else {
296             scrollableEvent_->SetAxis(axis_);
297         }
298     }
299 
300     void OnColorConfigurationUpdate() override;
301 
302 private:
303     void OnModifyDone() override;
304     void OnAttachToFrameNode() override;
305     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override;
306     void ValidateOffset();
307     void SetAccessibilityAction();
308     void InitPanRecognizer();
309     void HandleDragStart(const GestureEvent& info);
310     void HandleDragUpdate(const GestureEvent& info);
311     void HandleDragEnd(const GestureEvent& info);
312     void ProcessFrictionMotion(double value);
313     void ProcessFrictionMotionStop();
314 
315     RefPtr<ScrollBarProxy> scrollBarProxy_;
316     RefPtr<ScrollableEvent> scrollableEvent_;
317     Axis axis_ = Axis::VERTICAL;
318     DisplayMode displayMode_ { DisplayMode::AUTO };
319     float currentOffset_ = 0.0f;
320     float lastOffset_ = 0.0f;
321     float scrollableDistance_ = 0.0f;
322     float controlDistance_ = 0.0f;
323     bool  controlDistanceChanged_ = false;
324     float scrollableNodeOffset_ = 0.0f;
325     bool hasChild_ = false;
326     bool preFrameChildState_ = false;
327     float friction_ = BAR_FRICTION;
328     float frictionPosition_ = 0.0;
329     float dragStartPosition_ = 0.0f;
330     float dragEndPosition_ = 0.0f;
331 
332     float childOffset_ = 0.0f;  // main size of child
333     RefPtr<ScrollBarOverlayModifier> scrollBarOverlayModifier_;
334     RefPtr<ScrollBar> scrollBar_;
335     RefPtr<PanRecognizer> panRecognizer_;
336     RefPtr<FrictionMotion> frictionMotion_;
337     RefPtr<Animator> frictionController_;
338     ScrollPositionCallback scrollPositionCallback_;
339     ScrollEndCallback scrollEndCallback_;
340     RectF childRect_;
341     uint8_t opacity_ = UINT8_MAX;
342     CancelableCallback<void()> disapplearDelayTask_;
343     std::shared_ptr<AnimationUtils::Animation> disappearAnimation_;
344     bool isReverse_ = false;
345 
346     // dump info
347     std::list<OuterScrollBarLayoutInfo> outerScrollBarLayoutInfos_;
348 };
349 
350 } // namespace OHOS::Ace::NG
351 
352 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_BAR_SCROLL_BAR_PATTERN_H
353