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