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/marquee/marquee_model_ng.h"
17
18 #include "base/utils/utils.h"
19 #include "core/components_ng/base/frame_node.h"
20 #include "core/components_ng/base/view_stack_processor.h"
21 #include "core/components_ng/pattern/marquee/marquee_paint_property.h"
22 #include "core/components_ng/pattern/marquee/marquee_pattern.h"
23 #include "core/components_ng/pattern/text/text_layout_property.h"
24 #include "core/components_ng/pattern/text/text_pattern.h"
25 #include "core/components_ng/property/property.h"
26
27 namespace OHOS::Ace::NG {
28 constexpr int32_t TEXT_MAX_LINES = 1;
Create()29 void MarqueeModelNG::Create()
30 {
31 auto* stack = ViewStackProcessor::GetInstance();
32 auto nodeId = stack->ClaimNodeId();
33 ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::MARQUEE_ETS_TAG, nodeId);
34 auto frameNode = FrameNode::GetOrCreateFrameNode(
35 V2::MARQUEE_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<MarqueePattern>(); });
36 if (frameNode->GetChildren().empty()) {
37 auto textNode = FrameNode::CreateFrameNode(
38 V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
39 auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
40 textLayoutProperty->UpdateMaxLines(1);
41 frameNode->AddChild(textNode);
42 } else {
43 auto textChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
44 CHECK_NULL_VOID(textChild);
45 auto textLayoutProperty = textChild->GetLayoutProperty<TextLayoutProperty>();
46 CHECK_NULL_VOID(textLayoutProperty);
47 textLayoutProperty->UpdateMaxLines(1);
48 }
49 stack->Push(frameNode);
50 }
51
SetValue(const std::optional<std::string> & srcValue)52 void MarqueeModelNG::SetValue(const std::optional<std::string>& srcValue)
53 {
54 if (srcValue.has_value()) {
55 ACE_UPDATE_LAYOUT_PROPERTY(MarqueeLayoutProperty, Src, srcValue.value());
56 } else {
57 ACE_RESET_LAYOUT_PROPERTY_WITH_FLAG(MarqueeLayoutProperty, Src, PROPERTY_UPDATE_MEASURE);
58 }
59 }
60
SetPlayerStatus(const std::optional<bool> & playerStatus)61 void MarqueeModelNG::SetPlayerStatus(const std::optional<bool>& playerStatus)
62 {
63 if (playerStatus.has_value()) {
64 ACE_UPDATE_PAINT_PROPERTY(MarqueePaintProperty, PlayerStatus, playerStatus.value());
65 } else {
66 ACE_RESET_PAINT_PROPERTY_WITH_FLAG(MarqueePaintProperty, PlayerStatus, PROPERTY_UPDATE_RENDER);
67 }
68 }
69
SetScrollAmount(const std::optional<double> & scrollAmount)70 void MarqueeModelNG::SetScrollAmount(const std::optional<double>& scrollAmount)
71 {
72 if (scrollAmount.has_value()) {
73 ACE_UPDATE_PAINT_PROPERTY(MarqueePaintProperty, ScrollAmount, scrollAmount.value());
74 } else {
75 ACE_RESET_PAINT_PROPERTY_WITH_FLAG(MarqueePaintProperty, ScrollAmount, PROPERTY_UPDATE_RENDER);
76 }
77 }
78
SetLoop(const std::optional<int32_t> & loop)79 void MarqueeModelNG::SetLoop(const std::optional<int32_t>& loop)
80 {
81 if (loop.has_value()) {
82 ACE_UPDATE_PAINT_PROPERTY(MarqueePaintProperty, Loop, loop.value());
83 } else {
84 ACE_RESET_PAINT_PROPERTY_WITH_FLAG(MarqueePaintProperty, Loop, PROPERTY_UPDATE_RENDER);
85 }
86 }
87
SetDirection(const std::optional<MarqueeDirection> & direction)88 void MarqueeModelNG::SetDirection(const std::optional<MarqueeDirection>& direction)
89 {
90 if (direction.has_value()) {
91 ACE_UPDATE_PAINT_PROPERTY(MarqueePaintProperty, Direction, direction.value());
92 } else {
93 ACE_RESET_PAINT_PROPERTY_WITH_FLAG(MarqueePaintProperty, Direction, PROPERTY_UPDATE_RENDER);
94 }
95 }
96
SetAllowScale(const std::optional<bool> & allowScale)97 void MarqueeModelNG::SetAllowScale(const std::optional<bool>& allowScale)
98 {
99 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
100 CHECK_NULL_VOID(frameNode);
101 auto textChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
102 ACE_UPDATE_LAYOUT_PROPERTY(MarqueeLayoutProperty, AllowScale, allowScale.value_or(true));
103 CHECK_NULL_VOID(textChild);
104 ACE_UPDATE_NODE_LAYOUT_PROPERTY(TextLayoutProperty, AllowScale, allowScale.value_or(true), textChild);
105 }
106
SetTextColor(const std::optional<Color> & textColor)107 void MarqueeModelNG::SetTextColor(const std::optional<Color>& textColor)
108 {
109 ACE_UPDATE_RENDER_CONTEXT(ForegroundColor, textColor.value_or(Color()));
110 ACE_RESET_RENDER_CONTEXT(RenderContext, ForegroundColorStrategy);
111 ACE_UPDATE_RENDER_CONTEXT(ForegroundColorFlag, true);
112 if (textColor.has_value()) {
113 ACE_UPDATE_LAYOUT_PROPERTY(MarqueeLayoutProperty, FontColor, textColor.value());
114 } else {
115 ACE_RESET_LAYOUT_PROPERTY_WITH_FLAG(MarqueeLayoutProperty, FontColor, PROPERTY_UPDATE_MEASURE);
116 }
117 }
118
SetFontSize(const std::optional<Dimension> & fontSize)119 void MarqueeModelNG::SetFontSize(const std::optional<Dimension>& fontSize)
120 {
121 if (fontSize.has_value()) {
122 ACE_UPDATE_LAYOUT_PROPERTY(MarqueeLayoutProperty, FontSize, fontSize.value());
123 } else {
124 ACE_RESET_LAYOUT_PROPERTY_WITH_FLAG(MarqueeLayoutProperty, FontSize, PROPERTY_UPDATE_MEASURE);
125 }
126 }
127
SetFontWeight(const std::optional<FontWeight> & fontWeight)128 void MarqueeModelNG::SetFontWeight(const std::optional<FontWeight>& fontWeight)
129 {
130 if (fontWeight.has_value()) {
131 ACE_UPDATE_LAYOUT_PROPERTY(MarqueeLayoutProperty, FontWeight, fontWeight.value());
132 } else {
133 ACE_RESET_LAYOUT_PROPERTY_WITH_FLAG(MarqueeLayoutProperty, FontWeight, PROPERTY_UPDATE_MEASURE);
134 }
135 }
136
SetFontFamily(const std::optional<std::vector<std::string>> & fontFamilies)137 void MarqueeModelNG::SetFontFamily(const std::optional<std::vector<std::string>>& fontFamilies)
138 {
139 if (fontFamilies.has_value()) {
140 ACE_UPDATE_LAYOUT_PROPERTY(MarqueeLayoutProperty, FontFamily, fontFamilies.value());
141 } else {
142 ACE_RESET_LAYOUT_PROPERTY_WITH_FLAG(MarqueeLayoutProperty, FontFamily, PROPERTY_UPDATE_MEASURE);
143 }
144 }
145
SetMarqueeUpdateStrategy(const std::optional<MarqueeUpdateStrategy> & marqueeUpdateStrategy)146 void MarqueeModelNG::SetMarqueeUpdateStrategy(const std::optional<MarqueeUpdateStrategy>& marqueeUpdateStrategy)
147 {
148 if (marqueeUpdateStrategy.has_value()) {
149 ACE_UPDATE_LAYOUT_PROPERTY(MarqueeLayoutProperty, MarqueeUpdateStrategy, marqueeUpdateStrategy.value());
150 } else {
151 ACE_RESET_LAYOUT_PROPERTY_WITH_FLAG(MarqueeLayoutProperty, MarqueeUpdateStrategy, PROPERTY_UPDATE_NORMAL);
152 }
153 }
154
SetOnStart(std::function<void ()> && onChange)155 void MarqueeModelNG::SetOnStart(std::function<void()>&& onChange)
156 {
157 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
158 CHECK_NULL_VOID(frameNode);
159 auto eventHub = frameNode->GetEventHub<MarqueeEventHub>();
160 CHECK_NULL_VOID(eventHub);
161 eventHub->SetOnStart(std::move(onChange));
162 }
163
SetOnBounce(std::function<void ()> && onChange)164 void MarqueeModelNG::SetOnBounce(std::function<void()>&& onChange)
165 {
166 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
167 CHECK_NULL_VOID(frameNode);
168 auto eventHub = frameNode->GetEventHub<MarqueeEventHub>();
169 CHECK_NULL_VOID(eventHub);
170 eventHub->SetOnBounce(std::move(onChange));
171 }
172
SetOnFinish(std::function<void ()> && onChange)173 void MarqueeModelNG::SetOnFinish(std::function<void()>&& onChange)
174 {
175 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
176 CHECK_NULL_VOID(frameNode);
177 auto eventHub = frameNode->GetEventHub<MarqueeEventHub>();
178 CHECK_NULL_VOID(eventHub);
179 eventHub->SetOnFinish(std::move(onChange));
180 }
181
CreateFrameNode(int32_t nodeId)182 RefPtr<FrameNode> MarqueeModelNG::CreateFrameNode(int32_t nodeId)
183 {
184 auto frameNode = FrameNode::CreateFrameNode(V2::MARQUEE_ETS_TAG, nodeId, AceType::MakeRefPtr<MarqueePattern>());
185 CHECK_NULL_RETURN(frameNode, nullptr);
186 if (frameNode->GetChildren().empty()) {
187 auto textNode = FrameNode::CreateFrameNode(
188 V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
189 CHECK_NULL_RETURN(textNode, nullptr);
190 auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
191 CHECK_NULL_RETURN(textLayoutProperty, nullptr);
192 textLayoutProperty->UpdateMaxLines(TEXT_MAX_LINES);
193 frameNode->AddChild(textNode);
194 } else {
195 auto textChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
196 CHECK_NULL_RETURN(textChild, nullptr);
197 auto textLayoutProperty = textChild->GetLayoutProperty<TextLayoutProperty>();
198 CHECK_NULL_RETURN(textLayoutProperty, nullptr);
199 textLayoutProperty->UpdateMaxLines(TEXT_MAX_LINES);
200 }
201 return frameNode;
202 }
203
SetAllowScale(FrameNode * frameNode,const bool allowScale)204 void MarqueeModelNG::SetAllowScale(FrameNode* frameNode, const bool allowScale)
205 {
206 CHECK_NULL_VOID(frameNode);
207 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MarqueeLayoutProperty, AllowScale, allowScale, frameNode);
208 auto textChild = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
209 CHECK_NULL_VOID(textChild);
210 ACE_UPDATE_NODE_LAYOUT_PROPERTY(TextLayoutProperty, AllowScale, allowScale, textChild);
211 }
212
SetFontWeight(FrameNode * frameNode,const std::optional<FontWeight> & fontWeight)213 void MarqueeModelNG::SetFontWeight(FrameNode* frameNode, const std::optional<FontWeight>& fontWeight)
214 {
215 CHECK_NULL_VOID(frameNode);
216 if (fontWeight.has_value()) {
217 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MarqueeLayoutProperty, FontWeight, fontWeight.value(), frameNode);
218 } else {
219 ACE_RESET_NODE_LAYOUT_PROPERTY_WITH_FLAG(MarqueeLayoutProperty, FontWeight,
220 PROPERTY_UPDATE_MEASURE, frameNode);
221 }
222 }
223
SetFontFamily(FrameNode * frameNode,const std::optional<std::vector<std::string>> & fontFamilies)224 void MarqueeModelNG::SetFontFamily(FrameNode* frameNode, const std::optional<std::vector<std::string>>& fontFamilies)
225 {
226 CHECK_NULL_VOID(frameNode);
227 if (fontFamilies.has_value()) {
228 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MarqueeLayoutProperty, FontFamily, fontFamilies.value(), frameNode);
229 } else {
230 ACE_RESET_NODE_LAYOUT_PROPERTY_WITH_FLAG(MarqueeLayoutProperty, FontFamily,
231 PROPERTY_UPDATE_MEASURE, frameNode);
232 }
233 }
234
SetFontSize(FrameNode * frameNode,const std::optional<Dimension> & fontSize)235 void MarqueeModelNG::SetFontSize(FrameNode* frameNode, const std::optional<Dimension>& fontSize)
236 {
237 if (fontSize.has_value()) {
238 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MarqueeLayoutProperty, FontSize, fontSize.value(), frameNode);
239 } else {
240 ACE_RESET_NODE_LAYOUT_PROPERTY_WITH_FLAG(
241 MarqueeLayoutProperty, FontSize, PROPERTY_UPDATE_MEASURE, frameNode);
242 }
243 }
244
SetTextColor(FrameNode * frameNode,const std::optional<Color> & textColor)245 void MarqueeModelNG::SetTextColor(FrameNode* frameNode, const std::optional<Color>& textColor)
246 {
247 ACE_UPDATE_NODE_RENDER_CONTEXT(ForegroundColor, textColor.value_or(Color()), frameNode);
248 ACE_RESET_NODE_RENDER_CONTEXT(RenderContext, ForegroundColorStrategy, frameNode);
249 ACE_UPDATE_NODE_RENDER_CONTEXT(ForegroundColorFlag, true, frameNode);
250 if (textColor.has_value()) {
251 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MarqueeLayoutProperty, FontColor, textColor.value(), frameNode);
252 } else {
253 ACE_RESET_NODE_LAYOUT_PROPERTY_WITH_FLAG(
254 MarqueeLayoutProperty, FontColor, PROPERTY_UPDATE_MEASURE, frameNode);
255 }
256 }
257
SetMarqueeUpdateStrategy(FrameNode * frameNode,const std::optional<MarqueeUpdateStrategy> & marqueeUpdateStrategy)258 void MarqueeModelNG::SetMarqueeUpdateStrategy(
259 FrameNode* frameNode, const std::optional<MarqueeUpdateStrategy>& marqueeUpdateStrategy)
260 {
261 CHECK_NULL_VOID(frameNode);
262 if (marqueeUpdateStrategy.has_value()) {
263 ACE_UPDATE_NODE_LAYOUT_PROPERTY(
264 MarqueeLayoutProperty, MarqueeUpdateStrategy, marqueeUpdateStrategy.value(), frameNode);
265 } else {
266 ACE_RESET_NODE_LAYOUT_PROPERTY_WITH_FLAG(
267 MarqueeLayoutProperty, MarqueeUpdateStrategy, PROPERTY_UPDATE_MEASURE, frameNode);
268 }
269 }
270
SetOnStart(FrameNode * frameNode,std::function<void ()> && onChange)271 void MarqueeModelNG::SetOnStart(FrameNode* frameNode, std::function<void()>&& onChange)
272 {
273 CHECK_NULL_VOID(frameNode);
274 auto eventHub = frameNode->GetEventHub<MarqueeEventHub>();
275 CHECK_NULL_VOID(eventHub);
276 eventHub->SetOnStart(std::move(onChange));
277 }
278
SetOnBounce(FrameNode * frameNode,std::function<void ()> && onChange)279 void MarqueeModelNG::SetOnBounce(FrameNode* frameNode, std::function<void()>&& onChange)
280 {
281 CHECK_NULL_VOID(frameNode);
282 auto eventHub = frameNode->GetEventHub<MarqueeEventHub>();
283 CHECK_NULL_VOID(eventHub);
284 eventHub->SetOnBounce(std::move(onChange));
285 }
286
SetOnFinish(FrameNode * frameNode,std::function<void ()> && onChange)287 void MarqueeModelNG::SetOnFinish(FrameNode* frameNode, std::function<void()>&& onChange)
288 {
289 CHECK_NULL_VOID(frameNode);
290 auto eventHub = frameNode->GetEventHub<MarqueeEventHub>();
291 CHECK_NULL_VOID(eventHub);
292 eventHub->SetOnFinish(std::move(onChange));
293 }
294
SetMarqueeFrameRateRange(FrameNode * frameNode,const RefPtr<FrameRateRange> & rateRange,MarqueeDynamicSyncSceneType type)295 void MarqueeModelNG::SetMarqueeFrameRateRange(
296 FrameNode* frameNode, const RefPtr<FrameRateRange>& rateRange, MarqueeDynamicSyncSceneType type)
297 {
298 CHECK_NULL_VOID(frameNode);
299 auto pattern = frameNode->GetPattern<MarqueePattern>();
300 CHECK_NULL_VOID(pattern);
301 pattern->SetMarqueeFrameRateRange(rateRange, type);
302 }
303
SetValue(FrameNode * frameNode,const std::optional<std::string> & srcValue)304 void MarqueeModelNG::SetValue(FrameNode* frameNode, const std::optional<std::string>& srcValue)
305 {
306 if (srcValue.has_value()) {
307 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MarqueeLayoutProperty, Src, srcValue.value(), frameNode);
308 }
309 }
310
ResetValue(FrameNode * frameNode)311 void MarqueeModelNG::ResetValue(FrameNode* frameNode)
312 {
313 ACE_RESET_NODE_LAYOUT_PROPERTY_WITH_FLAG(MarqueeLayoutProperty, Src, PROPERTY_UPDATE_MEASURE, frameNode);
314 }
315
SetPlayerStatus(FrameNode * frameNode,const std::optional<bool> & playerStatus)316 void MarqueeModelNG::SetPlayerStatus(FrameNode* frameNode, const std::optional<bool>& playerStatus)
317 {
318 if (playerStatus.has_value()) {
319 ACE_UPDATE_NODE_PAINT_PROPERTY(MarqueePaintProperty, PlayerStatus, playerStatus.value(), frameNode);
320 }
321 }
322
ResetPlayerStatus(FrameNode * frameNode)323 void MarqueeModelNG::ResetPlayerStatus(FrameNode* frameNode)
324 {
325 ACE_RESET_NODE_PAINT_PROPERTY_WITH_FLAG(MarqueePaintProperty, PlayerStatus, PROPERTY_UPDATE_RENDER, frameNode);
326 }
327
SetScrollAmount(FrameNode * frameNode,const std::optional<double> & scrollAmount)328 void MarqueeModelNG::SetScrollAmount(FrameNode* frameNode, const std::optional<double>& scrollAmount)
329 {
330 if (scrollAmount.has_value()) {
331 ACE_UPDATE_NODE_PAINT_PROPERTY(MarqueePaintProperty, ScrollAmount, scrollAmount.value(), frameNode);
332 }
333 }
334
ResetScrollAmount(FrameNode * frameNode)335 void MarqueeModelNG::ResetScrollAmount(FrameNode* frameNode)
336 {
337 ACE_RESET_NODE_PAINT_PROPERTY_WITH_FLAG(MarqueePaintProperty, ScrollAmount, PROPERTY_UPDATE_RENDER, frameNode);
338 }
339
SetLoop(FrameNode * frameNode,const std::optional<int32_t> & loop)340 void MarqueeModelNG::SetLoop(FrameNode* frameNode, const std::optional<int32_t>& loop)
341 {
342 if (loop.has_value()) {
343 ACE_UPDATE_NODE_PAINT_PROPERTY(MarqueePaintProperty, Loop, loop.value(), frameNode);
344 }
345 }
346
ResetLoop(FrameNode * frameNode)347 void MarqueeModelNG::ResetLoop(FrameNode* frameNode)
348 {
349 ACE_RESET_NODE_PAINT_PROPERTY_WITH_FLAG(MarqueePaintProperty, Loop, PROPERTY_UPDATE_RENDER, frameNode);
350 }
351
SetDirection(FrameNode * frameNode,const std::optional<MarqueeDirection> & direction)352 void MarqueeModelNG::SetDirection(FrameNode* frameNode, const std::optional<MarqueeDirection>& direction)
353 {
354 if (direction.has_value()) {
355 ACE_UPDATE_NODE_PAINT_PROPERTY(MarqueePaintProperty, Direction, direction.value(), frameNode);
356 }
357 }
358
ResetDirection(FrameNode * frameNode)359 void MarqueeModelNG::ResetDirection(FrameNode* frameNode)
360 {
361 ACE_RESET_NODE_PAINT_PROPERTY_WITH_FLAG(MarqueePaintProperty, Direction, PROPERTY_UPDATE_RENDER, frameNode);
362 }
363 } // namespace OHOS::Ace::NG
364