1 /* 2 * Copyright (c) 2021-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_SCROLL_SCROLL_BAR_CONTROLLER_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SCROLL_SCROLL_BAR_CONTROLLER_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/common/vibrator/vibrator.h" 25 #include "core/event/touch_event.h" 26 #include "core/gestures/drag_recognizer.h" 27 #include "core/gestures/pan_recognizer.h" 28 #include "core/gestures/raw_recognizer.h" 29 #include "core/pipeline/base/render_node.h" 30 31 namespace OHOS::Ace { 32 33 using ScrollBarPositionCallback = std::function<bool(double, int32_t source)>; 34 using ScrollBarEndCallback = std::function<void(int32_t)>; 35 using ScrollBarEventCallback = std::function<void()>; 36 using ScrollBarTouchEventCallback = std::function<void(double)>; 37 38 class ScrollBarController : public TouchEventTarget { 39 DECLARE_ACE_TYPE(ScrollBarController, TouchEventTarget); 40 41 public: 42 ScrollBarController() = default; 43 ~ScrollBarController() override = default; 44 45 void Initialize(const WeakPtr<PipelineContext>& context, bool isVertical); 46 void HandleScrollBarEnd(); 47 void HandleTouchDown(); 48 void HandleTouchUp(); 49 void HandleDragUpdate(const GestureEvent& info); 50 void HandleDragEnd(const GestureEvent& info); 51 virtual void MarkScrollRender(); 52 void Reset(); 53 DispatchEvent(const TouchEvent & point)54 bool DispatchEvent(const TouchEvent& point) override 55 { 56 return true; 57 } HandleEvent(const TouchEvent & event)58 bool HandleEvent(const TouchEvent& event) override 59 { 60 if (panRecognizer_) { 61 panRecognizer_->HandleEvent(event); 62 } 63 if (rawRecognizer_) { 64 return rawRecognizer_->HandleEvent(event); 65 } 66 return true; 67 } HandleEvent(const AxisEvent & event)68 bool HandleEvent(const AxisEvent& event) override 69 { 70 if (panRecognizer_) { 71 return panRecognizer_->HandleEvent(event); 72 } 73 return false; 74 } 75 SetCallback(const ScrollBarPositionCallback & callback)76 void SetCallback(const ScrollBarPositionCallback& callback) 77 { 78 callback_ = callback; 79 } 80 SetBarEndCallback(const ScrollBarEndCallback & barEndCallback)81 void SetBarEndCallback(const ScrollBarEndCallback& barEndCallback) 82 { 83 barEndCallback_ = barEndCallback; 84 } 85 SetCoordinateOffset(const Offset & offset)86 void SetCoordinateOffset(const Offset& offset) const 87 { 88 if (panRecognizer_) { 89 panRecognizer_->SetCoordinateOffset(offset); 90 } 91 if (rawRecognizer_) { 92 rawRecognizer_->SetCoordinateOffset(offset); 93 } 94 } 95 SetScrollEndCallback(const ScrollBarEventCallback & scrollEndCallback)96 void SetScrollEndCallback(const ScrollBarEventCallback& scrollEndCallback) 97 { 98 scrollEndCallback_ = scrollEndCallback; 99 } 100 SetTouchUpCallback(const ScrollBarTouchEventCallback & touchUpCallback)101 void SetTouchUpCallback(const ScrollBarTouchEventCallback& touchUpCallback) 102 { 103 touchUpCallback_ = touchUpCallback; 104 } 105 SetTouchDownCallback(const ScrollBarTouchEventCallback & touchDownCallback)106 void SetTouchDownCallback(const ScrollBarTouchEventCallback& touchDownCallback) 107 { 108 touchDownCallback_ = touchDownCallback; 109 } 110 SetScrollNode(const WeakPtr<RenderNode> & scroll)111 void SetScrollNode(const WeakPtr<RenderNode>& scroll) 112 { 113 scroll_ = scroll; 114 } 115 IsActive()116 bool IsActive() const 117 { 118 return isActive_; 119 } 120 SetActive(bool isActive)121 void SetActive(bool isActive) 122 { 123 isActive_ = isActive; 124 } 125 SetInactiveWidth(const Dimension & inactiveWidth)126 void SetInactiveWidth(const Dimension& inactiveWidth) 127 { 128 inactiveWidth_ = inactiveWidth; 129 } 130 SetActiveWidth(const Dimension & activeWidth)131 void SetActiveWidth(const Dimension& activeWidth) 132 { 133 activeWidth_ = activeWidth; 134 } 135 GetInactiveWidth()136 const Dimension& GetInactiveWidth() const 137 { 138 return inactiveWidth_; 139 } 140 GetActiveWidth()141 const Dimension& GetActiveWidth() const 142 { 143 return activeWidth_; 144 } 145 IsPressed()146 bool IsPressed() const 147 { 148 return isPressed_; 149 } 150 151 void SetIsHover(bool isInBarRegion); 152 StopScrollEndAnimator()153 void StopScrollEndAnimator() 154 { 155 if (scrollEndAnimator_ && !scrollEndAnimator_->IsStopped()) { 156 scrollEndAnimator_->Stop(); 157 } 158 } 159 void OnFlushTouchEventsBegin() override; 160 void OnFlushTouchEventsEnd() override; 161 162 protected: 163 virtual bool UpdateScrollPosition(double offset, int32_t source); 164 165 virtual void ProcessScrollMotion(double position); 166 167 virtual bool CheckScroll(); 168 169 // Play grow when hover or pressed, from inactive with to active width. 170 void PlayGrowAnimation(); 171 // Play shrink animation when lost hover or pressed state, from active with to inactive width. 172 void PlayShrinkAnimation(); 173 174 void InitBarEndAnimation(const WeakPtr<PipelineContext>& context); 175 176 WeakPtr<RenderNode> scroll_; 177 ScrollBarPositionCallback callback_; 178 ScrollBarEventCallback scrollEndCallback_; 179 ScrollBarEndCallback barEndCallback_; 180 ScrollBarTouchEventCallback touchUpCallback_; 181 ScrollBarTouchEventCallback touchDownCallback_; 182 183 RefPtr<PanRecognizer> panRecognizer_; 184 RefPtr<RawRecognizer> rawRecognizer_; 185 186 RefPtr<Animator> scrollEndAnimator_; 187 RefPtr<Animator> touchAnimator_; 188 RefPtr<Animator> dragEndAnimator_; 189 RefPtr<FrictionMotion> dragEndMotion_; 190 RefPtr<Vibrator> vibrator_; 191 WeakPtr<PipelineContext> context_; 192 193 bool isVertical_ = true; 194 bool isActive_ = false; 195 // Whether scroll bar is pressed, use different style when pressed. 196 bool isPressed_ = false; 197 // Whether scroll bar is hover. 198 bool isHover_ = false; 199 // Whether event is in scroll bar region. 200 bool isInBar_ = false; 201 double currentPos_ = 0.0; 202 Dimension activeWidth_; 203 Dimension inactiveWidth_; 204 }; 205 206 } // namespace OHOS::Ace 207 208 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SCROLL_SCROLL_BAR_CONTROLLER_H 209