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/interfaces/native/node/calendar_picker_modifier.h"
17
18 #include "base/json/json_util.h"
19 #include "core/components_ng/base/frame_node.h"
20 #include "core/components_ng/base/view_abstract.h"
21 #include "core/pipeline/base/element_register.h"
22 #include "frameworks/core/components_ng/pattern/calendar_picker/calendar_picker_model_ng.h"
23 #include "frameworks/core/components_ng/pattern/picker/picker_type_define.h"
24
25 namespace OHOS::Ace::NG {
26 namespace {
27 constexpr int NUM_0 = 0;
28 constexpr int NUM_1 = 1;
29 constexpr int NUM_2 = 2;
30 } // namespace
SetHintRadius(ArkUINodeHandle node,float radius,int32_t unit)31 void SetHintRadius(ArkUINodeHandle node, float radius, int32_t unit)
32 {
33 auto* frameNode = reinterpret_cast<FrameNode*>(node);
34 CHECK_NULL_VOID(frameNode);
35 Dimension radiusDimension(radius, static_cast<DimensionUnit>(unit));
36 CalendarPickerModelNG::SetHintRadiusWithNode(frameNode, radiusDimension);
37 }
38
GetHintRadius(ArkUINodeHandle node)39 float GetHintRadius(ArkUINodeHandle node)
40 {
41 auto* frameNode = reinterpret_cast<FrameNode*>(node);
42 CHECK_NULL_RETURN(frameNode, 0.0f);
43 return CalendarPickerModelNG::GetHintRadius(frameNode).Value();
44 }
45
SetSelectedDate(ArkUINodeHandle node,uint32_t year,uint32_t month,uint32_t day)46 void SetSelectedDate(ArkUINodeHandle node, uint32_t year, uint32_t month, uint32_t day)
47 {
48 auto* frameNode = reinterpret_cast<FrameNode*>(node);
49 CHECK_NULL_VOID(frameNode);
50 CalendarPickerModelNG::SetSelectDateWithNode(frameNode, year, month, day);
51 }
52
GetSelectedDate(ArkUINodeHandle node)53 ArkUISelectedDateType GetSelectedDate(ArkUINodeHandle node)
54 {
55 ArkUISelectedDateType selectedDate = { 0, 0, 0 };
56 auto* frameNode = reinterpret_cast<FrameNode*>(node);
57 CHECK_NULL_RETURN(frameNode, selectedDate);
58 auto pickDate = CalendarPickerModelNG::GetSelectDateWithNode(frameNode);
59 selectedDate.year = static_cast<uint32_t>(pickDate.GetYear());
60 selectedDate.month = static_cast<uint32_t>(pickDate.GetMonth());
61 selectedDate.day = static_cast<uint32_t>(pickDate.GetDay());
62 return selectedDate;
63 }
64
ResetSelectedDate(ArkUINodeHandle node)65 void ResetSelectedDate(ArkUINodeHandle node)
66 {
67 auto* frameNode = reinterpret_cast<FrameNode*>(node);
68 CHECK_NULL_VOID(frameNode);
69 auto currentDate = PickerDate::Current();
70 CalendarPickerModelNG::SetSelectDateWithNode(
71 frameNode, currentDate.GetYear(), currentDate.GetMonth(), currentDate.GetDay());
72 }
73
SetTextStyleWithWeightEnum(ArkUINodeHandle node,uint32_t color,float fontSize,int32_t fontSizeUnit,int32_t fontWeight)74 void SetTextStyleWithWeightEnum(
75 ArkUINodeHandle node, uint32_t color, float fontSize, int32_t fontSizeUnit, int32_t fontWeight)
76 {
77 auto* frameNode = reinterpret_cast<FrameNode*>(node);
78 CHECK_NULL_VOID(frameNode);
79 NG::PickerTextStyle textStyle;
80 textStyle.textColor = Color(color);
81 Dimension fontSizeDimension(fontSize, DimensionUnit::FP);
82 textStyle.fontSize = fontSizeDimension;
83 textStyle.fontWeight = static_cast<Ace::FontWeight>(fontWeight);
84 CalendarPickerModelNG::SetTextStyle(frameNode, textStyle);
85 }
86
SetTextStyle(ArkUINodeHandle node,uint32_t color,const char * fontSize,const char * fontweight)87 void SetTextStyle(ArkUINodeHandle node, uint32_t color, const char* fontSize, const char* fontweight)
88 {
89 auto* frameNode = reinterpret_cast<FrameNode*>(node);
90 CHECK_NULL_VOID(frameNode);
91 NG::PickerTextStyle textStyle;
92 textStyle.textColor = Color(color);
93 CalcDimension fontSizeDimension =
94 StringUtils::StringToCalcDimension(std::string(fontSize), false, DimensionUnit::FP);
95 if (fontSizeDimension.Unit() == DimensionUnit::PERCENT) {
96 textStyle.fontSize = Dimension(-1);
97 } else {
98 textStyle.fontSize = fontSizeDimension;
99 }
100 textStyle.fontWeight = StringUtils::StringToFontWeight(fontweight, FontWeight::NORMAL);
101 CalendarPickerModelNG::SetTextStyle(frameNode, textStyle);
102 }
103
GetTextStyle(ArkUINodeHandle node)104 ArkUICalendarTextStyleType GetTextStyle(ArkUINodeHandle node)
105 {
106 ArkUICalendarTextStyleType textStyle = { Color::BLACK.GetValue(), 0.0f, 0 };
107 auto* frameNode = reinterpret_cast<FrameNode*>(node);
108 CHECK_NULL_RETURN(frameNode, textStyle);
109 auto currentTextStyle = CalendarPickerModelNG::GetTextStyle(frameNode);
110 textStyle.fontColor = currentTextStyle.textColor.has_value() ? currentTextStyle.textColor.value().GetValue()
111 : Color::BLACK.GetValue();
112 textStyle.fontSize = currentTextStyle.fontSize.has_value() ? currentTextStyle.fontSize.value().Value() : 0.0f;
113 textStyle.fontWeight = currentTextStyle.fontWeight.has_value()
114 ? static_cast<int32_t>(currentTextStyle.fontWeight.value())
115 : static_cast<int32_t>(FontWeight::NORMAL);
116 return textStyle;
117 }
118
ResetTextStyle(ArkUINodeHandle node)119 void ResetTextStyle(ArkUINodeHandle node)
120 {
121 auto* frameNode = reinterpret_cast<FrameNode*>(node);
122 CHECK_NULL_VOID(frameNode);
123 auto pipeline = PipelineBase::GetCurrentContext();
124 CHECK_NULL_VOID(pipeline);
125 RefPtr<CalendarTheme> calendarTheme = pipeline->GetTheme<CalendarTheme>();
126 CHECK_NULL_VOID(calendarTheme);
127 NG::PickerTextStyle textStyle;
128 textStyle.fontSize = calendarTheme->GetEntryFontSize();
129 textStyle.textColor = calendarTheme->GetEntryFontColor();
130 textStyle.fontWeight = FontWeight::NORMAL;
131 CalendarPickerModelNG::SetTextStyle(frameNode, textStyle);
132 }
133
SetEdgeAlign(ArkUINodeHandle node,const ArkUI_Float32 * values,const int * units,int32_t size,int32_t alignType)134 void SetEdgeAlign(ArkUINodeHandle node, const ArkUI_Float32* values, const int* units, int32_t size, int32_t alignType)
135 {
136 auto* frameNode = reinterpret_cast<FrameNode*>(node);
137 CHECK_NULL_VOID(frameNode);
138 if (size < NUM_2) {
139 return;
140 }
141
142 Dimension dx = Dimension(values[NUM_0], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_0]));
143 Dimension dy = Dimension(values[NUM_1], static_cast<OHOS::Ace::DimensionUnit>(units[NUM_1]));
144 NG::CalendarEdgeAlign align = static_cast<NG::CalendarEdgeAlign>(alignType);
145 DimensionOffset offset = DimensionOffset(dx, dy);
146 CalendarPickerModelNG::SetEdgeAlign(frameNode, align, offset);
147 }
148
GetEdgeAlign(ArkUINodeHandle node)149 ArkUIEdgeAlignType GetEdgeAlign(ArkUINodeHandle node)
150 {
151 ArkUIEdgeAlignType align = { 0, 0.0f, 0.0f };
152 auto* frameNode = reinterpret_cast<FrameNode*>(node);
153 CHECK_NULL_RETURN(frameNode, align);
154 auto offset = CalendarPickerModelNG::GetEdgeOffset(frameNode);
155 align.alignType = static_cast<int32_t>(CalendarPickerModelNG::GetEdgeAlignType(frameNode));
156 align.offsetX = offset.GetX().ConvertToVp();
157 align.offsetY = offset.GetY().ConvertToVp();
158 return align;
159 }
160
ResetEdgeAlign(ArkUINodeHandle node)161 void ResetEdgeAlign(ArkUINodeHandle node)
162 {
163 auto* frameNode = reinterpret_cast<FrameNode*>(node);
164 CHECK_NULL_VOID(frameNode);
165 NG::CalendarEdgeAlign alignType = NG::CalendarEdgeAlign::EDGE_ALIGN_END;
166 DimensionOffset offset;
167 CalendarPickerModelNG::SetEdgeAlign(frameNode, alignType, offset);
168 }
169
SetCalendarPickerHeight(ArkUINodeHandle node,ArkUI_Float32 value,ArkUI_Int32 unit)170 void SetCalendarPickerHeight(ArkUINodeHandle node, ArkUI_Float32 value, ArkUI_Int32 unit)
171 {
172 auto* frameNode = reinterpret_cast<FrameNode*>(node);
173 CHECK_NULL_VOID(frameNode);
174 DimensionUnit unitEnum = static_cast<OHOS::Ace::DimensionUnit>(unit);
175 Dimension height = Dimension(value, unitEnum);
176 if (height.IsValid()) {
177 ViewAbstract::SetHeight(frameNode, CalcLength(height));
178 } else {
179 CalendarPickerModelNG::ClearHeight(frameNode);
180 }
181 }
182
ResetCalendarPickerHeight(ArkUINodeHandle node)183 void ResetCalendarPickerHeight(ArkUINodeHandle node)
184 {
185 auto* frameNode = reinterpret_cast<FrameNode*>(node);
186 CHECK_NULL_VOID(frameNode);
187 CalendarPickerModelNG::ClearHeight(frameNode);
188 }
189
SetCalendarPickerBorderColor(ArkUINodeHandle node,ArkUI_Uint32 color)190 void SetCalendarPickerBorderColor(ArkUINodeHandle node, ArkUI_Uint32 color)
191 {
192 auto* frameNode = reinterpret_cast<FrameNode*>(node);
193 CHECK_NULL_VOID(frameNode);
194 ViewAbstract::SetBorderColor(frameNode, Color(color));
195 }
196
ResetCalendarPickerBorderColor(ArkUINodeHandle node)197 void ResetCalendarPickerBorderColor(ArkUINodeHandle node)
198 {
199 auto* frameNode = reinterpret_cast<FrameNode*>(node);
200 CHECK_NULL_VOID(frameNode);
201 CalendarPickerModelNG::ClearBorderColor(frameNode);
202 }
203
SetCalendarPickerBorderRadius(ArkUINodeHandle node,const ArkUI_Float32 value,const ArkUI_Int32 unit)204 void SetCalendarPickerBorderRadius(ArkUINodeHandle node, const ArkUI_Float32 value, const ArkUI_Int32 unit)
205 {
206 auto *frameNode = reinterpret_cast<FrameNode *>(node);
207 CHECK_NULL_VOID(frameNode);
208 Dimension radius =
209 Dimension(static_cast<double>(value), static_cast<OHOS::Ace::DimensionUnit>(unit));
210 ViewAbstract::SetBorderRadius(frameNode, radius);
211 }
212
ResetCalendarPickerBorderRadius(ArkUINodeHandle node)213 void ResetCalendarPickerBorderRadius(ArkUINodeHandle node)
214 {
215 auto* frameNode = reinterpret_cast<FrameNode*>(node);
216 CHECK_NULL_VOID(frameNode);
217 CalendarPickerModelNG::ClearBorderRadius(frameNode);
218 }
219
ResetCalendarPickerBorderWidth(ArkUINodeHandle node)220 void ResetCalendarPickerBorderWidth(ArkUINodeHandle node)
221 {
222 auto* frameNode = reinterpret_cast<FrameNode*>(node);
223 CHECK_NULL_VOID(frameNode);
224 CalendarPickerModelNG::ClearBorderWidth(frameNode);
225 }
226
IsPaddingValid(NG::PaddingProperty & paddings,CalcLength topDim,CalcLength rightDim,CalcLength bottomDim,CalcLength leftDim)227 bool IsPaddingValid(NG::PaddingProperty& paddings, CalcLength topDim,
228 CalcLength rightDim, CalcLength bottomDim, CalcLength leftDim)
229 {
230 bool hasValue = false;
231 if (topDim.IsValid()) {
232 paddings.top = std::optional<CalcLength>(topDim);
233 hasValue = true;
234 }
235 if (bottomDim.IsValid()) {
236 paddings.bottom = std::optional<CalcLength>(bottomDim);
237 hasValue = true;
238 }
239 if (leftDim.IsValid()) {
240 paddings.left = std::optional<CalcLength>(leftDim);
241 hasValue = true;
242 }
243 if (rightDim.IsValid()) {
244 paddings.right = std::optional<CalcLength>(rightDim);
245 hasValue = true;
246 }
247 return hasValue;
248 }
249
SetCalendarPickerPadding(ArkUINodeHandle node,const struct ArkUISizeType * top,const struct ArkUISizeType * right,const struct ArkUISizeType * bottom,const struct ArkUISizeType * left)250 void SetCalendarPickerPadding(ArkUINodeHandle node, const struct ArkUISizeType* top, const struct ArkUISizeType* right,
251 const struct ArkUISizeType* bottom, const struct ArkUISizeType* left)
252 {
253 auto* frameNode = reinterpret_cast<FrameNode*>(node);
254 CHECK_NULL_VOID(frameNode);
255 CalcLength topDim;
256 CalcLength rightDim;
257 CalcLength bottomDim;
258 CalcLength leftDim;
259 if (top->string != nullptr) {
260 topDim = CalcLength(top->string);
261 } else {
262 topDim = CalcLength(top->value, static_cast<DimensionUnit>(top->unit));
263 }
264 if (right->string != nullptr) {
265 rightDim = CalcLength(right->string);
266 } else {
267 rightDim = CalcLength(right->value, static_cast<DimensionUnit>(right->unit));
268 }
269 if (bottom->string != nullptr) {
270 bottomDim = CalcLength(bottom->string);
271 } else {
272 bottomDim = CalcLength(bottom->value, static_cast<DimensionUnit>(bottom->unit));
273 }
274 if (left->string != nullptr) {
275 leftDim = CalcLength(left->string);
276 } else {
277 leftDim = CalcLength(left->value, static_cast<DimensionUnit>(left->unit));
278 }
279 NG::PaddingProperty paddings;
280 paddings.top = std::optional<CalcLength>();
281 paddings.bottom = std::optional<CalcLength>();
282 paddings.left = std::optional<CalcLength>();
283 paddings.right = std::optional<CalcLength>();
284
285 if (IsPaddingValid(paddings, topDim, rightDim, bottomDim, leftDim)) {
286 CalendarPickerModelNG::SetPadding(frameNode, paddings);
287 } else {
288 CalendarPickerModelNG::ClearPadding(frameNode);
289 }
290 }
291
ResetCalendarPickerPadding(ArkUINodeHandle node)292 void ResetCalendarPickerPadding(ArkUINodeHandle node)
293 {
294 auto* frameNode = reinterpret_cast<FrameNode*>(node);
295 CHECK_NULL_VOID(frameNode);
296 CalendarPickerModelNG::ClearPadding(frameNode);
297 }
298
SetCalendarPickerBorder(ArkUINodeHandle node,uint32_t color)299 void SetCalendarPickerBorder(ArkUINodeHandle node, uint32_t color)
300 {
301 auto* frameNode = reinterpret_cast<FrameNode*>(node);
302 CHECK_NULL_VOID(frameNode);
303
304 ViewAbstract::SetBorderColor(frameNode, Color(color));
305 }
306
ResetCalendarPickerBorder(ArkUINodeHandle node)307 void ResetCalendarPickerBorder(ArkUINodeHandle node)
308 {
309 auto* frameNode = reinterpret_cast<FrameNode*>(node);
310 CHECK_NULL_VOID(frameNode);
311
312 auto pipeline = PipelineBase::GetCurrentContext();
313 CHECK_NULL_VOID(pipeline);
314 RefPtr<CalendarTheme> calendarTheme = pipeline->GetTheme<CalendarTheme>();
315 CHECK_NULL_VOID(calendarTheme);
316 ViewAbstract::SetBorderWidth(frameNode, calendarTheme->GetEntryBorderWidth());
317 ViewAbstract::SetBorderColor(frameNode, calendarTheme->GetEntryBorderColor());
318 ViewAbstract::SetBorderRadius(frameNode, calendarTheme->GetEntryBorderRadius());
319 ViewAbstract::SetBorderStyle(frameNode, BorderStyle::SOLID);
320 }
321
322 namespace NodeModifier {
GetCalendarPickerModifier()323 const ArkUICalendarPickerModifier* GetCalendarPickerModifier()
324 {
325 static const ArkUICalendarPickerModifier modifier = { SetHintRadius, SetSelectedDate, ResetSelectedDate,
326 SetTextStyleWithWeightEnum, SetTextStyle, ResetTextStyle, SetEdgeAlign, ResetEdgeAlign,
327 SetCalendarPickerPadding, ResetCalendarPickerPadding, SetCalendarPickerBorder, ResetCalendarPickerBorder,
328 GetHintRadius, GetSelectedDate, GetTextStyle, GetEdgeAlign, SetCalendarPickerHeight, ResetCalendarPickerHeight,
329 SetCalendarPickerBorderColor, ResetCalendarPickerBorderColor, SetCalendarPickerBorderRadius,
330 ResetCalendarPickerBorderRadius, ResetCalendarPickerBorderWidth };
331
332 return &modifier;
333 }
334
GetCJUICalendarPickerModifier()335 const CJUICalendarPickerModifier* GetCJUICalendarPickerModifier()
336 {
337 static const CJUICalendarPickerModifier modifier = { SetHintRadius, SetSelectedDate, ResetSelectedDate,
338 SetTextStyleWithWeightEnum, SetTextStyle, ResetTextStyle, SetEdgeAlign, ResetEdgeAlign,
339 SetCalendarPickerPadding, ResetCalendarPickerPadding, SetCalendarPickerBorder, ResetCalendarPickerBorder,
340 GetHintRadius, GetSelectedDate, GetTextStyle, GetEdgeAlign, SetCalendarPickerHeight, ResetCalendarPickerHeight,
341 SetCalendarPickerBorderColor, ResetCalendarPickerBorderColor, SetCalendarPickerBorderRadius,
342 ResetCalendarPickerBorderRadius, ResetCalendarPickerBorderWidth };
343
344 return &modifier;
345 }
346
ParseDateByStr(const std::string & date,ArkUISelectedDateType & selectedDate)347 void ParseDateByStr(const std::string& date, ArkUISelectedDateType& selectedDate)
348 {
349 auto json = JsonUtil::ParseJsonString(date);
350 if (!json || json->IsNull()) {
351 return;
352 }
353 auto year = json->GetValue("year");
354 if (year && year->IsNumber()) {
355 uint32_t yearVal = year->GetInt() > 0 ? static_cast<uint32_t>(year->GetInt()) : 0;
356 selectedDate.year = yearVal; // local date start from 1900
357 }
358 auto month = json->GetValue("month");
359 if (month && month->IsNumber()) {
360 uint32_t monthVal = month->GetInt() > 0 ? static_cast<uint32_t>(month->GetInt()) : 0;
361 selectedDate.month = monthVal;
362 }
363 auto day = json->GetValue("day");
364 if (day && day->IsNumber()) {
365 uint32_t dayVal = day->GetInt() > 0 ? static_cast<uint32_t>(day->GetInt()) : 0;
366 selectedDate.day = dayVal;
367 }
368 }
369
SetCalendarPickerOnChange(ArkUINodeHandle node,void * extraParam)370 void SetCalendarPickerOnChange(ArkUINodeHandle node, void* extraParam)
371 {
372 auto* frameNode = reinterpret_cast<FrameNode*>(node);
373 CHECK_NULL_VOID(frameNode);
374 auto onEvent = [node, extraParam](const std::string& dateStr) {
375 ArkUINodeEvent event;
376 event.kind = COMPONENT_ASYNC_EVENT;
377 event.extraParam = reinterpret_cast<intptr_t>(extraParam);
378 ArkUISelectedDateType selectedDate;
379 selectedDate.year = 0;
380 selectedDate.month = 0;
381 selectedDate.day = 0;
382 ParseDateByStr(dateStr, selectedDate);
383 event.componentAsyncEvent.subKind = ON_CALENDAR_PICKER_CHANGE;
384 event.componentAsyncEvent.data[NUM_0].u32 = selectedDate.year;
385 event.componentAsyncEvent.data[NUM_1].u32 = selectedDate.month;
386 event.componentAsyncEvent.data[NUM_2].u32 = selectedDate.day;
387 SendArkUIAsyncEvent(&event);
388 };
389 CalendarPickerModelNG::SetOnChangeWithNode(frameNode, std::move(onEvent));
390 }
391 } // namespace NodeModifier
392 } // namespace OHOS::Ace::NG
393