1 /* 2 * Copyright (c) 2022 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/components/common/properties/color.h" 26 #include "core/components/common/properties/edge.h" 27 #include "core/components_ng/event/input_event.h" 28 #include "core/components_ng/event/touch_event.h" 29 30 namespace OHOS::Ace::NG { 31 32 constexpr double FACTOR_HALF = 0.5; 33 constexpr double DEFAULT_TOPANGLE = 60.0; 34 constexpr double DEFAULT_BOTTOMANGLE = 120.0; 35 constexpr double DEFAULT_MINANGLE = 10.0; 36 constexpr double STRAIGHT_ANGLE = 180.0; 37 constexpr Color PRESSED_BLEND_COLOR = Color(0x19000000); 38 39 enum class ShapeMode { 40 /* 41 * unspecified, follow theme. 42 */ 43 DEFAULT = 0, 44 /* 45 * rect scrollbar. 46 */ 47 RECT, 48 /* 49 * round scrollbar. 50 */ 51 ROUND, 52 }; 53 54 enum class DisplayMode { 55 /* 56 * do not display scrollbar. 57 */ 58 OFF = 0, 59 /* 60 * display scrollbar on demand. 61 */ 62 AUTO, 63 /* 64 * always display scrollbar. 65 */ 66 ON, 67 }; 68 69 enum class PositionMode { 70 /* 71 * display scrollbar on right. 72 */ 73 RIGHT = 0, 74 /* 75 * display scrollbar on left. 76 */ 77 LEFT, 78 /* 79 * display scrollbar on bottom. 80 */ 81 BOTTOM, 82 }; 83 84 class ScrollBar final : public AceType { 85 DECLARE_ACE_TYPE(ScrollBar, AceType); 86 87 public: 88 ScrollBar(); 89 explicit ScrollBar(DisplayMode displayMode, ShapeMode shapeMode = ShapeMode::RECT, 90 PositionMode positionMode = PositionMode::RIGHT); 91 ~ScrollBar() override = default; 92 93 bool InBarTouchRegion(const Point& point) const; 94 bool InBarActiveRegion(const Point& point) const; 95 bool NeedScrollBar() const; 96 bool NeedPaint() const; 97 void UpdateScrollBarRegion( 98 const Offset& offset, const Size& size, const Offset& lastOffset, double estimatedHeight); 99 double GetNormalWidthToPx() const; 100 float CalcPatternOffset(float scrollBarOffset) const; 101 GetShapeMode()102 ShapeMode GetShapeMode() const 103 { 104 return shapeMode_; 105 } 106 GetDisplayMode()107 DisplayMode GetDisplayMode() const 108 { 109 return displayMode_; 110 } 111 GetPositionMode()112 PositionMode GetPositionMode() const 113 { 114 return positionMode_; 115 } 116 SetPadding(const Edge & padding)117 void SetPadding(const Edge& padding) 118 { 119 padding_ = padding; 120 } 121 GetPadding()122 const Edge& GetPadding() const 123 { 124 return padding_; 125 } 126 SetBackgroundColor(const Color & backgroundColor)127 void SetBackgroundColor(const Color& backgroundColor) 128 { 129 backgroundColor_ = backgroundColor; 130 } 131 GetBackgroundColor()132 const Color& GetBackgroundColor() const 133 { 134 return backgroundColor_; 135 } 136 SetForegroundColor(const Color & foregroundColor)137 void SetForegroundColor(const Color& foregroundColor) 138 { 139 foregroundColor_ = foregroundColor; 140 } 141 GetForegroundColor()142 Color GetForegroundColor() const 143 { 144 return IsPressed() ? foregroundColor_.BlendColor(PRESSED_BLEND_COLOR) : foregroundColor_; 145 } 146 GetTopAngle()147 double GetTopAngle() const 148 { 149 return topAngle_; 150 } 151 GetBottomAngle()152 double GetBottomAngle() const 153 { 154 return bottomAngle_; 155 } 156 GetTrickStartAngle()157 double GetTrickStartAngle() const 158 { 159 return trickStartAngle_; 160 } 161 GetTrickSweepAngle()162 double GetTrickSweepAngle() const 163 { 164 return trickSweepAngle_; 165 } 166 SetMinHeight(const Dimension & minHeight)167 void SetMinHeight(const Dimension& minHeight) 168 { 169 minHeight_ = minHeight; 170 } 171 GetMinHeight()172 const Dimension& GetMinHeight() const 173 { 174 return minHeight_; 175 } 176 SetMinDynamicHeight(const Dimension & minDynamicHeight)177 void SetMinDynamicHeight(const Dimension& minDynamicHeight) 178 { 179 minDynamicHeight_ = minDynamicHeight; 180 } 181 GetMinDynamicHeight()182 const Dimension& GetMinDynamicHeight() const 183 { 184 return minDynamicHeight_; 185 } 186 SetReservedHeight(const Dimension & height)187 void SetReservedHeight(const Dimension& height) 188 { 189 reservedHeight_ = height; 190 } 191 GetReservedHeight()192 const Dimension& GetReservedHeight() const 193 { 194 return reservedHeight_; 195 } 196 SetInactiveWidth(const Dimension & inactiveWidth)197 void SetInactiveWidth(const Dimension& inactiveWidth) 198 { 199 inactiveWidth_ = inactiveWidth; 200 } 201 SetActiveWidth(const Dimension & activeWidth)202 void SetActiveWidth(const Dimension& activeWidth) 203 { 204 activeWidth_ = activeWidth; 205 } 206 GetActiveWidth()207 const Dimension& GetActiveWidth() const 208 { 209 return activeWidth_; 210 } 211 SetNormalWidth(const Dimension & normalWidth)212 void SetNormalWidth(const Dimension& normalWidth) 213 { 214 normalWidth_ = normalWidth; 215 } 216 GetActiveRect()217 const Rect& GetActiveRect() const 218 { 219 return activeRect_; 220 } 221 SetTouchWidth(const Dimension & touchWidth)222 void SetTouchWidth(const Dimension& touchWidth) 223 { 224 touchWidth_ = touchWidth; 225 } 226 GetTouchWidth()227 const Dimension& GetTouchWidth() const 228 { 229 return touchWidth_; 230 } 231 GetBarRect()232 const Rect& GetBarRect() const 233 { 234 return barRect_; 235 } 236 SetScrollable(bool isScrollable)237 void SetScrollable(bool isScrollable) 238 { 239 isScrollable_ = isScrollable; 240 } 241 IsScrollable()242 bool IsScrollable() const 243 { 244 return isScrollable_; 245 } 246 SetPositionMode(PositionMode positionMode)247 void SetPositionMode(PositionMode positionMode) 248 { 249 if (positionMode_ != positionMode) { 250 positionModeUpdate_ = true; 251 positionMode_ = positionMode; 252 } 253 } 254 SetShapeMode(ShapeMode shapeMode)255 void SetShapeMode(ShapeMode shapeMode) 256 { 257 shapeMode_ = shapeMode; 258 } 259 SetDisplayMode(DisplayMode displayMode)260 void SetDisplayMode(DisplayMode displayMode) 261 { 262 displayMode_ = displayMode; 263 if (displayMode_ == DisplayMode::AUTO) { 264 PlayBarEndAnimation(); 265 } 266 } 267 SetOutBoundary(double outBoundary)268 void SetOutBoundary(double outBoundary) 269 { 270 inSpring = !NearEqual(outBoundary_, outBoundary, 0.000001f); 271 outBoundary_ = outBoundary; 272 } 273 SetPosition(const Dimension & position)274 void SetPosition(const Dimension& position) 275 { 276 position_ = position; 277 } 278 GetPosition()279 const Dimension& GetPosition() const 280 { 281 return position_; 282 } 283 SetPressed(bool press)284 void SetPressed(bool press) 285 { 286 isPressed_ = press; 287 } 288 IsPressed()289 bool IsPressed() const 290 { 291 return isPressed_; 292 } 293 SetHover(bool hover)294 void SetHover(bool hover) 295 { 296 isHover_ = hover; 297 } 298 IsHover()299 bool IsHover() const 300 { 301 return isHover_; 302 } 303 SetDriving(bool isDriving)304 void SetDriving(bool isDriving) 305 { 306 isDriving_ = isDriving; 307 } 308 IsDriving()309 bool IsDriving() const 310 { 311 return isDriving_; 312 } 313 GetOpacity()314 uint8_t GetOpacity() const 315 { 316 return opacity_; 317 } 318 OnScrollEnd()319 void OnScrollEnd() 320 { 321 if (displayMode_ == DisplayMode::AUTO) { 322 PlayBarEndAnimation(); 323 } 324 } 325 MarkNeedRender()326 void MarkNeedRender() 327 { 328 if (markNeedRenderFunc_) { 329 markNeedRenderFunc_(); 330 } 331 } 332 SetMarkNeedRenderFunc(std::function<void ()> && func)333 void SetMarkNeedRenderFunc(std::function<void()>&& func) 334 { 335 markNeedRenderFunc_ = func; 336 } 337 GetTouchEvent()338 RefPtr<TouchEventImpl> GetTouchEvent() 339 { 340 return touchEvent_; 341 } 342 GetMouseEvent()343 RefPtr<InputEvent> GetMouseEvent() 344 { 345 return mouseEvent_; 346 } 347 348 void SetGestureEvent(); 349 void SetMouseEvent(); 350 void FlushBarWidth(); 351 void PlayAdaptAnimation(double activeSize, double activeMainOffset, double inactiveSize, double inactiveMainOffset); 352 void PlayGrowAnimation(); 353 void PlayShrinkAnimation(); 354 void PlayBarEndAnimation(); 355 356 protected: 357 void InitTheme(); 358 359 private: 360 void SetBarRegion(const Offset& offset, const Size& size); 361 void SetRectTrickRegion(const Offset& offset, const Size& size, const Offset& lastOffset, double mainScrollExtent); 362 void SetRoundTrickRegion(const Offset& offset, const Size& size, const Offset& lastOffset, double mainScrollExtent); 363 void UpdateActiveRectSize(double activeSize); 364 void UpdateActiveRectOffset(double activeMainOffset); 365 double NormalizeToPx(const Dimension& dimension) const; 366 367 DisplayMode displayMode_ = DisplayMode::AUTO; 368 ShapeMode shapeMode_ = ShapeMode::RECT; 369 PositionMode positionMode_ = PositionMode::RIGHT; 370 Edge padding_; 371 Color backgroundColor_; 372 Color foregroundColor_; 373 Rect touchRegion_; 374 Rect barRect_; 375 Rect activeRect_; 376 Dimension minHeight_; // this is min static height 377 Dimension minDynamicHeight_; // this is min dynamic height when on the top or bottom 378 Dimension reservedHeight_; // this is reservedHeight on the bottom 379 Dimension inactiveWidth_; 380 Dimension activeWidth_; 381 Dimension normalWidth_; 382 Dimension touchWidth_; 383 384 Dimension position_; 385 386 double trickStartAngle_ = 0.0; 387 double trickSweepAngle_ = 0.0; 388 double topAngle_ = DEFAULT_TOPANGLE; 389 double bottomAngle_ = DEFAULT_BOTTOMANGLE; 390 double minAngle_ = DEFAULT_MINANGLE; 391 double outBoundary_ = 0.0; 392 double offsetScale_ = 1.0f; 393 double scrollableOffset_ = 0.0; 394 double barRegionSize_ = 0.0; 395 396 bool isScrollable_ = false; 397 398 bool isPressed_ = false; 399 bool isDriving_ = false; // false: scroll driving; true: bar driving 400 bool isHover_ = false; 401 bool inSpring = false; // whether bar in the spring state 402 bool positionModeUpdate_ = false; 403 404 Offset paintOffset_; 405 Size viewPortSize_; 406 Offset lastOffset_; 407 double estimatedHeight_ = 0.0; 408 uint8_t opacity_ = UINT8_MAX; 409 RefPtr<TouchEventImpl> touchEvent_; 410 RefPtr<InputEvent> mouseEvent_; 411 RefPtr<Animator> touchAnimator_; 412 RefPtr<Animator> scrollEndAnimator_; 413 RefPtr<Animator> adaptAnimator_; 414 std::function<void()> markNeedRenderFunc_; 415 }; 416 417 } // namespace OHOS::Ace::NG 418 419 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_INNER_SCROLL_BAR_H 420