1 /*
2 * Copyright (c) 2023-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_NG_PATTERNS_SCROLLABLE_SCROLLABLE_PROPERTIES_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLLABLE_SCROLLABLE_PROPERTIES_H
18
19 #include <functional>
20 #include <optional>
21
22 #include "base/geometry/dimension.h"
23 #include "base/geometry/ng/size_t.h"
24 #include "core/components_ng/base/frame_scene_status.h"
25 #include "core/components_ng/event/pan_event.h"
26 #include "core/components_ng/event/touch_event.h"
27 #include "core/components_ng/property/layout_constraint.h"
28
29 namespace OHOS::Ace {
30 constexpr float DEFAULT_SCROLL_TO_MASS = 1.0f;
31 constexpr float DEFAULT_SCROLL_TO_STIFFNESS = 227.0f;
32 constexpr float DEFAULT_SCROLL_TO_DAMPING = 33.0f;
33 constexpr float DEFAULT_SCROLL_TO_VELOCITY = 7.0f;
34 // for add item and scrollEdge(Edge.Bottom) in one layout
35 constexpr int32_t LAST_ITEM = -1;
36
37 enum class ScrollState {
38 IDLE = 0,
39 SCROLL,
40 FLING,
41 };
42
43 enum class NestedScrollMode {
44 SELF_ONLY = 0,
45 SELF_FIRST,
46 PARENT_FIRST,
47 PARALLEL,
48 };
49
50 enum class ScrollSnapAlign {
51 NONE = 0,
52 START,
53 CENTER,
54 END,
55 };
56
57 enum class ScrollPagingStatus {
58 // no enablePaging set
59 NONE = 0,
60 // enablePaging is false
61 INVALID,
62 // enablePaging is true
63 VALID,
64 };
65
66 // use in dumpInfo, excluding events truggered per frame,
67 // such as onScroll, onScrollFrameBegin, onWillScroll, onDidScroll
68 enum class ScrollableEventType {
69 ON_SCROLL_START = 0,
70 ON_SCROLL_STOP,
71 ON_SCROLL_EDGE,
72 ON_REACH_START,
73 ON_REACH_END,
74 };
75
76 struct ScrollInfo {
77 Dimension dx;
78 Dimension dy;
79
80 bool operator==(const ScrollInfo& scrollInfo) const
81 {
82 return dx == scrollInfo.dx && dy == scrollInfo.dy;
83 }
84 };
85
86 struct ScrollFrameInfo {
87 Dimension offset;
88 ScrollState state;
89
90 bool operator==(const ScrollFrameInfo& scrollInfo) const
91 {
92 return offset == scrollInfo.offset && state == scrollInfo.state;
93 }
94 };
95
96 struct ScrollFrameResult {
97 Dimension offset;
98
99 bool operator==(const ScrollFrameResult& scrollRes) const
100 {
101 return offset == scrollRes.offset;
102 }
103 };
104
105 struct ScrollSnapOptions {
106 int32_t snapAlign;
107 int32_t enableSnapToStart;
108 int32_t enableSnapToEnd;
109 std::vector<Dimension> paginationParams;
110 };
111
112 struct NestedScrollOptions {
113 NestedScrollMode forward;
114 NestedScrollMode backward;
115
NeedParentNestedScrollOptions116 bool NeedParent() const
117 {
118 return forward != NestedScrollMode::SELF_ONLY || backward != NestedScrollMode::SELF_ONLY;
119 }
120
NeedParentNestedScrollOptions121 bool NeedParent(bool forward) const
122 {
123 return forward ? this->forward != NestedScrollMode::SELF_ONLY : backward != NestedScrollMode::SELF_ONLY;
124 }
125
126 bool operator==(const NestedScrollOptions& other) const
127 {
128 return forward == other.forward && backward == other.backward;
129 }
130
131 bool operator!=(const NestedScrollOptions& other) const
132 {
133 return !(*this == other);
134 }
135
ToStringNestedScrollOptions136 std::string ToString() const
137 {
138 return "NestedScrollOptions forward: " + std::to_string(static_cast<int32_t>(forward)) +
139 ", backward: " + std::to_string(static_cast<int32_t>(backward));
140 }
141
GetNestedScrollModeStrNestedScrollOptions142 std::string GetNestedScrollModeStr(NestedScrollMode mode) const
143 {
144 switch (mode) {
145 case NestedScrollMode::SELF_ONLY:
146 return "NestedScrollMode.SELF_ONLY";
147 case NestedScrollMode::SELF_FIRST:
148 return "NestedScrollMode.SELF_FIRST";
149 case NestedScrollMode::PARENT_FIRST:
150 return "NestedScrollMode.PARENT_FIRST";
151 case NestedScrollMode::PARALLEL:
152 return "NestedScrollMode.PARALLEL";
153 default:
154 return "";
155 }
156 }
157 };
158
159 struct NestedScrollOptionsExt {
160 NestedScrollMode scrollUp;
161 NestedScrollMode scrollDown;
162 NestedScrollMode scrollLeft;
163 NestedScrollMode scrollRight;
164
ToStringNestedScrollOptionsExt165 std::string ToString() const
166 {
167 return "NestedScrollOptionsExt scrollUp: " + std::to_string(static_cast<int32_t>(scrollUp)) +
168 ", scrollDown: " + std::to_string(static_cast<int32_t>(scrollDown)) +
169 ", scrollLeft: " + std::to_string(static_cast<int32_t>(scrollLeft)) +
170 ", scrollRight: " + std::to_string(static_cast<int32_t>(scrollRight));
171 }
172 };
173
174 struct ListItemIndex {
175 int32_t index = -1;
176 int32_t area = -1;
177 int32_t indexInGroup = -1;
178 };
179
180 constexpr int32_t SCROLL_FROM_NONE = 0;
181 constexpr int32_t SCROLL_FROM_UPDATE = 1;
182 constexpr int32_t SCROLL_FROM_ANIMATION = 2;
183 constexpr int32_t SCROLL_FROM_JUMP = 3;
184 constexpr int32_t SCROLL_FROM_ANIMATION_SPRING = 4;
185 constexpr int32_t SCROLL_FROM_CHILD = 5;
186 constexpr int32_t SCROLL_FROM_BAR = 6;
187 constexpr int32_t SCROLL_FROM_FOCUS_JUMP = 7;
188 constexpr int32_t SCROLL_FROM_ROTATE = 8;
189 constexpr int32_t SCROLL_FROM_INDEXER = 9;
190 constexpr int32_t SCROLL_FROM_START = 10; // from drag start
191 constexpr int32_t SCROLL_FROM_AXIS = 11;
192 constexpr int32_t SCROLL_FROM_ANIMATION_CONTROLLER = 12;
193 constexpr int32_t SCROLL_FROM_BAR_FLING = 13;
194
GetSourceStr(int32_t scrollSource)195 inline std::string GetSourceStr(int32_t scrollSource)
196 {
197 switch (scrollSource) {
198 case SCROLL_FROM_NONE:
199 return "SCROLL_FROM_NONE";
200 case SCROLL_FROM_UPDATE:
201 return "SCROLL_FROM_UPDATE";
202 case SCROLL_FROM_ANIMATION:
203 return "SCROLL_FROM_ANIMATION";
204 case SCROLL_FROM_JUMP:
205 return "SCROLL_FROM_JUMP";
206 case SCROLL_FROM_ANIMATION_SPRING:
207 return "SCROLL_FROM_ANIMATION_SPRING";
208 case SCROLL_FROM_CHILD:
209 return "SCROLL_FROM_CHILD";
210 case SCROLL_FROM_BAR:
211 return "SCROLL_FROM_BAR";
212 case SCROLL_FROM_FOCUS_JUMP:
213 return "SCROLL_FROM_FOCUS_JUMP";
214 case SCROLL_FROM_ROTATE:
215 return "SCROLL_FROM_ROTATE";
216 case SCROLL_FROM_INDEXER:
217 return "SCROLL_FROM_INDEXER";
218 case SCROLL_FROM_START:
219 return "SCROLL_FROM_START";
220 case SCROLL_FROM_AXIS:
221 return "SCROLL_FROM_AXIS";
222 case SCROLL_FROM_ANIMATION_CONTROLLER:
223 return "SCROLL_FROM_ANIMATION_CONTROLLER";
224 case SCROLL_FROM_BAR_FLING:
225 return "SCROLL_FROM_BAR_FLING";
226 default:
227 return "";
228 }
229 }
230
231 struct ScrollableEventsFiredInfo {
232 uint64_t eventFiredTime_ = 0;
233 ScrollableEventType eventType_;
234 int32_t scrollSource_ = 0;
235
ToStringScrollableEventsFiredInfo236 std::string ToString() const
237 {
238 return std::string("event type: ")
239 .append(GetEventStr())
240 .append(" fired in ")
241 .append(std::to_string(eventFiredTime_))
242 .append(", source is ")
243 .append(GetSourceStr(scrollSource_));
244 }
245
GetEventStrScrollableEventsFiredInfo246 std::string GetEventStr() const
247 {
248 switch (eventType_) {
249 case ScrollableEventType::ON_SCROLL_START:
250 return "onScrollStart";
251 case ScrollableEventType::ON_SCROLL_STOP:
252 return "onScrollStop";
253 case ScrollableEventType::ON_SCROLL_EDGE:
254 return "onScrollEdge";
255 case ScrollableEventType::ON_REACH_START:
256 return "onReachStart";
257 case ScrollableEventType::ON_REACH_END:
258 return "onReachEnd";
259 default:
260 return "";
261 }
262 }
263 };
264
265 struct ScrollableFrameInfo {
266 uint64_t scrollStateTime_ = 0;
267 int32_t scrollState_ = 0;
268 bool canOverScroll_ = false;
269 uint32_t canOverScrollInfo_ = 0;
270
ToStringScrollableFrameInfo271 std::string ToString() const
272 {
273 return std::string("scroll from: ")
274 .append(GetSourceStr(scrollState_))
275 .append(" canOverScroll: ")
276 .append(std::to_string(canOverScroll_))
277 .append(" isScrollableSpringEffect: ")
278 .append((canOverScrollInfo_ >> 4) & 1 ? "true" : "false")
279 .append(" isScrollable: ")
280 .append((canOverScrollInfo_ >> 3) & 1 ? "true" : "false")
281 .append(" scrollableIdle: ")
282 .append((canOverScrollInfo_ >> 2) & 1 ? "true" : "false")
283 .append(" animateOverScroll: ")
284 .append((canOverScrollInfo_ >> 1) & 1 ? "true" : "false")
285 .append(" animateCanOverScroll: ")
286 .append(canOverScrollInfo_ & 1 ? "true" : "false")
287 .append(" fired in ")
288 .append(std::to_string(scrollStateTime_));
289 }
290 };
291
292 struct ScrollLayoutInfo {
293 uint64_t changedTime_ = 0;
294 float scrollableDistance_ = 0;
295 NG::SizeF scrollSize_;
296 NG::SizeF viewPort_;
297 NG::SizeF childSize_;
298
ToStringScrollLayoutInfo299 std::string ToString() const
300 {
301 return std::string("scrollableDistance changed, scrollableDistance: ")
302 .append(std::to_string(scrollableDistance_))
303 .append(" scrollSize: ")
304 .append(scrollSize_.ToString())
305 .append(" viewPort: ")
306 .append(viewPort_.ToString())
307 .append(" childSize: ")
308 .append(childSize_.ToString())
309 .append(" fired in ")
310 .append(std::to_string(changedTime_));
311 }
312 };
313
314 struct ScrollMeasureInfo {
315 uint64_t changedTime_ = 0;
316 std::optional<NG::LayoutConstraintF> parentConstraint_;
317 std::optional<NG::LayoutConstraintF> childConstraint_;
318 NG::SizeF selfSize_;
319 NG::SizeF childSize_;
320
ToStringScrollMeasureInfo321 std::string ToString() const
322 {
323 return std::string("Scroll Measure changed, parentConstraint: ")
324 .append(parentConstraint_->ToString())
325 .append(" childConstraint: ")
326 .append(childConstraint_->ToString())
327 .append(" selfSize: ")
328 .append(selfSize_.ToString())
329 .append(" childSize: ")
330 .append(childSize_.ToString())
331 .append(" fired in ")
332 .append(std::to_string(changedTime_));
333 }
334 };
335
336 struct InnerScrollBarLayoutInfo {
337 uint64_t layoutTime_ = 0;
338 Size viewPortSize_;
339 Offset lastOffset_;
340 double estimatedHeight_ = 0.0;
341 double outBoundary_ = 0.0;
342 Rect activeRect_;
343
ToStringInnerScrollBarLayoutInfo344 std::string ToString() const
345 {
346 return std::string("inner scrollBar layout, viewPortSize:")
347 .append(viewPortSize_.ToString())
348 .append(" lastOffset: ")
349 .append(lastOffset_.ToString())
350 .append(" estimatedHeight: ")
351 .append(std::to_string(estimatedHeight_))
352 .append(" outBoundary: ")
353 .append(std::to_string(outBoundary_))
354 .append(" activeRect: ")
355 .append(activeRect_.ToString())
356 .append(" fired in ")
357 .append(std::to_string(layoutTime_));
358 }
359 };
360
361 struct OuterScrollBarLayoutInfo {
362 uint64_t layoutTime_ = 0;
363 float currentOffset_ = 0.f;
364 float scrollableNodeOffset_ = 0.f;
365
ToStringOuterScrollBarLayoutInfo366 std::string ToString() const
367 {
368 return std::string("outer scrollBar layout, currentOffset:")
369 .append(std::to_string(currentOffset_))
370 .append(" scrollableNodeOffset: ")
371 .append(std::to_string(scrollableNodeOffset_))
372 .append(" fired in ")
373 .append(std::to_string(layoutTime_));
374 }
375 };
376
377 enum class ScrollSource {
378 DRAG = 0, // constexpr int32_t SCROLL_FROM_UPDATE = 1;
379 FLING, // constexpr int32_t SCROLL_FROM_ANIMATION = 2;
380 EDGE_EFFECT, // constexpr int32_t SCROLL_FROM_ANIMATION_SPRING = 4;
381 OTHER_USER_INPUT, // constexpr int32_t SCROLL_FROM_AXIS = 11;
382 SCROLL_BAR, // constexpr int32_t SCROLL_FROM_BAR = 6;
383 SCROLL_BAR_FLING, // constexpr int32_t SCROLL_FROM_BAR_FLING = 13;
384 SCROLLER, // constexpr int32_t SCROLL_FROM_JUMP = 3;
385 SCROLLER_ANIMATION, // constexpr int32_t SCROLL_FROM_ANIMATION_CONTROLLER = 12;
386 };
387
388 // app tail animation
389 constexpr char TRAILING_ANIMATION[] = "TRAILING_ANIMATION ";
390
391 // scroller animation, such as scrollTo, scrollPage
392 constexpr char SCROLLER_ANIMATION[] = "CUSTOM_ANIMATOR_SCROLLER_ANIMATION ";
393
394 // scrollToEdge at a fixed speed
395 constexpr char SCROLLER_FIX_VELOCITY_ANIMATION[] = "SCROLLER_FIX_VELOCITY_ANIMATION ";
396
397 using OnScrollEvent = std::function<void(Dimension, ScrollState)>;
398 using OnDidScrollEvent = std::function<void(Dimension, ScrollState, ScrollSource, bool, bool)>;
399 using OnWillScrollEvent = std::function<ScrollFrameResult(Dimension, ScrollState, ScrollSource)>;
400 using OnScrollBeginEvent = std::function<ScrollInfo(Dimension, Dimension)>;
401 using OnScrollFrameBeginEvent = std::function<ScrollFrameResult(Dimension, ScrollState)>;
402 using OnScrollStartEvent = std::function<void()>;
403 using OnScrollStopEvent = std::function<void()>;
404 using OnReachEvent = std::function<void()>;
405 using OnScrollIndexEvent = std::function<void(int32_t, int32_t, int32_t)>;
406 using OnScrollVisibleContentChangeEvent = std::function<void(ListItemIndex, ListItemIndex)>;
407
408 using ScrollPositionCallback = std::function<bool(double, int32_t source)>;
409 using ScrollEndCallback = std::function<void()>;
410 using CalePredictSnapOffsetCallback =
411 std::function<std::optional<float>(float delta, float dragDistance, float velocity)>;
412 using StartScrollSnapMotionCallback = std::function<void(float scrollSnapDelta, float scrollSnapVelocity)>;
413 using ScrollBarFRCallback = std::function<void(double velocity, NG::SceneStatus sceneStatus)>;
414
415 struct ScrollerObserver {
416 RefPtr<NG::TouchEventImpl> onTouchEvent;
417 GestureEventFunc onPanActionEndEvent;
418 OnReachEvent onReachStartEvent;
419 OnReachEvent onReachEndEvent;
420 OnScrollStartEvent onScrollStartEvent;
421 OnScrollStopEvent onScrollStopEvent;
422 OnDidScrollEvent onDidScrollEvent;
423 };
424 using ScrollPageCallback = std::function<void(bool, bool smooth)>;
425 } // namespace OHOS::Ace
426
427 #endif
428