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 ListItemIndex {
160 int32_t index = -1;
161 int32_t area = -1;
162 int32_t indexInGroup = -1;
163 };
164
165 constexpr int32_t SCROLL_FROM_NONE = 0;
166 constexpr int32_t SCROLL_FROM_UPDATE = 1;
167 constexpr int32_t SCROLL_FROM_ANIMATION = 2;
168 constexpr int32_t SCROLL_FROM_JUMP = 3;
169 constexpr int32_t SCROLL_FROM_ANIMATION_SPRING = 4;
170 constexpr int32_t SCROLL_FROM_CHILD = 5;
171 constexpr int32_t SCROLL_FROM_BAR = 6;
172 constexpr int32_t SCROLL_FROM_FOCUS_JUMP = 7;
173 constexpr int32_t SCROLL_FROM_ROTATE = 8;
174 constexpr int32_t SCROLL_FROM_INDEXER = 9;
175 constexpr int32_t SCROLL_FROM_START = 10; // from drag start
176 constexpr int32_t SCROLL_FROM_AXIS = 11;
177 constexpr int32_t SCROLL_FROM_ANIMATION_CONTROLLER = 12;
178 constexpr int32_t SCROLL_FROM_BAR_FLING = 13;
179
GetSourceStr(int32_t scrollSource)180 inline std::string GetSourceStr(int32_t scrollSource)
181 {
182 switch (scrollSource) {
183 case SCROLL_FROM_NONE:
184 return "SCROLL_FROM_NONE";
185 case SCROLL_FROM_UPDATE:
186 return "SCROLL_FROM_UPDATE";
187 case SCROLL_FROM_ANIMATION:
188 return "SCROLL_FROM_ANIMATION";
189 case SCROLL_FROM_JUMP:
190 return "SCROLL_FROM_JUMP";
191 case SCROLL_FROM_ANIMATION_SPRING:
192 return "SCROLL_FROM_ANIMATION_SPRING";
193 case SCROLL_FROM_CHILD:
194 return "SCROLL_FROM_CHILD";
195 case SCROLL_FROM_BAR:
196 return "SCROLL_FROM_BAR";
197 case SCROLL_FROM_FOCUS_JUMP:
198 return "SCROLL_FROM_FOCUS_JUMP";
199 case SCROLL_FROM_ROTATE:
200 return "SCROLL_FROM_ROTATE";
201 case SCROLL_FROM_INDEXER:
202 return "SCROLL_FROM_INDEXER";
203 case SCROLL_FROM_START:
204 return "SCROLL_FROM_START";
205 case SCROLL_FROM_AXIS:
206 return "SCROLL_FROM_AXIS";
207 case SCROLL_FROM_ANIMATION_CONTROLLER:
208 return "SCROLL_FROM_ANIMATION_CONTROLLER";
209 case SCROLL_FROM_BAR_FLING:
210 return "SCROLL_FROM_BAR_FLING";
211 default:
212 return "";
213 }
214 }
215
216 struct ScrollableEventsFiredInfo {
217 uint64_t eventFiredTime_ = 0;
218 ScrollableEventType eventType_;
219 int32_t scrollSource_ = 0;
220
ToStringScrollableEventsFiredInfo221 std::string ToString() const
222 {
223 return std::string("event type: ")
224 .append(GetEventStr())
225 .append(" fired in ")
226 .append(std::to_string(eventFiredTime_))
227 .append(", source is ")
228 .append(GetSourceStr(scrollSource_));
229 }
230
GetEventStrScrollableEventsFiredInfo231 std::string GetEventStr() const
232 {
233 switch (eventType_) {
234 case ScrollableEventType::ON_SCROLL_START:
235 return "onScrollStart";
236 case ScrollableEventType::ON_SCROLL_STOP:
237 return "onScrollStop";
238 case ScrollableEventType::ON_SCROLL_EDGE:
239 return "onScrollEdge";
240 case ScrollableEventType::ON_REACH_START:
241 return "onReachStart";
242 case ScrollableEventType::ON_REACH_END:
243 return "onReachEnd";
244 default:
245 return "";
246 }
247 }
248 };
249
250 struct ScrollableFrameInfo {
251 uint64_t scrollStateTime_ = 0;
252 int32_t scrollState_ = 0;
253 bool canOverScroll_ = false;
254 uint32_t canOverScrollInfo_ = 0;
255
ToStringScrollableFrameInfo256 std::string ToString() const
257 {
258 return std::string("scroll from: ")
259 .append(GetSourceStr(scrollState_))
260 .append(" canOverScroll: ")
261 .append(std::to_string(canOverScroll_))
262 .append(" isScrollableSpringEffect: ")
263 .append((canOverScrollInfo_ >> 4) & 1 ? "true" : "false")
264 .append(" isScrollable: ")
265 .append((canOverScrollInfo_ >> 3) & 1 ? "true" : "false")
266 .append(" scrollableIdle: ")
267 .append((canOverScrollInfo_ >> 2) & 1 ? "true" : "false")
268 .append(" animateOverScroll: ")
269 .append((canOverScrollInfo_ >> 1) & 1 ? "true" : "false")
270 .append(" animateCanOverScroll: ")
271 .append(canOverScrollInfo_ & 1 ? "true" : "false")
272 .append(" fired in ")
273 .append(std::to_string(scrollStateTime_));
274 }
275 };
276
277 struct ScrollLayoutInfo {
278 uint64_t changedTime_ = 0;
279 float scrollableDistance_ = 0;
280 NG::SizeF scrollSize_;
281 NG::SizeF viewPort_;
282 NG::SizeF childSize_;
283
ToStringScrollLayoutInfo284 std::string ToString() const
285 {
286 return std::string("scrollableDistance changed, scrollableDistance: ")
287 .append(std::to_string(scrollableDistance_))
288 .append(" scrollSize: ")
289 .append(scrollSize_.ToString())
290 .append(" viewPort: ")
291 .append(viewPort_.ToString())
292 .append(" childSize: ")
293 .append(childSize_.ToString())
294 .append(" fired in ")
295 .append(std::to_string(changedTime_));
296 }
297 };
298
299 struct ScrollMeasureInfo {
300 uint64_t changedTime_ = 0;
301 std::optional<NG::LayoutConstraintF> parentConstraint_;
302 std::optional<NG::LayoutConstraintF> childConstraint_;
303 NG::SizeF selfSize_;
304 NG::SizeF childSize_;
305
ToStringScrollMeasureInfo306 std::string ToString() const
307 {
308 return std::string("Scroll Measure changed, parentConstraint: ")
309 .append(parentConstraint_->ToString())
310 .append(" childConstraint: ")
311 .append(childConstraint_->ToString())
312 .append(" selfSize: ")
313 .append(selfSize_.ToString())
314 .append(" childSize: ")
315 .append(childSize_.ToString())
316 .append(" fired in ")
317 .append(std::to_string(changedTime_));
318 }
319 };
320
321 struct InnerScrollBarLayoutInfo {
322 uint64_t layoutTime_ = 0;
323 Size viewPortSize_;
324 Offset lastOffset_;
325 double estimatedHeight_ = 0.0;
326 double outBoundary_ = 0.0;
327 Rect activeRect_;
328
ToStringInnerScrollBarLayoutInfo329 std::string ToString() const
330 {
331 return std::string("inner scrollBar layout, viewPortSize:")
332 .append(viewPortSize_.ToString())
333 .append(" lastOffset: ")
334 .append(lastOffset_.ToString())
335 .append(" estimatedHeight: ")
336 .append(std::to_string(estimatedHeight_))
337 .append(" outBoundary: ")
338 .append(std::to_string(outBoundary_))
339 .append(" activeRect: ")
340 .append(activeRect_.ToString())
341 .append(" fired in ")
342 .append(std::to_string(layoutTime_));
343 }
344 };
345
346 struct OuterScrollBarLayoutInfo {
347 uint64_t layoutTime_ = 0;
348 float currentOffset_ = 0.f;
349 float scrollableNodeOffset_ = 0.f;
350
ToStringOuterScrollBarLayoutInfo351 std::string ToString() const
352 {
353 return std::string("outer scrollBar layout, currentOffset:")
354 .append(std::to_string(currentOffset_))
355 .append(" scrollableNodeOffset: ")
356 .append(std::to_string(scrollableNodeOffset_))
357 .append(" fired in ")
358 .append(std::to_string(layoutTime_));
359 }
360 };
361
362 enum class ScrollSource {
363 DRAG = 0, // constexpr int32_t SCROLL_FROM_UPDATE = 1;
364 FLING, // constexpr int32_t SCROLL_FROM_ANIMATION = 2;
365 EDGE_EFFECT, // constexpr int32_t SCROLL_FROM_ANIMATION_SPRING = 4;
366 OTHER_USER_INPUT, // constexpr int32_t SCROLL_FROM_AXIS = 11;
367 SCROLL_BAR, // constexpr int32_t SCROLL_FROM_BAR = 6;
368 SCROLL_BAR_FLING, // constexpr int32_t SCROLL_FROM_BAR_FLING = 13;
369 SCROLLER, // constexpr int32_t SCROLL_FROM_JUMP = 3;
370 SCROLLER_ANIMATION, // constexpr int32_t SCROLL_FROM_ANIMATION_CONTROLLER = 12;
371 };
372
373 // app tail animation
374 constexpr char TRAILING_ANIMATION[] = "TRAILING_ANIMATION ";
375
376 // scroller animation, such as scrollTo, scrollPage
377 constexpr char SCROLLER_ANIMATION[] = "CUSTOM_ANIMATOR_SCROLLER_ANIMATION ";
378
379 // scrollToEdge at a fixed speed
380 constexpr char SCROLLER_FIX_VELOCITY_ANIMATION[] = "SCROLLER_FIX_VELOCITY_ANIMATION ";
381
382 using OnScrollEvent = std::function<void(Dimension, ScrollState)>;
383 using OnDidScrollEvent = std::function<void(Dimension, ScrollState, bool, bool)>;
384 using OnWillScrollEvent = std::function<ScrollFrameResult(Dimension, ScrollState, ScrollSource)>;
385 using OnScrollBeginEvent = std::function<ScrollInfo(Dimension, Dimension)>;
386 using OnScrollFrameBeginEvent = std::function<ScrollFrameResult(Dimension, ScrollState)>;
387 using OnScrollStartEvent = std::function<void()>;
388 using OnScrollStopEvent = std::function<void()>;
389 using OnReachEvent = std::function<void()>;
390 using OnScrollIndexEvent = std::function<void(int32_t, int32_t, int32_t)>;
391 using OnScrollVisibleContentChangeEvent = std::function<void(ListItemIndex, ListItemIndex)>;
392
393 using ScrollPositionCallback = std::function<bool(double, int32_t source)>;
394 using ScrollEndCallback = std::function<void()>;
395 using CalePredictSnapOffsetCallback =
396 std::function<std::optional<float>(float delta, float dragDistance, float velocity)>;
397 using StartScrollSnapMotionCallback = std::function<void(float scrollSnapDelta, float scrollSnapVelocity)>;
398 using ScrollBarFRCallback = std::function<void(double velocity, NG::SceneStatus sceneStatus)>;
399
400 struct ScrollerObserver {
401 RefPtr<NG::TouchEventImpl> onTouchEvent;
402 GestureEventFunc onPanActionEndEvent;
403 OnReachEvent onReachStartEvent;
404 OnReachEvent onReachEndEvent;
405 OnScrollStartEvent onScrollStartEvent;
406 OnScrollStopEvent onScrollStopEvent;
407 OnDidScrollEvent onDidScrollEvent;
408 };
409 } // namespace OHOS::Ace
410
411 #endif
412