• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "core/components_ng/pattern/refresh/refresh_model_ng.h"
17 
18 #include <string>
19 
20 #include "base/utils/multi_thread.h"
21 #include "core/components_ng/pattern/refresh/refresh_pattern.h"
22 #include "core/components_ng/pattern/render_node/render_node_pattern.h"
23 #include "frameworks/base/geometry/dimension.h"
24 #include "frameworks/base/geometry/ng/offset_t.h"
25 #include "frameworks/base/i18n/localization.h"
26 #include "frameworks/base/utils/time_util.h"
27 #include "frameworks/core/components_ng/base/frame_node.h"
28 #include "frameworks/core/components_ng/base/view_stack_processor.h"
29 #include "frameworks/core/components_ng/event/event_hub.h"
30 #include "core/common/resource/resource_parse_utils.h"
31 
32 namespace OHOS::Ace::NG {
33 
34 namespace {
35 constexpr double DEFAULT_INDICATOR_OFFSET = 16.0;
36 constexpr int32_t DEFAULT_FRICTION_RATIO = 62;
37 constexpr double DEFAULT_REFRESH_OFFSET = 64.0f;
38 } // namespace
39 
Create()40 void RefreshModelNG::Create()
41 {
42     auto* stack = ViewStackProcessor::GetInstance();
43     auto nodeId = stack->ClaimNodeId();
44     ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::REFRESH_ETS_TAG, nodeId);
45     auto frameNode = FrameNode::GetOrCreateFrameNode(
46         V2::REFRESH_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<RefreshPattern>(); });
47     CHECK_NULL_VOID(frameNode);
48     stack->Push(frameNode);
49     if (frameNode->GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
50         auto pattern = frameNode->GetPattern<RefreshPattern>();
51         CHECK_NULL_VOID(pattern);
52         pattern->UpdateNestedModeForChildren(NestedScrollOptions({
53             .forward = NestedScrollMode::PARENT_FIRST,
54             .backward = NestedScrollMode::SELF_FIRST,
55         }));
56     }
57     ACE_UPDATE_LAYOUT_PROPERTY(
58         RefreshLayoutProperty, IndicatorOffset, Dimension(DEFAULT_INDICATOR_OFFSET, DimensionUnit::VP));
59     ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, Friction, DEFAULT_FRICTION_RATIO);
60 }
61 
CreateFrameNode(int32_t nodeId)62 RefPtr<FrameNode> RefreshModelNG::CreateFrameNode(int32_t nodeId)
63 {
64     auto frameNode = FrameNode::CreateFrameNode(V2::REFRESH_ETS_TAG, nodeId, AceType::MakeRefPtr<RefreshPattern>());
65     CHECK_NULL_RETURN(frameNode, frameNode);
66     if (frameNode->GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
67         auto pattern = frameNode->GetPattern<RefreshPattern>();
68         CHECK_NULL_RETURN(pattern, frameNode);
69         pattern->UpdateNestedModeForChildren(NestedScrollOptions({
70             .forward = NestedScrollMode::PARENT_FIRST,
71             .backward = NestedScrollMode::SELF_FIRST,
72         }));
73     }
74     auto layoutProperty = frameNode->GetLayoutProperty<RefreshLayoutProperty>();
75     layoutProperty->UpdateIndicatorOffset(Dimension(DEFAULT_INDICATOR_OFFSET, DimensionUnit::VP));
76     layoutProperty->UpdateFriction(DEFAULT_FRICTION_RATIO);
77     return frameNode;
78 }
79 
SetPullToRefresh(bool pullToRefresh)80 void RefreshModelNG::SetPullToRefresh(bool pullToRefresh)
81 {
82     ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, PullToRefresh, pullToRefresh);
83 }
84 
SetRefreshOffset(const Dimension & offset)85 void RefreshModelNG::SetRefreshOffset(const Dimension& offset)
86 {
87     ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, RefreshOffset, offset);
88 }
89 
SetRefreshing(bool isRefreshing)90 void RefreshModelNG::SetRefreshing(bool isRefreshing)
91 {
92     ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, IsRefreshing, isRefreshing);
93 }
94 
SetIndicatorOffset(const Dimension & indicatorOffset)95 void RefreshModelNG::SetIndicatorOffset(const Dimension& indicatorOffset)
96 {
97     ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, IndicatorOffset, indicatorOffset);
98 }
99 
SetFriction(int32_t friction)100 void RefreshModelNG::SetFriction(int32_t friction)
101 {
102     ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, Friction, friction);
103 }
104 
SetLoadingText(const std::string & loadingText)105 void RefreshModelNG::SetLoadingText(const std::string& loadingText)
106 {
107     ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, LoadingText, loadingText);
108 }
109 
CreateWithResourceObj(const RefPtr<ResourceObject> & resObj)110 void RefreshModelNG::CreateWithResourceObj(const RefPtr<ResourceObject>& resObj)
111 {
112     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
113     CHECK_NULL_VOID(frameNode);
114     auto pattern = frameNode->GetPattern<RefreshPattern>();
115     CHECK_NULL_VOID(pattern);
116     pattern->RemoveResObj("refresh.promptText");
117     CHECK_NULL_VOID(resObj);
118     auto&& updateFunc = [weak = AceType::WeakClaim(frameNode)](const RefPtr<ResourceObject>& resObj) {
119         auto node = weak.Upgrade();
120         CHECK_NULL_VOID(node);
121         std::string result;
122         if (!ResourceParseUtils::ParseResString(resObj, result)) {
123             ACE_RESET_NODE_LAYOUT_PROPERTY(RefreshLayoutProperty, LoadingText, AceType::RawPtr(node));
124         } else {
125             ACE_UPDATE_NODE_LAYOUT_PROPERTY(RefreshLayoutProperty, LoadingText, result, AceType::RawPtr(node));
126         }
127     };
128     pattern->AddResObj("refresh.promptText", resObj, std::move(updateFunc));
129 }
130 
ResetLoadingText()131 void RefreshModelNG::ResetLoadingText()
132 {
133     ACE_RESET_LAYOUT_PROPERTY(RefreshLayoutProperty, LoadingText);
134 }
135 
SetOnStateChange(StateChangeEvent && stateChange)136 void RefreshModelNG::SetOnStateChange(StateChangeEvent&& stateChange)
137 {
138     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
139     CHECK_NULL_VOID(frameNode);
140     auto eventHub = frameNode->GetOrCreateEventHub<RefreshEventHub>();
141     CHECK_NULL_VOID(eventHub);
142     eventHub->SetOnStateChange(std::move(stateChange));
143 }
144 
SetOnRefreshing(RefreshingEvent && refreshing)145 void RefreshModelNG::SetOnRefreshing(RefreshingEvent&& refreshing)
146 {
147     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
148     CHECK_NULL_VOID(frameNode);
149     auto eventHub = frameNode->GetOrCreateEventHub<RefreshEventHub>();
150     CHECK_NULL_VOID(eventHub);
151     eventHub->SetOnRefreshing(std::move(refreshing));
152 }
153 
SetChangeEvent(RefreshChangeEvent && changeEvent)154 void RefreshModelNG::SetChangeEvent(RefreshChangeEvent&& changeEvent)
155 {
156     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
157     CHECK_NULL_VOID(frameNode);
158     auto eventHub = frameNode->GetOrCreateEventHub<RefreshEventHub>();
159     CHECK_NULL_VOID(eventHub);
160     eventHub->SetChangeEvent(std::move(changeEvent));
161 }
162 
SetOnOffsetChange(OffsetChangeEvent && dragOffset)163 void RefreshModelNG::SetOnOffsetChange(OffsetChangeEvent&& dragOffset)
164 {
165     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
166     CHECK_NULL_VOID(frameNode);
167     auto eventHub = frameNode->GetOrCreateEventHub<RefreshEventHub>();
168     CHECK_NULL_VOID(eventHub);
169     eventHub->SetOnOffsetChange(std::move(dragOffset));
170 }
171 
ResetOnOffsetChange()172 void RefreshModelNG::ResetOnOffsetChange()
173 {
174     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
175     CHECK_NULL_VOID(frameNode);
176     auto eventHub = frameNode->GetOrCreateEventHub<RefreshEventHub>();
177     CHECK_NULL_VOID(eventHub);
178     eventHub->ResetOnOffsetChange();
179 }
180 
SetMaxPullDownDistance(const std::optional<float> & maxDistance)181 void RefreshModelNG::SetMaxPullDownDistance(const std::optional<float>& maxDistance)
182 {
183     if (maxDistance.has_value()) {
184         ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, MaxPullDownDistance, maxDistance.value());
185     } else {
186         ACE_RESET_LAYOUT_PROPERTY(RefreshLayoutProperty, MaxPullDownDistance);
187     }
188 }
189 
SetMaxPullDownDistance(FrameNode * frameNode,const std::optional<float> & maxDistance)190 void RefreshModelNG::SetMaxPullDownDistance(FrameNode* frameNode, const std::optional<float>& maxDistance)
191 {
192     if (maxDistance.has_value()) {
193         ACE_UPDATE_NODE_LAYOUT_PROPERTY(RefreshLayoutProperty, MaxPullDownDistance, maxDistance.value(), frameNode);
194     } else {
195         ACE_RESET_NODE_LAYOUT_PROPERTY(RefreshLayoutProperty, MaxPullDownDistance, frameNode);
196     }
197 }
198 
SetPullDownRatio(const std::optional<float> & pullDownRatio)199 void RefreshModelNG::SetPullDownRatio(const std::optional<float>& pullDownRatio)
200 {
201     if (pullDownRatio.has_value()) {
202         ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, PullDownRatio, pullDownRatio.value());
203     } else {
204         ACE_RESET_LAYOUT_PROPERTY(RefreshLayoutProperty, PullDownRatio);
205     }
206 }
207 
SetPullDownRatio(FrameNode * frameNode,const std::optional<float> & pullDownRatio)208 void RefreshModelNG::SetPullDownRatio(FrameNode* frameNode, const std::optional<float>& pullDownRatio)
209 {
210     if (pullDownRatio.has_value()) {
211         ACE_UPDATE_NODE_LAYOUT_PROPERTY(RefreshLayoutProperty, PullDownRatio, pullDownRatio.value(), frameNode);
212     } else {
213         ACE_RESET_NODE_LAYOUT_PROPERTY(RefreshLayoutProperty, PullDownRatio, frameNode);
214     }
215 }
216 
SetCustomBuilder(const RefPtr<NG::UINode> & customBuilder)217 void RefreshModelNG::SetCustomBuilder(const RefPtr<NG::UINode>& customBuilder)
218 {
219     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
220     CHECK_NULL_VOID(frameNode);
221     auto pattern = frameNode->GetPattern<RefreshPattern>();
222     CHECK_NULL_VOID(pattern);
223     pattern->AddCustomBuilderNode(customBuilder);
224 }
225 
SetIsCustomBuilderExist(bool isCustomBuilderExist)226 void RefreshModelNG::SetIsCustomBuilderExist(bool isCustomBuilderExist)
227 {
228     ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, IsCustomBuilderExist, isCustomBuilderExist);
229 }
230 
SetCustomBuilder(FrameNode * frameNode,FrameNode * customBuilder)231 void RefreshModelNG::SetCustomBuilder(FrameNode* frameNode, FrameNode* customBuilder)
232 {
233     // call SetCustomBuilderMultiThread by multi thread
234     FREE_NODE_CHECK(frameNode, SetCustomBuilder, frameNode, customBuilder);
235     CHECK_NULL_VOID(frameNode);
236     auto pattern = frameNode->GetPattern<RefreshPattern>();
237     CHECK_NULL_VOID(pattern);
238     pattern->AddCustomBuilderNode(AceType::Claim<UINode>(customBuilder));
239 }
240 
SetOnStateChange(FrameNode * frameNode,StateChangeEvent && stateChange)241 void RefreshModelNG::SetOnStateChange(FrameNode* frameNode, StateChangeEvent&& stateChange)
242 {
243     CHECK_NULL_VOID(frameNode);
244     auto eventHub = frameNode->GetOrCreateEventHub<RefreshEventHub>();
245     CHECK_NULL_VOID(eventHub);
246     eventHub->SetOnStateChange(std::move(stateChange));
247 }
248 
SetOnRefreshing(FrameNode * frameNode,RefreshingEvent && refreshing)249 void RefreshModelNG::SetOnRefreshing(FrameNode* frameNode, RefreshingEvent&& refreshing)
250 {
251     CHECK_NULL_VOID(frameNode);
252     auto eventHub = frameNode->GetOrCreateEventHub<RefreshEventHub>();
253     CHECK_NULL_VOID(eventHub);
254     eventHub->SetOnRefreshing(std::move(refreshing));
255 }
256 
SetOnOffsetChange(FrameNode * frameNode,OffsetChangeEvent && dragOffset)257 void RefreshModelNG::SetOnOffsetChange(FrameNode* frameNode, OffsetChangeEvent&& dragOffset)
258 {
259     CHECK_NULL_VOID(frameNode);
260     auto eventHub = frameNode->GetOrCreateEventHub<RefreshEventHub>();
261     CHECK_NULL_VOID(eventHub);
262     eventHub->SetOnOffsetChange(std::move(dragOffset));
263 }
264 
ResetOnOffsetChange(FrameNode * frameNode)265 void RefreshModelNG::ResetOnOffsetChange(FrameNode* frameNode)
266 {
267     CHECK_NULL_VOID(frameNode);
268     auto eventHub = frameNode->GetOrCreateEventHub<RefreshEventHub>();
269     CHECK_NULL_VOID(eventHub);
270     eventHub->ResetOnOffsetChange();
271 }
272 
SetRefreshing(FrameNode * frameNode,bool isRefreshing)273 void RefreshModelNG::SetRefreshing(FrameNode* frameNode, bool isRefreshing)
274 {
275     ACE_UPDATE_NODE_LAYOUT_PROPERTY(RefreshLayoutProperty, IsRefreshing, isRefreshing, frameNode);
276 }
277 
GetRefreshing(FrameNode * frameNode)278 bool RefreshModelNG::GetRefreshing(FrameNode* frameNode)
279 {
280     bool value = false;
281     ACE_GET_NODE_LAYOUT_PROPERTY_WITH_DEFAULT_VALUE(RefreshLayoutProperty, IsRefreshing, value, frameNode, value);
282     return value;
283 }
284 
SetRefreshOffset(FrameNode * frameNode,const Dimension & offset)285 void RefreshModelNG::SetRefreshOffset(FrameNode* frameNode, const Dimension& offset)
286 {
287     ACE_UPDATE_NODE_LAYOUT_PROPERTY(RefreshLayoutProperty, RefreshOffset, offset, frameNode);
288 }
289 
SetPullToRefresh(FrameNode * frameNode,bool pullToRefresh)290 void RefreshModelNG::SetPullToRefresh(FrameNode* frameNode, bool pullToRefresh)
291 {
292     ACE_UPDATE_NODE_LAYOUT_PROPERTY(RefreshLayoutProperty, PullToRefresh, pullToRefresh, frameNode);
293 }
294 
GetMaxPullDownDistance(FrameNode * frameNode)295 float RefreshModelNG::GetMaxPullDownDistance(FrameNode* frameNode)
296 {
297     float value = std::numeric_limits<float>::infinity();
298     ACE_GET_NODE_LAYOUT_PROPERTY_WITH_DEFAULT_VALUE(RefreshLayoutProperty, MaxPullDownDistance,
299         value, frameNode, value);
300     return value;
301 }
302 
GetPullDownRatio(FrameNode * frameNode)303 float RefreshModelNG::GetPullDownRatio(FrameNode* frameNode)
304 {
305     float value = 1.0;
306     ACE_GET_NODE_LAYOUT_PROPERTY_WITH_DEFAULT_VALUE(RefreshLayoutProperty, PullDownRatio, value, frameNode, value);
307     return value;
308 }
309 
GetRefreshOffset(FrameNode * frameNode)310 Dimension RefreshModelNG::GetRefreshOffset(FrameNode* frameNode)
311 {
312     Dimension value(DEFAULT_REFRESH_OFFSET, DimensionUnit::VP);
313     ACE_GET_NODE_LAYOUT_PROPERTY_WITH_DEFAULT_VALUE(RefreshLayoutProperty, RefreshOffset, value, frameNode, value);
314     return value;
315 }
316 
GetPullToRefresh(FrameNode * frameNode)317 bool RefreshModelNG::GetPullToRefresh(FrameNode* frameNode)
318 {
319     bool value = true;
320     ACE_GET_NODE_LAYOUT_PROPERTY_WITH_DEFAULT_VALUE(RefreshLayoutProperty, PullToRefresh, value, frameNode, value);
321     return value;
322 }
323 
SetChangeEvent(FrameNode * frameNode,RefreshChangeEvent && changeEvent)324 void RefreshModelNG::SetChangeEvent(FrameNode* frameNode, RefreshChangeEvent&& changeEvent)
325 {
326     CHECK_NULL_VOID(frameNode);
327     auto eventHub = frameNode->GetOrCreateEventHub<RefreshEventHub>();
328     CHECK_NULL_VOID(eventHub);
329     eventHub->SetChangeEvent(std::move(changeEvent));
330 }
331 
SetStepOffsetChange(FrameNode * frameNode,OffsetChangeEvent && dragOffset)332 void RefreshModelNG::SetStepOffsetChange(FrameNode* frameNode, OffsetChangeEvent&& dragOffset)
333 {
334     CHECK_NULL_VOID(frameNode);
335     auto eventHub = frameNode->GetOrCreateEventHub<RefreshEventHub>();
336     CHECK_NULL_VOID(eventHub);
337     eventHub->SetOnStepOffsetChange(std::move(dragOffset));
338 }
339 } // namespace OHOS::Ace::NG
340