• 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_property.h"
31 #include "core/components_ng/pattern/scroll_bar/scroll_bar_paint_method.h"
32 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
33 #include "core/components_ng/render/animation_utils.h"
34 
35 namespace OHOS::Ace::NG {
36 
37 class ScrollBarPattern : public Pattern {
38     DECLARE_ACE_TYPE(ScrollBarPattern, Pattern);
39 
40 public:
41     ScrollBarPattern() = default;
~ScrollBarPattern()42     ~ScrollBarPattern() override
43     {
44         if (scrollBarProxy_) {
45             scrollBarProxy_->UnRegisterScrollBar(AceType::WeakClaim(this));
46         }
47         scrollBarProxy_ = nullptr;
48         scrollableEvent_ = nullptr;
49         disappearAnimation_ = nullptr;
50     }
51 
IsAtomicNode()52     bool IsAtomicNode() const override
53     {
54         return false;
55     }
56 
CreateLayoutProperty()57     RefPtr<LayoutProperty> CreateLayoutProperty() override
58     {
59         return MakeRefPtr<ScrollBarLayoutProperty>();
60     }
61 
CreatePaintProperty()62     RefPtr<PaintProperty> CreatePaintProperty() override
63     {
64         return MakeRefPtr<ScrollBarPaintProperty>();
65     }
66 
CreateAccessibilityProperty()67     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
68     {
69         return MakeRefPtr<ScrollBarAccessibilityProperty>();
70     }
71 
CreateLayoutAlgorithm()72     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
73     {
74         auto layoutAlgorithm = MakeRefPtr<ScrollBarLayoutAlgorithm>(currentOffset_);
75         return layoutAlgorithm;
76     }
77 
CreateEventHub()78     RefPtr<EventHub> CreateEventHub() override
79     {
80         return MakeRefPtr<ScrollEventHub>();
81     }
82 
GetCurrentPosition()83     float GetCurrentPosition() const
84     {
85         return currentOffset_;
86     }
87 
SetCurrentPosition(float currentOffset)88     void SetCurrentPosition(float currentOffset)
89     {
90         currentOffset_ = currentOffset;
91     }
92 
GetAxis()93     Axis GetAxis() const
94     {
95         return axis_;
96     }
97 
GetScrollableDistance()98     float GetScrollableDistance() const
99     {
100         return scrollableDistance_;
101     }
102 
SetScrollBarProxy(const RefPtr<ScrollBarProxy> & scrollBarProxy)103     void SetScrollBarProxy(const RefPtr<ScrollBarProxy>& scrollBarProxy)
104     {
105         scrollBarProxy_ = scrollBarProxy;
106     }
107 
GetDisplayMode()108     const DisplayMode& GetDisplayMode() const
109     {
110         return displayMode_;
111     }
112 
GetControlDistance()113     float GetControlDistance() const
114     {
115         return controlDistance_;
116     }
117 
SetControlDistance(float controlDistance)118     void SetControlDistance(float controlDistance)
119     {
120         if (Positive(controlDistance_) ? !Positive(controlDistance) : Positive(controlDistance)) {
121             controlDistanceChanged_ = true;
122         }
123         controlDistance_ = controlDistance;
124     }
125 
GetScrollableNodeOffset()126     float GetScrollableNodeOffset() const
127     {
128         return scrollableNodeOffset_;
129     }
130 
SetScrollableNodeOffset(float scrollableNodeOffset)131     void SetScrollableNodeOffset(float scrollableNodeOffset)
132     {
133         scrollableNodeOffset_ = scrollableNodeOffset;
134     }
135 
136     bool IsAtTop() const;
137     bool IsAtBottom() const;
138     bool UpdateCurrentOffset(float offset, int32_t source, bool isMouseWheelScroll = false);
139 
140     /**
141      * @brief Stops the motion animator of the scroll bar.
142      */
StopMotion()143     inline void StopMotion()
144     {
145         if (frictionController_ && frictionController_->IsRunning()) {
146             frictionController_->Stop();
147         }
148     }
149     // disappear Animator
150     void StartDisappearAnimator();
151     void StopDisappearAnimator();
152     void SetOpacity(uint8_t value);
153     void SendAccessibilityEvent(AccessibilityEventType eventType);
154 
SetChildOffset(float childOffset)155     void SetChildOffset(float childOffset)
156     {
157         childOffset_ = childOffset;
158     };
159 
GetChildOffset()160     float GetChildOffset() const
161     {
162         return childOffset_;
163     };
164 
SetChildRect(const RectF & rect)165     void SetChildRect(const RectF& rect)
166     {
167         childRect_ = rect;
168     }
169 
SetDisappearAnimation(const std::shared_ptr<AnimationUtils::Animation> & disappearAnimation)170     void SetDisappearAnimation(const std::shared_ptr<AnimationUtils::Animation>& disappearAnimation)
171     {
172         disappearAnimation_ = disappearAnimation;
173     }
174 
175     void OnCollectTouchTarget(const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl,
176         TouchTestResult& result, const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent,
177         ResponseLinkResult& responseLinkResult, bool inBarRect = false);
178 
GetMainOffset(const Offset & offset)179     float GetMainOffset(const Offset& offset) const
180     {
181         return axis_ == Axis::HORIZONTAL ? offset.GetX() : offset.GetY();
182     }
183 
SetDragStartPosition(float position)184     void SetDragStartPosition(float position)
185     {
186         dragStartPosition_ = position;
187     }
188 
SetDragEndPosition(float position)189     void SetDragEndPosition(float position)
190     {
191         dragEndPosition_ = position;
192     }
193 
GetDragOffset()194     float GetDragOffset()
195     {
196         return dragEndPosition_ - dragStartPosition_;
197     }
198 
199     void SetScrollBar(DisplayMode displayMode);
200     void UpdateScrollBarOffset(int32_t scrollSource);
201     void HandleScrollBarOutBoundary(float scrollBarOutBoundaryExtent);
202     void UpdateScrollBarRegion(
203         float offset, float estimatedHeight, Size viewPort, Offset viewOffset, int32_t scrollSource);
204     void RegisterScrollBarEventTask();
205     void InitScrollBarGestureEvent();
206     bool UpdateScrollBarDisplay();
207     bool IsReverse() const;
208     void SetReverse(bool reverse);
209 
GetGestureHub()210     RefPtr<GestureEventHub> GetGestureHub()
211     {
212         auto host = GetHost();
213         CHECK_NULL_RETURN(host, nullptr);
214         auto hub = host->GetOrCreateEventHub<EventHub>();
215         CHECK_NULL_RETURN(hub, nullptr);
216         return hub->GetOrCreateGestureEventHub();
217     }
218 
GetInputHub()219     RefPtr<InputEventHub> GetInputHub()
220     {
221         auto host = GetHost();
222         CHECK_NULL_RETURN(host, nullptr);
223         auto hub = host->GetOrCreateEventHub<EventHub>();
224         CHECK_NULL_RETURN(hub, nullptr);
225         return hub->GetOrCreateInputEventHub();
226     }
227 
CreateScrollBarOverlayModifier()228     void CreateScrollBarOverlayModifier()
229     {
230         CHECK_NULL_VOID(scrollBar_ && scrollBar_->NeedPaint());
231         CHECK_NULL_VOID(!scrollBarOverlayModifier_);
232         scrollBarOverlayModifier_ = AceType::MakeRefPtr<ScrollBarOverlayModifier>();
233         scrollBarOverlayModifier_->SetRect(scrollBar_->GetActiveRect());
234         scrollBarOverlayModifier_->SetPositionMode(scrollBar_->GetPositionMode());
235     }
236 
CreateNodePaintMethod()237     RefPtr<NodePaintMethod> CreateNodePaintMethod() override
238     {
239         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
240             auto paint = MakeRefPtr<ScrollBarPaintMethod>(hasChild_);
241             paint->SetScrollBar(scrollBar_);
242             if (scrollBar_ && !HasChild()) {
243                 auto activeRect = scrollBar_->GetActiveRect();
244                 auto offset = activeRect.GetOffset();
245                 auto offsetF = OffsetF(offset.GetX(), offset.GetY());
246                 auto size = activeRect.GetSize();
247                 auto sizeF = SizeF(size.Width(), size.Height());
248                 childRect_ = RectF(offsetF, sizeF);
249             }
250             CreateScrollBarOverlayModifier();
251             paint->SetScrollBarOverlayModifier(scrollBarOverlayModifier_);
252             return paint;
253         } else {
254             return Pattern::CreateNodePaintMethod();
255         }
256     }
257 
SetChild(bool hasChild)258     void SetChild(bool hasChild)
259     {
260         hasChild_ = hasChild;
261     }
262 
SetPreFrameChildState(bool preFrameChildState)263     void SetPreFrameChildState(bool preFrameChildState)
264     {
265         preFrameChildState_ = preFrameChildState;
266     }
267 
GetPreFrameChildState()268     bool GetPreFrameChildState()
269     {
270         return preFrameChildState_;
271     }
272 
HasChild()273     bool HasChild()
274     {
275         return hasChild_;
276     }
277 
CheckChildState()278     bool CheckChildState()
279     {
280         auto currentChildState = HasChild();
281         auto preChildState = GetPreFrameChildState();
282         if (preChildState != currentChildState) {
283             SetPreFrameChildState(currentChildState);
284             return true;
285         }
286         return false;
287     }
288     void InitClickEvent();
289     void HandleClickEvent();
290     void InitLongPressEvent();
291     void HandleLongPress(bool smooth);
292     void InitMouseEvent();
293     bool IsInScrollBar();
294     void ScheduleCaretLongPress();
295     void StartLongPressEventTimer();
296     void OnCollectClickTarget(const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl,
297         TouchTestResult& result, const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent,
298         ResponseLinkResult& responseLinkResult);
299     void OnCollectLongPressTarget(const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl,
300         TouchTestResult& result, const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent,
301         ResponseLinkResult& responseLinkResult);
302     void AddScrollBarLayoutInfo();
303 
304     void GetAxisDumpInfo();
305     void GetAxisDumpInfo(std::unique_ptr<JsonValue>& json);
306 
307     void GetDisplayModeDumpInfo();
308     void GetDisplayModeDumpInfo(std::unique_ptr<JsonValue>& json);
309 
310     void GetPanDirectionDumpInfo();
311     void GetPanDirectionDumpInfo(std::unique_ptr<JsonValue>& json);
312     void DumpAdvanceInfo() override;
313     void DumpAdvanceInfo(std::unique_ptr<JsonValue>& json) override;
314 
SetScrollEnabled(bool enabled)315     void SetScrollEnabled(bool enabled)
316     {
317         CHECK_NULL_VOID(scrollableEvent_);
318         scrollableEvent_->SetEnabled(enabled);
319         if (!enabled) {
320             scrollableEvent_->SetAxis(Axis::NONE);
321         } else {
322             scrollableEvent_->SetAxis(axis_);
323         }
324     }
325 
326     void OnColorConfigurationUpdate() override;
327     void OnColorModeChange(uint32_t colorMode) override;
328 
GetScrollBarProxy()329     RefPtr<ScrollBarProxy> GetScrollBarProxy()
330     {
331         return scrollBarProxy_;
332     }
333 
SetEnableNestedSorll(bool enableNestedSorll)334     void SetEnableNestedSorll(bool enableNestedSorll)
335     {
336         enableNestedSorll_ = enableNestedSorll;
337     }
338 
GetEnableNestedSorll()339     bool GetEnableNestedSorll() const
340     {
341         return enableNestedSorll_;
342     }
343 
344     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override;
345 
GetScrollBar()346     RefPtr<ScrollBar> GetScrollBar() const
347     {
348         return scrollBar_;
349     }
350 
351     PositionMode GetPositionMode();
352 
GetScrollBarOverlayModifier()353     RefPtr<ScrollBarOverlayModifier> GetScrollBarOverlayModifier() const
354     {
355         return scrollBarOverlayModifier_;
356     }
357 
CreateScrollBar()358     virtual RefPtr<ScrollBar> CreateScrollBar() const
359     {
360         return AceType::MakeRefPtr<ScrollBar>();
361     }
362 
UseInnerScrollBar()363     virtual bool UseInnerScrollBar() const
364     {
365         return !hasChild_ && Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE);
366     }
367 
368     virtual void SetBarCollectClickAndLongPressTargetCallback();
369 
SetScrollBarOverlayModifier(RefPtr<ScrollBarOverlayModifier> & scrollBarOverlayModifier)370     void SetScrollBarOverlayModifier(RefPtr<ScrollBarOverlayModifier>& scrollBarOverlayModifier)
371     {
372         scrollBarOverlayModifier_ = scrollBarOverlayModifier;
373     }
374 
375     void OnModifyDone() override;
376 
377 private:
378     bool ScrollPositionCallback(double offset, int32_t source, bool isMouseWheelScroll = false);
379     void InitScrollEndCallback();
380     void AddScrollableEvent();
381     void SetInBarRegionCallback();
382     void SetBarCollectTouchTargetCallback();
383     void SetBarRectCollectTouchTargetCallback();
384     void SetInBarRectRegionCallback();
385     void OnAttachToFrameNode() override;
386     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override;
387     void ValidateOffset();
388     void SetAccessibilityAction();
389     void InitPanRecognizer();
390     void HandleDragStart(const GestureEvent& info);
391     void HandleDragUpdate(const GestureEvent& info);
392     void HandleDragEnd(const GestureEvent& info);
393     void ProcessFrictionMotion(double value);
394     void ProcessFrictionMotionStop();
395 
396     RefPtr<ScrollBarProxy> scrollBarProxy_;
397     RefPtr<ScrollableEvent> scrollableEvent_;
398     Axis axis_ = Axis::VERTICAL;
399     DisplayMode displayMode_ { DisplayMode::AUTO };
400     float currentOffset_ = 0.0f;
401     float lastOffset_ = 0.0f;
402     float scrollableDistance_ = 0.0f;
403     float controlDistance_ = 0.0f;
404     bool  controlDistanceChanged_ = false;
405     float scrollableNodeOffset_  = 0.0f;
406     bool hasChild_ = false;
407     bool preFrameChildState_ = false;
408     float friction_ = BAR_FRICTION;
409     float frictionPosition_ = 0.0;
410     float dragStartPosition_ = 0.0f;
411     float dragEndPosition_ = 0.0f;
412 
413     float childOffset_ = 0.0f;  // main size of child
414     RefPtr<ScrollBarOverlayModifier> scrollBarOverlayModifier_;
415     RefPtr<ScrollBar> scrollBar_;
416     RefPtr<PanRecognizer> panRecognizer_;
417     RefPtr<FrictionMotion> frictionMotion_;
418     RefPtr<Animator> frictionController_;
419     ScrollEndCallback scrollEndCallback_;
420     RectF childRect_;
421     uint8_t opacity_ = UINT8_MAX;
422     CancelableCallback<void()> disapplearDelayTask_;
423     std::shared_ptr<AnimationUtils::Animation> disappearAnimation_;
424     bool isReverse_ = false;
425 
426     // dump info
427     std::list<OuterScrollBarLayoutInfo> outerScrollBarLayoutInfos_;
428     bool isMousePressed_ = false;
429     bool isScrolling_ = false;
430     RefPtr<ClickRecognizer> clickRecognizer_;
431     RefPtr<LongPressRecognizer> longPressRecognizer_;
432     RefPtr<InputEvent> mouseEvent_;
433     Offset locationInfo_;
434     //Determine whether the current scroll direction is scrolling upwards or downwards
435     bool scrollingUp_ = false;
436     bool scrollingDown_ = false;
437     bool enableNestedSorll_ = false;
438 };
439 
440 } // namespace OHOS::Ace::NG
441 
442 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_BAR_SCROLL_BAR_PATTERN_H
443