1 /* 2 * Copyright (c) 2021-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_SCROLL_RENDER_SCROLL_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SCROLL_RENDER_SCROLL_H 18 19 #include <utility> 20 21 #include "base/geometry/axis.h" 22 #include "base/memory/ace_type.h" 23 #include "core/animation/curve.h" 24 #include "core/components/common/properties/scroll_bar.h" 25 #include "core/components/refresh/render_refresh_target.h" 26 #include "core/components/scroll/scroll_bar_controller.h" 27 #include "core/components/scroll/scroll_component.h" 28 #include "core/components/scroll/scroll_edge_effect.h" 29 #include "core/components/scroll/scroll_position_controller.h" 30 #include "core/gestures/raw_recognizer.h" 31 #include "core/pipeline/base/render_node.h" 32 #include "core/components/common/layout/constants.h" 33 34 namespace OHOS::Ace { 35 36 enum class ScrollType { 37 SCROLL_INDEX = 0, 38 SCROLL_PAGE_DOWN, 39 SCROLL_PAGE_UP, 40 SCROLL_BOTTOM, 41 SCROLL_TOP, 42 }; 43 44 class RenderScroll : public RenderNode, public RenderRefreshTarget { 45 DECLARE_ACE_TYPE(RenderScroll, RenderNode, RenderRefreshTarget) 46 47 public: 48 ~RenderScroll() override; 49 50 static double CalculateFriction(double gamma); 51 static double CalculateOffsetByFriction(double extentOffset, double delta, double friction); 52 53 virtual void JumpToIndex(int32_t index); 54 virtual void ScrollToEdge(ScrollEdgeType scrollEdgeType, bool smooth); 55 virtual bool ScrollPage(bool reverse, bool smooth, const std::function<void()>& onFinish = nullptr); 56 virtual void JumpToPosition(double position, int32_t source = SCROLL_FROM_JUMP); 57 // notify start position in global main axis NotifyDragStart(double startPosition)58 virtual void NotifyDragStart(double startPosition) {} 59 // notify drag offset in global main axis NotifyDragUpdate(double dragOffset,int32_t source)60 virtual void NotifyDragUpdate(double dragOffset, int32_t source) {} ProcessScrollOverCallback(double velocity)61 virtual void ProcessScrollOverCallback(double velocity) {} 62 void AnimateTo(double position, float duration, const RefPtr<Curve>& curve, bool limitDuration = true, 63 const std::function<void()>& onFinish = nullptr); 64 bool AnimateToTarget(const ComposeId& targetId, float duration, const RefPtr<Curve>& curve, 65 bool limitDuration = true, const std::function<void()>& onFinish = nullptr); 66 void ScrollBy(double pixelX, double pixelY, bool smooth, const std::function<void()>& onFinish = nullptr); 67 68 double GetCurrentPosition() const; 69 bool UpdateOffset(Offset& delta, int32_t source); 70 bool ScrollPageByChild(Offset& delta, int32_t source) override; 71 double GetEstimatedHeight(); 72 void OnChildAdded(const RefPtr<RenderNode>& child) override; 73 74 void UpdateTouchRect() override; 75 GetFixPositionOnWatch(double destination,double current)76 virtual double GetFixPositionOnWatch(double destination, double current) 77 { 78 return destination; 79 } 80 IsAtTop()81 bool IsAtTop() const 82 { 83 return LessOrEqual(GetMainOffset(currentOffset_), 0.0); 84 } 85 IsAtBottom()86 bool IsAtBottom() const 87 { 88 auto outViewportSize = mainScrollExtent_ - GetMainSize(viewPort_); 89 bool atBottom = GreatOrEqual(GetMainOffset(currentOffset_), outViewportSize); 90 return LessOrEqual(outViewportSize, 0.0) || (atBottom && ReachMaxCount()); 91 } 92 IsScrollStop()93 bool IsScrollStop() const 94 { 95 return (scrollable_ ? scrollable_->IsMotionStop() : true) && (animator_ ? (!animator_->IsRunning()) : true); 96 } 97 IsDragging()98 bool IsDragging() const 99 { 100 return scrollable_ && scrollable_->IsDragging(); 101 } 102 103 bool CanScrollVertically(const Offset& delta); 104 bool ScrollPageCheck(Offset& delta, int32_t source); 105 GetMainOffset(const Offset & offset)106 double GetMainOffset(const Offset& offset) const 107 { 108 return axis_ == Axis::HORIZONTAL ? offset.GetX() : offset.GetY(); 109 } 110 GetMainSize(const Size & size)111 double GetMainSize(const Size& size) const 112 { 113 return axis_ == Axis::HORIZONTAL ? size.Width() : size.Height(); 114 } 115 GetViewPort()116 Size GetViewPort() const 117 { 118 return viewPort_; 119 } 120 GetCrossSize(const Size & size)121 double GetCrossSize(const Size& size) const 122 { 123 return axis_ == Axis::HORIZONTAL ? size.Height() : size.Width(); 124 } 125 GetAxis()126 Axis GetAxis() const 127 { 128 return axis_; 129 } 130 SetDirection(FlexDirection direction)131 void SetDirection(FlexDirection direction) 132 { 133 direction_ = direction; 134 } 135 GetDirection()136 FlexDirection GetDirection() const 137 { 138 return direction_; 139 } 140 IsRowReverse()141 bool IsRowReverse() const 142 { 143 return (axis_ == Axis::HORIZONTAL && rightToLeft_) || direction_ == FlexDirection::ROW_REVERSE; 144 } 145 IsColReverse()146 bool IsColReverse() const 147 { 148 return direction_ == FlexDirection::COLUMN_REVERSE; 149 } 150 ReachMaxCount()151 virtual bool ReachMaxCount() const 152 { 153 return true; 154 } 155 GetMainScrollExtent()156 virtual double GetMainScrollExtent() const 157 { 158 return mainScrollExtent_; 159 } 160 SetScrollPage(bool scrollPage)161 void SetScrollPage(bool scrollPage) 162 { 163 scrollPage_ = scrollPage; 164 } 165 GetBarDisappearFlag()166 int32_t GetBarDisappearFlag() const 167 { 168 return scrollBarOpacity_; 169 } 170 GetCurrentOffset()171 Offset GetCurrentOffset() const 172 { 173 return currentOffset_; 174 } 175 GetLastOffset()176 const Offset& GetLastOffset() const 177 { 178 return lastOffset_; 179 } 180 SetNeedMove(bool needMove)181 void SetNeedMove(bool needMove) 182 { 183 moveStatus_.second = moveStatus_.first; 184 moveStatus_.first = needMove; 185 } 186 187 virtual void HandleRotate(double rotateValue, bool isVertical); 188 189 void HandleScrollOverByBar(double velocity); 190 SetMainScrollExtentForBar(double value)191 void SetMainScrollExtentForBar(double value) 192 { 193 scrollBarExtent_ = value; 194 } 195 GetScrollBar()196 RefPtr<ScrollBar> GetScrollBar() const 197 { 198 return scrollBar_; 199 } 200 GetScrollBarOutBoundaryExtent()201 double GetScrollBarOutBoundaryExtent() const 202 { 203 return scrollBarOutBoundaryExtent_; 204 } 205 IsSpringMotionRunning()206 bool IsSpringMotionRunning() const 207 { 208 return scrollable_ ? scrollable_->IsSpringMotionRunning() : false; 209 } 210 211 virtual bool IsOutOfBottomBoundary(); 212 213 virtual bool IsOutOfTopBoundary(); 214 215 virtual bool HandleCrashTop(); 216 virtual bool HandleCrashBottom(); 217 SetIsFromRotate(bool isRotate)218 void SetIsFromRotate(bool isRotate) 219 { 220 isFromRotate_ = isRotate; 221 } 222 IsFromRotate()223 bool IsFromRotate() 224 { 225 return isFromRotate_; 226 } 227 228 void HandleAxisEvent(const AxisEvent& event) override; 229 230 bool IsAxisScrollable(AxisDirection direction) override; 231 232 void HandleMouseHoverEvent(const MouseState mouseState) override; 233 bool HandleMouseEvent(const MouseEvent& event) override; 234 235 // distribute 236 std::string ProvideRestoreInfo() override; 237 SetHasWidth(const bool & hasWidth)238 void SetHasWidth(const bool& hasWidth) 239 { 240 hasWidth_ = hasWidth; 241 } 242 GetHasWidth()243 const bool& GetHasWidth() const 244 { 245 return hasWidth_; 246 } 247 SetHasHeight(const bool & hasHeight)248 void SetHasHeight(const bool& hasHeight) 249 { 250 hasHeight_ = hasHeight; 251 } 252 GetHasHeight()253 const bool& GetHasHeight() const 254 { 255 return hasHeight_; 256 } 257 258 protected: 259 explicit RenderScroll(); 260 261 void ResetEdgeEffect(); 262 void ResetScrollable(); 263 bool ValidateOffset(int32_t source); 264 void DoJump(double position, int32_t source = SCROLL_FROM_JUMP); 265 void Update(const RefPtr<Component>& component) override; 266 void InitScrollBar(const RefPtr<ScrollBar>& scrollBar); 267 void InitScrollBarProxy(); 268 AdjustTouchRestrict(TouchRestrict & touchRestrict)269 virtual void AdjustTouchRestrict(TouchRestrict& touchRestrict) {} 270 271 Edge padding_; 272 Axis axis_ = Axis::FREE; 273 std::pair<bool, bool> moveStatus_; 274 Offset currentBottomOffset_; 275 Offset currentOffset_; 276 double currentDeltaInMain_ = 0.0; 277 Offset correctedDelta_; 278 Offset lastOffset_; 279 double overScroll_ = 0.0; 280 double mainScrollExtent_ = 0.0; 281 double outBoundaryExtent_ = 0.0; 282 double estimatedHeight_ = 0.0; 283 double moveDistance_ = 0.0; 284 bool scrollPage_ = false; 285 bool isFromRotate_ = false; 286 RefPtr<ScrollPositionController> positionController_; 287 RefPtr<ScrollEdgeEffect> scrollEffect_; 288 RefPtr<Scrollable> scrollable_; 289 290 RefPtr<ScrollBar> scrollBar_; 291 bool inLinkRefresh_ = false; 292 WeakPtr<RenderRefresh> refreshParent_; 293 bool rightToLeft_ = false; 294 bool enable_ = true; 295 bool isRoot_ = false; 296 297 // used for scrollBar 298 double scrollBarExtent_ = 0.0; 299 double scrollBarOutBoundaryExtent_ = 0.0; 300 bool scrollBarExtentFlag_ = false; 301 int32_t scrollBarOpacity_ = 0; 302 303 double friction_ = 0.0; 304 RefPtr<SpringProperty> springProperty_; 305 RefPtr<ScrollBarProxy> scrollBarProxy_; 306 ScrollBeginCallback onScrollBegin_; 307 308 private: 309 bool IsOutOfBoundary(); 310 bool IsCrashBottom(); 311 bool IsCrashTop(); 312 void Initialize(); 313 void AdjustOffset(Offset& delta, int32_t source); 314 void OnTouchTestHit( 315 const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result) override; 316 void HandleScrollPosition(double scrollX, double scrollY, int32_t scrollState) const; 317 void SetEdgeEffectAttribute(); 318 void ResetScrollEventCallBack(); 319 void HandleScrollEffect(); 320 void SetBarCallBack(bool isVertical); 321 void HandleScrollBarEnd(); 322 void HandleScrollBarOutBoundary(); 323 void OnReachStart() const; 324 void OnReachEnd() const; 325 void OnReachTop() const; 326 void OnReachBottom() const; 327 328 // distribute 329 void ApplyRestoreInfo(); 330 331 FlexDirection direction_ { FlexDirection::COLUMN }; 332 using OnReachFunc = std::function<void(const std::string&)>; 333 OnReachFunc onReachStart_; 334 OnReachFunc onReachEnd_; 335 OnReachFunc onReachTop_; 336 OnReachFunc onReachBottom_; 337 338 RefPtr<Animator> animator_; 339 RefPtr<RawRecognizer> touchRecognizer_; 340 341 bool hasWidth_ = false; 342 bool hasHeight_ = false; 343 }; 344 345 } // namespace OHOS::Ace 346 347 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SCROLL_RENDER_SCROLL_H 348