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_SCROLLABEL_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SCROLL_SCROLLABEL_H 18 19 #include <functional> 20 21 #include "core/animation/animator.h" 22 #include "core/animation/friction_motion.h" 23 #include "core/animation/scroll_motion.h" 24 #include "core/event/touch_event.h" 25 #include "core/gestures/drag_recognizer.h" 26 #include "core/gestures/raw_recognizer.h" 27 #include "core/gestures/timeout_recognizer.h" 28 #include "core/pipeline/base/related_node.h" 29 #include "core/pipeline/base/render_node.h" 30 31 namespace OHOS::Ace { 32 33 constexpr int32_t SCROLL_FROM_NONE = 0; 34 constexpr int32_t SCROLL_FROM_UPDATE = 1; 35 constexpr int32_t SCROLL_FROM_ANIMATION = 2; 36 constexpr int32_t SCROLL_FROM_JUMP = 3; 37 constexpr int32_t SCROLL_FROM_ANIMATION_SPRING = 4; 38 constexpr int32_t SCROLL_FROM_CHILD = 5; 39 constexpr int32_t SCROLL_FROM_BAR = 6; 40 constexpr int32_t SCROLL_FROM_FOCUS_JUMP = 7; 41 constexpr int32_t SCROLL_FROM_ROTATE = 8; 42 constexpr int32_t SCROLL_FROM_INDEXER = 9; 43 constexpr int32_t SCROLL_FROM_START = 10; // from drag start 44 45 using ScrollPositionCallback = std::function<bool(double, int32_t source)>; 46 using ScrollEventCallback = std::function<void()>; 47 using OutBoundaryCallback = std::function<bool()>; 48 using ScrollOverCallback = std::function<void(double velocity)>; 49 using DragEndForRefreshCallback = std::function<void()>; 50 using DragCancelRefreshCallback = std::function<void()>; 51 using WatchFixCallback = std::function<double(double final, double current)>; 52 53 class Scrollable : public TouchEventTarget, public RelatedChild { 54 DECLARE_ACE_TYPE(Scrollable, TouchEventTarget); 55 56 public: 57 Scrollable() = default; Scrollable(ScrollPositionCallback && callback,Axis axis)58 Scrollable(ScrollPositionCallback&& callback, Axis axis) : callback_(std::move(callback)), axis_(axis) {} 59 ~Scrollable() override; 60 61 static void SetVelocityScale(double sVelocityScale); 62 static void SetFriction(double sFriction); 63 64 void Initialize(const WeakPtr<PipelineContext>& context); 65 IsMotionStop()66 bool IsMotionStop() const 67 { 68 return (springController_ ? (!springController_->IsRunning()) : true) && 69 (controller_ ? (!controller_->IsRunning()) : true) && !moved_; 70 } 71 IsSpringMotionRunning()72 bool IsSpringMotionRunning() const 73 { 74 return springController_ ? springController_->IsRunning() : false; 75 } 76 SetAxis(Axis axis)77 void SetAxis(Axis axis) 78 { 79 axis_ = axis; 80 } 81 SetScrollableNode(const WeakPtr<RenderNode> & node)82 void SetScrollableNode(const WeakPtr<RenderNode>& node) 83 { 84 scrollableNode_ = node; 85 } 86 GetMainOffset(const Offset & offset)87 double GetMainOffset(const Offset& offset) const 88 { 89 return axis_ == Axis::HORIZONTAL ? offset.GetX() : offset.GetY(); 90 } 91 GetMainSize(const Size & size)92 double GetMainSize(const Size& size) const 93 { 94 return axis_ == Axis::HORIZONTAL ? size.Width() : size.Height(); 95 } 96 SetCallback(const ScrollPositionCallback & callback)97 void SetCallback(const ScrollPositionCallback& callback) 98 { 99 callback_ = callback; 100 } 101 SetCoordinateOffset(const Offset & offset)102 void SetCoordinateOffset(const Offset& offset) const 103 { 104 if (timeoutRecognizer_) { 105 timeoutRecognizer_->SetCoordinateOffset(offset); 106 } else if (dragRecognizer_) { 107 dragRecognizer_->SetCoordinateOffset(offset); 108 } 109 110 if (rawRecognizer_) { 111 rawRecognizer_->SetCoordinateOffset(offset); 112 } 113 } 114 SetDragTouchRestrict(const TouchRestrict & touchRestrict)115 void SetDragTouchRestrict(const TouchRestrict& touchRestrict) 116 { 117 if (dragRecognizer_) { 118 dragRecognizer_->SetTouchRestrict(touchRestrict); 119 } 120 } 121 SetScrollEndCallback(const ScrollEventCallback & scrollEndCallback)122 void SetScrollEndCallback(const ScrollEventCallback& scrollEndCallback) 123 { 124 scrollEndCallback_ = scrollEndCallback; 125 } 126 SetScrollTouchUpCallback(const ScrollEventCallback & scrollTouchUpCallback)127 void SetScrollTouchUpCallback(const ScrollEventCallback& scrollTouchUpCallback) 128 { 129 scrollTouchUpCallback_ = scrollTouchUpCallback; 130 } 131 132 void HandleTouchDown(); 133 void HandleTouchUp(); 134 void HandleDragStart(const DragStartInfo& info); 135 void HandleDragUpdate(const DragUpdateInfo& info); 136 void HandleDragEnd(const DragEndInfo& info); 137 138 void ProcessScrollMotionStop(); 139 DispatchEvent(const TouchEvent & point)140 bool DispatchEvent(const TouchEvent& point) override 141 { 142 return true; 143 } HandleEvent(const TouchEvent & event)144 bool HandleEvent(const TouchEvent& event) override 145 { 146 if (timeoutRecognizer_) { 147 timeoutRecognizer_->HandleEvent(event); 148 } 149 if (rawRecognizer_) { 150 return rawRecognizer_->HandleEvent(event); 151 } 152 return true; 153 } 154 SetScrollEnd(const ScrollEventCallback & scrollEnd)155 void SetScrollEnd(const ScrollEventCallback& scrollEnd) 156 { 157 scrollEnd_ = scrollEnd; 158 } 159 SetScrollOverCallBack(const ScrollOverCallback & scrollOverCallback)160 void SetScrollOverCallBack(const ScrollOverCallback& scrollOverCallback) 161 { 162 scrollOverCallback_ = scrollOverCallback; 163 } 164 SetNotifyScrollOverCallBack(const ScrollOverCallback & scrollOverCallback)165 void SetNotifyScrollOverCallBack(const ScrollOverCallback& scrollOverCallback) 166 { 167 notifyScrollOverCallback_ = scrollOverCallback; 168 } 169 SetOutBoundaryCallback(const OutBoundaryCallback & outBoundaryCallback)170 void SetOutBoundaryCallback(const OutBoundaryCallback& outBoundaryCallback) 171 { 172 outBoundaryCallback_ = outBoundaryCallback; 173 } 174 SetDragEndCallback(const DragEndForRefreshCallback & dragEndCallback)175 void SetDragEndCallback(const DragEndForRefreshCallback& dragEndCallback) 176 { 177 dragEndCallback_ = dragEndCallback; 178 } 179 SetDragCancel(const DragCancelRefreshCallback & dragCancelCallback)180 void SetDragCancel(const DragCancelRefreshCallback& dragCancelCallback) 181 { 182 dragCancelCallback_ = dragCancelCallback; 183 } 184 SetWatchFixCallback(const WatchFixCallback & watchFixCallback)185 void SetWatchFixCallback(const WatchFixCallback& watchFixCallback) 186 { 187 watchFixCallback_ = watchFixCallback; 188 } 189 MarkNeedCenterFix(bool needFix)190 void MarkNeedCenterFix(bool needFix) 191 { 192 needCenterFix_ = needFix; 193 } 194 GetCurrentVelocity()195 double GetCurrentVelocity() const 196 { 197 return currentVelocity_; 198 }; 199 200 void StartSpringMotion( 201 double mainPosition, double mainVelocity, const ExtentPair& extent, const ExtentPair& initExtent); 202 203 bool IsAnimationNotRunning() const; 204 205 bool Idle() const; 206 207 bool IsStopped() const; 208 209 void StopScrollable(); 210 Available()211 bool Available() const 212 { 213 return available_; 214 } 215 MarkAvailable(bool available)216 void MarkAvailable(bool available) 217 { 218 available_ = available; 219 } 220 GetContext()221 WeakPtr<PipelineContext> GetContext() const 222 { 223 return context_; 224 } 225 SetNodeId(int32_t nodeId)226 void SetNodeId(int32_t nodeId) 227 { 228 nodeId_ = nodeId; 229 } 230 231 void ProcessScrollOverCallback(double velocity); 232 233 void SetSlipFactor(double SlipFactor); 234 SetOverSpringProperty(const RefPtr<SpringProperty> & property)235 void SetOverSpringProperty(const RefPtr<SpringProperty>& property) 236 { 237 if (property && property->IsValid()) { 238 spring_ = property; 239 } 240 } 241 ChangeMoveStatus(bool flag)242 void ChangeMoveStatus(bool flag) 243 { 244 moved_ = flag; 245 } 246 247 static const RefPtr<SpringProperty>& GetDefaultOverSpringProperty(); 248 249 private: 250 bool UpdateScrollPosition(double offset, int32_t source) const; 251 void ProcessSpringMotion(double position); 252 void ProcessScrollMotion(double position); 253 void FixScrollMotion(double position); 254 255 ScrollPositionCallback callback_; 256 ScrollEventCallback scrollEnd_; 257 ScrollEventCallback scrollEndCallback_; 258 ScrollEventCallback scrollTouchUpCallback_; 259 ScrollOverCallback scrollOverCallback_; // scroll motion controller when edge set to spring 260 ScrollOverCallback notifyScrollOverCallback_; // scroll motion controller when edge set to spring 261 OutBoundaryCallback outBoundaryCallback_; // whether out of boundary check when edge set to spring 262 DragEndForRefreshCallback dragEndCallback_; 263 DragCancelRefreshCallback dragCancelCallback_; 264 WatchFixCallback watchFixCallback_; 265 Axis axis_; 266 RefPtr<TimeoutRecognizer> timeoutRecognizer_; 267 RefPtr<DragRecognizer> dragRecognizer_; 268 RefPtr<RawRecognizer> rawRecognizer_; 269 RefPtr<Animator> controller_; 270 RefPtr<Animator> springController_; 271 RefPtr<FrictionMotion> motion_; 272 RefPtr<ScrollMotion> scrollMotion_; 273 RefPtr<SpringProperty> spring_; 274 WeakPtr<PipelineContext> context_; 275 WeakPtr<RenderNode> scrollableNode_; 276 double currentPos_ = 0.0; 277 double currentVelocity_ = 0.0; 278 bool scrollPause_ = false; 279 bool touchUp_ = false; 280 bool moved_ = false; 281 bool isTouching_ = false; 282 bool available_ = true; 283 bool needCenterFix_ = false; 284 int32_t nodeId_ = 0; 285 double slipFactor_ = 0.0; 286 static double sFriction_; 287 static double sVelocityScale_; 288 }; 289 290 } // namespace OHOS::Ace 291 292 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SCROLL_SCROLLABEL_H 293