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