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_SCROLL_POSITION_CONTROLLER_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SCROLL_SCROLL_POSITION_CONTROLLER_H 18 19 #include <functional> 20 21 #include "core/animation/curve.h" 22 #include "core/components/scroll/scroll_controller.h" 23 #include "core/components/scroll/scrollable.h" 24 #include "core/pipeline/base/render_node.h" 25 26 namespace OHOS::Ace { 27 28 using OnScrollFunc = std::function<void(const std::string&)>; 29 30 class ScrollEventInfo : public BaseEventInfo, public EventToJSONStringAdapter { 31 DECLARE_RELATIONSHIP_OF_CLASSES(ScrollEventInfo, BaseEventInfo, EventToJSONStringAdapter); 32 public: 33 ScrollEventInfo(ScrollEvent type, double scrollX, double scrollY, int32_t scrollState); 34 35 ~ScrollEventInfo() = default; 36 37 std::string ToJSONString() const override; 38 GetType()39 ScrollEvent GetType() const 40 { 41 return type_; 42 } 43 GetScrollX()44 double GetScrollX() const 45 { 46 return scrollX_; 47 } 48 GetScrollY()49 double GetScrollY() const 50 { 51 return scrollY_; 52 } 53 GetScrollState()54 int32_t GetScrollState() const 55 { 56 return scrollState_; 57 } 58 SetScrollType(ScrollEvent type)59 void SetScrollType(ScrollEvent type) 60 { 61 type_ = type; 62 } 63 64 private: 65 ScrollEvent type_ = ScrollEvent::SCROLL_TOP; 66 double scrollX_ = 0.0; 67 double scrollY_ = 0.0; 68 int32_t scrollState_ = -1; 69 }; 70 71 using ScrollEventFunc = std::function<void(std::shared_ptr<ScrollEventInfo>&)>; 72 class ACE_EXPORT ScrollPositionController : public ScrollController { 73 DECLARE_ACE_TYPE(ScrollPositionController, ScrollController); 74 75 public: 76 ScrollPositionController() = default; 77 ~ScrollPositionController() override = default; 78 SetInitialIndex(int32_t index)79 void SetInitialIndex(int32_t index) 80 { 81 if (index == 0) { 82 flags_ = POSITION_TOP; 83 } else { 84 flags_ = POSITION_MIDDLE; 85 } 86 initialIndex_ = index; 87 } 88 GetInitialIndex()89 int32_t GetInitialIndex() const 90 { 91 return initialIndex_; 92 } 93 SetInitialOffset(double initialOffset)94 void SetInitialOffset(double initialOffset) 95 { 96 if (NearZero(initialOffset)) { 97 flags_ = POSITION_TOP; 98 } else { 99 flags_ = POSITION_MIDDLE; 100 } 101 initialOffset_ = initialOffset; 102 } 103 GetInitialOffset()104 double GetInitialOffset() const 105 { 106 return initialOffset_; 107 } 108 109 double GetCurrentPosition() const; 110 Axis GetScrollDirection() const override; 111 112 void JumpTo(int32_t index, int32_t source) override; 113 void JumpTo(double position); 114 bool AnimateTo(const Dimension& position, float duration, const RefPtr<Curve>& curve) override; 115 bool AnimateTo(double position, float duration, const RefPtr<Curve>& curve, bool limitDuration = true, 116 const std::function<void()>& onFinish = nullptr); 117 bool AnimateToTarget(const ComposeId& targetId, float duration, const RefPtr<Curve>& curve, 118 bool limitDuration = true, const std::function<void()>& onFinish = nullptr); 119 void ScrollBy(double pixelX, double pixelY, bool smooth) override; 120 void ScrollArrow(double scrollDistance, bool reverse, bool smooth); 121 void ScrollToEdge(ScrollEdgeType scrollEdgeType, bool smooth) override; 122 void ScrollPage(bool reverse, bool smooth) override; 123 Offset GetCurrentOffset() const override; 124 125 SetScrollEvent(ScrollEvent event,const ScrollEventFunc & scrollEvent)126 void SetScrollEvent( 127 ScrollEvent event, const ScrollEventFunc& scrollEvent) 128 { 129 switch (event) { 130 case ScrollEvent::SCROLL_TOP: 131 scrollTop_ = scrollEvent; 132 break; 133 case ScrollEvent::SCROLL_BOTTOM: 134 scrollBottom_ = scrollEvent; 135 break; 136 case ScrollEvent::SCROLL_END: 137 scrollEnd_ = scrollEvent; 138 break; 139 case ScrollEvent::SCROLL_TOUCHUP: 140 scrollTouchUp_ = scrollEvent; 141 break; 142 case ScrollEvent::SCROLL_POSITION: 143 scrollPosition_ = scrollEvent; 144 break; 145 case ScrollEvent::SCROLL_EDGE: 146 scrollEdge_ = scrollEvent; 147 break; 148 default: 149 LOGW("unknown scroll event"); 150 break; 151 } 152 } 153 HandleScrollEvent(std::shared_ptr<ScrollEventInfo> info)154 void HandleScrollEvent(std::shared_ptr<ScrollEventInfo> info) const 155 { 156 if (!info) { 157 LOGE("scroll event info is null"); 158 return; 159 } 160 auto eventType = info->GetType(); 161 switch (eventType) { 162 case ScrollEvent::SCROLL_TOP: 163 if (scrollTop_) { 164 scrollTop_(info); 165 } 166 if (scrollEdge_) { 167 scrollEdge_(info); 168 } 169 break; 170 case ScrollEvent::SCROLL_BOTTOM: 171 if (scrollBottom_) { 172 scrollBottom_(info); 173 } 174 if (scrollEdge_) { 175 scrollEdge_(info); 176 } 177 break; 178 case ScrollEvent::SCROLL_END: 179 if (scrollEnd_) { 180 scrollEnd_(info); 181 } 182 break; 183 case ScrollEvent::SCROLL_TOUCHUP: 184 if (scrollTouchUp_) { 185 scrollTouchUp_(info); 186 } 187 break; 188 case ScrollEvent::SCROLL_POSITION: 189 if (scrollPosition_) { 190 scrollPosition_(info); 191 } 192 break; 193 default: 194 LOGW("handle unknown scroll event"); 195 break; 196 } 197 } 198 SetTop()199 void SetTop() 200 { 201 flags_ |= POSITION_TOP; 202 } 203 SetBottom()204 void SetBottom() 205 { 206 flags_ |= POSITION_BOTTOM; 207 } 208 SetMiddle()209 void SetMiddle() 210 { 211 flags_ = POSITION_MIDDLE; 212 } 213 IsTop()214 bool IsTop() const 215 { 216 return (flags_ & POSITION_TOP); 217 } 218 IsBottom()219 bool IsBottom() const 220 { 221 return (flags_ & POSITION_BOTTOM); 222 } 223 SetNonScrollable()224 void SetNonScrollable() 225 { 226 flags_ = (POSITION_TOP | POSITION_BOTTOM); 227 } 228 229 using OnFirstChanged = std::function<void(int32_t)>; AddFirstChangedCallback(const OnFirstChanged & callback)230 void AddFirstChangedCallback(const OnFirstChanged& callback) 231 { 232 onChanged_ = callback; 233 } 234 235 using IndexerRotation = std::function<bool()>; AddIndexerStateQueryCallback(const IndexerRotation & callback)236 void AddIndexerStateQueryCallback(const IndexerRotation& callback) 237 { 238 indexerRotationCallback_ = callback; 239 } 240 IsScrollNeedRotation()241 bool IsScrollNeedRotation() 242 { 243 return !(indexerRotationCallback_ && indexerRotationCallback_()); 244 } 245 SetFirstItemIndex(int32_t firstIndex)246 void SetFirstItemIndex(int32_t firstIndex) 247 { 248 firstIndex_ = firstIndex; 249 if (onChanged_) { 250 onChanged_(firstIndex_); 251 } 252 } 253 GetFirstItemIndex()254 int32_t GetFirstItemIndex() const 255 { 256 return firstIndex_; 257 } 258 259 private: 260 int32_t initialIndex_ = 0; 261 double initialOffset_ = 0.0; 262 OnFirstChanged onChanged_; 263 IndexerRotation indexerRotationCallback_; 264 int32_t firstIndex_ = 0; 265 266 ScrollEventFunc scrollTop_; 267 ScrollEventFunc scrollBottom_; 268 ScrollEventFunc scrollTouchUp_; 269 ScrollEventFunc scrollEnd_; 270 ScrollEventFunc scrollPosition_; 271 ScrollEventFunc scrollEdge_; 272 uint32_t flags_ = POSITION_TOP; 273 }; 274 275 } // namespace OHOS::Ace 276 277 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SCROLL_SCROLL_POSITION_CONTROLLER_H 278