• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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_interface.h"
23 #include "core/components/scroll/scrollable.h"
24 #include "core/pipeline/base/render_node.h"
25 
26 namespace OHOS::Ace {
27 
28 constexpr uint32_t POSITION_MIDDLE = 0;
29 constexpr uint32_t POSITION_TOP = 1 << 0;
30 constexpr uint32_t POSITION_BOTTOM = 1 << 1;
31 
32 enum class ScrollEvent : size_t {
33     SCROLL_TOP = 0,
34     SCROLL_BOTTOM,
35     SCROLL_TOUCHUP,
36     SCROLL_END,
37     SCROLL_POSITION,
38     SCROLL_EDGE,
39     SCROLL_LEFT,
40     SCROLL_RIGHT,
41     UNKNOWN,
42 };
43 
44 using OnScrollFunc = std::function<void(const std::string&)>;
45 
46 class ScrollEventInfo : public BaseEventInfo, public EventToJSONStringAdapter {
47     DECLARE_RELATIONSHIP_OF_CLASSES(ScrollEventInfo, BaseEventInfo, EventToJSONStringAdapter);
48 public:
49     ScrollEventInfo(ScrollEvent type, double scrollX, double scrollY, int32_t scrollState);
50 
51     ~ScrollEventInfo() = default;
52 
53     std::string ToJSONString() const override;
54 
GetType()55     ScrollEvent GetType() const
56     {
57         return type_;
58     }
59 
GetScrollX()60     double GetScrollX() const
61     {
62         return scrollX_;
63     }
64 
GetScrollY()65     double GetScrollY() const
66     {
67         return scrollY_;
68     }
69 
GetScrollState()70     int32_t GetScrollState() const
71     {
72         return scrollState_;
73     }
74 
SetScrollType(ScrollEvent type)75     void SetScrollType(ScrollEvent type)
76     {
77         type_ = type;
78     }
79 
80 private:
81     ScrollEvent type_ = ScrollEvent::SCROLL_TOP;
82     double scrollX_ = 0.0;
83     double scrollY_ = 0.0;
84     int32_t scrollState_ = -1;
85 };
86 
87 using ScrollEventFunc = std::function<void(std::shared_ptr<ScrollEventInfo>&)>;
88 class ACE_EXPORT ScrollPositionController : public ScrollController {
89     DECLARE_ACE_TYPE(ScrollPositionController, AceType);
90 
91 public:
92     ScrollPositionController() = default;
93     ~ScrollPositionController() override = default;
94 
SetInitialIndex(int32_t index)95     void SetInitialIndex(int32_t index)
96     {
97         if (index == 0) {
98             flags_ = POSITION_TOP;
99         } else {
100             flags_ = POSITION_MIDDLE;
101         }
102         initialIndex_ = index;
103     }
104 
GetInitialIndex()105     int32_t GetInitialIndex() const
106     {
107         return initialIndex_;
108     }
109 
SetInitialOffset(double initialOffset)110     void SetInitialOffset(double initialOffset)
111     {
112         if (NearZero(initialOffset)) {
113             flags_ = POSITION_TOP;
114         } else {
115             flags_ = POSITION_MIDDLE;
116         }
117         initialOffset_ = initialOffset;
118     }
119 
GetInitialOffset()120     double GetInitialOffset() const
121     {
122         return initialOffset_;
123     }
124 
125     double GetCurrentPosition() const;
126     Axis GetScrollDirection() const override;
127 
128     void JumpTo(int32_t index, int32_t source = SCROLL_FROM_JUMP) override;
129     void JumpTo(double position);
130     bool AnimateTo(const Dimension& position, float duration, const RefPtr<Curve>& curve) override;
131     bool AnimateTo(double position, float duration, const RefPtr<Curve>& curve, bool limitDuration = true,
132         const std::function<void()>& onFinish = nullptr);
133     bool AnimateToTarget(const ComposeId& targetId, float duration, const RefPtr<Curve>& curve,
134         bool limitDuration = true, const std::function<void()>& onFinish = nullptr);
135     void ScrollBy(double pixelX, double pixelY, bool smooth) override;
136     void ScrollArrow(double scrollDistance, bool reverse, bool smooth);
137     void ScrollToEdge(ScrollEdgeType scrollEdgeType, bool smooth) override;
138     void ScrollPage(bool reverse, bool smooth) override;
139     Offset GetCurrentOffset() const override;
140 
141 
SetScrollEvent(ScrollEvent event,const ScrollEventFunc & scrollEvent)142     void SetScrollEvent(
143         ScrollEvent event, const ScrollEventFunc& scrollEvent)
144     {
145         switch (event) {
146             case ScrollEvent::SCROLL_TOP:
147                 scrollTop_ = scrollEvent;
148                 break;
149             case ScrollEvent::SCROLL_BOTTOM:
150                 scrollBottom_ = scrollEvent;
151                 break;
152             case ScrollEvent::SCROLL_END:
153                 scrollEnd_ = scrollEvent;
154                 break;
155             case ScrollEvent::SCROLL_TOUCHUP:
156                 scrollTouchUp_ = scrollEvent;
157                 break;
158             case ScrollEvent::SCROLL_POSITION:
159                 scrollPosition_ = scrollEvent;
160                 break;
161             case ScrollEvent::SCROLL_EDGE:
162                 scrollEdge_ = scrollEvent;
163                 break;
164             default:
165                 LOGW("unknown scroll event");
166                 break;
167         }
168     }
169 
HandleScrollEvent(std::shared_ptr<ScrollEventInfo> info)170     void HandleScrollEvent(std::shared_ptr<ScrollEventInfo> info) const
171     {
172         if (!info) {
173             LOGE("scroll event info is null");
174             return;
175         }
176         auto eventType = info->GetType();
177         switch (eventType) {
178             case ScrollEvent::SCROLL_TOP:
179                 if (scrollTop_) {
180                     scrollTop_(info);
181                 }
182                 if (scrollEdge_) {
183                     scrollEdge_(info);
184                 }
185                 break;
186             case ScrollEvent::SCROLL_BOTTOM:
187                 if (scrollBottom_) {
188                     scrollBottom_(info);
189                 }
190                 if (scrollEdge_) {
191                     scrollEdge_(info);
192                 }
193                 break;
194             case ScrollEvent::SCROLL_END:
195                 if (scrollEnd_) {
196                     scrollEnd_(info);
197                 }
198                 break;
199             case ScrollEvent::SCROLL_TOUCHUP:
200                 if (scrollTouchUp_) {
201                     scrollTouchUp_(info);
202                 }
203                 break;
204             case ScrollEvent::SCROLL_POSITION:
205                 if (scrollPosition_) {
206                     scrollPosition_(info);
207                 }
208                 break;
209             default:
210                 LOGW("handle unknown scroll event");
211                 break;
212         }
213     }
214 
SetTop()215     void SetTop()
216     {
217         flags_ |= POSITION_TOP;
218     }
219 
SetBottom()220     void SetBottom()
221     {
222         flags_ |= POSITION_BOTTOM;
223     }
224 
SetMiddle()225     void SetMiddle()
226     {
227         flags_ = POSITION_MIDDLE;
228     }
229 
IsTop()230     bool IsTop() const
231     {
232         return (flags_ & POSITION_TOP);
233     }
234 
IsBottom()235     bool IsBottom() const
236     {
237         return (flags_ & POSITION_BOTTOM);
238     }
239 
SetNonScrollable()240     void SetNonScrollable()
241     {
242         flags_ = (POSITION_TOP | POSITION_BOTTOM);
243     }
244 
245     using OnFirstChanged = std::function<void(int32_t)>;
AddFirstChangedCallback(const OnFirstChanged & callback)246     void AddFirstChangedCallback(const OnFirstChanged& callback)
247     {
248         onChanged_ = callback;
249     }
250 
251     using IndexerRotation = std::function<bool()>;
AddIndexerStateQueryCallback(const IndexerRotation & callback)252     void AddIndexerStateQueryCallback(const IndexerRotation& callback)
253     {
254         indexerRotationCallback_ = callback;
255     }
256 
IsScrollNeedRotation()257     bool IsScrollNeedRotation()
258     {
259         return  !(indexerRotationCallback_ && indexerRotationCallback_());
260     }
261 
SetFirstItemIndex(int32_t firstIndex)262     void SetFirstItemIndex(int32_t firstIndex)
263     {
264         firstIndex_ = firstIndex;
265         if (onChanged_) {
266             onChanged_(firstIndex_);
267         }
268     }
269 
GetFirstItemIndex()270     int32_t GetFirstItemIndex() const
271     {
272         return firstIndex_;
273     }
274 
275 private:
276     int32_t initialIndex_ = 0;
277     double initialOffset_ = 0.0;
278     OnFirstChanged onChanged_;
279     IndexerRotation indexerRotationCallback_;
280     int32_t firstIndex_ = 0;
281 
282     ScrollEventFunc scrollTop_;
283     ScrollEventFunc scrollBottom_;
284     ScrollEventFunc scrollTouchUp_;
285     ScrollEventFunc scrollEnd_;
286     ScrollEventFunc scrollPosition_;
287     ScrollEventFunc scrollEdge_;
288     uint32_t flags_ = POSITION_TOP;
289 };
290 
291 } // namespace OHOS::Ace
292 
293 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SCROLL_SCROLL_POSITION_CONTROLLER_H
294