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