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 #include "core/interfaces/native/node/radio_modifier.h"
16
17 #include <string>
18
19 #include "core/components/checkable/checkable_theme.h"
20 #include "core/components/common/layout/constants.h"
21 #include "core/components/theme/theme_manager.h"
22 #include "core/components_ng/base/frame_node.h"
23 #include "core/components_ng/base/view_abstract.h"
24 #include "core/components_ng/pattern/radio/radio_model_ng.h"
25 #include "core/pipeline/base/element_register.h"
26 #include "core/pipeline_ng/pipeline_context.h"
27
28
29 namespace OHOS::Ace::NG {
30 namespace {
31 constexpr bool DEFAULT_CHECKED = false;
32 const int32_t ERROR_INT_CODE = -1;
33 std::string g_radioStrValue;
34
SetRadioChecked(ArkUINodeHandle node,ArkUI_Bool isCheck)35 void SetRadioChecked(ArkUINodeHandle node, ArkUI_Bool isCheck)
36 {
37 auto* frameNode = reinterpret_cast<FrameNode*>(node);
38 CHECK_NULL_VOID(frameNode);
39 RadioModelNG::SetChecked(frameNode, isCheck);
40 }
41
ResetRadioChecked(ArkUINodeHandle node)42 void ResetRadioChecked(ArkUINodeHandle node)
43 {
44 auto* frameNode = reinterpret_cast<FrameNode*>(node);
45 CHECK_NULL_VOID(frameNode);
46 RadioModelNG::SetChecked(frameNode, DEFAULT_CHECKED);
47 }
48
SetRadioStyle(ArkUINodeHandle node,ArkUI_Uint32 checkedBackgroundColor,ArkUI_Uint32 uncheckedBorderColor,ArkUI_Uint32 indicatorColor)49 void SetRadioStyle(ArkUINodeHandle node, ArkUI_Uint32 checkedBackgroundColor, ArkUI_Uint32 uncheckedBorderColor,
50 ArkUI_Uint32 indicatorColor)
51 {
52 auto* frameNode = reinterpret_cast<FrameNode*>(node);
53 CHECK_NULL_VOID(frameNode);
54
55 RadioModelNG::SetCheckedBackgroundColor(frameNode, Color(checkedBackgroundColor));
56 RadioModelNG::SetUncheckedBorderColor(frameNode, Color(uncheckedBorderColor));
57 RadioModelNG::SetIndicatorColor(frameNode, Color(indicatorColor));
58 }
59
ResetRadioStyle(ArkUINodeHandle node)60 void ResetRadioStyle(ArkUINodeHandle node)
61 {
62 auto* frameNode = reinterpret_cast<FrameNode*>(node);
63 CHECK_NULL_VOID(frameNode);
64
65 auto context = frameNode->GetContext();
66 CHECK_NULL_VOID(context);
67 auto themeManager = context->GetThemeManager();
68 CHECK_NULL_VOID(themeManager);
69 auto theme = themeManager->GetTheme<RadioTheme>();
70 CHECK_NULL_VOID(theme);
71
72 RadioModelNG::SetCheckedBackgroundColor(frameNode, theme->GetActiveColor());
73 RadioModelNG::SetUncheckedBorderColor(frameNode, theme->GetInactiveColor());
74 RadioModelNG::SetIndicatorColor(frameNode, theme->GetPointColor());
75 }
76
SetRadioWidth(ArkUINodeHandle node,ArkUI_Float32 value,ArkUI_Int32 unit,ArkUI_CharPtr calcValue)77 void SetRadioWidth(ArkUINodeHandle node, ArkUI_Float32 value, ArkUI_Int32 unit, ArkUI_CharPtr calcValue)
78 {
79 auto* frameNode = reinterpret_cast<FrameNode*>(node);
80 CHECK_NULL_VOID(frameNode);
81 auto unitEnum = static_cast<OHOS::Ace::DimensionUnit>(unit);
82 if (unitEnum == DimensionUnit::CALC) {
83 ViewAbstract::SetWidth(frameNode, CalcLength(CalcLength(std::string(calcValue))));
84 } else {
85 ViewAbstract::SetWidth(frameNode, CalcLength(value, unitEnum));
86 }
87 }
88
ResetRadioWidth(ArkUINodeHandle node)89 void ResetRadioWidth(ArkUINodeHandle node)
90 {
91 auto* frameNode = reinterpret_cast<FrameNode*>(node);
92 CHECK_NULL_VOID(frameNode);
93 ViewAbstract::ClearWidthOrHeight(frameNode, true);
94 }
95
SetRadioHeight(ArkUINodeHandle node,ArkUI_Float32 value,ArkUI_Int32 unit,ArkUI_CharPtr calcValue)96 void SetRadioHeight(ArkUINodeHandle node, ArkUI_Float32 value, ArkUI_Int32 unit, ArkUI_CharPtr calcValue)
97 {
98 auto* frameNode = reinterpret_cast<FrameNode*>(node);
99 CHECK_NULL_VOID(frameNode);
100 auto unitEnum = static_cast<OHOS::Ace::DimensionUnit>(unit);
101 if (unitEnum == DimensionUnit::CALC) {
102 ViewAbstract::SetHeight(frameNode, CalcLength(CalcLength(std::string(calcValue))));
103 } else {
104 ViewAbstract::SetHeight(frameNode, CalcLength(value, unitEnum));
105 }
106 }
107
ResetRadioHeight(ArkUINodeHandle node)108 void ResetRadioHeight(ArkUINodeHandle node)
109 {
110 auto* frameNode = reinterpret_cast<FrameNode*>(node);
111 CHECK_NULL_VOID(frameNode);
112 ViewAbstract::ClearWidthOrHeight(frameNode, false);
113 }
114
SetRadioSize(ArkUINodeHandle node,ArkUI_Float32 widthValue,ArkUI_Int32 widthUnit,ArkUI_Float32 heightValue,ArkUI_Int32 heightUnit)115 void SetRadioSize(ArkUINodeHandle node, ArkUI_Float32 widthValue, ArkUI_Int32 widthUnit, ArkUI_Float32 heightValue,
116 ArkUI_Int32 heightUnit)
117 {
118 auto* frameNode = reinterpret_cast<FrameNode*>(node);
119 CHECK_NULL_VOID(frameNode);
120 RadioModelNG::SetWidth(frameNode, Dimension(widthValue, static_cast<OHOS::Ace::DimensionUnit>(widthUnit)));
121 RadioModelNG::SetHeight(frameNode, Dimension(heightValue, static_cast<OHOS::Ace::DimensionUnit>(heightUnit)));
122 }
123
ResetRadioSize(ArkUINodeHandle node)124 void ResetRadioSize(ArkUINodeHandle node)
125 {
126 auto* frameNode = reinterpret_cast<FrameNode*>(node);
127 CHECK_NULL_VOID(frameNode);
128 auto pipeline = PipelineBase::GetCurrentContext();
129 CHECK_NULL_VOID(pipeline);
130 auto radioTheme = pipeline->GetTheme<RadioTheme>();
131 CHECK_NULL_VOID(radioTheme);
132 auto defaultWidth = radioTheme->GetDefaultWidth();
133 auto horizontalPadding = radioTheme->GetHotZoneHorizontalPadding();
134 auto width = defaultWidth - horizontalPadding * 2; //2 is Calculate the parameters of the formula
135
136 auto defaultHeight = radioTheme->GetDefaultHeight();
137 auto verticalPadding = radioTheme->GetHotZoneVerticalPadding();
138 auto height = defaultHeight - verticalPadding * 2; //2 is Calculate the parameters of the formula
139 RadioModelNG::SetWidth(frameNode, width);
140 RadioModelNG::SetHeight(frameNode, height);
141 }
142
SetRadioHoverEffect(ArkUINodeHandle node,ArkUI_Int32 hoverEffectValue)143 void SetRadioHoverEffect(ArkUINodeHandle node, ArkUI_Int32 hoverEffectValue)
144 {
145 auto* frameNode = reinterpret_cast<FrameNode*>(node);
146 CHECK_NULL_VOID(frameNode);
147 OHOS::Ace::HoverEffectType hoverEffect = OHOS::Ace::HoverEffectType::AUTO;
148 hoverEffect = static_cast<OHOS::Ace::HoverEffectType>(hoverEffectValue);
149 RadioModelNG::SetHoverEffect(frameNode, hoverEffect);
150 }
151
ResetRadioHoverEffect(ArkUINodeHandle node)152 void ResetRadioHoverEffect(ArkUINodeHandle node)
153 {
154 auto* frameNode = reinterpret_cast<FrameNode*>(node);
155 CHECK_NULL_VOID(frameNode);
156 RadioModelNG::SetHoverEffect(frameNode, OHOS::Ace::HoverEffectType::AUTO);
157 }
158
SetRadioPadding(ArkUINodeHandle node,const struct ArkUISizeType * top,const struct ArkUISizeType * right,const struct ArkUISizeType * bottom,const struct ArkUISizeType * left)159 void SetRadioPadding(ArkUINodeHandle node, const struct ArkUISizeType* top, const struct ArkUISizeType* right,
160 const struct ArkUISizeType* bottom, const struct ArkUISizeType* left)
161 {
162 auto* frameNode = reinterpret_cast<FrameNode*>(node);
163 CHECK_NULL_VOID(frameNode);
164 CalcLength topDimen;
165 CalcLength rightDimen;
166 CalcLength bottomDimen;
167 CalcLength leftDimen;
168 if (top->string != nullptr) {
169 topDimen = CalcLength(top->string);
170 } else {
171 topDimen = CalcLength(top->value, static_cast<DimensionUnit>(top->unit));
172 }
173 if (right->string != nullptr) {
174 rightDimen = CalcLength(right->string);
175 } else {
176 rightDimen = CalcLength(right->value, static_cast<DimensionUnit>(right->unit));
177 }
178 if (bottom->string != nullptr) {
179 bottomDimen = CalcLength(bottom->string);
180 } else {
181 bottomDimen = CalcLength(bottom->value, static_cast<DimensionUnit>(bottom->unit));
182 }
183 if (left->string != nullptr) {
184 leftDimen = CalcLength(left->string);
185 } else {
186 leftDimen = CalcLength(left->value, static_cast<DimensionUnit>(left->unit));
187 }
188 NG::PaddingProperty paddings;
189 paddings.top = std::optional<CalcLength>(topDimen);
190 paddings.bottom = std::optional<CalcLength>(bottomDimen);
191 paddings.left = std::optional<CalcLength>(leftDimen);
192 paddings.right = std::optional<CalcLength>(rightDimen);
193 RadioModelNG::SetPadding(frameNode, paddings);
194 }
195
ResetRadioPadding(ArkUINodeHandle node)196 void ResetRadioPadding(ArkUINodeHandle node)
197 {
198 auto* frameNode = reinterpret_cast<FrameNode*>(node);
199 CHECK_NULL_VOID(frameNode);
200 NG::PaddingProperty paddings;
201 paddings.top = std::optional<CalcLength>(CalcLength(0.0, DimensionUnit::VP));
202 paddings.bottom = std::optional<CalcLength>(CalcLength(0.0, DimensionUnit::VP));
203 paddings.left = std::optional<CalcLength>(CalcLength(0.0, DimensionUnit::VP));
204 paddings.right = std::optional<CalcLength>(CalcLength(0.0, DimensionUnit::VP));
205 RadioModelNG::SetPadding(frameNode, paddings);
206 }
207
SetRadioResponseRegion(ArkUINodeHandle node,const ArkUI_Float32 * values,const ArkUI_Int32 * units,ArkUI_Uint32 length)208 void SetRadioResponseRegion(
209 ArkUINodeHandle node, const ArkUI_Float32* values, const ArkUI_Int32* units, ArkUI_Uint32 length)
210 {
211 auto* frameNode = reinterpret_cast<FrameNode*>(node);
212 CHECK_NULL_VOID(frameNode);
213 std::vector<DimensionRect> region;
214 for (uint32_t i = 0; i < length / 4; i++) { //4 is 4 different parameters
215 CalcDimension xDimen =
216 CalcDimension(values[i * 4 + 0], static_cast<DimensionUnit>(units[i * 4 + 0])); //4:parameters
217 CalcDimension yDimen =
218 CalcDimension(values[i * 4 + 1], static_cast<DimensionUnit>(units[i * 4 + 1])); //4:parameters
219 CalcDimension widthDimen =
220 CalcDimension(values[i * 4 + 2], static_cast<DimensionUnit>(units[i * 4 + 2])); //4:parameters, 2:width
221 CalcDimension heightDimen =
222 CalcDimension(values[i * 4 + 3], static_cast<DimensionUnit>(units[i * 4 + 3])); //4:parameters, 3:height
223 DimensionOffset offsetDimen(xDimen, yDimen);
224 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
225 region.emplace_back(dimenRect);
226 }
227 RadioModelNG::SetResponseRegion(frameNode, region);
228 }
229
ResetRadioResponseRegion(ArkUINodeHandle node)230 void ResetRadioResponseRegion(ArkUINodeHandle node)
231 {
232 auto* frameNode = reinterpret_cast<FrameNode*>(node);
233 CHECK_NULL_VOID(frameNode);
234 std::vector<DimensionRect> region;
235 CalcDimension xDimen = CalcDimension(0.0, DimensionUnit::VP);
236 CalcDimension yDimen = CalcDimension(0.0, DimensionUnit::VP);
237 CalcDimension widthDimen = CalcDimension(1, DimensionUnit::PERCENT);
238 CalcDimension heightDimen = CalcDimension(1, DimensionUnit::PERCENT);
239 DimensionOffset offsetDimen(xDimen, yDimen);
240 DimensionRect dimenRect(widthDimen, heightDimen, offsetDimen);
241 region.emplace_back(dimenRect);
242 RadioModelNG::SetResponseRegion(frameNode, region);
243 }
244
GetRadioChecked(ArkUINodeHandle node)245 ArkUI_Bool GetRadioChecked(ArkUINodeHandle node)
246 {
247 auto* frameNode = reinterpret_cast<FrameNode*>(node);
248 CHECK_NULL_RETURN(frameNode, ERROR_INT_CODE);
249 return static_cast<ArkUI_Bool>(RadioModelNG::GetChecked(frameNode));
250 }
251
GetRadioStyle(ArkUINodeHandle node,ArkUIRadioStyleOption * options)252 void GetRadioStyle(ArkUINodeHandle node, ArkUIRadioStyleOption* options)
253 {
254 auto* frameNode = reinterpret_cast<FrameNode*>(node);
255 CHECK_NULL_VOID(frameNode);
256 options->checkedBackgroundColor = RadioModelNG::GetCheckedBackgroundColor(frameNode).GetValue();
257 options->uncheckedBorderColor = RadioModelNG::GetUncheckedBorderColor(frameNode).GetValue();
258 options->indicatorColor = RadioModelNG::GetIndicatorColor(frameNode).GetValue();
259 }
260
SetRadioValue(ArkUINodeHandle node,ArkUI_CharPtr value)261 void SetRadioValue(ArkUINodeHandle node, ArkUI_CharPtr value)
262 {
263 auto* frameNode = reinterpret_cast<FrameNode*>(node);
264 CHECK_NULL_VOID(frameNode);
265 RadioModelNG::SetRadioValue(frameNode, std::string(value));
266 }
267
ResetRadioValue(ArkUINodeHandle node)268 void ResetRadioValue(ArkUINodeHandle node)
269 {
270 auto* frameNode = reinterpret_cast<FrameNode*>(node);
271 CHECK_NULL_VOID(frameNode);
272 RadioModelNG::SetRadioValue(frameNode, "");
273 }
274
GetSetRadioValue(ArkUINodeHandle node)275 ArkUI_CharPtr GetSetRadioValue(ArkUINodeHandle node)
276 {
277 auto* frameNode = reinterpret_cast<FrameNode*>(node);
278 CHECK_NULL_RETURN(frameNode, nullptr);
279 g_radioStrValue = RadioModelNG::GetRadioValue(frameNode);
280 return g_radioStrValue.c_str();
281 }
282
SetRadioGroup(ArkUINodeHandle node,ArkUI_CharPtr value)283 void SetRadioGroup(ArkUINodeHandle node, ArkUI_CharPtr value)
284 {
285 auto* frameNode = reinterpret_cast<FrameNode*>(node);
286 CHECK_NULL_VOID(frameNode);
287 RadioModelNG::SetRadioGroup(frameNode, std::string(value));
288 }
289
ResetRadioGroup(ArkUINodeHandle node)290 void ResetRadioGroup(ArkUINodeHandle node)
291 {
292 auto* frameNode = reinterpret_cast<FrameNode*>(node);
293 CHECK_NULL_VOID(frameNode);
294 RadioModelNG::SetRadioGroup(frameNode, "");
295 }
296
GetRadioGroup(ArkUINodeHandle node)297 ArkUI_CharPtr GetRadioGroup(ArkUINodeHandle node)
298 {
299 auto* frameNode = reinterpret_cast<FrameNode*>(node);
300 CHECK_NULL_RETURN(frameNode, nullptr);
301 g_radioStrValue = RadioModelNG::GetRadioGroup(frameNode);
302 return g_radioStrValue.c_str();
303 }
304 } // namespace
305
306 namespace NodeModifier {
GetRadioModifier()307 const ArkUIRadioModifier* GetRadioModifier()
308 {
309 static const ArkUIRadioModifier modifier = { SetRadioChecked, ResetRadioChecked, SetRadioStyle, ResetRadioStyle,
310 SetRadioWidth, ResetRadioWidth, SetRadioHeight, ResetRadioHeight, SetRadioSize, ResetRadioSize,
311 SetRadioHoverEffect, ResetRadioHoverEffect, SetRadioPadding, ResetRadioPadding, SetRadioResponseRegion,
312 ResetRadioResponseRegion, GetRadioChecked, GetRadioStyle, SetRadioValue, ResetRadioValue, GetSetRadioValue,
313 SetRadioGroup, ResetRadioGroup, GetRadioGroup };
314
315 return &modifier;
316 }
317
GetCJUIRadioModifier()318 const CJUIRadioModifier* GetCJUIRadioModifier()
319 {
320 static const CJUIRadioModifier modifier = { SetRadioChecked, ResetRadioChecked, SetRadioStyle, ResetRadioStyle,
321 SetRadioWidth, ResetRadioWidth, SetRadioHeight, ResetRadioHeight, SetRadioSize, ResetRadioSize,
322 SetRadioHoverEffect, ResetRadioHoverEffect, SetRadioPadding, ResetRadioPadding, SetRadioResponseRegion,
323 ResetRadioResponseRegion, GetRadioChecked, GetRadioStyle, SetRadioValue, ResetRadioValue, GetSetRadioValue,
324 SetRadioGroup, ResetRadioGroup, GetRadioGroup };
325
326 return &modifier;
327 }
328
SetOnRadioChange(ArkUINodeHandle node,void * extraParam)329 void SetOnRadioChange(ArkUINodeHandle node, void* extraParam)
330 {
331 auto* frameNode = reinterpret_cast<FrameNode*>(node);
332 CHECK_NULL_VOID(frameNode);
333 auto onChange = [node, extraParam](const bool value) {
334 ArkUINodeEvent event;
335 event.kind = COMPONENT_ASYNC_EVENT;
336 event.extraParam = reinterpret_cast<intptr_t>(extraParam);
337 event.componentAsyncEvent.subKind = ON_RADIO_CHANGE;
338 event.componentAsyncEvent.data[0].i32 = static_cast<int>(value);
339 SendArkUIAsyncEvent(&event);
340 };
341 RadioModelNG::SetOnChange(frameNode, std::move(onChange));
342 }
343 } // namespace NodeModifier
344 } // namespace OHOS::Ace::NG