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_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 39 namespace OHOS::Ace::NG { 40 41 constexpr double FACTOR_HALF = 0.5; 42 constexpr double DEFAULT_TOPANGLE = 60.0; 43 constexpr double DEFAULT_BOTTOMANGLE = 120.0; 44 constexpr double DEFAULT_MINANGLE = 10.0; 45 constexpr double STRAIGHT_ANGLE = 180.0; 46 constexpr double BAR_FRICTION = 0.9; 47 constexpr Color PRESSED_BLEND_COLOR = Color(0x19000000); 48 using DragFRCSceneCallback = std::function<void(double velocity, NG::SceneStatus sceneStatus)>; 49 50 enum class BarDirection { 51 BAR_NONE = 0, 52 PAGE_UP, 53 PAGE_DOWN, 54 }; 55 56 class ScrollBar final : public AceType { 57 DECLARE_ACE_TYPE(ScrollBar, AceType); 58 59 public: 60 ScrollBar(); 61 ScrollBar(DisplayMode displayMode, ShapeMode shapeMode = ShapeMode::RECT, 62 PositionMode positionMode = PositionMode::RIGHT); 63 ~ScrollBar() override = default; 64 GetShapeMode()65 ShapeMode GetShapeMode() const 66 { 67 return shapeMode_; 68 } GetDisplayMode()69 DisplayMode GetDisplayMode() const 70 { 71 return displayMode_; 72 } GetPositionMode()73 PositionMode GetPositionMode() const 74 { 75 return positionMode_; 76 } SetPadding(const Edge & padding)77 void SetPadding(const Edge& padding) 78 { 79 padding_ = padding; 80 } GetPadding()81 const Edge& GetPadding() const 82 { 83 return padding_; 84 } SetBackgroundColor(const Color & backgroundColor)85 void SetBackgroundColor(const Color& backgroundColor) 86 { 87 backgroundColor_ = backgroundColor; 88 } GetBackgroundColor()89 const Color& GetBackgroundColor() const 90 { 91 return backgroundColor_; 92 } SetForegroundColor(const Color & foregroundColor)93 void SetForegroundColor(const Color& foregroundColor) 94 { 95 foregroundColor_ = foregroundColor; 96 } GetTopAngle()97 double GetTopAngle() const 98 { 99 return topAngle_; 100 } GetBottomAngle()101 double GetBottomAngle() const 102 { 103 return bottomAngle_; 104 } GetTrickStartAngle()105 double GetTrickStartAngle() const 106 { 107 return trickStartAngle_; 108 } GetTrickSweepAngle()109 double GetTrickSweepAngle() const 110 { 111 return trickSweepAngle_; 112 } SetMinHeight(const Dimension & minHeight)113 void SetMinHeight(const Dimension& minHeight) 114 { 115 minHeight_ = minHeight; 116 } GetMinHeight()117 const Dimension& GetMinHeight() const 118 { 119 return minHeight_; 120 } SetMinDynamicHeight(const Dimension & minDynamicHeight)121 void SetMinDynamicHeight(const Dimension& minDynamicHeight) 122 { 123 minDynamicHeight_ = minDynamicHeight; 124 } GetMinDynamicHeight()125 const Dimension& GetMinDynamicHeight() const 126 { 127 return minDynamicHeight_; 128 } SetInactiveWidth(const Dimension & inactiveWidth)129 void SetInactiveWidth(const Dimension& inactiveWidth) 130 { 131 inactiveWidth_ = inactiveWidth; 132 } SetActiveWidth(const Dimension & activeWidth)133 void SetActiveWidth(const Dimension& activeWidth) 134 { 135 activeWidth_ = activeWidth; 136 } GetActiveWidth()137 const Dimension& GetActiveWidth() const 138 { 139 return activeWidth_; 140 } GetActiveRect()141 const Rect& GetActiveRect() const 142 { 143 return activeRect_; 144 } SetTouchWidth(const Dimension & touchWidth)145 void SetTouchWidth(const Dimension& touchWidth) 146 { 147 touchWidth_ = touchWidth; 148 } GetTouchWidth()149 const Dimension& GetTouchWidth() const 150 { 151 return touchWidth_; 152 } GetBarRect()153 const Rect& GetBarRect() const 154 { 155 return barRect_; 156 } IsScrollable()157 bool IsScrollable() const 158 { 159 return isScrollable_; 160 } GetPositionModeUpdate()161 bool GetPositionModeUpdate() const 162 { 163 return positionModeUpdate_; 164 } 165 SetShapeMode(ShapeMode shapeMode)166 void SetShapeMode(ShapeMode shapeMode) 167 { 168 shapeMode_ = shapeMode; 169 } GetOutBoundary()170 double GetOutBoundary() const 171 { 172 return outBoundary_; 173 } SetOutBoundary(double outBoundary)174 void SetOutBoundary(double outBoundary) 175 { 176 outBoundary_ = outBoundary; 177 } SetIsOutOfBoundary(bool isOutOfBoundary)178 void SetIsOutOfBoundary(bool isOutOfBoundary) 179 { 180 isOutOfBoundary_ = isOutOfBoundary; 181 } SetPosition(const Dimension & position)182 void SetPosition(const Dimension& position) 183 { 184 position_ = position; 185 } GetPosition()186 const Dimension& GetPosition() const 187 { 188 return position_; 189 } SetPressed(bool press)190 void SetPressed(bool press) 191 { 192 isPressed_ = press; 193 } IsPressed()194 bool IsPressed() const 195 { 196 return isPressed_; 197 } SetHover(bool hover)198 void SetHover(bool hover) 199 { 200 isHover_ = hover; 201 } IsHover()202 bool IsHover() const 203 { 204 return isHover_; 205 } GetOpacityAnimationType()206 OpacityAnimationType GetOpacityAnimationType() const 207 { 208 return opacityAnimationType_; 209 } SetOpacityAnimationType(OpacityAnimationType opacityAnimationType)210 void SetOpacityAnimationType(OpacityAnimationType opacityAnimationType) 211 { 212 opacityAnimationType_ = opacityAnimationType; 213 } GetHoverAnimationType()214 HoverAnimationType GetHoverAnimationType() const 215 { 216 return hoverAnimationType_; 217 } SetHoverAnimationType(HoverAnimationType hoverAnimationType)218 void SetHoverAnimationType(HoverAnimationType hoverAnimationType) 219 { 220 hoverAnimationType_ = hoverAnimationType; 221 } GetNeedAdaptAnimation()222 bool GetNeedAdaptAnimation() const 223 { 224 return needAdaptAnimation_; 225 } SetMarkNeedRenderFunc(std::function<void ()> && func)226 void SetMarkNeedRenderFunc(std::function<void()>&& func) 227 { 228 markNeedRenderFunc_ = func; 229 } GetTouchEvent()230 RefPtr<TouchEventImpl> GetTouchEvent() 231 { 232 return touchEvent_; 233 } GetMouseEvent()234 RefPtr<InputEvent> GetMouseEvent() 235 { 236 return mouseEvent_; 237 } GetHoverEvent()238 RefPtr<InputEvent> GetHoverEvent() const 239 { 240 return hoverEvent_; 241 } SetIsUserNormalWidth(bool isUserNormalWidth)242 void SetIsUserNormalWidth(bool isUserNormalWidth) 243 { 244 isUserNormalWidth_ = isUserNormalWidth; 245 } GetIsUserNormalWidth()246 bool GetIsUserNormalWidth() const 247 { 248 return isUserNormalWidth_; 249 } SetStartReservedHeight(const Dimension & startReservedHeight)250 void SetStartReservedHeight(const Dimension& startReservedHeight) 251 { 252 startReservedHeight_ = startReservedHeight; 253 } GetStartReservedHeight()254 const Dimension& GetStartReservedHeight() const 255 { 256 return startReservedHeight_; 257 } SetEndReservedHeight(const Dimension & endReservedHeight)258 void SetEndReservedHeight(const Dimension& endReservedHeight) 259 { 260 endReservedHeight_ = endReservedHeight; 261 } GetEndReservedHeight()262 const Dimension& GetEndReservedHeight() const 263 { 264 return endReservedHeight_; 265 } SetHostBorderRadius(const BorderRadiusProperty & hostBorderRadius)266 void SetHostBorderRadius(const BorderRadiusProperty& hostBorderRadius) 267 { 268 hostBorderRadius_ = hostBorderRadius; 269 } GetHostBorderRadius()270 const BorderRadiusProperty& GetHostBorderRadius() const 271 { 272 return hostBorderRadius_; 273 } SetScrollPositionCallback(ScrollPositionCallback && callback)274 void SetScrollPositionCallback(ScrollPositionCallback&& callback) 275 { 276 scrollPositionCallback_ = std::move(callback); 277 } GetScrollPositionCallback()278 const ScrollPositionCallback& GetScrollPositionCallback() const 279 { 280 return scrollPositionCallback_; 281 } SetScrollEndCallback(ScrollEndCallback && scrollEndCallback)282 void SetScrollEndCallback(ScrollEndCallback&& scrollEndCallback) 283 { 284 scrollEndCallback_ = std::move(scrollEndCallback); 285 } GetScrollEndCallback()286 const ScrollEndCallback& GetScrollEndCallback() const 287 { 288 return scrollEndCallback_; 289 } SetCalePredictSnapOffsetCallback(CalePredictSnapOffsetCallback && calePredictSnapOffsetCallback)290 void SetCalePredictSnapOffsetCallback(CalePredictSnapOffsetCallback&& calePredictSnapOffsetCallback) 291 { 292 calePredictSnapOffsetCallback_ = std::move(calePredictSnapOffsetCallback); 293 } GetCalePredictSnapOffsetCallback()294 const CalePredictSnapOffsetCallback& GetCalePredictSnapOffsetCallback() const 295 { 296 return calePredictSnapOffsetCallback_; 297 } SetStartScrollSnapMotionCallback(StartScrollSnapMotionCallback && startScrollSnapMotionCallback)298 void SetStartScrollSnapMotionCallback(StartScrollSnapMotionCallback&& startScrollSnapMotionCallback) 299 { 300 startScrollSnapMotionCallback_ = std::move(startScrollSnapMotionCallback); 301 } GetStartScrollSnapMotionCallback()302 const StartScrollSnapMotionCallback& GetStartScrollSnapMotionCallback() const 303 { 304 return startScrollSnapMotionCallback_; 305 } SetDragFRCSceneCallback(DragFRCSceneCallback && dragFRCSceneCallback)306 void SetDragFRCSceneCallback(DragFRCSceneCallback&& dragFRCSceneCallback) 307 { 308 dragFRCSceneCallback_ = std::move(dragFRCSceneCallback); 309 } SetDragStartPosition(float position)310 void SetDragStartPosition(float position) 311 { 312 dragStartPosition_ = position; 313 } SetDragEndPosition(float position)314 void SetDragEndPosition(float position) 315 { 316 dragEndPosition_ = position; 317 } GetDragOffset()318 float GetDragOffset() 319 { 320 return dragEndPosition_ - dragStartPosition_; 321 } IsReverse()322 bool IsReverse() 323 { 324 return isReverse_; 325 } 326 327 Axis GetPanDirection() const; 328 GetTouchRegion()329 Rect GetTouchRegion() const 330 { 331 return touchRegion_; 332 } 333 BarDirection CheckBarDirection(const Point& point); GetClickEvent()334 RefPtr<ClickEvent> GetClickEvent() 335 { 336 return clickevent_; 337 } SetAxis(Axis axis)338 void SetAxis(Axis axis) 339 { 340 axis_ = axis; 341 } 342 343 void OnCollectTouchTarget(const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl, 344 TouchTestResult& result, const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent, 345 ResponseLinkResult& responseLinkResult); 346 bool InBarTouchRegion(const Point& point) const; 347 bool InBarHoverRegion(const Point& point) const; 348 bool InBarRectRegion(const Point& point) const; 349 bool NeedScrollBar() const; 350 bool NeedPaint() const; 351 void UpdateScrollBarRegion( 352 const Offset& offset, const Size& size, const Offset& lastOffset, double estimatedHeight); 353 double GetNormalWidthToPx() const; 354 float CalcPatternOffset(float scrollBarOffset) const; 355 Color GetForegroundColor() const; 356 void SetHoverWidth(const RefPtr<ScrollBarTheme>& theme); 357 void SetNormalWidth(const Dimension& normalWidth); 358 void SetScrollable(bool isScrollable); 359 void SetPositionMode(PositionMode positionMode); 360 void SetDisplayMode(DisplayMode displayMode); 361 void PlayScrollBarDisappearAnimation(); 362 void PlayScrollBarAppearAnimation(); 363 void PlayScrollBarGrowAnimation(); 364 void PlayScrollBarShrinkAnimation(); 365 void PlayScrollBarAdaptAnimation(); 366 void MarkNeedRender(); 367 void SetGestureEvent(); 368 void SetMouseEvent(); 369 void SetHoverEvent(); 370 void FlushBarWidth(); 371 void CalcReservedHeight(); 372 void ScheduleDisappearDelayTask(); 373 float GetMainOffset(const Offset& offset) const; 374 void SetReverse(bool reverse); 375 // infos for dump 376 void AddScrollBarLayoutInfo(); 377 void GetShapeModeDumpInfo(); 378 void GetPositionModeDumpInfo(); 379 void GetAxisDumpInfo(); 380 void GetPanDirectionDumpInfo(); 381 void DumpAdvanceInfo(); 382 void StopFlingAnimation(); SetScrollPageCallback(ScrollPageCallback && scrollPageCallback)383 void SetScrollPageCallback(ScrollPageCallback&& scrollPageCallback) 384 { 385 scrollPageCallback_ = std::move(scrollPageCallback); 386 } 387 void OnCollectLongPressTarget(const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl, 388 TouchTestResult& result, const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent, 389 ResponseLinkResult& responseLinkResult); 390 void InitLongPressEvent(); 391 void HandleLongPress(bool smooth); 392 bool AnalysisUpOrDown(Point point, bool& reverse); 393 void ScheduleCaretLongPress(); 394 395 protected: 396 void InitTheme(); 397 398 private: 399 void SetBarRegion(const Offset& offset, const Size& size); 400 void SetRectTrickRegion(const Offset& offset, const Size& size, const Offset& lastOffset, double mainScrollExtent); 401 void SetRoundTrickRegion(const Offset& offset, const Size& size, const Offset& lastOffset, double mainScrollExtent); 402 void UpdateActiveRectSize(double activeSize); 403 void UpdateActiveRectOffset(double activeMainOffset); 404 double NormalizeToPx(const Dimension& dimension) const; 405 void InitPanRecognizer(); 406 void HandleDragStart(const GestureEvent& info); 407 void HandleDragUpdate(const GestureEvent& info); 408 void HandleDragEnd(const GestureEvent& info); 409 void ProcessFrictionMotion(double value); 410 void ProcessFrictionMotionStop(); 411 412 DisplayMode displayMode_ = DisplayMode::AUTO; 413 ShapeMode shapeMode_ = ShapeMode::RECT; 414 PositionMode positionMode_ = PositionMode::RIGHT; 415 BorderRadiusProperty hostBorderRadius_; 416 Edge padding_; 417 Color backgroundColor_; 418 Color foregroundColor_; 419 Rect touchRegion_; 420 Rect hoverRegion_; 421 Rect barRect_; 422 Rect activeRect_; 423 Dimension minHeight_; // this is min static height 424 Dimension minDynamicHeight_; // this is min dynamic height when on the top or bottom 425 Dimension startReservedHeight_; // this is reservedHeight on the start 426 Dimension endReservedHeight_; // this is reservedHeight on the end 427 Dimension inactiveWidth_; 428 Dimension activeWidth_; 429 double barWidth_ = 0.0; // actual width of the scrollbar 430 Dimension normalWidth_; // user-set width of the scrollbar 431 Dimension themeNormalWidth_; 432 Dimension touchWidth_; 433 Dimension hoverWidth_; 434 435 Dimension position_; 436 437 double trickStartAngle_ = 0.0; 438 double trickSweepAngle_ = 0.0; 439 double topAngle_ = DEFAULT_TOPANGLE; 440 double bottomAngle_ = DEFAULT_BOTTOMANGLE; 441 double minAngle_ = DEFAULT_MINANGLE; 442 double outBoundary_ = 0.0; 443 double offsetScale_ = 1.0f; 444 double scrollableOffset_ = 0.0; 445 double barRegionSize_ = 0.0; 446 double friction_ = BAR_FRICTION; 447 double frictionPosition_ = 0.0; 448 float dragStartPosition_ = 0.0f; 449 float dragEndPosition_ = 0.0f; 450 451 bool isScrollable_ = false; 452 453 bool isPressed_ = false; 454 bool isDriving_ = false; // false: scroll driving; true: bar driving 455 bool isHover_ = false; 456 bool isOutOfBoundary_ = false; // whether bar in the spring state 457 bool positionModeUpdate_ = false; 458 bool normalWidthUpdate_ = false; 459 bool isUserNormalWidth_ = false; 460 bool needAdaptAnimation_ = false; 461 bool isReverse_ = false; 462 bool isReverseUpdate_ = false; 463 464 Offset paintOffset_; 465 Size viewPortSize_; 466 Offset lastOffset_; 467 double estimatedHeight_ = 0.0; 468 RefPtr<TouchEventImpl> touchEvent_; 469 RefPtr<InputEvent> mouseEvent_; 470 RefPtr<InputEvent> hoverEvent_; 471 RefPtr<PanRecognizer> panRecognizer_; 472 RefPtr<Animator> frictionController_; 473 RefPtr<FrictionMotion> frictionMotion_; 474 std::function<void()> markNeedRenderFunc_; 475 ScrollPositionCallback scrollPositionCallback_; 476 ScrollEndCallback scrollEndCallback_; 477 CalePredictSnapOffsetCallback calePredictSnapOffsetCallback_; 478 StartScrollSnapMotionCallback startScrollSnapMotionCallback_; 479 ScrollPageCallback scrollPageCallback_; 480 OpacityAnimationType opacityAnimationType_ = OpacityAnimationType::NONE; 481 HoverAnimationType hoverAnimationType_ = HoverAnimationType::NONE; 482 CancelableCallback<void()> disappearDelayTask_; 483 Axis axis_ = Axis::VERTICAL; 484 485 DragFRCSceneCallback dragFRCSceneCallback_; 486 487 // dump info 488 std::list<InnerScrollBarLayoutInfo> innerScrollBarLayoutInfos_; 489 bool needAddLayoutInfo = false; 490 491 RefPtr<ClickEvent> clickevent_; 492 RefPtr<LongPressRecognizer> longPressRecognizer_; 493 bool isMousePressed_ = false; 494 Offset locationInfo_; 495 }; 496 497 } // namespace OHOS::Ace::NG 498 499 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_INNER_SCROLL_BAR_H 500