• 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 #include "core/components/scroll/scroll_position_controller.h"
17 
18 #include "core/animation/curves.h"
19 #include "core/components/scroll/render_scroll.h"
20 
21 namespace OHOS::Ace {
22 
ScrollEventInfo(ScrollEvent type,double scrollX,double scrollY,int32_t scrollState)23 ScrollEventInfo::ScrollEventInfo(ScrollEvent type, double scrollX, double scrollY, int32_t scrollState)
24     : BaseEventInfo("scroll"), type_(type), scrollX_(scrollX), scrollY_(scrollY), scrollState_(scrollState)
25 {}
26 
ToJSONString() const27 std::string ScrollEventInfo::ToJSONString() const
28 {
29     switch (type_) {
30         case ScrollEvent::SCROLL_TOP:
31             return std::string("\"scrolltop\",null");
32         case ScrollEvent::SCROLL_BOTTOM:
33             return std::string("\"scrollbottom\",null");
34         case ScrollEvent::SCROLL_END:
35             return std::string("\"scrollend\",null");
36         case ScrollEvent::SCROLL_TOUCHUP:
37             return std::string("\"scrolltouchup\",null");
38         case ScrollEvent::SCROLL_POSITION:
39             return std::string("\"scroll\",{\"scrollX\":")
40                         .append(std::to_string(scrollX_))
41                         .append(",\"scrollY\":")
42                         .append(std::to_string(scrollY_))
43                         .append(",\"scrollState\":")
44                         .append(std::to_string(scrollState_))
45                         .append("},null");
46         default:
47             return "";
48     }
49 }
50 
JumpTo(int32_t index,int32_t source)51 void ScrollPositionController::JumpTo(int32_t index, int32_t source)
52 {
53     RefPtr<RenderNode> node = scroll_.Upgrade();
54     if (node) {
55         auto scroll = AceType::DynamicCast<RenderScroll>(node);
56         if (scroll) {
57             scroll->JumpToIndex(index, source);
58         }
59     }
60 }
61 
JumpTo(double position)62 void ScrollPositionController::JumpTo(double position)
63 {
64     RefPtr<RenderNode> node = scroll_.Upgrade();
65     if (node) {
66         auto scroll = AceType::DynamicCast<RenderScroll>(node);
67         if (scroll) {
68             scroll->JumpToPosition(position);
69         }
70     }
71 }
72 
AnimateTo(double position,float duration,const RefPtr<Curve> & curve,bool limitDuration,const std::function<void ()> & onFinish)73 bool ScrollPositionController::AnimateTo(double position, float duration, const RefPtr<Curve>& curve,
74     bool limitDuration, const std::function<void()>& onFinish)
75 {
76     RefPtr<RenderNode> node = scroll_.Upgrade();
77     if (node) {
78         auto scroll = AceType::DynamicCast<RenderScroll>(node);
79         if (scroll) {
80             scroll->AnimateTo(position, duration, curve, limitDuration, onFinish);
81             return true;
82         }
83     }
84     return false;
85 }
86 
AnimateTo(const Dimension & position,float duration,const RefPtr<Curve> & curve)87 bool ScrollPositionController::AnimateTo(const Dimension& position, float duration, const RefPtr<Curve>& curve)
88 {
89     RefPtr<RenderNode> node = scroll_.Upgrade();
90     if (node) {
91         auto scroll = AceType::DynamicCast<RenderScroll>(node);
92         if (scroll && scroll->GetAxis() != Axis::NONE) {
93             auto normalizedPos = scroll->NormalizePercentToPx(position, scroll->GetAxis() == Axis::VERTICAL);
94             scroll->AnimateTo(normalizedPos, duration, curve, true, nullptr);
95             return true;
96         }
97     }
98     return false;
99 }
100 
AnimateToTarget(const ComposeId & targetId,float duration,const RefPtr<Curve> & curve,bool limitDuration,const std::function<void ()> & onFinish)101 bool ScrollPositionController::AnimateToTarget(const ComposeId& targetId, float duration, const RefPtr<Curve>& curve,
102     bool limitDuration, const std::function<void()>& onFinish)
103 {
104     RefPtr<RenderNode> node = scroll_.Upgrade();
105     if (node) {
106         auto scroll = AceType::DynamicCast<RenderScroll>(node);
107         if (scroll) {
108             return scroll->AnimateToTarget(targetId, duration, curve, limitDuration, onFinish);
109         }
110     }
111     return false;
112 }
113 
ScrollBy(double pixelX,double pixelY,bool smooth)114 void ScrollPositionController::ScrollBy(double pixelX, double pixelY, bool smooth)
115 {
116     RefPtr<RenderNode> node = scroll_.Upgrade();
117     if (node) {
118         auto scroll = AceType::DynamicCast<RenderScroll>(node);
119         if (scroll) {
120             scroll->ScrollBy(pixelX, pixelY, smooth);
121         }
122     }
123 }
124 
ScrollArrow(double scrollDistance,bool reverse,bool smooth)125 void ScrollPositionController::ScrollArrow(double scrollDistance, bool reverse, bool smooth)
126 {
127     if (scrollDistance > 0.0) {
128         RefPtr<RenderNode> node = scroll_.Upgrade();
129         if (node) {
130             auto scroll = AceType::DynamicCast<RenderScroll>(node);
131             if (scroll) {
132                 if (reverse) {
133                     ScrollBy(-scrollDistance, -scrollDistance, smooth);
134                 } else {
135                     ScrollBy(scrollDistance, scrollDistance, smooth);
136                 }
137             }
138         }
139     }
140 }
141 
GetCurrentPosition() const142 double ScrollPositionController::GetCurrentPosition() const
143 {
144     RefPtr<RenderNode> node = scroll_.Upgrade();
145     if (!node) {
146         return 0.0;
147     }
148     auto scroll = AceType::DynamicCast<RenderScroll>(node);
149     if (!scroll) {
150         return 0.0;
151     }
152 
153     return scroll->GetCurrentPosition();
154 }
155 
GetScrollDirection() const156 Axis ScrollPositionController::GetScrollDirection() const
157 {
158     auto direction = Axis::VERTICAL;
159     RefPtr<RenderNode> node = scroll_.Upgrade();
160     if (node) {
161         auto scroll = AceType::DynamicCast<RenderScroll>(node);
162         if (scroll) {
163             direction = scroll->GetAxis();
164         }
165     }
166     return direction;
167 }
168 
ScrollToEdge(ScrollEdgeType scrollEdgeType,bool smooth)169 void ScrollPositionController::ScrollToEdge(ScrollEdgeType scrollEdgeType, bool smooth)
170 {
171     RefPtr<RenderNode> node = scroll_.Upgrade();
172     if (node) {
173         auto scroll = AceType::DynamicCast<RenderScroll>(node);
174         if (scroll && scroll->GetAxis() != Axis::NONE) {
175             scroll->ScrollToEdge(scrollEdgeType, smooth);
176         }
177     }
178 }
179 
ScrollPage(bool reverse,bool smooth)180 void ScrollPositionController::ScrollPage(bool reverse, bool smooth)
181 {
182     RefPtr<RenderNode> node = scroll_.Upgrade();
183     if (node) {
184         auto scroll = AceType::DynamicCast<RenderScroll>(node);
185         if (scroll && scroll->GetAxis() != Axis::NONE) {
186             scroll->ScrollPage(reverse, smooth);
187         }
188     }
189 }
190 
GetCurrentOffset() const191 Offset ScrollPositionController::GetCurrentOffset() const
192 {
193     RefPtr<RenderNode> node = scroll_.Upgrade();
194     auto scroll = AceType::DynamicCast<RenderScroll>(node);
195     if (!scroll) {
196         return Offset::Zero();
197     }
198 
199     auto ctx = scroll->GetContext().Upgrade();
200     if (!ctx) {
201         return Offset::Zero();
202     }
203     if (!ctx->GetIsDeclarative()) {
204         return scroll->GetCurrentOffset();
205     }
206 
207     auto pxOffset = scroll->GetCurrentOffset();
208     auto x = Dimension(pxOffset.GetX(), DimensionUnit::PX);
209     auto y = Dimension(pxOffset.GetY(), DimensionUnit::PX);
210     Offset offset(ctx->ConvertPxToVp(x), ctx->ConvertPxToVp(y));
211 
212     return offset;
213 }
214 
215 } // namespace OHOS::Ace
216