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/touch_event.h"
26 #include "core/components_ng/property/layout_constraint.h"
27 #include "ui/properties/scrollable_properties.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 NestedScrollMode {
38 SELF_ONLY = 0,
39 SELF_FIRST,
40 PARENT_FIRST,
41 PARALLEL,
42 };
43
44 enum class ScrollSnapAlign {
45 NONE = 0,
46 START,
47 CENTER,
48 END,
49 };
50
51 enum class ScrollBarShape {
52 RECT = 0,
53 ARC,
54 };
55
56 enum class ScrollPagingStatus {
57 // no enablePaging set
58 NONE = 0,
59 // enablePaging is false
60 INVALID,
61 // enablePaging is true
62 VALID,
63 };
64
65 enum class SnapType {
66 SCROLL_SNAP = 0,
67 LIST_SNAP,
68 NONE_SNAP
69 };
70
71 enum class SnapDirection {
72 FORWARD = 0,
73 BACKWARD,
74 NONE
75 };
76
77 // use in dumpInfo, excluding events truggered per frame,
78 // such as onScroll, onScrollFrameBegin, onWillScroll, onDidScroll
79 enum class ScrollableEventType {
80 ON_SCROLL_START = 0,
81 ON_SCROLL_STOP,
82 ON_SCROLL_EDGE,
83 ON_REACH_START,
84 ON_REACH_END,
85 };
86
87 struct ScrollInfo {
88 Dimension dx;
89 Dimension dy;
90
91 bool operator==(const ScrollInfo& scrollInfo) const
92 {
93 return dx == scrollInfo.dx && dy == scrollInfo.dy;
94 }
95 };
96
97 struct ScrollFrameInfo {
98 Dimension offset;
99 ScrollState state;
100
101 bool operator==(const ScrollFrameInfo& scrollInfo) const
102 {
103 return offset == scrollInfo.offset && state == scrollInfo.state;
104 }
105 };
106
107 struct ScrollSnapOptions {
108 int32_t snapAlign;
109 int32_t enableSnapToStart;
110 int32_t enableSnapToEnd;
111 std::vector<Dimension> paginationParams;
112 };
113
114 struct NestedScrollOptions {
115 NestedScrollMode forward;
116 NestedScrollMode backward;
117
NeedParentNestedScrollOptions118 bool NeedParent() const
119 {
120 return forward != NestedScrollMode::SELF_ONLY || backward != NestedScrollMode::SELF_ONLY;
121 }
122
NeedParentNestedScrollOptions123 bool NeedParent(bool forward) const
124 {
125 return forward ? this->forward != NestedScrollMode::SELF_ONLY : backward != NestedScrollMode::SELF_ONLY;
126 }
127
128 bool operator==(const NestedScrollOptions& other) const
129 {
130 return forward == other.forward && backward == other.backward;
131 }
132
133 bool operator!=(const NestedScrollOptions& other) const
134 {
135 return !(*this == other);
136 }
137
ToStringNestedScrollOptions138 std::string ToString() const
139 {
140 return "NestedScrollOptions forward: " + std::to_string(static_cast<int32_t>(forward)) +
141 ", backward: " + std::to_string(static_cast<int32_t>(backward));
142 }
143
GetNestedScrollModeStrNestedScrollOptions144 std::string GetNestedScrollModeStr(NestedScrollMode mode) const
145 {
146 switch (mode) {
147 case NestedScrollMode::SELF_ONLY:
148 return "NestedScrollMode.SELF_ONLY";
149 case NestedScrollMode::SELF_FIRST:
150 return "NestedScrollMode.SELF_FIRST";
151 case NestedScrollMode::PARENT_FIRST:
152 return "NestedScrollMode.PARENT_FIRST";
153 case NestedScrollMode::PARALLEL:
154 return "NestedScrollMode.PARALLEL";
155 default:
156 return "";
157 }
158 }
159 };
160
161 struct NestedScrollOptionsExt {
162 NestedScrollMode scrollUp;
163 NestedScrollMode scrollDown;
164 NestedScrollMode scrollLeft;
165 NestedScrollMode scrollRight;
166
ToStringNestedScrollOptionsExt167 std::string ToString() const
168 {
169 return "NestedScrollOptionsExt scrollUp: " + std::to_string(static_cast<int32_t>(scrollUp)) +
170 ", scrollDown: " + std::to_string(static_cast<int32_t>(scrollDown)) +
171 ", scrollLeft: " + std::to_string(static_cast<int32_t>(scrollLeft)) +
172 ", scrollRight: " + std::to_string(static_cast<int32_t>(scrollRight));
173 }
174 };
175
176 struct ScrollBarMargin {
177 Dimension start_;
178 Dimension end_;
179
180 bool operator==(const ScrollBarMargin& other) const
181 {
182 return this->start_ == other.start_ && this->end_ == other.end_;
183 }
184
185 bool operator!=(const ScrollBarMargin& other) const
186 {
187 return !(*this == other);
188 }
189
ToStringScrollBarMargin190 std::string ToString() const
191 {
192 return "ScrollBarMargin start: " + start_.ToString() + ", end: " + end_.ToString();
193 }
194 };
195
196 struct ListItemIndex {
197 int32_t index = -1;
198 int32_t area = -1;
199 int32_t indexInGroup = -1;
200 };
201
202 constexpr int32_t SCROLL_FROM_NONE = 0;
203 constexpr int32_t SCROLL_FROM_UPDATE = 1;
204 constexpr int32_t SCROLL_FROM_ANIMATION = 2;
205 constexpr int32_t SCROLL_FROM_JUMP = 3;
206 constexpr int32_t SCROLL_FROM_ANIMATION_SPRING = 4;
207 constexpr int32_t SCROLL_FROM_CHILD = 5;
208 constexpr int32_t SCROLL_FROM_BAR = 6;
209 constexpr int32_t SCROLL_FROM_FOCUS_JUMP = 7;
210 constexpr int32_t SCROLL_FROM_ROTATE = 8;
211 constexpr int32_t SCROLL_FROM_INDEXER = 9;
212 constexpr int32_t SCROLL_FROM_START = 10; // from drag start
213 constexpr int32_t SCROLL_FROM_AXIS = 11;
214 constexpr int32_t SCROLL_FROM_ANIMATION_CONTROLLER = 12;
215 constexpr int32_t SCROLL_FROM_BAR_FLING = 13;
216 constexpr int32_t SCROLL_FROM_CROWN = 14;
217 constexpr int32_t SCROLL_FROM_STATUSBAR = 15;
218
GetSourceStr(int32_t scrollSource)219 inline std::string GetSourceStr(int32_t scrollSource)
220 {
221 switch (scrollSource) {
222 case SCROLL_FROM_NONE:
223 return "SCROLL_FROM_NONE";
224 case SCROLL_FROM_UPDATE:
225 return "SCROLL_FROM_UPDATE";
226 case SCROLL_FROM_ANIMATION:
227 return "SCROLL_FROM_ANIMATION";
228 case SCROLL_FROM_JUMP:
229 return "SCROLL_FROM_JUMP";
230 case SCROLL_FROM_ANIMATION_SPRING:
231 return "SCROLL_FROM_ANIMATION_SPRING";
232 case SCROLL_FROM_CHILD:
233 return "SCROLL_FROM_CHILD";
234 case SCROLL_FROM_BAR:
235 return "SCROLL_FROM_BAR";
236 case SCROLL_FROM_FOCUS_JUMP:
237 return "SCROLL_FROM_FOCUS_JUMP";
238 case SCROLL_FROM_ROTATE:
239 return "SCROLL_FROM_ROTATE";
240 case SCROLL_FROM_INDEXER:
241 return "SCROLL_FROM_INDEXER";
242 case SCROLL_FROM_START:
243 return "SCROLL_FROM_START";
244 case SCROLL_FROM_AXIS:
245 return "SCROLL_FROM_AXIS";
246 case SCROLL_FROM_ANIMATION_CONTROLLER:
247 return "SCROLL_FROM_ANIMATION_CONTROLLER";
248 case SCROLL_FROM_BAR_FLING:
249 return "SCROLL_FROM_BAR_FLING";
250 default:
251 return "";
252 }
253 }
254
255 struct ScrollableEventsFiredInfo {
256 uint64_t eventFiredTime_ = 0;
257 ScrollableEventType eventType_;
258 int32_t scrollSource_ = 0;
259
ToStringScrollableEventsFiredInfo260 std::string ToString() const
261 {
262 return std::string("event type: ")
263 .append(GetEventStr())
264 .append(" fired in ")
265 .append(std::to_string(eventFiredTime_))
266 .append(", source is ")
267 .append(GetSourceStr(scrollSource_));
268 }
269
GetEventStrScrollableEventsFiredInfo270 std::string GetEventStr() const
271 {
272 switch (eventType_) {
273 case ScrollableEventType::ON_SCROLL_START:
274 return "onScrollStart";
275 case ScrollableEventType::ON_SCROLL_STOP:
276 return "onScrollStop";
277 case ScrollableEventType::ON_SCROLL_EDGE:
278 return "onScrollEdge";
279 case ScrollableEventType::ON_REACH_START:
280 return "onReachStart";
281 case ScrollableEventType::ON_REACH_END:
282 return "onReachEnd";
283 default:
284 return "";
285 }
286 }
287
ToJsonScrollableEventsFiredInfo288 void ToJson(std::unique_ptr<JsonValue>& json) const
289 {
290 json->Put("event type", GetEventStr().c_str());
291 json->Put("fired in", std::to_string(eventFiredTime_).c_str());
292 json->Put("source is", GetSourceStr(scrollSource_).c_str());
293 }
294 };
295
296 struct ScrollableFrameInfo {
297 uint64_t scrollStateTime_ = 0;
298 int32_t scrollState_ = 0;
299 bool canOverScroll_ = false;
300 uint32_t canOverScrollInfo_ = 0;
301
ToStringScrollableFrameInfo302 std::string ToString() const
303 {
304 return std::string("scroll from: ")
305 .append(GetSourceStr(scrollState_))
306 .append(" canOverScroll: ")
307 .append(std::to_string(canOverScroll_))
308 .append(" isScrollableSpringEffect: ")
309 .append((canOverScrollInfo_ >> 4) & 1 ? "true" : "false")
310 .append(" isScrollable: ")
311 .append((canOverScrollInfo_ >> 3) & 1 ? "true" : "false")
312 .append(" scrollableIdle: ")
313 .append((canOverScrollInfo_ >> 2) & 1 ? "true" : "false")
314 .append(" animateOverScroll: ")
315 .append((canOverScrollInfo_ >> 1) & 1 ? "true" : "false")
316 .append(" animateCanOverScroll: ")
317 .append(canOverScrollInfo_ & 1 ? "true" : "false")
318 .append(" fired in ")
319 .append(std::to_string(scrollStateTime_));
320 }
321
ToJsonScrollableFrameInfo322 void ToJson(std::unique_ptr<JsonValue>& json) const
323 {
324 json->Put("scroll from", GetSourceStr(scrollState_).c_str());
325 json->Put("canOverScroll", std::to_string(canOverScroll_).c_str());
326 json->Put("isScrollableSpringEffect",
327 (canOverScrollInfo_ >> 4) & 1 ? "true" : "false"); // 4: isScrollableSpringEffect
328 json->Put("isScrollable", (canOverScrollInfo_ >> 3) & 1 ? "true" : "false"); // 3: isScrollable
329 json->Put("scrollableIdle", (canOverScrollInfo_ >> 2) & 1 ? "true" : "false"); // 2: scrollableIdle
330 json->Put("animateOverScroll", (canOverScrollInfo_ >> 1) & 1 ? "true" : "false");
331 json->Put("animateCanOverScroll", canOverScrollInfo_ & 1 ? "true" : "false");
332 json->Put("scroll from", std::to_string(scrollStateTime_).c_str());
333 }
334 };
335
336 struct ScrollLayoutInfo {
337 uint64_t changedTime_ = 0;
338 float scrollableDistance_ = 0;
339 NG::SizeF scrollSize_;
340 NG::SizeF viewPort_;
341 NG::SizeF childSize_;
342
ToStringScrollLayoutInfo343 std::string ToString() const
344 {
345 return std::string("scrollableDistance changed, scrollableDistance: ")
346 .append(std::to_string(scrollableDistance_))
347 .append(" scrollSize: ")
348 .append(scrollSize_.ToString())
349 .append(" viewPort: ")
350 .append(viewPort_.ToString())
351 .append(" childSize: ")
352 .append(childSize_.ToString())
353 .append(" fired in ")
354 .append(std::to_string(changedTime_));
355 }
356
ToJsonScrollLayoutInfo357 void ToJson(std::unique_ptr<JsonValue>& json) const
358 {
359 json->Put("scrollableDistance changed, scrollableDistance", std::to_string(scrollableDistance_).c_str());
360 json->Put("scrollSize", scrollSize_.ToString().c_str());
361 json->Put("viewPort", viewPort_.ToString().c_str());
362 json->Put("childSize", childSize_.ToString().c_str());
363 json->Put("fired in", std::to_string(changedTime_).c_str());
364 }
365 };
366
367 struct ScrollMeasureInfo {
368 uint64_t changedTime_ = 0;
369 std::optional<NG::LayoutConstraintF> parentConstraint_;
370 std::optional<NG::LayoutConstraintF> childConstraint_;
371 NG::SizeF selfSize_;
372 NG::SizeF childSize_;
373
ToStringScrollMeasureInfo374 std::string ToString() const
375 {
376 return std::string("Scroll Measure changed, parentConstraint: ")
377 .append(parentConstraint_->ToString())
378 .append(" childConstraint: ")
379 .append(childConstraint_->ToString())
380 .append(" selfSize: ")
381 .append(selfSize_.ToString())
382 .append(" childSize: ")
383 .append(childSize_.ToString())
384 .append(" fired in ")
385 .append(std::to_string(changedTime_));
386 }
387
ToJsonScrollMeasureInfo388 void ToJson(std::unique_ptr<JsonValue>& json) const
389 {
390 json->Put("Scroll Measure changed, parentConstraint", parentConstraint_->ToString().c_str());
391 json->Put("childConstraint", childConstraint_->ToString().c_str());
392 json->Put("selfSize", selfSize_.ToString().c_str());
393 json->Put("childSize", childSize_.ToString().c_str());
394 json->Put("fired in", std::to_string(changedTime_).c_str());
395 }
396 };
397
398 struct InnerScrollBarLayoutInfo {
399 uint64_t layoutTime_ = 0;
400 Size viewPortSize_;
401 Offset lastOffset_;
402 double estimatedHeight_ = 0.0;
403 double outBoundary_ = 0.0;
404 Rect activeRect_;
405
ToStringInnerScrollBarLayoutInfo406 std::string ToString() const
407 {
408 return std::string("inner scrollBar layout, viewPortSize:")
409 .append(viewPortSize_.ToString())
410 .append(" lastOffset: ")
411 .append(lastOffset_.ToString())
412 .append(" estimatedHeight: ")
413 .append(std::to_string(estimatedHeight_))
414 .append(" outBoundary: ")
415 .append(std::to_string(outBoundary_))
416 .append(" activeRect: ")
417 .append(activeRect_.ToString())
418 .append(" fired in ")
419 .append(std::to_string(layoutTime_));
420 }
421
ToJsonInnerScrollBarLayoutInfo422 void ToJson(std::unique_ptr<JsonValue>& json) const
423 {
424 json->Put("inner scrollBar layout, viewPortSize", viewPortSize_.ToString().c_str());
425 json->Put("lastOffset", lastOffset_.ToString().c_str());
426 json->Put("estimatedHeight", estimatedHeight_);
427 json->Put("outBoundary", std::to_string(outBoundary_).c_str());
428 json->Put("activeRect", activeRect_.ToString().c_str());
429 json->Put("fired in", std::to_string(layoutTime_).c_str());
430 }
431 };
432
433 struct OuterScrollBarLayoutInfo {
434 uint64_t layoutTime_ = 0;
435 float currentOffset_ = 0.f;
436 float scrollableNodeOffset_ = 0.f;
437
ToStringOuterScrollBarLayoutInfo438 std::string ToString() const
439 {
440 return std::string("outer scrollBar layout, currentOffset:")
441 .append(std::to_string(currentOffset_))
442 .append(" scrollableNodeOffset: ")
443 .append(std::to_string(scrollableNodeOffset_))
444 .append(" fired in ")
445 .append(std::to_string(layoutTime_));
446 }
447
ToJsonOuterScrollBarLayoutInfo448 void ToJson(std::unique_ptr<JsonValue>& json) const
449 {
450 json->Put("outer scrollBar layout, currentOffset", std::to_string(currentOffset_).c_str());
451 json->Put("scrollableNodeOffset", std::to_string(scrollableNodeOffset_).c_str());
452 json->Put("fired in", std::to_string(layoutTime_).c_str());
453 }
454 };
455
456 struct SnapAnimationOptions {
457 float snapDelta = 0.f;
458 float animationVelocity = 0.f;
459 float dragDistance = 0.f;
460 SnapDirection snapDirection = SnapDirection::NONE;
461 bool fromScrollBar = false;
462 };
463
464 // app tail animation
465 constexpr char TRAILING_ANIMATION[] = "TRAILING_ANIMATION ";
466
467 // scroller animation, such as scrollTo, scrollPage
468 constexpr char SCROLLER_ANIMATION[] = "CUSTOM_ANIMATOR_SCROLLER_ANIMATION ";
469
470 // scrollToEdge at a fixed speed
471 constexpr char SCROLLER_FIX_VELOCITY_ANIMATION[] = "SCROLLER_FIX_VELOCITY_ANIMATION ";
472
473 using OnScrollEvent = std::function<void(Dimension, ScrollState)>;
474 using OnDidScrollEvent = std::function<void(Dimension, ScrollSource, bool, bool)>;
475 using OnScrollerAreaChangeEvent = std::function<void(Dimension, ScrollSource, bool, bool)>;
476 using OnWillScrollEvent = std::function<ScrollFrameResult(Dimension, ScrollState, ScrollSource)>;
477 using OnScrollBeginEvent = std::function<ScrollInfo(Dimension, Dimension)>;
478 using OnScrollFrameBeginEvent = std::function<ScrollFrameResult(Dimension, ScrollState)>;
479 using OnScrollStartEvent = std::function<void()>;
480 using OnScrollStopEvent = std::function<void()>;
481 using OnReachEvent = std::function<void()>;
482 using OnScrollIndexEvent = std::function<void(int32_t, int32_t, int32_t)>;
483 using ScrollIndexFunc = std::function<void(int32_t, int32_t)>;
484 using OnScrollVisibleContentChangeEvent = std::function<void(ListItemIndex, ListItemIndex)>;
485 using OnWillStopDraggingEvent = std::function<void(Dimension)>;
486
487 using ScrollPositionCallback = std::function<bool(double, int32_t source)>;
488 using ScrollEndCallback = std::function<void()>;
489 using StartSnapAnimationCallback = std::function<bool(SnapAnimationOptions)>;
490 using ScrollBarFRCallback = std::function<void(double velocity, NG::SceneStatus sceneStatus)>;
491 using ScrollPageCallback = std::function<void(bool, bool smooth)>;
492 using OnWillScrollEventEx = std::function<void(ScrollFrameResult&, ScrollState, ScrollSource)>;
493 using TwoDimensionOnWillScrollEvent = std::function<void(ScrollFrameResult&,
494 ScrollFrameResult&, ScrollState, ScrollSource)>;
495
496 struct ScrollerObserver {
497 RefPtr<NG::TouchEventImpl> onTouchEvent;
498 OnReachEvent onReachStartEvent;
499 OnReachEvent onReachEndEvent;
500 OnScrollStartEvent onScrollStartEvent;
501 OnScrollStopEvent onScrollStopEvent;
502 OnDidScrollEvent onDidScrollEvent;
503 OnScrollerAreaChangeEvent onScrollerAreaChangeEvent;
504 OnWillScrollEventEx onWillScrollEventEx;
505 TwoDimensionOnWillScrollEvent twoDimensionOnWillScrollEvent;
506 };
507 } // namespace OHOS::Ace
508
509 #endif
510