• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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_INNER_SCROLL_BAR_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_INNER_SCROLL_BAR_H
18 
19 #include <cmath>
20 
21 #include "base/geometry/dimension.h"
22 #include "base/geometry/offset.h"
23 #include "base/geometry/rect.h"
24 #include "base/utils/utils.h"
25 #include "core/animation/friction_motion.h"
26 #include "core/components/common/layout/constants.h"
27 #include "core/components/common/properties/color.h"
28 #include "core/components/common/properties/edge.h"
29 #include "core/components/scroll/scroll_bar_theme.h"
30 #include "core/components_ng/base/frame_scene_status.h"
31 #include "core/components_ng/event/input_event.h"
32 #include "core/components_ng/event/touch_event.h"
33 #include "core/components_ng/gestures/recognizers/pan_recognizer.h"
34 #include "core/components_ng/pattern/scroll/inner/scroll_bar_overlay_modifier.h"
35 #include "core/components_ng/pattern/scrollable/scrollable_properties.h"
36 #include "core/components_ng/property/border_property.h"
37 
38 namespace OHOS::Ace::NG {
39 
40 constexpr double FACTOR_HALF = 0.5;
41 constexpr double DEFAULT_TOPANGLE = 60.0;
42 constexpr double DEFAULT_BOTTOMANGLE = 120.0;
43 constexpr double DEFAULT_MINANGLE = 10.0;
44 constexpr double STRAIGHT_ANGLE = 180.0;
45 constexpr double BAR_FRICTION = 0.9;
46 constexpr Color PRESSED_BLEND_COLOR = Color(0x19000000);
47 using DragFRCSceneCallback = std::function<void(double velocity, NG::SceneStatus sceneStatus)>;
48 
49 class ScrollBar final : public AceType {
50     DECLARE_ACE_TYPE(ScrollBar, AceType);
51 
52 public:
53     ScrollBar();
54     ScrollBar(DisplayMode displayMode, ShapeMode shapeMode = ShapeMode::RECT,
55         PositionMode positionMode = PositionMode::RIGHT);
56     ~ScrollBar() override = default;
57 
58     bool InBarTouchRegion(const Point& point) const;
59     bool InBarHoverRegion(const Point& point) const;
60     bool InBarRectRegion(const Point& point) const;
61     bool NeedScrollBar() const;
62     bool NeedPaint() const;
63     void UpdateScrollBarRegion(
64         const Offset& offset, const Size& size, const Offset& lastOffset, double estimatedHeight);
65     double GetNormalWidthToPx() const;
66     float CalcPatternOffset(float scrollBarOffset) const;
67 
GetShapeMode()68     ShapeMode GetShapeMode() const
69     {
70         return shapeMode_;
71     }
72 
GetDisplayMode()73     DisplayMode GetDisplayMode() const
74     {
75         return displayMode_;
76     }
77 
GetPositionMode()78     PositionMode GetPositionMode() const
79     {
80         return positionMode_;
81     }
82 
SetPadding(const Edge & padding)83     void SetPadding(const Edge& padding)
84     {
85         padding_ = padding;
86     }
87 
GetPadding()88     const Edge& GetPadding() const
89     {
90         return padding_;
91     }
92 
SetBackgroundColor(const Color & backgroundColor)93     void SetBackgroundColor(const Color& backgroundColor)
94     {
95         backgroundColor_ = backgroundColor;
96     }
97 
GetBackgroundColor()98     const Color& GetBackgroundColor() const
99     {
100         return backgroundColor_;
101     }
102 
SetForegroundColor(const Color & foregroundColor)103     void SetForegroundColor(const Color& foregroundColor)
104     {
105         foregroundColor_ = foregroundColor;
106     }
107 
GetForegroundColor()108     Color GetForegroundColor() const
109     {
110         return IsPressed() ? foregroundColor_.BlendColor(PRESSED_BLEND_COLOR) : foregroundColor_;
111     }
112 
GetTopAngle()113     double GetTopAngle() const
114     {
115         return topAngle_;
116     }
117 
GetBottomAngle()118     double GetBottomAngle() const
119     {
120         return bottomAngle_;
121     }
122 
GetTrickStartAngle()123     double GetTrickStartAngle() const
124     {
125         return trickStartAngle_;
126     }
127 
GetTrickSweepAngle()128     double GetTrickSweepAngle() const
129     {
130         return trickSweepAngle_;
131     }
132 
SetMinHeight(const Dimension & minHeight)133     void SetMinHeight(const Dimension& minHeight)
134     {
135         minHeight_ = minHeight;
136     }
137 
GetMinHeight()138     const Dimension& GetMinHeight() const
139     {
140         return minHeight_;
141     }
142 
SetMinDynamicHeight(const Dimension & minDynamicHeight)143     void SetMinDynamicHeight(const Dimension& minDynamicHeight)
144     {
145         minDynamicHeight_ = minDynamicHeight;
146     }
147 
GetMinDynamicHeight()148     const Dimension& GetMinDynamicHeight() const
149     {
150         return minDynamicHeight_;
151     }
152 
SetInactiveWidth(const Dimension & inactiveWidth)153     void SetInactiveWidth(const Dimension& inactiveWidth)
154     {
155         inactiveWidth_ = inactiveWidth;
156     }
157 
SetActiveWidth(const Dimension & activeWidth)158     void SetActiveWidth(const Dimension& activeWidth)
159     {
160         activeWidth_ = activeWidth;
161     }
162 
SetHoverWidth(const RefPtr<ScrollBarTheme> & theme)163     void SetHoverWidth(const RefPtr<ScrollBarTheme>& theme)
164     {
165         hoverWidth_ = theme->GetActiveWidth() + theme->GetScrollBarMargin() * 2;
166     }
167 
GetActiveWidth()168     const Dimension& GetActiveWidth() const
169     {
170         return activeWidth_;
171     }
172 
SetNormalWidth(const Dimension & normalWidth)173     void SetNormalWidth(const Dimension& normalWidth)
174     {
175         if (normalWidth_ != normalWidth) {
176             normalWidthUpdate_ = true;
177             normalWidth_ = normalWidth;
178             CalcReservedHeight();
179             MarkNeedRender();
180         }
181     }
182 
GetActiveRect()183     const Rect& GetActiveRect() const
184     {
185         return activeRect_;
186     }
187 
SetTouchWidth(const Dimension & touchWidth)188     void SetTouchWidth(const Dimension& touchWidth)
189     {
190         touchWidth_ = touchWidth;
191     }
192 
GetTouchWidth()193     const Dimension& GetTouchWidth() const
194     {
195         return touchWidth_;
196     }
197 
GetBarRect()198     const Rect& GetBarRect() const
199     {
200         return barRect_;
201     }
202 
SetScrollable(bool isScrollable)203     void SetScrollable(bool isScrollable)
204     {
205         CHECK_NULL_VOID(isScrollable_ != isScrollable);
206         isScrollable_ = isScrollable;
207     }
208 
IsScrollable()209     bool IsScrollable() const
210     {
211         return isScrollable_;
212     }
213 
SetPositionMode(PositionMode positionMode)214     void SetPositionMode(PositionMode positionMode)
215     {
216         if (positionMode_ != positionMode) {
217             positionModeUpdate_ = true;
218             positionMode_ = positionMode;
219             if (panRecognizer_) {
220                 PanDirection panDirection;
221                 panDirection.type =
222                     positionMode_ == PositionMode::BOTTOM ? PanDirection::HORIZONTAL : PanDirection::VERTICAL;
223                 panRecognizer_->SetDirection(panDirection);
224             }
225         }
226     }
227 
GetPositionModeUpdate()228     bool GetPositionModeUpdate() const
229     {
230         return positionModeUpdate_;
231     }
232 
SetShapeMode(ShapeMode shapeMode)233     void SetShapeMode(ShapeMode shapeMode)
234     {
235         shapeMode_ = shapeMode;
236     }
237 
SetDisplayMode(DisplayMode displayMode)238     void SetDisplayMode(DisplayMode displayMode)
239     {
240         CHECK_NULL_VOID(displayMode_ != displayMode);
241         displayMode_ = displayMode;
242     }
243 
GetOutBoundary()244     double GetOutBoundary() const
245     {
246         return outBoundary_;
247     }
248 
SetOutBoundary(double outBoundary)249     void SetOutBoundary(double outBoundary)
250     {
251         outBoundary_ = outBoundary;
252     }
253 
SetIsOutOfBoundary(bool isOutOfBoundary)254     void SetIsOutOfBoundary(bool isOutOfBoundary)
255     {
256         isOutOfBoundary_ = isOutOfBoundary;
257     }
258 
SetPosition(const Dimension & position)259     void SetPosition(const Dimension& position)
260     {
261         position_ = position;
262     }
263 
GetPosition()264     const Dimension& GetPosition() const
265     {
266         return position_;
267     }
268 
SetPressed(bool press)269     void SetPressed(bool press)
270     {
271         isPressed_ = press;
272     }
273 
IsPressed()274     bool IsPressed() const
275     {
276         return isPressed_;
277     }
278 
SetHover(bool hover)279     void SetHover(bool hover)
280     {
281         isHover_ = hover;
282     }
283 
IsHover()284     bool IsHover() const
285     {
286         return isHover_;
287     }
288 
PlayScrollBarDisappearAnimation()289     void PlayScrollBarDisappearAnimation()
290     {
291         if (displayMode_ == DisplayMode::AUTO && isScrollable_ && !isHover_ && !isPressed_) {
292             opacityAnimationType_ = OpacityAnimationType::DISAPPEAR;
293             MarkNeedRender();
294         }
295     }
296 
PlayScrollBarAppearAnimation()297     void PlayScrollBarAppearAnimation()
298     {
299         if (displayMode_ == DisplayMode::AUTO && isScrollable_) {
300             disappearDelayTask_.Cancel();
301             opacityAnimationType_ = OpacityAnimationType::APPEAR;
302             MarkNeedRender();
303         }
304     }
305 
GetOpacityAnimationType()306     OpacityAnimationType GetOpacityAnimationType() const
307     {
308         return opacityAnimationType_;
309     }
310 
SetOpacityAnimationType(OpacityAnimationType opacityAnimationType)311     void SetOpacityAnimationType(OpacityAnimationType opacityAnimationType)
312     {
313         opacityAnimationType_ = opacityAnimationType;
314     }
315 
GetHoverAnimationType()316     HoverAnimationType GetHoverAnimationType() const
317     {
318         return hoverAnimationType_;
319     }
320 
SetHoverAnimationType(HoverAnimationType hoverAnimationType)321     void SetHoverAnimationType(HoverAnimationType hoverAnimationType)
322     {
323         hoverAnimationType_ = hoverAnimationType;
324     }
325 
326 
PlayScrollBarGrowAnimation()327     void PlayScrollBarGrowAnimation()
328     {
329         PlayScrollBarAppearAnimation();
330         normalWidth_ = activeWidth_;
331         FlushBarWidth();
332         hoverAnimationType_ = HoverAnimationType::GROW;
333         MarkNeedRender();
334     }
335 
PlayScrollBarShrinkAnimation()336     void PlayScrollBarShrinkAnimation()
337     {
338         normalWidth_ = inactiveWidth_;
339         FlushBarWidth();
340         hoverAnimationType_ = HoverAnimationType::SHRINK;
341         MarkNeedRender();
342     }
343 
PlayScrollBarAdaptAnimation()344     void PlayScrollBarAdaptAnimation()
345     {
346         needAdaptAnimation_ = true;
347         MarkNeedRender();
348     }
349 
GetNeedAdaptAnimation()350     bool GetNeedAdaptAnimation() const
351     {
352         return needAdaptAnimation_;
353     }
354 
MarkNeedRender()355     void MarkNeedRender()
356     {
357         if (markNeedRenderFunc_) {
358             markNeedRenderFunc_();
359         }
360     }
361 
SetMarkNeedRenderFunc(std::function<void ()> && func)362     void SetMarkNeedRenderFunc(std::function<void()>&& func)
363     {
364         markNeedRenderFunc_ = func;
365     }
366 
GetTouchEvent()367     RefPtr<TouchEventImpl> GetTouchEvent()
368     {
369         return touchEvent_;
370     }
371 
GetMouseEvent()372     RefPtr<InputEvent> GetMouseEvent()
373     {
374         return mouseEvent_;
375     }
376 
GetHoverEvent()377     RefPtr<InputEvent> GetHoverEvent() const
378     {
379         return hoverEvent_;
380     }
381 
SetIsUserNormalWidth(bool isUserNormalWidth)382     void SetIsUserNormalWidth(bool isUserNormalWidth)
383     {
384         isUserNormalWidth_ = isUserNormalWidth;
385     }
386 
GetIsUserNormalWidth()387     bool GetIsUserNormalWidth() const
388     {
389         return isUserNormalWidth_;
390     }
391 
SetStartReservedHeight(const Dimension & startReservedHeight)392     void SetStartReservedHeight(const Dimension& startReservedHeight)
393     {
394         startReservedHeight_ = startReservedHeight;
395     }
396 
GetStartReservedHeight()397     const Dimension& GetStartReservedHeight() const
398     {
399         return startReservedHeight_;
400     }
401 
SetEndReservedHeight(const Dimension & endReservedHeight)402     void SetEndReservedHeight(const Dimension& endReservedHeight)
403     {
404         endReservedHeight_ = endReservedHeight;
405     }
406 
GetEndReservedHeight()407     const Dimension& GetEndReservedHeight() const
408     {
409         return endReservedHeight_;
410     }
411 
SetHostBorderRadius(const BorderRadiusProperty & hostBorderRadius)412     void SetHostBorderRadius(const BorderRadiusProperty& hostBorderRadius)
413     {
414         hostBorderRadius_ = hostBorderRadius;
415     }
416 
GetHostBorderRadius()417     const BorderRadiusProperty& GetHostBorderRadius() const
418     {
419         return hostBorderRadius_;
420     }
421 
SetScrollPositionCallback(ScrollPositionCallback && callback)422     void SetScrollPositionCallback(ScrollPositionCallback&& callback)
423     {
424         scrollPositionCallback_ = std::move(callback);
425     }
426 
GetScrollPositionCallback()427     const ScrollPositionCallback& GetScrollPositionCallback() const
428     {
429         return scrollPositionCallback_;
430     }
431 
SetScrollEndCallback(ScrollEndCallback && scrollEndCallback)432     void SetScrollEndCallback(ScrollEndCallback&& scrollEndCallback)
433     {
434         scrollEndCallback_ = std::move(scrollEndCallback);
435     }
436 
GetScrollEndCallback()437     const ScrollEndCallback& GetScrollEndCallback() const
438     {
439         return scrollEndCallback_;
440     }
441 
SetCalePredictSnapOffsetCallback(CalePredictSnapOffsetCallback && calePredictSnapOffsetCallback)442     void SetCalePredictSnapOffsetCallback(CalePredictSnapOffsetCallback&& calePredictSnapOffsetCallback)
443     {
444         calePredictSnapOffsetCallback_ = std::move(calePredictSnapOffsetCallback);
445     }
446 
GetCalePredictSnapOffsetCallback()447     const CalePredictSnapOffsetCallback& GetCalePredictSnapOffsetCallback() const
448     {
449         return calePredictSnapOffsetCallback_;
450     }
451 
SetStartScrollSnapMotionCallback(StartScrollSnapMotionCallback && startScrollSnapMotionCallback)452     void SetStartScrollSnapMotionCallback(StartScrollSnapMotionCallback&& startScrollSnapMotionCallback)
453     {
454         startScrollSnapMotionCallback_ = std::move(startScrollSnapMotionCallback);
455     }
456 
GetStartScrollSnapMotionCallback()457     const StartScrollSnapMotionCallback& GetStartScrollSnapMotionCallback() const
458     {
459         return startScrollSnapMotionCallback_;
460     }
461 
462     void SetGestureEvent();
463     void SetMouseEvent();
464     void SetHoverEvent();
465     void FlushBarWidth();
466     void CalcReservedHeight();
467     void OnCollectTouchTarget(const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl,
468         TouchTestResult& result, const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent);
469     void ScheduleDisappearDelayTask();
470 
SetDragFRCSceneCallback(DragFRCSceneCallback && dragFRCSceneCallback)471     void SetDragFRCSceneCallback(DragFRCSceneCallback&& dragFRCSceneCallback)
472     {
473         dragFRCSceneCallback_ = std::move(dragFRCSceneCallback);
474     }
475 
GetMainOffset(const Offset & offset)476     float GetMainOffset(const Offset& offset) const
477     {
478         return positionMode_ == PositionMode::BOTTOM ? offset.GetX() : offset.GetY();
479     }
480 
SetDragStartPosition(float position)481     void SetDragStartPosition(float position)
482     {
483         dragStartPosition_ = position;
484     }
485 
SetDragEndPosition(float position)486     void SetDragEndPosition(float position)
487     {
488         dragEndPosition_ = position;
489     }
490 
GetDragOffset()491     float GetDragOffset()
492     {
493         return dragEndPosition_ - dragStartPosition_;
494     }
495 
SetReverse(bool reverse)496     void SetReverse(bool reverse)
497     {
498         isReverse_ = reverse;
499     }
500 
IsReverse()501     bool IsReverse()
502     {
503         return isReverse_;
504     }
505 
506 protected:
507     void InitTheme();
508 
509 private:
510     void SetBarRegion(const Offset& offset, const Size& size);
511     void SetRectTrickRegion(const Offset& offset, const Size& size, const Offset& lastOffset, double mainScrollExtent);
512     void SetRoundTrickRegion(const Offset& offset, const Size& size, const Offset& lastOffset, double mainScrollExtent);
513     void UpdateActiveRectSize(double activeSize);
514     void UpdateActiveRectOffset(double activeMainOffset);
515     double NormalizeToPx(const Dimension& dimension) const;
516     void InitPanRecognizer();
517     void HandleDragStart(const GestureEvent& info);
518     void HandleDragUpdate(const GestureEvent& info);
519     void HandleDragEnd(const GestureEvent& info);
520     void ProcessFrictionMotion(double value);
521     void ProcessFrictionMotionStop();
522 
523     DisplayMode displayMode_ = DisplayMode::AUTO;
524     ShapeMode shapeMode_ = ShapeMode::RECT;
525     PositionMode positionMode_ = PositionMode::RIGHT;
526     BorderRadiusProperty hostBorderRadius_;
527     Edge padding_;
528     Color backgroundColor_;
529     Color foregroundColor_;
530     Rect touchRegion_;
531     Rect hoverRegion_;
532     Rect barRect_;
533     Rect activeRect_;
534     Dimension minHeight_;           // this is min static height
535     Dimension minDynamicHeight_;    // this is min dynamic height when on the top or bottom
536     Dimension startReservedHeight_; // this is reservedHeight on the start
537     Dimension endReservedHeight_;   // this is reservedHeight on the end
538     Dimension inactiveWidth_;
539     Dimension activeWidth_;
540     Dimension normalWidth_;
541     Dimension touchWidth_;
542     Dimension hoverWidth_;
543 
544     Dimension position_;
545 
546     double trickStartAngle_ = 0.0;
547     double trickSweepAngle_ = 0.0;
548     double topAngle_ = DEFAULT_TOPANGLE;
549     double bottomAngle_ = DEFAULT_BOTTOMANGLE;
550     double minAngle_ = DEFAULT_MINANGLE;
551     double outBoundary_ = 0.0;
552     double offsetScale_ = 1.0f;
553     double scrollableOffset_ = 0.0;
554     double barRegionSize_ = 0.0;
555     double friction_ = BAR_FRICTION;
556     double frictionPosition_ = 0.0;
557     float dragStartPosition_ = 0.0f;
558     float dragEndPosition_ = 0.0f;
559 
560     bool isScrollable_ = false;
561 
562     bool isPressed_ = false;
563     bool isDriving_ = false; // false: scroll driving; true: bar driving
564     bool isHover_ = false;
565     bool isOutOfBoundary_ = false; // whether bar in the spring state
566     bool positionModeUpdate_ = false;
567     bool normalWidthUpdate_ = false;
568     bool isUserNormalWidth_ = false;
569     bool needAdaptAnimation_ = false;
570     bool isReverse_ = false;
571 
572     Offset paintOffset_;
573     Size viewPortSize_;
574     Offset lastOffset_;
575     double estimatedHeight_ = 0.0;
576     RefPtr<TouchEventImpl> touchEvent_;
577     RefPtr<InputEvent> mouseEvent_;
578     RefPtr<InputEvent> hoverEvent_;
579     RefPtr<PanRecognizer> panRecognizer_;
580     RefPtr<Animator> frictionController_;
581     RefPtr<FrictionMotion> frictionMotion_;
582     std::function<void()> markNeedRenderFunc_;
583     ScrollPositionCallback scrollPositionCallback_;
584     ScrollEndCallback scrollEndCallback_;
585     CalePredictSnapOffsetCallback calePredictSnapOffsetCallback_;
586     StartScrollSnapMotionCallback startScrollSnapMotionCallback_;
587     OpacityAnimationType opacityAnimationType_ = OpacityAnimationType::NONE;
588     HoverAnimationType hoverAnimationType_ = HoverAnimationType::NONE;
589     CancelableCallback<void()> disappearDelayTask_;
590 
591     DragFRCSceneCallback dragFRCSceneCallback_;
592 };
593 
594 } // namespace OHOS::Ace::NG
595 
596 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_INNER_SCROLL_BAR_H
597