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