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_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 ScrollToIndex(int32_t index, bool smooth, ScrollAlign align, std::optional<float> extraOffset) override; 113 void JumpTo(double position); 114 bool AnimateTo(const Dimension& position, float duration, const RefPtr<Curve>& curve, bool smooth, 115 bool canOverScroll = false) override; 116 bool AnimateTo(double position, float duration, const RefPtr<Curve>& curve, bool limitDuration = true, 117 const std::function<void()>& onFinish = nullptr); 118 bool AnimateToTarget(const ComposeId& targetId, float duration, const RefPtr<Curve>& curve, 119 bool limitDuration = true, const std::function<void()>& onFinish = nullptr); 120 void ScrollBy(double pixelX, double pixelY, bool smooth) override; 121 void ScrollArrow(double scrollDistance, bool reverse, bool smooth); 122 void ScrollToEdge(ScrollEdgeType scrollEdgeType, bool smooth) override; 123 void ScrollPage(bool reverse, bool smooth) override; 124 Offset GetCurrentOffset() const override; 125 126 SetScrollEvent(ScrollEvent event,const ScrollEventFunc & scrollEvent)127 void SetScrollEvent( 128 ScrollEvent event, const ScrollEventFunc& scrollEvent) 129 { 130 switch (event) { 131 case ScrollEvent::SCROLL_TOP: 132 scrollTop_ = scrollEvent; 133 break; 134 case ScrollEvent::SCROLL_BOTTOM: 135 scrollBottom_ = scrollEvent; 136 break; 137 case ScrollEvent::SCROLL_END: 138 scrollEnd_ = scrollEvent; 139 break; 140 case ScrollEvent::SCROLL_TOUCHUP: 141 scrollTouchUp_ = scrollEvent; 142 break; 143 case ScrollEvent::SCROLL_POSITION: 144 scrollPosition_ = scrollEvent; 145 break; 146 case ScrollEvent::SCROLL_EDGE: 147 scrollEdge_ = scrollEvent; 148 break; 149 default: 150 LOGW("unknown scroll event"); 151 break; 152 } 153 } 154 HandleScrollEvent(std::shared_ptr<ScrollEventInfo> info)155 void HandleScrollEvent(std::shared_ptr<ScrollEventInfo> info) const 156 { 157 if (!info) { 158 LOGE("scroll event info is null"); 159 return; 160 } 161 auto eventType = info->GetType(); 162 switch (eventType) { 163 case ScrollEvent::SCROLL_TOP: 164 if (scrollTop_) { 165 scrollTop_(info); 166 } 167 if (scrollEdge_) { 168 scrollEdge_(info); 169 } 170 break; 171 case ScrollEvent::SCROLL_BOTTOM: 172 if (scrollBottom_) { 173 scrollBottom_(info); 174 } 175 if (scrollEdge_) { 176 scrollEdge_(info); 177 } 178 break; 179 case ScrollEvent::SCROLL_END: 180 if (scrollEnd_) { 181 scrollEnd_(info); 182 } 183 break; 184 case ScrollEvent::SCROLL_TOUCHUP: 185 if (scrollTouchUp_) { 186 scrollTouchUp_(info); 187 } 188 break; 189 case ScrollEvent::SCROLL_POSITION: 190 if (scrollPosition_) { 191 scrollPosition_(info); 192 } 193 break; 194 default: 195 LOGW("handle unknown scroll event"); 196 break; 197 } 198 } 199 SetTop()200 void SetTop() 201 { 202 flags_ |= POSITION_TOP; 203 } 204 SetBottom()205 void SetBottom() 206 { 207 flags_ |= POSITION_BOTTOM; 208 } 209 SetMiddle()210 void SetMiddle() 211 { 212 flags_ = POSITION_MIDDLE; 213 } 214 IsTop()215 bool IsTop() const 216 { 217 return (flags_ & POSITION_TOP); 218 } 219 IsBottom()220 bool IsBottom() const 221 { 222 return (flags_ & POSITION_BOTTOM); 223 } 224 SetNonScrollable()225 void SetNonScrollable() 226 { 227 flags_ = (POSITION_TOP | POSITION_BOTTOM); 228 } 229 230 using OnFirstChanged = std::function<void(int32_t)>; AddFirstChangedCallback(const OnFirstChanged & callback)231 void AddFirstChangedCallback(const OnFirstChanged& callback) 232 { 233 onChanged_ = callback; 234 } 235 236 using IndexerRotation = std::function<bool()>; AddIndexerStateQueryCallback(const IndexerRotation & callback)237 void AddIndexerStateQueryCallback(const IndexerRotation& callback) 238 { 239 indexerRotationCallback_ = callback; 240 } 241 IsScrollNeedRotation()242 bool IsScrollNeedRotation() 243 { 244 return !(indexerRotationCallback_ && indexerRotationCallback_()); 245 } 246 SetFirstItemIndex(int32_t firstIndex)247 void SetFirstItemIndex(int32_t firstIndex) 248 { 249 firstIndex_ = firstIndex; 250 if (onChanged_) { 251 onChanged_(firstIndex_); 252 } 253 } 254 GetFirstItemIndex()255 int32_t GetFirstItemIndex() const 256 { 257 return firstIndex_; 258 } 259 260 private: 261 int32_t initialIndex_ = 0; 262 double initialOffset_ = 0.0; 263 OnFirstChanged onChanged_; 264 IndexerRotation indexerRotationCallback_; 265 int32_t firstIndex_ = 0; 266 267 ScrollEventFunc scrollTop_; 268 ScrollEventFunc scrollBottom_; 269 ScrollEventFunc scrollTouchUp_; 270 ScrollEventFunc scrollEnd_; 271 ScrollEventFunc scrollPosition_; 272 ScrollEventFunc scrollEdge_; 273 uint32_t flags_ = POSITION_TOP; 274 }; 275 276 } // namespace OHOS::Ace 277 278 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SCROLL_SCROLL_POSITION_CONTROLLER_H 279