1 /*
2 * Copyright (c) 2023 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/button/button_model_ng.h"
17
18 #include "base/utils/utils.h"
19 #include "core/components/button/button_theme.h"
20 #include "core/components/common/layout/constants.h"
21 #include "core/components_ng/base/frame_node.h"
22 #include "core/components_ng/base/view_stack_processor.h"
23 #include "core/components_ng/pattern/button/button_event_hub.h"
24 #include "core/components_ng/pattern/button/button_pattern.h"
25 #include "core/components_ng/pattern/text/text_pattern.h"
26
27 namespace OHOS::Ace::NG {
SetFontSize(const Dimension & fontSize)28 void ButtonModelNG::SetFontSize(const Dimension& fontSize)
29 {
30 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, FontSize, fontSize);
31 }
32
SetFontWeight(const Ace::FontWeight & fontWeight)33 void ButtonModelNG::SetFontWeight(const Ace::FontWeight& fontWeight)
34 {
35 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, FontWeight, fontWeight);
36 }
37
SetFontStyle(const Ace::FontStyle & fontStyle)38 void ButtonModelNG::SetFontStyle(const Ace::FontStyle& fontStyle)
39 {
40 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, FontStyle, fontStyle);
41 }
42
SetFontFamily(const std::vector<std::string> & fontFamily)43 void ButtonModelNG::SetFontFamily(const std::vector<std::string>& fontFamily)
44 {
45 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, FontFamily, fontFamily);
46 }
47
SetFontColor(const Color & textColor)48 void ButtonModelNG::SetFontColor(const Color& textColor)
49 {
50 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, FontColor, textColor);
51 ACE_UPDATE_RENDER_CONTEXT(ForegroundColor, textColor);
52 }
53
SetType(const int value)54 void ButtonModelNG::SetType(const int value)
55 {
56 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, Type, static_cast<ButtonType>(value));
57 }
58
SetStateEffect(const bool stateEffect)59 void ButtonModelNG::SetStateEffect(const bool stateEffect)
60 {
61 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
62 CHECK_NULL_VOID(frameNode);
63 auto buttonEventHub = frameNode->GetEventHub<ButtonEventHub>();
64 CHECK_NULL_VOID(buttonEventHub);
65 buttonEventHub->SetStateEffect(stateEffect);
66 }
67
SetLabelStyle(ButtonParameters & buttonParameters)68 void ButtonModelNG::SetLabelStyle(ButtonParameters& buttonParameters)
69 {
70 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
71 CHECK_NULL_VOID(frameNode);
72 SetLabelStyle(frameNode, buttonParameters);
73 }
74
SetButtonStyle(const std::optional<ButtonStyleMode> & buttonStyle)75 void ButtonModelNG::SetButtonStyle(const std::optional<ButtonStyleMode>& buttonStyle)
76 {
77 if (buttonStyle.has_value()) {
78 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, ButtonStyle, buttonStyle.value());
79 auto context = PipelineBase::GetCurrentContextSafely();
80 CHECK_NULL_VOID(context);
81 auto buttonTheme = context->GetTheme<ButtonTheme>();
82 CHECK_NULL_VOID(buttonTheme);
83 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
84 auto layoutProperty = frameNode->GetLayoutProperty<ButtonLayoutProperty>();
85 CHECK_NULL_VOID(layoutProperty);
86 ButtonRole buttonRole = layoutProperty->GetButtonRole().value_or(ButtonRole::NORMAL);
87 auto bgColor = buttonTheme->GetBgColor(buttonStyle.value(), buttonRole);
88 auto textColor = buttonTheme->GetTextColor(buttonStyle.value(), buttonRole);
89 BackgroundColor(bgColor, true);
90 SetFontColor(textColor);
91 }
92 }
93
SetRole(const std::optional<ButtonRole> & buttonRole)94 void ButtonModelNG::SetRole(const std::optional<ButtonRole>& buttonRole)
95 {
96 if (buttonRole.has_value()) {
97 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, ButtonRole, buttonRole.value());
98 auto context = PipelineBase::GetCurrentContextSafely();
99 CHECK_NULL_VOID(context);
100 auto buttonTheme = context->GetTheme<ButtonTheme>();
101 CHECK_NULL_VOID(buttonTheme);
102 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
103 auto layoutProperty = frameNode->GetLayoutProperty<ButtonLayoutProperty>();
104 CHECK_NULL_VOID(layoutProperty);
105 ButtonStyleMode buttonStyleMode = layoutProperty->GetButtonStyle().value_or(ButtonStyleMode::EMPHASIZE);
106 auto bgColor = buttonTheme->GetBgColor(buttonStyleMode, buttonRole.value());
107 auto textColor = buttonTheme->GetTextColor(buttonStyleMode, buttonRole.value());
108 BackgroundColor(bgColor, true);
109 SetFontColor(textColor);
110 }
111 }
112
SetControlSize(const std::optional<ControlSize> & controlSize)113 void ButtonModelNG::SetControlSize(const std::optional<ControlSize>& controlSize)
114 {
115 if (controlSize.has_value()) {
116 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, ControlSize, controlSize.value());
117 auto context = PipelineBase::GetCurrentContextSafely();
118 CHECK_NULL_VOID(context);
119 auto buttonTheme = context->GetTheme<ButtonTheme>();
120 CHECK_NULL_VOID(buttonTheme);
121 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
122 CHECK_NULL_VOID(frameNode);
123 SetButtonSize(frameNode, controlSize, buttonTheme);
124 Dimension fontSize = buttonTheme->GetTextSize(controlSize.value());
125 SetFontSize(fontSize);
126 }
127 }
128
SetRole(FrameNode * frameNode,const std::optional<ButtonRole> & buttonRole)129 void ButtonModelNG::SetRole(FrameNode* frameNode, const std::optional<ButtonRole>& buttonRole)
130 {
131 if (buttonRole.has_value()) {
132 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, ButtonRole, buttonRole.value(), frameNode);
133 auto context = PipelineBase::GetCurrentContextSafely();
134 CHECK_NULL_VOID(context);
135 auto buttonTheme = context->GetTheme<ButtonTheme>();
136 CHECK_NULL_VOID(buttonTheme);
137 auto layoutProperty = frameNode->GetLayoutProperty<ButtonLayoutProperty>();
138 CHECK_NULL_VOID(layoutProperty);
139 ButtonStyleMode buttonStyleMode = layoutProperty->GetButtonStyle().value_or(ButtonStyleMode::EMPHASIZE);
140 auto bgColor = buttonTheme->GetBgColor(buttonStyleMode, buttonRole.value());
141 auto textColor = buttonTheme->GetTextColor(buttonStyleMode, buttonRole.value());
142 BackgroundColor(frameNode, bgColor, true);
143 SetFontColor(frameNode, textColor);
144 }
145 }
146
SetButtonStyle(FrameNode * frameNode,const std::optional<ButtonStyleMode> & buttonStyle)147 void ButtonModelNG::SetButtonStyle(FrameNode* frameNode, const std::optional<ButtonStyleMode>& buttonStyle)
148 {
149 if (buttonStyle.has_value()) {
150 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, ButtonStyle, buttonStyle.value(), frameNode);
151 auto context = PipelineBase::GetCurrentContextSafely();
152 CHECK_NULL_VOID(context);
153 auto buttonTheme = context->GetTheme<ButtonTheme>();
154 CHECK_NULL_VOID(buttonTheme);
155 auto layoutProperty = frameNode->GetLayoutProperty<ButtonLayoutProperty>();
156 CHECK_NULL_VOID(layoutProperty);
157 ButtonRole buttonRole = layoutProperty->GetButtonRole().value_or(ButtonRole::NORMAL);
158 auto bgColor = buttonTheme->GetBgColor(buttonStyle.value(), buttonRole);
159 auto textColor = buttonTheme->GetTextColor(buttonStyle.value(), buttonRole);
160 BackgroundColor(frameNode, bgColor, true);
161 SetFontColor(frameNode, textColor);
162 }
163 }
164
SetButtonSize(FrameNode * frameNode,const std::optional<ControlSize> & controlSize,RefPtr<ButtonTheme> buttonTheme)165 void ButtonModelNG::SetButtonSize(FrameNode* frameNode, const std::optional<ControlSize>& controlSize,
166 RefPtr<ButtonTheme> buttonTheme)
167 {
168 auto layoutProperty = frameNode->GetLayoutProperty<ButtonLayoutProperty>();
169 CHECK_NULL_VOID(layoutProperty);
170 if (controlSize.has_value()) {
171 auto padding = buttonTheme->GetPadding(controlSize.value());
172 ButtonStyleMode buttonStyle = layoutProperty->GetButtonStyle().value_or(ButtonStyleMode::EMPHASIZE);
173 PaddingProperty defaultPadding;
174 if (buttonStyle == ButtonStyleMode::TEXT && controlSize.value() == ControlSize::SMALL) {
175 float leftPadding = buttonTheme->GetPaddingText().ConvertToPx();
176 float rightPadding = buttonTheme->GetPaddingText().ConvertToPx();
177 defaultPadding = { CalcLength(leftPadding), CalcLength(rightPadding),
178 CalcLength(padding.Top()), CalcLength(padding.Bottom()) };
179 } else {
180 defaultPadding = { CalcLength(padding.Left()), CalcLength(padding.Right()),
181 CalcLength(padding.Top()), CalcLength(padding.Bottom()) };
182 }
183 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, Padding, defaultPadding);
184 }
185 }
186
SetControlSize(FrameNode * frameNode,const std::optional<ControlSize> & controlSize)187 void ButtonModelNG::SetControlSize(FrameNode* frameNode, const std::optional<ControlSize>& controlSize)
188 {
189 if (controlSize.has_value()) {
190 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, ControlSize, controlSize.value(), frameNode);
191 auto context = PipelineBase::GetCurrentContextSafely();
192 CHECK_NULL_VOID(context);
193 auto buttonTheme = context->GetTheme<ButtonTheme>();
194 CHECK_NULL_VOID(buttonTheme);
195 SetButtonSize(frameNode, controlSize, buttonTheme);
196 Dimension fontSize = buttonTheme->GetTextSize(controlSize.value());
197 SetFontSize(frameNode, fontSize);
198 }
199 }
200
CreateWithLabel(const CreateWithPara & para,std::list<RefPtr<Component>> & buttonChildren)201 void ButtonModelNG::CreateWithLabel(const CreateWithPara& para, std::list<RefPtr<Component>>& buttonChildren)
202 {
203 CreateWithLabel(para.label.value());
204 SetTypeAndStateEffect(para.type, para.stateEffect);
205 SetButtonStyle(para.buttonStyleMode);
206 SetControlSize(para.controlSize);
207 SetRole(para.buttonRole);
208 }
209
CreateWithLabel(const std::string & label)210 void ButtonModelNG::CreateWithLabel(const std::string& label)
211 {
212 auto* stack = ViewStackProcessor::GetInstance();
213 auto nodeId = stack->ClaimNodeId();
214 ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::BUTTON_ETS_TAG, nodeId);
215 auto buttonNode = FrameNode::GetOrCreateFrameNode(
216 V2::BUTTON_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<ButtonPattern>(); });
217 CHECK_NULL_VOID(buttonNode);
218 if (buttonNode->GetChildren().empty()) {
219 auto textNode = FrameNode::CreateFrameNode(
220 V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
221 CHECK_NULL_VOID(textNode);
222 textNode->SetInternal();
223 SetTextDefaultStyle(textNode, label);
224 buttonNode->AddChild(textNode);
225 }
226 auto buttonAccessibilityProperty = buttonNode->GetAccessibilityProperty<AccessibilityProperty>();
227 CHECK_NULL_VOID(buttonAccessibilityProperty);
228 buttonAccessibilityProperty->SetText(label);
229 stack->Push(buttonNode);
230 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, Label, label);
231 auto layoutProperty = buttonNode->GetLayoutProperty();
232 CHECK_NULL_VOID(layoutProperty);
233 if (layoutProperty->GetPaddingProperty()) {
234 return;
235 }
236 auto context = PipelineBase::GetCurrentContextSafely();
237 CHECK_NULL_VOID(context);
238 auto buttonTheme = context->GetTheme<ButtonTheme>();
239 CHECK_NULL_VOID(buttonTheme);
240 auto padding = buttonTheme->GetPadding();
241 PaddingProperty defaultPadding = { CalcLength(padding.Left()), CalcLength(padding.Right()),
242 CalcLength(padding.Top()), CalcLength(padding.Bottom()), std::nullopt, std::nullopt };
243 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, Padding, defaultPadding);
244 }
245
SetLabel(FrameNode * frameNode,const char * label)246 void ButtonModelNG::SetLabel(FrameNode* frameNode, const char* label)
247 {
248 CHECK_NULL_VOID(frameNode);
249 if (frameNode->GetChildren().empty()) {
250 auto textNode = FrameNode::CreateFrameNode(
251 V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
252 CHECK_NULL_VOID(textNode);
253 textNode->SetInternal();
254 SetTextDefaultStyle(textNode, label);
255 frameNode->AddChild(textNode);
256 }
257 auto buttonAccessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
258 CHECK_NULL_VOID(buttonAccessibilityProperty);
259 buttonAccessibilityProperty->SetText(label);
260 auto layoutProperty = frameNode->GetLayoutProperty<ButtonLayoutProperty>();
261 CHECK_NULL_VOID(layoutProperty);
262 layoutProperty->UpdateLabel(label);
263 if (layoutProperty->GetPaddingProperty()) {
264 return;
265 }
266 auto context = frameNode->GetContext();
267 CHECK_NULL_VOID(context);
268 auto buttonTheme = context->GetTheme<ButtonTheme>();
269 CHECK_NULL_VOID(buttonTheme);
270 auto padding = buttonTheme->GetPadding();
271 PaddingProperty defaultPadding = { CalcLength(padding.Left()), CalcLength(padding.Right()),
272 CalcLength(padding.Top()), CalcLength(padding.Bottom()), std::nullopt, std::nullopt };
273 layoutProperty->UpdatePadding(defaultPadding);
274 }
275
Create(const CreateWithPara & para,std::list<RefPtr<Component>> & buttonChildren)276 void ButtonModelNG::Create(const CreateWithPara& para, std::list<RefPtr<Component>>& buttonChildren) {}
277
CreateWithChild(const CreateWithPara & para)278 void ButtonModelNG::CreateWithChild(const CreateWithPara& para)
279 {
280 std::string tagName = "Button";
281 Create(tagName);
282 if (para.optionSetFirst.has_value() && para.optionSetFirst.value()) {
283 SetTypeAndStateEffect(para.type, para.stateEffect);
284 SetButtonStyle(para.buttonStyleMode);
285 SetControlSize(para.controlSize);
286 SetRole(para.buttonRole);
287 } else if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
288 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, Type, ButtonType::ROUNDED_RECTANGLE);
289 }
290 }
291
Create(const std::string & tagName)292 void ButtonModelNG::Create(const std::string& tagName)
293 {
294 auto* stack = ViewStackProcessor::GetInstance();
295 auto nodeId = stack->ClaimNodeId();
296 ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", tagName.c_str(), nodeId);
297 auto frameNode =
298 FrameNode::GetOrCreateFrameNode(tagName, nodeId, []() { return AceType::MakeRefPtr<ButtonPattern>(); });
299 stack->Push(frameNode);
300 }
301
CreateFrameNode(int32_t nodeId)302 RefPtr<FrameNode> ButtonModelNG::CreateFrameNode(int32_t nodeId)
303 {
304 auto frameNode = FrameNode::CreateFrameNode(V2::BUTTON_ETS_TAG, nodeId, AceType::MakeRefPtr<ButtonPattern>());
305 CHECK_NULL_RETURN(frameNode, nullptr);
306 auto layoutProperty = frameNode->GetLayoutProperty();
307 CHECK_NULL_RETURN(layoutProperty, nullptr);
308 if (layoutProperty->GetPaddingProperty()) {
309 return frameNode;
310 }
311 auto context = PipelineBase::GetCurrentContextSafely();
312 CHECK_NULL_RETURN(context, nullptr);
313 auto buttonTheme = context->GetTheme<ButtonTheme>();
314 CHECK_NULL_RETURN(buttonTheme, nullptr);
315 auto padding = buttonTheme->GetPadding();
316 PaddingProperty defaultPadding = { CalcLength(padding.Left()), CalcLength(padding.Right()),
317 CalcLength(padding.Top()), CalcLength(padding.Bottom()), std::nullopt, std::nullopt };
318 layoutProperty->UpdatePadding(defaultPadding);
319 return frameNode;
320 }
321
Padding(const PaddingProperty & paddingNew,const Edge & paddingOld)322 void ButtonModelNG::Padding(const PaddingProperty& paddingNew, const Edge& paddingOld)
323 {
324 NG::ViewAbstract::SetPadding(paddingNew);
325 auto button = ViewStackProcessor::GetInstance()->GetMainFrameNode();
326 CHECK_NULL_VOID(button);
327 auto pattern = button->GetPattern<ButtonPattern>();
328 CHECK_NULL_VOID(pattern);
329 pattern->SetHasCustomPadding(true);
330 }
331
OnClick(GestureEventFunc && tapEventFunc,ClickEventFunc && clickEventFunc,double distanceThreshold)332 void ButtonModelNG::OnClick(GestureEventFunc&& tapEventFunc, ClickEventFunc&& clickEventFunc, double distanceThreshold)
333 {
334 ViewAbstract::SetOnClick(std::move(tapEventFunc), distanceThreshold);
335 }
336
BackgroundColor(const Color & color,const bool & colorFlag)337 void ButtonModelNG::BackgroundColor(const Color& color, const bool& colorFlag)
338 {
339 ViewAbstract::SetBackgroundColor(color);
340 }
341
BackgroundColor(FrameNode * frameNode,const Color & color,const bool & colorFlag)342 void ButtonModelNG::BackgroundColor(FrameNode* frameNode, const Color& color, const bool& colorFlag)
343 {
344 ViewAbstract::SetBackgroundColor(frameNode, color);
345 }
346
SetSize(const std::optional<Dimension> & width,const std::optional<Dimension> & height)347 void ButtonModelNG::SetSize(const std::optional<Dimension>& width, const std::optional<Dimension>& height)
348 {
349 if (width.has_value()) {
350 NG::ViewAbstract::SetWidth(NG::CalcLength(width.value()));
351 }
352
353 if (height.has_value()) {
354 NG::ViewAbstract::SetHeight(NG::CalcLength(height.value()));
355 }
356 }
357
SetBorderRadius(const Dimension & radius)358 void ButtonModelNG::SetBorderRadius(const Dimension& radius)
359 {
360 NG::BorderRadiusProperty borderRadius;
361 borderRadius.radiusTopLeft = radius;
362 borderRadius.radiusTopRight = radius;
363 borderRadius.radiusBottomLeft = radius;
364 borderRadius.radiusBottomRight = radius;
365 borderRadius.multiValued = true;
366 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, BorderRadius, borderRadius);
367 }
368
SetBorderRadius(FrameNode * frameNode,const Dimension & radius)369 void ButtonModelNG::SetBorderRadius(FrameNode* frameNode, const Dimension& radius)
370 {
371 NG::BorderRadiusProperty borderRadius;
372 borderRadius.radiusTopLeft = radius;
373 borderRadius.radiusTopRight = radius;
374 borderRadius.radiusBottomLeft = radius;
375 borderRadius.radiusBottomRight = radius;
376 borderRadius.multiValued = true;
377 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, BorderRadius, borderRadius, frameNode);
378 }
379
SetBorderRadius(const std::optional<Dimension> & radiusTopLeft,const std::optional<Dimension> & radiusTopRight,const std::optional<Dimension> & radiusBottomLeft,const std::optional<Dimension> & radiusBottomRight)380 void ButtonModelNG::SetBorderRadius(const std::optional<Dimension>& radiusTopLeft,
381 const std::optional<Dimension>& radiusTopRight, const std::optional<Dimension>& radiusBottomLeft,
382 const std::optional<Dimension>& radiusBottomRight)
383 {
384 NG::BorderRadiusProperty borderRadius;
385 borderRadius.radiusTopLeft = radiusTopLeft;
386 borderRadius.radiusTopRight = radiusTopRight;
387 borderRadius.radiusBottomLeft = radiusBottomLeft;
388 borderRadius.radiusBottomRight = radiusBottomRight;
389 borderRadius.multiValued = true;
390 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, BorderRadius, borderRadius);
391 }
392
SetLocalizedBorderRadius(const std::optional<Dimension> & radiusTopStart,const std::optional<Dimension> & radiusTopEnd,const std::optional<Dimension> & radiusBottomStart,const std::optional<Dimension> & radiusBottomEnd)393 void ButtonModelNG::SetLocalizedBorderRadius(const std::optional<Dimension>& radiusTopStart,
394 const std::optional<Dimension>& radiusTopEnd, const std::optional<Dimension>& radiusBottomStart,
395 const std::optional<Dimension>& radiusBottomEnd)
396 {
397 NG::BorderRadiusProperty borderRadius;
398 borderRadius.radiusTopStart = radiusTopStart;
399 borderRadius.radiusTopEnd = radiusTopEnd;
400 borderRadius.radiusBottomStart = radiusBottomStart;
401 borderRadius.radiusBottomEnd = radiusBottomEnd;
402 borderRadius.multiValued = true;
403 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, BorderRadius, borderRadius);
404 }
405
SetBorderRadius(FrameNode * frameNode,const std::optional<Dimension> & radiusTopLeft,const std::optional<Dimension> & radiusTopRight,const std::optional<Dimension> & radiusBottomLeft,const std::optional<Dimension> & radiusBottomRight)406 void ButtonModelNG::SetBorderRadius(FrameNode* frameNode, const std::optional<Dimension>& radiusTopLeft,
407 const std::optional<Dimension>& radiusTopRight, const std::optional<Dimension>& radiusBottomLeft,
408 const std::optional<Dimension>& radiusBottomRight)
409 {
410 NG::BorderRadiusProperty borderRadius;
411 borderRadius.radiusTopLeft = radiusTopLeft;
412 borderRadius.radiusTopRight = radiusTopRight;
413 borderRadius.radiusBottomLeft = radiusBottomLeft;
414 borderRadius.radiusBottomRight = radiusBottomRight;
415 borderRadius.multiValued = true;
416 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, BorderRadius, borderRadius, frameNode);
417 }
418
SetTypeAndStateEffect(const std::optional<ButtonType> & type,const std::optional<bool> & stateEffect)419 void ButtonModelNG::SetTypeAndStateEffect(const std::optional<ButtonType>& type, const std::optional<bool>& stateEffect)
420 {
421 if (type.has_value()) {
422 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, Type, type.value());
423 } else {
424 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
425 // undefined use ROUNDED_RECTANGLE type.
426 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, Type, ButtonType::ROUNDED_RECTANGLE);
427 } else {
428 // undefined use capsule type.
429 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, Type, ButtonType::CAPSULE);
430 }
431 }
432
433 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
434 CHECK_NULL_VOID(frameNode);
435 auto buttonEventHub = frameNode->GetEventHub<ButtonEventHub>();
436 CHECK_NULL_VOID(buttonEventHub);
437 buttonEventHub->SetStateEffect(stateEffect.value_or(true));
438 }
439
SetTextDefaultStyle(const RefPtr<FrameNode> & textNode,const std::string & label)440 void ButtonModelNG::SetTextDefaultStyle(const RefPtr<FrameNode>& textNode, const std::string& label)
441 {
442 CHECK_NULL_VOID(textNode);
443 auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
444 CHECK_NULL_VOID(textLayoutProperty);
445 auto context = textNode->GetContext();
446 CHECK_NULL_VOID(context);
447 auto buttonTheme = context->GetTheme<ButtonTheme>();
448 CHECK_NULL_VOID(buttonTheme);
449 auto textStyle = buttonTheme->GetTextStyle();
450 textLayoutProperty->UpdateContent(label);
451 textLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
452 textLayoutProperty->UpdateMaxLines(buttonTheme->GetTextMaxLines());
453 textLayoutProperty->UpdateFontWeight(textStyle.GetFontWeight());
454 textLayoutProperty->UpdateAdaptFontSizeStep(Dimension(1.0, DimensionUnit::FP));
455 }
456
SetFontSize(FrameNode * frameNode,const Dimension & fontSize)457 void ButtonModelNG::SetFontSize(FrameNode* frameNode, const Dimension& fontSize)
458 {
459 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, FontSize, fontSize, frameNode);
460 CHECK_NULL_VOID(frameNode);
461 auto textNode = AceType::DynamicCast<FrameNode>(frameNode->GetFirstChild());
462 CHECK_NULL_VOID(textNode);
463 auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
464 CHECK_NULL_VOID(textLayoutProperty);
465 textLayoutProperty->ResetAdaptMinFontSize();
466 textLayoutProperty->ResetAdaptMaxFontSize();
467 }
468
SetFontWeight(FrameNode * frameNode,const Ace::FontWeight & fontWeight)469 void ButtonModelNG::SetFontWeight(FrameNode* frameNode, const Ace::FontWeight& fontWeight)
470 {
471 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, FontWeight, fontWeight, frameNode);
472 }
473
SetFontStyle(FrameNode * frameNode,const Ace::FontStyle & fontStyle)474 void ButtonModelNG::SetFontStyle(FrameNode* frameNode, const Ace::FontStyle& fontStyle)
475 {
476 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, FontStyle, fontStyle, frameNode);
477 }
478
SetFontFamily(FrameNode * frameNode,const std::vector<std::string> & fontFamily)479 void ButtonModelNG::SetFontFamily(FrameNode* frameNode, const std::vector<std::string>& fontFamily)
480 {
481 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, FontFamily, fontFamily, frameNode);
482 }
483
SetFontColor(FrameNode * frameNode,const Color & textColor)484 void ButtonModelNG::SetFontColor(FrameNode* frameNode, const Color& textColor)
485 {
486 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, FontColor, textColor, frameNode);
487 ACE_UPDATE_NODE_RENDER_CONTEXT(ForegroundColor, textColor, frameNode);
488 }
489
SetType(FrameNode * frameNode,const int value)490 void ButtonModelNG::SetType(FrameNode* frameNode, const int value)
491 {
492 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, Type, static_cast<ButtonType>(value), frameNode);
493 }
494
SetStateEffect(FrameNode * frameNode,const bool stateEffect)495 void ButtonModelNG::SetStateEffect(FrameNode* frameNode, const bool stateEffect)
496 {
497 CHECK_NULL_VOID(frameNode);
498 auto buttonEventHub = frameNode->GetEventHub<ButtonEventHub>();
499 CHECK_NULL_VOID(buttonEventHub);
500 buttonEventHub->SetStateEffect(stateEffect);
501 }
502
SetLabelStyle(FrameNode * frameNode,const ButtonParameters & buttonParameters)503 void ButtonModelNG::SetLabelStyle(FrameNode* frameNode, const ButtonParameters& buttonParameters)
504 {
505 if (buttonParameters.textOverflow.has_value()) {
506 ACE_UPDATE_NODE_LAYOUT_PROPERTY(
507 ButtonLayoutProperty, TextOverflow, buttonParameters.textOverflow.value(), frameNode);
508 }
509 if (buttonParameters.maxLines.has_value()) {
510 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, MaxLines, buttonParameters.maxLines.value(), frameNode);
511 }
512 if (buttonParameters.minFontSize.has_value()) {
513 ACE_UPDATE_NODE_LAYOUT_PROPERTY(
514 ButtonLayoutProperty, MinFontSize, buttonParameters.minFontSize.value(), frameNode);
515 }
516 if (buttonParameters.maxFontSize.has_value()) {
517 ACE_UPDATE_NODE_LAYOUT_PROPERTY(
518 ButtonLayoutProperty, MaxFontSize, buttonParameters.maxFontSize.value(), frameNode);
519 }
520 if (buttonParameters.heightAdaptivePolicy.has_value()) {
521 ACE_UPDATE_NODE_LAYOUT_PROPERTY(
522 ButtonLayoutProperty, HeightAdaptivePolicy, buttonParameters.heightAdaptivePolicy.value(), frameNode);
523 }
524 if (buttonParameters.fontSize.has_value()) {
525 auto fontSize = buttonParameters.fontSize.value();
526 if (GreatOrEqual(fontSize.Value(), 0.0)) {
527 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, FontSize, fontSize, frameNode);
528 } else {
529 auto layoutProperty = frameNode->GetLayoutProperty<ButtonLayoutProperty>();
530 CHECK_NULL_VOID(layoutProperty);
531 auto context = PipelineBase::GetCurrentContextSafely();
532 CHECK_NULL_VOID(context);
533 auto buttonTheme = context->GetTheme<ButtonTheme>();
534 CHECK_NULL_VOID(buttonTheme);
535 auto themeFontSize = buttonTheme->GetTextSize(layoutProperty->GetControlSizeValue(ControlSize::NORMAL));
536 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, FontSize, themeFontSize, frameNode);
537 }
538 }
539 if (buttonParameters.fontWeight.has_value()) {
540 ACE_UPDATE_NODE_LAYOUT_PROPERTY(
541 ButtonLayoutProperty, FontWeight, buttonParameters.fontWeight.value(), frameNode);
542 }
543 if (buttonParameters.fontFamily.has_value()) {
544 ACE_UPDATE_NODE_LAYOUT_PROPERTY(
545 ButtonLayoutProperty, FontFamily, buttonParameters.fontFamily.value(), frameNode);
546 }
547 if (buttonParameters.fontStyle.has_value()) {
548 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, FontStyle, buttonParameters.fontStyle.value(), frameNode);
549 }
550 }
551
SetSize(FrameNode * frameNode,const std::optional<Dimension> & width,const std::optional<Dimension> & height)552 void ButtonModelNG::SetSize(
553 FrameNode* frameNode, const std::optional<Dimension>& width, const std::optional<Dimension>& height)
554 {
555 if (width.has_value()) {
556 NG::ViewAbstract::SetWidth(frameNode, NG::CalcLength(width.value()));
557 }
558
559 if (height.has_value()) {
560 NG::ViewAbstract::SetHeight(frameNode, NG::CalcLength(height.value()));
561 }
562 }
563
GetLabel(FrameNode * frameNode)564 std::string ButtonModelNG::GetLabel(FrameNode* frameNode)
565 {
566 std::string value;
567 ACE_GET_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, Label, value, frameNode);
568 return value;
569 }
570
GetFontSize(FrameNode * frameNode)571 Dimension ButtonModelNG::GetFontSize(FrameNode* frameNode)
572 {
573 Dimension value;
574 ACE_GET_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, FontSize, value, frameNode);
575 return value;
576 }
577
GetFontWeight(FrameNode * frameNode)578 Ace::FontWeight ButtonModelNG::GetFontWeight(FrameNode* frameNode)
579 {
580 Ace::FontWeight value = Ace::FontWeight::NORMAL;
581 ACE_GET_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, FontWeight, value, frameNode);
582 return value;
583 }
584
GetFontColor(FrameNode * frameNode)585 Color ButtonModelNG::GetFontColor(FrameNode* frameNode)
586 {
587 Color value;
588 ACE_GET_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, FontColor, value, frameNode);
589 return value;
590 }
591
GetAutoDisable(FrameNode * frameNode)592 bool ButtonModelNG::GetAutoDisable(FrameNode* frameNode)
593 {
594 bool value = false;
595 ACE_GET_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, AutoDisable, value, frameNode);
596 return value;
597 }
598
SetBuilderFunc(FrameNode * frameNode,NG::ButtonMakeCallback && makeFunc)599 void ButtonModelNG::SetBuilderFunc(FrameNode* frameNode, NG::ButtonMakeCallback&& makeFunc)
600 {
601 CHECK_NULL_VOID(frameNode);
602 auto pattern = frameNode->GetPattern<ButtonPattern>();
603 CHECK_NULL_VOID(pattern);
604 pattern->SetBuilderFunc(std::move(makeFunc));
605 }
606
TriggerClick(FrameNode * frameNode,double xPos,double yPos)607 void ButtonModelNG::TriggerClick(FrameNode* frameNode, double xPos, double yPos)
608 {
609 auto pattern = frameNode->GetPattern<ButtonPattern>();
610 CHECK_NULL_VOID(pattern);
611 auto host = pattern->GetHost();
612 CHECK_NULL_VOID(host);
613 auto gestureEventHub = host->GetOrCreateGestureEventHub();
614 if (!gestureEventHub->IsClickable()) {
615 return;
616 }
617 pattern->SetButtonPress(xPos, yPos);
618 }
619
ResetBorderRadius()620 void ButtonModelNG::ResetBorderRadius()
621 {
622 ACE_RESET_LAYOUT_PROPERTY_WITH_FLAG(ButtonLayoutProperty, BorderRadius, PROPERTY_UPDATE_MEASURE);
623 }
624
GetType(FrameNode * frameNode)625 ButtonType ButtonModelNG::GetType(FrameNode* frameNode)
626 {
627 ButtonType value = ButtonType::CAPSULE;
628 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
629 value = ButtonType::ROUNDED_RECTANGLE;
630 ACE_GET_NODE_LAYOUT_PROPERTY_WITH_DEFAULT_VALUE(ButtonLayoutProperty, Type, value,
631 frameNode, ButtonType::ROUNDED_RECTANGLE);
632 } else {
633 ACE_GET_NODE_LAYOUT_PROPERTY_WITH_DEFAULT_VALUE(ButtonLayoutProperty, Type, value,
634 frameNode, ButtonType::CAPSULE);
635 }
636
637 return value;
638 }
639
ApplyTheme(FrameNode * frameNode,ButtonStyleMode buttonStyle,ButtonRole buttonRole)640 void ButtonModelNG::ApplyTheme(FrameNode* frameNode, ButtonStyleMode buttonStyle, ButtonRole buttonRole)
641 {
642 auto context = PipelineBase::GetCurrentContextSafely();
643 CHECK_NULL_VOID(context);
644 auto buttonTheme = context->GetTheme<ButtonTheme>();
645 CHECK_NULL_VOID(buttonTheme);
646 auto bgColor = buttonTheme->GetBgColor(buttonStyle, buttonRole);
647 auto textColor = buttonTheme->GetTextColor(buttonStyle, buttonRole);
648 BackgroundColor(frameNode, bgColor, true);
649 auto property = frameNode->GetLayoutProperty<ButtonLayoutProperty>();
650 CHECK_NULL_VOID(property);
651 if (!property->GetCreateWithLabelValue(false)) {
652 return;
653 }
654 SetFontColor(frameNode, textColor);
655 }
656
SetLabelWithCheck(FrameNode * frameNode,const char * label)657 void ButtonModelNG::SetLabelWithCheck(FrameNode* frameNode, const char* label)
658 {
659 auto property = frameNode->GetLayoutProperty<ButtonLayoutProperty>();
660 CHECK_NULL_VOID(property);
661 if (!property->GetCreateWithLabelValue(false)) {
662 return;
663 }
664 SetLabel(frameNode, label);
665 }
666
SetCreateWithLabel(bool createWithLabel)667 void ButtonModelNG::SetCreateWithLabel(bool createWithLabel)
668 {
669 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, CreateWithLabel, createWithLabel);
670 }
671
SetMinFontScale(float minFontScale)672 void ButtonModelNG::SetMinFontScale(float minFontScale)
673 {
674 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, MinFontScale, minFontScale);
675 }
676
SetMaxFontScale(float maxFontScale)677 void ButtonModelNG::SetMaxFontScale(float maxFontScale)
678 {
679 ACE_UPDATE_LAYOUT_PROPERTY(ButtonLayoutProperty, MaxFontScale, maxFontScale);
680 }
681
SetCreateWithLabel(FrameNode * frameNode,bool createWithLabel)682 void ButtonModelNG::SetCreateWithLabel(FrameNode* frameNode, bool createWithLabel)
683 {
684 auto property = frameNode->GetLayoutProperty<ButtonLayoutProperty>();
685 CHECK_NULL_VOID(property);
686 if (property->HasCreateWithLabel()) {
687 return;
688 }
689 property->UpdateCreateWithLabel(createWithLabel);
690 }
691
SetMinFontScale(FrameNode * frameNode,float minFontScale)692 void ButtonModelNG::SetMinFontScale(FrameNode* frameNode, float minFontScale)
693 {
694 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, MinFontScale, minFontScale, frameNode);
695 }
696
SetMaxFontScale(FrameNode * frameNode,float maxFontScale)697 void ButtonModelNG::SetMaxFontScale(FrameNode* frameNode, float maxFontScale)
698 {
699 ACE_UPDATE_NODE_LAYOUT_PROPERTY(ButtonLayoutProperty, MaxFontScale, maxFontScale, frameNode);
700 }
701
GetMinFontScale(FrameNode * frameNode)702 float ButtonModelNG::GetMinFontScale(FrameNode* frameNode)
703 {
704 CHECK_NULL_RETURN(frameNode, 0.0f);
705 float minFontScale = 0.0f;
706 ACE_GET_NODE_LAYOUT_PROPERTY_WITH_DEFAULT_VALUE(ButtonLayoutProperty, MinFontScale, minFontScale, frameNode, 0.0f);
707 return minFontScale;
708 }
709
GetMaxFontScale(FrameNode * frameNode)710 float ButtonModelNG::GetMaxFontScale(FrameNode* frameNode)
711 {
712 CHECK_NULL_RETURN(frameNode, 0.0f);
713 float maxFontScale = 0.0f;
714 ACE_GET_NODE_LAYOUT_PROPERTY_WITH_DEFAULT_VALUE(ButtonLayoutProperty, MaxFontScale, maxFontScale, frameNode,
715 static_cast<float>(INT32_MAX));
716 return maxFontScale;
717 }
718 } // namespace OHOS::Ace::NG
719