1 /*
2 * Copyright (c) 2022 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 "frameworks/base/geometry/dimension.h"
21 #include "frameworks/base/geometry/ng/offset_t.h"
22 #include "frameworks/base/i18n/localization.h"
23 #include "frameworks/base/utils/time_util.h"
24 #include "frameworks/core/components/refresh/refresh_theme.h"
25 #include "frameworks/core/components_ng/base/frame_node.h"
26 #include "frameworks/core/components_ng/base/view_stack_processor.h"
27 #include "frameworks/core/components_ng/event/event_hub.h"
28 #include "frameworks/core/components_ng/pattern/loading_progress/loading_progress_pattern.h"
29 #include "frameworks/core/components_ng/pattern/refresh/refresh_pattern.h"
30 #include "frameworks/core/components_ng/pattern/text/text_pattern.h"
31 #include "frameworks/core/components_v2/inspector/inspector_constants.h"
32
33 namespace OHOS::Ace::NG {
34
35 namespace {
36
37 constexpr int32_t CHILD_COUNT = 2;
38 constexpr double DEFAULT_INDICATOR_OFFSET = 16.0;
39 constexpr int32_t DEFAULT_FRICTION_RATIO = 42;
40 constexpr char REFRESH_LAST_UPDATED[] = "refresh.last_updated"; // I18n for last updated
41 constexpr Dimension LOADING_PROGRESS_SIZE = 32.0_vp;
42 } // namespace
43
Create()44 void RefreshModelNG::Create()
45 {
46 auto* stack = ViewStackProcessor::GetInstance();
47 auto nodeId = stack->ClaimNodeId();
48 auto frameNode = FrameNode::GetOrCreateFrameNode(
49 V2::REFRESH_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<RefreshPattern>(); });
50 CHECK_NULL_VOID(frameNode);
51 stack->Push(frameNode);
52 ACE_UPDATE_LAYOUT_PROPERTY(
53 RefreshLayoutProperty, IndicatorOffset, Dimension(DEFAULT_INDICATOR_OFFSET, DimensionUnit::VP));
54 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, Friction, DEFAULT_FRICTION_RATIO);
55 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, IsUseOffset, true);
56 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, IsShowLastTime, false);
57 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, ScrollableOffset, OffsetF(0.0, 0.0));
58 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, ShowTimeOffset, OffsetF(0.0, 0.0));
59 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, LoadingProcessOffset, OffsetF(0.0, 0.0));
60 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, TriggerRefreshDistance, Dimension(0.0, DimensionUnit::VP));
61 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, RefreshDistance, Dimension(0.0, DimensionUnit::VP));
62 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, IsRefresh, true);
63 }
64
Pop()65 void RefreshModelNG::Pop()
66 {
67 auto refreshNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
68 CHECK_NULL_VOID(refreshNode);
69 auto layoutProperty = refreshNode->GetLayoutProperty<RefreshLayoutProperty>();
70 CHECK_NULL_VOID(layoutProperty);
71 auto refreshRenderProperty = refreshNode->GetPaintProperty<RefreshRenderProperty>();
72 CHECK_NULL_VOID(refreshRenderProperty);
73 auto pattern = refreshNode->GetPattern<RefreshPattern>();
74 CHECK_NULL_VOID(pattern);
75 if (!pattern->GetIsCustomBuilderExist()) {
76 if (refreshNode->TotalChildCount() >= CHILD_COUNT) {
77 LOGI("%{public}s have %{public}d child", refreshNode->GetTag().c_str(), refreshNode->TotalChildCount());
78 return;
79 }
80 auto textChild = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, -1, AceType::MakeRefPtr<TextPattern>());
81 CHECK_NULL_VOID(textChild);
82 refreshNode->AddChild(textChild);
83 auto textLayoutProperty = textChild->GetLayoutProperty<TextLayoutProperty>();
84 CHECK_NULL_VOID(textLayoutProperty);
85 if (layoutProperty->GetIsShowLastTimeValue()) {
86 textLayoutProperty->UpdateContent(refreshRenderProperty->GetTimeTextValue());
87 auto lastTimeText = Localization::GetInstance()->GetEntryLetters(REFRESH_LAST_UPDATED);
88 refreshRenderProperty->UpdateLastTimeText(lastTimeText);
89 auto timeText = StringUtils::FormatString("");
90 refreshRenderProperty->UpdateTimeText(timeText);
91 }
92 auto textStyle = layoutProperty->GetTextStyle();
93 CHECK_NULL_VOID(textStyle);
94 textLayoutProperty->UpdateTextAlign(textStyle->GetTextAlign());
95 textLayoutProperty->UpdateTextBaseline(textStyle->GetTextBaseline());
96 textLayoutProperty->UpdateTextCase(textStyle->GetTextCase());
97 textLayoutProperty->UpdateTextColor(textStyle->GetTextColor());
98 textLayoutProperty->UpdateFontWeight(textStyle->GetFontWeight());
99 textLayoutProperty->UpdateFontFamily(textStyle->GetFontFamilies());
100 textLayoutProperty->UpdateTextDecoration(textStyle->GetTextDecoration());
101 textLayoutProperty->UpdateTextDecorationColor(textStyle->GetTextDecorationColor());
102 textLayoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
103
104 auto loadingProgressChild = FrameNode::CreateFrameNode(V2::LOADING_PROGRESS_ETS_TAG,
105 ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<LoadingProgressPattern>());
106 CHECK_NULL_VOID(loadingProgressChild);
107 auto gestureHub = loadingProgressChild->GetEventHub<EventHub>();
108 if (gestureHub) {
109 gestureHub->SetEnabled(false);
110 }
111 auto progressLayoutProperty = loadingProgressChild->GetLayoutProperty<LoadingProgressLayoutProperty>();
112 progressLayoutProperty->UpdateUserDefinedIdealSize(
113 CalcSize(CalcLength(LOADING_PROGRESS_SIZE.ConvertToPx()), CalcLength(LOADING_PROGRESS_SIZE.ConvertToPx())));
114 auto pipeline = PipelineContext::GetCurrentContext();
115 CHECK_NULL_VOID(pipeline);
116 auto themeManager = pipeline->GetThemeManager();
117 CHECK_NULL_VOID(themeManager);
118 auto theme = themeManager->GetTheme<RefreshTheme>();
119 CHECK_NULL_VOID(theme);
120 auto paintProperty = loadingProgressChild->GetPaintProperty<LoadingProgressPaintProperty>();
121 CHECK_NULL_VOID(paintProperty);
122 paintProperty->UpdateColor(theme->GetProgressColor());
123 auto progressContext = loadingProgressChild->GetRenderContext();
124 CHECK_NULL_VOID_NOLOG(progressContext);
125 progressContext->UpdateOpacity(0.0);
126 refreshNode->AddChild(loadingProgressChild);
127 loadingProgressChild->MarkDirtyNode();
128 }
129 NG::ViewStackProcessor::GetInstance()->PopContainer();
130 }
SetRefreshing(bool isRefreshing)131 void RefreshModelNG::SetRefreshing(bool isRefreshing)
132 {
133 ACE_UPDATE_PAINT_PROPERTY(RefreshRenderProperty, IsRefreshing, isRefreshing);
134 }
135
SetRefreshDistance(const Dimension & refreshDistance)136 void RefreshModelNG::SetRefreshDistance(const Dimension& refreshDistance)
137 {
138 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, RefreshDistance, refreshDistance);
139 }
140
SetUseOffset(bool isUseOffset)141 void RefreshModelNG::SetUseOffset(bool isUseOffset)
142 {
143 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, IsUseOffset, isUseOffset);
144 }
145
SetIndicatorOffset(const Dimension & indicatorOffset)146 void RefreshModelNG::SetIndicatorOffset(const Dimension& indicatorOffset)
147 {
148 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, IndicatorOffset, indicatorOffset);
149 }
150
SetFriction(int32_t friction)151 void RefreshModelNG::SetFriction(int32_t friction)
152 {
153 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, Friction, friction);
154 }
155
IsRefresh(bool isRefresh)156 void RefreshModelNG::IsRefresh(bool isRefresh)
157 {
158 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, IsRefresh, isRefresh);
159 }
160
SetLoadingDistance(const Dimension & loadingDistance)161 void RefreshModelNG::SetLoadingDistance(const Dimension& loadingDistance)
162 {
163 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, LoadingDistance, loadingDistance);
164 }
165
SetProgressDistance(const Dimension & progressDistance)166 void RefreshModelNG::SetProgressDistance(const Dimension& progressDistance)
167 {
168 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, ProgressDistance, progressDistance);
169 }
170
SetProgressDiameter(const Dimension & progressDiameter)171 void RefreshModelNG::SetProgressDiameter(const Dimension& progressDiameter)
172 {
173 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, ProgressDiameter, progressDiameter);
174 }
175
SetMaxDistance(const Dimension & maxDistance)176 void RefreshModelNG::SetMaxDistance(const Dimension& maxDistance)
177 {
178 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, MaxDistance, maxDistance);
179 }
180
SetIsShowLastTime(bool isShowlastTime)181 void RefreshModelNG::SetIsShowLastTime(bool isShowlastTime)
182 {
183 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, IsShowLastTime, isShowlastTime);
184 }
185
SetShowTimeDistance(const Dimension & showTimeDistance)186 void RefreshModelNG::SetShowTimeDistance(const Dimension& showTimeDistance)
187 {
188 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, ShowTimeDistance, showTimeDistance);
189 }
190
SetTextStyle(const TextStyle & textStyle)191 void RefreshModelNG::SetTextStyle(const TextStyle& textStyle)
192 {
193 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, TextStyle, textStyle);
194 }
195
SetProgressColor(const Color & progressColor)196 void RefreshModelNG::SetProgressColor(const Color& progressColor)
197 {
198 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, ProgressColor, progressColor);
199 }
200
SetProgressBackgroundColor(const Color & backgroundColor)201 void RefreshModelNG::SetProgressBackgroundColor(const Color& backgroundColor)
202 {
203 ACE_UPDATE_LAYOUT_PROPERTY(RefreshLayoutProperty, BackgroundColor, backgroundColor);
204 }
205
SetOnStateChange(StateChangeEvent && stateChange)206 void RefreshModelNG::SetOnStateChange(StateChangeEvent&& stateChange)
207 {
208 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
209 CHECK_NULL_VOID(frameNode);
210 auto eventHub = frameNode->GetEventHub<RefreshEventHub>();
211 CHECK_NULL_VOID(eventHub);
212 eventHub->SetOnStateChange(std::move(stateChange));
213 }
214
SetOnRefreshing(RefreshingEvent && refreshing)215 void RefreshModelNG::SetOnRefreshing(RefreshingEvent&& refreshing)
216 {
217 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
218 CHECK_NULL_VOID(frameNode);
219 auto eventHub = frameNode->GetEventHub<RefreshEventHub>();
220 CHECK_NULL_VOID(eventHub);
221 eventHub->SetOnRefreshing(std::move(refreshing));
222 }
223
SetChangeEvent(ChangeEvent && changeEvent)224 void RefreshModelNG::SetChangeEvent(ChangeEvent&& changeEvent)
225 {
226 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
227 CHECK_NULL_VOID(frameNode);
228 auto eventHub = frameNode->GetEventHub<RefreshEventHub>();
229 CHECK_NULL_VOID(eventHub);
230 eventHub->SetChangeEvent(std::move(changeEvent));
231 }
232
SetCustomBuilder(const RefPtr<NG::UINode> & customBuilder)233 void RefreshModelNG::SetCustomBuilder(const RefPtr<NG::UINode>& customBuilder)
234 {
235 CHECK_NULL_VOID(customBuilder);
236 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
237 CHECK_NULL_VOID(frameNode);
238 auto pattern = frameNode->GetPattern<RefreshPattern>();
239 CHECK_NULL_VOID(pattern);
240 pattern->AddCustomBuilderNode(customBuilder);
241 }
242
243 } // namespace OHOS::Ace::NG
244