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/calendar_picker/calendar_picker_model_ng.h"
17
18 #include "base/i18n/localization.h"
19 #include "core/components/theme/icon_theme.h"
20 #include "core/components_ng/base/view_stack_processor.h"
21 #include "core/components_ng/pattern/button/button_pattern.h"
22 #include "core/components_ng/pattern/flex/flex_layout_pattern.h"
23 #include "core/components_ng/pattern/flex/flex_layout_property.h"
24 #include "core/components_ng/pattern/image/image_pattern.h"
25 #include "core/components_ng/pattern/text/text_pattern.h"
26 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
27
28 namespace OHOS::Ace::NG {
29 constexpr int32_t YEAR_NODE_INDEX = 0;
30 constexpr int32_t MONTH_NODE_INDEX = 2;
31 constexpr int32_t DAY_NODE_INDEX = 4;
32 constexpr int32_t DATE_NODE_COUNT = 3;
33 constexpr int32_t ONE_DIGIT_BOUNDARY = 10;
34 constexpr float DEFAULT_HINT_RADIUS = 16.0f;
35 static int32_t yearNodeIndex_ = 0;
36 static int32_t monthNodeIndex_ = 2;
37 static int32_t dayNodeIndex_ = 4;
Create(const CalendarSettingData & settingData)38 void CalendarPickerModelNG::Create(const CalendarSettingData& settingData)
39 {
40 auto* stack = ViewStackProcessor::GetInstance();
41 auto nodeId = stack->ClaimNodeId();
42 ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::CALENDAR_PICKER_ETS_TAG, nodeId);
43 auto pickerNode = CalendarPickerModelNG::CreateNode(nodeId, settingData);
44 stack->Push(pickerNode);
45 }
46
CreateFrameNode(int32_t nodeId)47 RefPtr<FrameNode> CalendarPickerModelNG::CreateFrameNode(int32_t nodeId)
48 {
49 NG::CalendarSettingData settingData;
50 return CalendarPickerModelNG::CreateNode(nodeId, settingData);
51 }
52
LayoutPicker(const RefPtr<CalendarPickerPattern> & pickerPattern,RefPtr<FrameNode> & pickerNode,const CalendarSettingData & settingData,const RefPtr<CalendarTheme> & theme)53 void CalendarPickerModelNG::LayoutPicker(const RefPtr<CalendarPickerPattern>& pickerPattern,
54 RefPtr<FrameNode>& pickerNode, const CalendarSettingData& settingData, const RefPtr<CalendarTheme>& theme)
55 {
56 auto textDirection = pickerNode->GetLayoutProperty()->GetNonAutoLayoutDirection();
57 if (!pickerPattern->HasContentNode()) {
58 auto contentNode = CalendarPickerModelNG::CreateCalendarNodeChild(
59 pickerPattern->GetContentId(), settingData, theme, textDirection);
60 CHECK_NULL_VOID(contentNode);
61 contentNode->MountToParent(pickerNode);
62 } else {
63 pickerPattern->SetDate(settingData.selectedDate.ToString(true));
64 }
65 auto flexNode = CalendarPickerModelNG::CreateButtonFlexChild(pickerPattern->GetButtonFlexId(), theme);
66 CHECK_NULL_VOID(flexNode);
67 flexNode->MountToParent(pickerNode);
68 if (!pickerPattern->HasAddNode()) {
69 auto addNode = CalendarPickerModelNG::CreateButtonChild(pickerPattern->GetAddId(), true, theme, textDirection);
70 CHECK_NULL_VOID(addNode);
71 addNode->MountToParent(flexNode, 0, true);
72 }
73 if (!pickerPattern->HasSubNode()) {
74 auto subNode = CalendarPickerModelNG::CreateButtonChild(pickerPattern->GetSubId(), false, theme, textDirection);
75 CHECK_NULL_VOID(subNode);
76 subNode->MountToParent(flexNode, 1, true);
77 }
78 }
79
CreateButtonChild(int32_t id,bool isAdd,const RefPtr<CalendarTheme> & theme,TextDirection textDirection)80 RefPtr<FrameNode> CalendarPickerModelNG::CreateButtonChild(
81 int32_t id, bool isAdd, const RefPtr<CalendarTheme>& theme, TextDirection textDirection)
82 {
83 auto buttonNode =
84 FrameNode::GetOrCreateFrameNode(V2::BUTTON_ETS_TAG, id, []() { return AceType::MakeRefPtr<ButtonPattern>(); });
85 CHECK_NULL_RETURN(buttonNode, nullptr);
86 auto buttonEventHub = buttonNode->GetEventHub<ButtonEventHub>();
87 CHECK_NULL_RETURN(buttonEventHub, nullptr);
88 buttonEventHub->SetStateEffect(true);
89
90 auto buttonLayoutProperty = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
91 CHECK_NULL_RETURN(buttonLayoutProperty, nullptr);
92 buttonLayoutProperty->UpdateType(ButtonType::NORMAL);
93
94 auto buttonPattern = buttonNode->GetPattern<ButtonPattern>();
95 CHECK_NULL_RETURN(buttonPattern, nullptr);
96
97 buttonNode->GetLayoutProperty()->UpdateUserDefinedIdealSize(
98 CalcSize(CalcLength(theme->GetEntryButtonWidth()), std::nullopt));
99 buttonNode->GetLayoutProperty()->UpdateLayoutWeight(1);
100 BorderWidthProperty borderWidth;
101 auto isRtl = textDirection == TextDirection::RTL;
102 if (isAdd) {
103 if (isRtl) {
104 borderWidth.rightDimen = theme->GetEntryBorderWidth();
105 } else {
106 borderWidth.leftDimen = theme->GetEntryBorderWidth();
107 }
108 borderWidth.bottomDimen = theme->GetEntryBorderWidth() / 2;
109 } else {
110 if (isRtl) {
111 borderWidth.rightDimen = theme->GetEntryBorderWidth();
112 } else {
113 borderWidth.leftDimen = theme->GetEntryBorderWidth();
114 }
115 borderWidth.topDimen = theme->GetEntryBorderWidth() / 2;
116 }
117 buttonNode->GetLayoutProperty()->UpdateBorderWidth(borderWidth);
118 BorderColorProperty borderColor;
119 borderColor.SetColor(theme->GetEntryBorderColor());
120 buttonNode->GetRenderContext()->UpdateBorderColor(borderColor);
121 buttonNode->MarkModifyDone();
122
123 auto imageNode = CreateButtonImageChild(isAdd, theme);
124 CHECK_NULL_RETURN(imageNode, nullptr);
125 imageNode->MountToParent(buttonNode);
126 return buttonNode;
127 }
128
CreateButtonImageChild(bool isAdd,const RefPtr<CalendarTheme> & theme)129 RefPtr<FrameNode> CalendarPickerModelNG::CreateButtonImageChild(bool isAdd, const RefPtr<CalendarTheme>& theme)
130 {
131 auto imageNode = FrameNode::CreateFrameNode(
132 V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
133 CHECK_NULL_RETURN(imageNode, nullptr);
134 imageNode->GetLayoutProperty()->UpdateUserDefinedIdealSize(
135 CalcSize(CalcLength(theme->GetEntryArrowWidth()), CalcLength(theme->GetEntryArrowHeight())));
136 auto pipeline = PipelineBase::GetCurrentContext();
137 CHECK_NULL_RETURN(pipeline, nullptr);
138 auto iconTheme = pipeline->GetTheme<IconTheme>();
139 std::string iconPath;
140 ImageSourceInfo imageSourceInfo;
141 if (isAdd) {
142 imageSourceInfo.SetResourceId(InternalResource::ResourceId::IC_PUBLIC_ARROW_UP_SVG);
143 iconPath = iconTheme->GetIconPath(InternalResource::ResourceId::IC_PUBLIC_ARROW_UP_SVG);
144 } else {
145 imageSourceInfo.SetResourceId(InternalResource::ResourceId::IC_PUBLIC_ARROW_DOWN_SVG);
146 iconPath = iconTheme->GetIconPath(InternalResource::ResourceId::IC_PUBLIC_ARROW_DOWN_SVG);
147 }
148 imageSourceInfo.SetSrc(iconPath, theme->GetEntryArrowColor());
149 imageNode->GetLayoutProperty<ImageLayoutProperty>()->UpdateImageSourceInfo(imageSourceInfo);
150 imageNode->MarkModifyDone();
151 return imageNode;
152 }
153
CreateButtonFlexChild(int32_t buttonFlexId,const RefPtr<CalendarTheme> & theme)154 RefPtr<FrameNode> CalendarPickerModelNG::CreateButtonFlexChild(int32_t buttonFlexId, const RefPtr<CalendarTheme>& theme)
155 {
156 auto flexNode = FrameNode::GetOrCreateFrameNode(
157 V2::COLUMN_ETS_TAG, buttonFlexId, []() { return AceType::MakeRefPtr<LinearLayoutPattern>(true); });
158 CHECK_NULL_RETURN(flexNode, nullptr);
159 auto flexLayoutProperty = flexNode->GetLayoutProperty<LinearLayoutProperty>();
160 CHECK_NULL_RETURN(flexLayoutProperty, nullptr);
161 flexLayoutProperty->UpdateMainAxisAlign(FlexAlign::CENTER);
162 flexLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT_CROSS_AXIS);
163 return flexNode;
164 }
165
CreateCalendarNodeChild(int32_t contentId,const CalendarSettingData & settingData,const RefPtr<CalendarTheme> & theme,TextDirection textDirection)166 RefPtr<FrameNode> CalendarPickerModelNG::CreateCalendarNodeChild(int32_t contentId,
167 const CalendarSettingData& settingData, const RefPtr<CalendarTheme>& theme, TextDirection textDirection)
168 {
169 auto contentNode = FrameNode::GetOrCreateFrameNode(
170 V2::ROW_ETS_TAG, contentId, []() { return AceType::MakeRefPtr<LinearLayoutPattern>(false); });
171 CHECK_NULL_RETURN(contentNode, nullptr);
172
173 auto linearLayoutProperty = contentNode->GetLayoutProperty<LinearLayoutProperty>();
174 CHECK_NULL_RETURN(linearLayoutProperty, nullptr);
175
176 linearLayoutProperty->UpdateMainAxisAlign(FlexAlign::CENTER);
177 linearLayoutProperty->UpdateCrossAxisAlign(FlexAlign::CENTER);
178 contentNode->GetRenderContext()->SetClipToFrame(true);
179 linearLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
180 BorderRadiusProperty borderRadius;
181 borderRadius.radiusTopLeft = theme->GetEntryBorderRadius();
182 borderRadius.radiusBottomLeft = theme->GetEntryBorderRadius();
183 borderRadius.radiusTopRight = theme->GetEntryBorderRadius();
184 borderRadius.radiusBottomLeft = theme->GetEntryBorderRadius();
185 contentNode->GetRenderContext()->UpdateBorderRadius(borderRadius);
186 PaddingProperty padding;
187 padding.top = CalcLength(theme->GetEntryDateTopBottomMargin());
188 padding.left = CalcLength(theme->GetEntryDateLeftRightMargin());
189 padding.right = CalcLength(theme->GetEntryDateLeftRightMargin());
190 padding.bottom = CalcLength(theme->GetEntryDateTopBottomMargin());
191 linearLayoutProperty->UpdatePadding(padding);
192 linearLayoutProperty->UpdateLayoutDirection(TextDirection::LTR);
193
194 CreateDateNode(contentId, settingData);
195 contentNode->MarkModifyDone();
196 return contentNode;
197 }
198
CreateDateNode(int32_t contentId,const CalendarSettingData & settingData)199 void CalendarPickerModelNG::CreateDateNode(int32_t contentId, const CalendarSettingData& settingData)
200 {
201 auto contentNode = FrameNode::GetOrCreateFrameNode(
202 V2::ROW_ETS_TAG, contentId, []() { return AceType::MakeRefPtr<LinearLayoutPattern>(false); });
203 CHECK_NULL_VOID(contentNode);
204 std::map<std::size_t, std::string> order = GetDateNodeOrder(settingData);
205
206 auto firstDateNode = CreateDateTextNode(order[0]);
207 CHECK_NULL_VOID(firstDateNode);
208 firstDateNode->MountToParent(contentNode);
209 auto textNode1 = CreateDateTextNode("/");
210 CHECK_NULL_VOID(textNode1);
211 textNode1->MountToParent(contentNode);
212 auto secondDateNode = CreateDateTextNode(order[1]);
213 CHECK_NULL_VOID(secondDateNode);
214 secondDateNode->MountToParent(contentNode);
215 auto textNode2 = CreateDateTextNode("/");
216 CHECK_NULL_VOID(textNode2);
217 textNode2->MountToParent(contentNode);
218 auto thirdDateNode = CreateDateTextNode(order[2]);
219 CHECK_NULL_VOID(thirdDateNode);
220 thirdDateNode->MountToParent(contentNode);
221 }
222
CreateDateTextNode(const std::string & textContent)223 RefPtr<FrameNode> CalendarPickerModelNG::CreateDateTextNode(const std::string& textContent)
224 {
225 auto pipeline = PipelineBase::GetCurrentContext();
226 CHECK_NULL_RETURN(pipeline, nullptr);
227 RefPtr<CalendarTheme> calendarTheme = pipeline->GetTheme<CalendarTheme>();
228 CHECK_NULL_RETURN(calendarTheme, nullptr);
229 auto textNode = FrameNode::CreateFrameNode(
230 V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
231 CHECK_NULL_RETURN(textNode, nullptr);
232 auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
233 CHECK_NULL_RETURN(textLayoutProperty, nullptr);
234 textLayoutProperty->UpdateContent(textContent);
235 textLayoutProperty->UpdateMaxLines(1);
236 textLayoutProperty->UpdateTextColor(calendarTheme->GetEntryFontColor());
237 textLayoutProperty->UpdateFontSize(calendarTheme->GetEntryFontSize());
238 textNode->MarkModifyDone();
239 return textNode;
240 }
241
CreateNode(int32_t nodeId,const CalendarSettingData & settingData)242 RefPtr<FrameNode> CalendarPickerModelNG::CreateNode(int32_t nodeId, const CalendarSettingData& settingData)
243 {
244 auto pickerNode = FrameNode::GetOrCreateFrameNode(
245 V2::CALENDAR_PICKER_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<CalendarPickerPattern>(); });
246 auto pickerPattern = pickerNode->GetPattern<CalendarPickerPattern>();
247 CHECK_NULL_RETURN(pickerPattern, pickerNode);
248 auto pipelineContext = pickerNode->GetContext();
249 CHECK_NULL_RETURN(pipelineContext, pickerNode);
250 RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
251 CHECK_NULL_RETURN(theme, pickerNode);
252 pickerPattern->SetCalendarData(settingData);
253 pickerNode->GetLayoutProperty()->UpdateUserDefinedIdealSize(
254 CalcSize(std::nullopt, CalcLength(theme->GetEntryHeight())));
255 BorderWidthProperty borderWidth;
256 borderWidth.SetBorderWidth(theme->GetEntryBorderWidth());
257 pickerNode->GetLayoutProperty()->UpdateBorderWidth(borderWidth);
258 CHECK_NULL_RETURN(pickerNode->GetRenderContext(), pickerNode);
259 BorderColorProperty borderColor;
260 borderColor.SetColor(theme->GetEntryBorderColor());
261 pickerNode->GetRenderContext()->UpdateBorderColor(borderColor);
262 BorderRadiusProperty borderRadius;
263 borderRadius.SetRadius(theme->GetEntryBorderRadius());
264 pickerNode->GetRenderContext()->UpdateBorderRadius(borderRadius);
265 pickerNode->GetRenderContext()->SetClipToFrame(true);
266 pickerNode->GetRenderContext()->SetClipToBounds(true);
267 pickerNode->GetRenderContext()->UpdateClipEdge(true);
268 CHECK_NULL_RETURN(pickerNode->GetLayoutProperty<LinearLayoutProperty>(), pickerNode);
269 pickerNode->GetLayoutProperty<LinearLayoutProperty>()->UpdateMainAxisAlign(FlexAlign::FLEX_START);
270 pickerNode->GetLayoutProperty<LinearLayoutProperty>()->UpdateCrossAxisAlign(FlexAlign::CENTER);
271 pickerNode->GetLayoutProperty<LinearLayoutProperty>()->UpdateMeasureType(MeasureType::MATCH_CONTENT);
272 CalendarPickerModelNG::LayoutPicker(pickerPattern, pickerNode, settingData, theme);
273
274 pickerNode->MarkModifyDone();
275 return pickerNode;
276 }
277
SetEdgeAlign(const CalendarEdgeAlign & alignType,const DimensionOffset & offset)278 void CalendarPickerModelNG::SetEdgeAlign(const CalendarEdgeAlign& alignType, const DimensionOffset& offset)
279 {
280 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
281 CHECK_NULL_VOID(frameNode);
282 auto pickerPattern = frameNode->GetPattern<CalendarPickerPattern>();
283 CHECK_NULL_VOID(pickerPattern);
284 pickerPattern->SetCalendarEdgeAlign(alignType);
285 pickerPattern->SetCalendarDialogOffset(offset);
286
287 ACE_UPDATE_LAYOUT_PROPERTY(CalendarPickerLayoutProperty, DialogAlignType, alignType);
288 ACE_UPDATE_LAYOUT_PROPERTY(CalendarPickerLayoutProperty, DialogOffset, offset);
289 }
290
SetTextStyle(const PickerTextStyle & textStyle)291 void CalendarPickerModelNG::SetTextStyle(const PickerTextStyle& textStyle)
292 {
293 auto pipeline = PipelineBase::GetCurrentContext();
294 CHECK_NULL_VOID(pipeline);
295 RefPtr<CalendarTheme> calendarTheme = pipeline->GetTheme<CalendarTheme>();
296 CHECK_NULL_VOID(calendarTheme);
297 if (textStyle.fontSize.has_value() && textStyle.fontSize->IsValid()) {
298 ACE_UPDATE_LAYOUT_PROPERTY(CalendarPickerLayoutProperty, FontSize, textStyle.fontSize.value());
299 } else {
300 ACE_UPDATE_LAYOUT_PROPERTY(CalendarPickerLayoutProperty, FontSize, calendarTheme->GetEntryFontSize());
301 }
302 ACE_UPDATE_LAYOUT_PROPERTY(
303 CalendarPickerLayoutProperty, Color, textStyle.textColor.value_or(calendarTheme->GetEntryFontColor()));
304 ACE_UPDATE_LAYOUT_PROPERTY(CalendarPickerLayoutProperty, Weight, textStyle.fontWeight.value_or(FontWeight::NORMAL));
305 }
306
SetOnChange(SelectedChangeEvent && onChange)307 void CalendarPickerModelNG::SetOnChange(SelectedChangeEvent&& onChange)
308 {
309 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
310 CHECK_NULL_VOID(frameNode);
311 auto eventHub = frameNode->GetEventHub<CalendarPickerEventHub>();
312 CHECK_NULL_VOID(eventHub);
313 eventHub->SetOnChangeEvent(std::move(onChange));
314 }
315
SetChangeEvent(SelectedChangeEvent && onChange)316 void CalendarPickerModelNG::SetChangeEvent(SelectedChangeEvent&& onChange)
317 {
318 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
319 CHECK_NULL_VOID(frameNode);
320 auto eventHub = frameNode->GetEventHub<CalendarPickerEventHub>();
321 CHECK_NULL_VOID(eventHub);
322 eventHub->SetChangeEvent(std::move(onChange));
323 }
324
SetPadding(const PaddingProperty & padding)325 void CalendarPickerModelNG::SetPadding(const PaddingProperty& padding)
326 {
327 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
328 CHECK_NULL_VOID(frameNode);
329 auto pickerPattern = frameNode->GetPattern<CalendarPickerPattern>();
330 CHECK_NULL_VOID(pickerPattern);
331 if (!pickerPattern->HasContentNode()) {
332 return;
333 }
334 auto contentNode = AceType::DynamicCast<FrameNode>(frameNode->GetFirstChild());
335 CHECK_NULL_VOID(contentNode);
336 auto linearLayoutProperty = contentNode->GetLayoutProperty();
337 CHECK_NULL_VOID(linearLayoutProperty);
338 linearLayoutProperty->UpdatePadding(padding);
339 }
340
SetTextStyle(FrameNode * frameNode,const PickerTextStyle & textStyle)341 void CalendarPickerModelNG::SetTextStyle(FrameNode* frameNode, const PickerTextStyle& textStyle)
342 {
343 auto pipeline = PipelineBase::GetCurrentContextSafely();
344 CHECK_NULL_VOID(pipeline);
345 RefPtr<CalendarTheme> calendarTheme = pipeline->GetTheme<CalendarTheme>();
346 CHECK_NULL_VOID(calendarTheme);
347 if (textStyle.fontSize.has_value() && textStyle.fontSize->IsValid()) {
348 ACE_UPDATE_NODE_LAYOUT_PROPERTY(CalendarPickerLayoutProperty, FontSize, textStyle.fontSize.value(), frameNode);
349 } else {
350 ACE_UPDATE_NODE_LAYOUT_PROPERTY(
351 CalendarPickerLayoutProperty, FontSize, calendarTheme->GetEntryFontSize(), frameNode);
352 }
353 ACE_UPDATE_NODE_LAYOUT_PROPERTY(CalendarPickerLayoutProperty, Color,
354 textStyle.textColor.value_or(calendarTheme->GetEntryFontColor()), frameNode);
355 ACE_UPDATE_NODE_LAYOUT_PROPERTY(
356 CalendarPickerLayoutProperty, Weight, textStyle.fontWeight.value_or(FontWeight::NORMAL), frameNode);
357 }
358
GetCalendarTheme()359 RefPtr<CalendarTheme> GetCalendarTheme()
360 {
361 auto pipeline = PipelineBase::GetCurrentContextSafely();
362 CHECK_NULL_RETURN(pipeline, nullptr);
363 return pipeline->GetTheme<CalendarTheme>();
364 }
365
GetTextStyle(FrameNode * frameNode)366 PickerTextStyle CalendarPickerModelNG::GetTextStyle(FrameNode* frameNode)
367 {
368 PickerTextStyle textStyle;
369 CHECK_NULL_RETURN(frameNode, textStyle);
370 auto calendarTheme = GetCalendarTheme();
371 CHECK_NULL_RETURN(calendarTheme, textStyle);
372 auto calendarPickerProperty = frameNode->GetLayoutProperty<CalendarPickerLayoutProperty>();
373 CHECK_NULL_RETURN(calendarPickerProperty, textStyle);
374 textStyle.textColor =
375 calendarPickerProperty->HasColor() ? calendarPickerProperty->GetColor() : calendarTheme->GetEntryFontColor();
376 textStyle.fontSize = calendarPickerProperty->HasFontSize() ? calendarPickerProperty->GetFontSize()
377 : calendarTheme->GetEntryFontSize();
378 textStyle.fontWeight =
379 calendarPickerProperty->HasWeight() ? calendarPickerProperty->GetWeight() : FontWeight::NORMAL;
380 return textStyle;
381 }
382
GetEdgeAlignType(FrameNode * frameNode)383 CalendarEdgeAlign CalendarPickerModelNG::GetEdgeAlignType(FrameNode* frameNode)
384 {
385 CHECK_NULL_RETURN(frameNode, CalendarEdgeAlign::EDGE_ALIGN_END);
386 auto layoutProperty = frameNode->GetLayoutProperty<CalendarPickerLayoutProperty>();
387 CHECK_NULL_RETURN(layoutProperty, CalendarEdgeAlign::EDGE_ALIGN_END);
388 return layoutProperty->GetDialogAlignType().value_or(CalendarEdgeAlign::EDGE_ALIGN_END);
389 }
390
GetEdgeOffset(FrameNode * frameNode)391 DimensionOffset CalendarPickerModelNG::GetEdgeOffset(FrameNode* frameNode)
392 {
393 DimensionOffset offsetDimension(0.0_vp, 0.0_vp);
394 CHECK_NULL_RETURN(frameNode, offsetDimension);
395 auto layoutProperty = frameNode->GetLayoutProperty<CalendarPickerLayoutProperty>();
396 CHECK_NULL_RETURN(layoutProperty, offsetDimension);
397 return layoutProperty->GetDialogOffset().value_or(offsetDimension);
398 }
399
SetEdgeAlign(FrameNode * frameNode,const CalendarEdgeAlign & alignType,const DimensionOffset & offset)400 void CalendarPickerModelNG::SetEdgeAlign(
401 FrameNode* frameNode, const CalendarEdgeAlign& alignType, const DimensionOffset& offset)
402 {
403 auto layoutProperty = frameNode->GetLayoutProperty<CalendarPickerLayoutProperty>();
404 CHECK_NULL_VOID(layoutProperty);
405 auto pickerPattern = frameNode->GetPattern<CalendarPickerPattern>();
406 CHECK_NULL_VOID(pickerPattern);
407 pickerPattern->SetCalendarEdgeAlign(alignType);
408 pickerPattern->SetCalendarDialogOffset(offset);
409
410 ACE_UPDATE_NODE_LAYOUT_PROPERTY(CalendarPickerLayoutProperty, DialogAlignType, alignType, frameNode);
411 ACE_UPDATE_NODE_LAYOUT_PROPERTY(CalendarPickerLayoutProperty, DialogOffset, offset, frameNode);
412 }
413
SetPadding(FrameNode * frameNode,const PaddingProperty & padding)414 void CalendarPickerModelNG::SetPadding(FrameNode* frameNode, const PaddingProperty& padding)
415 {
416 CHECK_NULL_VOID(frameNode);
417 auto pickerPattern = frameNode->GetPattern<CalendarPickerPattern>();
418 CHECK_NULL_VOID(pickerPattern);
419 if (!pickerPattern->HasContentNode()) {
420 return;
421 }
422 auto contentNode = AceType::DynamicCast<FrameNode>(frameNode->GetFirstChild());
423 CHECK_NULL_VOID(contentNode);
424 auto linearLayoutProperty = contentNode->GetLayoutProperty();
425 CHECK_NULL_VOID(linearLayoutProperty);
426 linearLayoutProperty->UpdatePadding(padding);
427 }
428
ClearPadding(FrameNode * frameNode)429 void CalendarPickerModelNG::ClearPadding(FrameNode* frameNode)
430 {
431 CHECK_NULL_VOID(frameNode);
432 auto pickerPattern = frameNode->GetPattern<CalendarPickerPattern>();
433 CHECK_NULL_VOID(pickerPattern);
434 if (!pickerPattern->HasContentNode()) {
435 return;
436 }
437 auto contentNode = AceType::DynamicCast<FrameNode>(frameNode->GetFirstChild());
438 CHECK_NULL_VOID(contentNode);
439 auto linearLayoutProperty = contentNode->GetLayoutProperty();
440 CHECK_NULL_VOID(linearLayoutProperty);
441 auto pipelineContext = frameNode->GetContext();
442 CHECK_NULL_VOID(pipelineContext);
443 RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
444 CHECK_NULL_VOID(theme);
445 PaddingProperty padding;
446 padding.top = CalcLength(theme->GetEntryDateTopBottomMargin());
447 padding.left = CalcLength(theme->GetEntryDateLeftRightMargin());
448 padding.right = CalcLength(theme->GetEntryDateLeftRightMargin());
449 padding.bottom = CalcLength(theme->GetEntryDateTopBottomMargin());
450 linearLayoutProperty->UpdatePadding(padding);
451 }
452
ClearHeight(FrameNode * frameNode)453 void CalendarPickerModelNG::ClearHeight(FrameNode* frameNode)
454 {
455 CHECK_NULL_VOID(frameNode);
456 auto pipelineContext = frameNode->GetContext();
457 CHECK_NULL_VOID(pipelineContext);
458 RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
459 CHECK_NULL_VOID(theme);
460 ViewAbstract::SetHeight(frameNode, CalcLength(theme->GetEntryHeight()));
461 }
462
ClearBorderColor(FrameNode * frameNode)463 void CalendarPickerModelNG::ClearBorderColor(FrameNode* frameNode)
464 {
465 CHECK_NULL_VOID(frameNode);
466 auto pipelineContext = frameNode->GetContext();
467 CHECK_NULL_VOID(pipelineContext);
468 RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
469 CHECK_NULL_VOID(theme);
470 BorderColorProperty borderColor;
471 borderColor.SetColor(theme->GetEntryBorderColor());
472 frameNode->GetRenderContext()->UpdateBorderColor(borderColor);
473 }
474
ClearBorderRadius(FrameNode * frameNode)475 void CalendarPickerModelNG::ClearBorderRadius(FrameNode* frameNode)
476 {
477 CHECK_NULL_VOID(frameNode);
478 auto pipelineContext = frameNode->GetContext();
479 CHECK_NULL_VOID(pipelineContext);
480 RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
481 CHECK_NULL_VOID(theme);
482 BorderRadiusProperty borderRadius;
483 borderRadius.SetRadius(theme->GetEntryBorderRadius());
484 frameNode->GetRenderContext()->UpdateBorderRadius(borderRadius);
485 }
486
ClearBorderWidth(FrameNode * frameNode)487 void CalendarPickerModelNG::ClearBorderWidth(FrameNode* frameNode)
488 {
489 CHECK_NULL_VOID(frameNode);
490 auto pipelineContext = frameNode->GetContext();
491 CHECK_NULL_VOID(pipelineContext);
492 RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
493 CHECK_NULL_VOID(theme);
494 BorderWidthProperty borderWidth;
495 borderWidth.SetBorderWidth(theme->GetEntryBorderWidth());
496 frameNode->GetLayoutProperty()->UpdateBorderWidth(borderWidth);
497 }
498
SetHintRadiusWithNode(FrameNode * frameNode,Dimension & radius)499 void CalendarPickerModelNG::SetHintRadiusWithNode(FrameNode* frameNode, Dimension& radius)
500 {
501 CHECK_NULL_VOID(frameNode);
502 auto pickerPattern = frameNode->GetPattern<CalendarPickerPattern>();
503 CHECK_NULL_VOID(pickerPattern);
504 auto calendarDate = pickerPattern->GetCalendarData();
505 calendarDate.dayRadius = radius;
506 pickerPattern->SetCalendarData(calendarDate);
507 }
508
SetSelectDateWithNode(FrameNode * frameNode,uint32_t year,uint32_t month,uint32_t day)509 void CalendarPickerModelNG::SetSelectDateWithNode(FrameNode* frameNode, uint32_t year, uint32_t month, uint32_t day)
510 {
511 CHECK_NULL_VOID(frameNode);
512 auto pickerPattern = frameNode->GetPattern<CalendarPickerPattern>();
513 CHECK_NULL_VOID(pickerPattern);
514 auto calendarDate = pickerPattern->GetCalendarData();
515 if (year > 0) {
516 calendarDate.selectedDate.SetYear(year);
517 auto yearNode = CalendarPickerModelNG::GetYearNode(frameNode);
518 if (yearNode) {
519 auto textLayoutProperty = yearNode->GetLayoutProperty<TextLayoutProperty>();
520 if (textLayoutProperty) {
521 textLayoutProperty->UpdateContent(std::to_string(year));
522 yearNode->MarkModifyDone();
523 yearNode->MarkDirtyNode();
524 }
525 }
526 }
527 if (month > 0) {
528 calendarDate.selectedDate.SetMonth(month);
529 auto monthNode = CalendarPickerModelNG::GetMonthNode(frameNode);
530 if (monthNode) {
531 auto textLayoutProperty = monthNode->GetLayoutProperty<TextLayoutProperty>();
532 if (textLayoutProperty) {
533 auto selectedMonthStr = (month < ONE_DIGIT_BOUNDARY ? "0" : "") + std::to_string(month);
534 textLayoutProperty->UpdateContent(selectedMonthStr);
535 monthNode->MarkModifyDone();
536 monthNode->MarkDirtyNode();
537 }
538 }
539 }
540 if (day > 0) {
541 calendarDate.selectedDate.SetDay(day);
542 auto dayNode = CalendarPickerModelNG::GetDayNode(frameNode);
543 if (dayNode) {
544 auto textLayoutProperty = dayNode->GetLayoutProperty<TextLayoutProperty>();
545 if (textLayoutProperty) {
546 auto selectedDayStr = (day < ONE_DIGIT_BOUNDARY ? "0" : "") + std::to_string(day);
547 textLayoutProperty->UpdateContent(selectedDayStr);
548 dayNode->MarkModifyDone();
549 dayNode->MarkDirtyNode();
550 }
551 }
552 }
553 pickerPattern->SetCalendarData(calendarDate);
554 }
555
GetYearNode(FrameNode * calendarPickerNode)556 RefPtr<FrameNode> CalendarPickerModelNG::GetYearNode(FrameNode* calendarPickerNode)
557 {
558 CHECK_NULL_RETURN(calendarPickerNode, nullptr);
559 auto feedbackNode = calendarPickerNode->GetFirstChild();
560 CHECK_NULL_RETURN(feedbackNode, nullptr);
561 return AceType::DynamicCast<FrameNode>(feedbackNode->GetChildAtIndex(yearNodeIndex_));
562 }
563
GetMonthNode(FrameNode * calendarPickerNode)564 RefPtr<FrameNode> CalendarPickerModelNG::GetMonthNode(FrameNode* calendarPickerNode)
565 {
566 CHECK_NULL_RETURN(calendarPickerNode, nullptr);
567 auto feedbackNode = calendarPickerNode->GetFirstChild();
568 CHECK_NULL_RETURN(feedbackNode, nullptr);
569 return AceType::DynamicCast<FrameNode>(feedbackNode->GetChildAtIndex(monthNodeIndex_));
570 }
571
GetDayNode(FrameNode * calendarPickerNode)572 RefPtr<FrameNode> CalendarPickerModelNG::GetDayNode(FrameNode* calendarPickerNode)
573 {
574 CHECK_NULL_RETURN(calendarPickerNode, nullptr);
575 auto feedbackNode = calendarPickerNode->GetFirstChild();
576 CHECK_NULL_RETURN(feedbackNode, nullptr);
577 return AceType::DynamicCast<FrameNode>(feedbackNode->GetChildAtIndex(dayNodeIndex_));
578 }
579
GetHintRadius(FrameNode * frameNode)580 Dimension CalendarPickerModelNG::GetHintRadius(FrameNode* frameNode)
581 {
582 Dimension defaultRadius(DEFAULT_HINT_RADIUS);
583 CHECK_NULL_RETURN(frameNode, defaultRadius);
584 auto pickerPattern = frameNode->GetPattern<CalendarPickerPattern>();
585 CHECK_NULL_RETURN(pickerPattern, defaultRadius);
586 auto calendarDate = pickerPattern->GetCalendarData();
587 return calendarDate.dayRadius.value_or(defaultRadius);
588 }
589
GetSelectDateWithNode(FrameNode * frameNode)590 PickerDate CalendarPickerModelNG::GetSelectDateWithNode(FrameNode* frameNode)
591 {
592 auto defaultSelectedDate = PickerDate::Current();
593 CHECK_NULL_RETURN(frameNode, defaultSelectedDate);
594 auto pickerPattern = frameNode->GetPattern<CalendarPickerPattern>();
595 CHECK_NULL_RETURN(pickerPattern, defaultSelectedDate);
596 return pickerPattern->GetCalendarData().selectedDate;
597 }
598
SetOnChangeWithNode(FrameNode * frameNode,SelectedChangeEvent && onChange)599 void CalendarPickerModelNG::SetOnChangeWithNode(FrameNode* frameNode, SelectedChangeEvent&& onChange)
600 {
601 CHECK_NULL_VOID(frameNode);
602 auto eventHub = frameNode->GetEventHub<CalendarPickerEventHub>();
603 CHECK_NULL_VOID(eventHub);
604 eventHub->SetOnChangeEvent(std::move(onChange));
605 }
606
GetDateNodeOrder(const CalendarSettingData & settingData)607 std::map<std::size_t, std::string> CalendarPickerModelNG::GetDateNodeOrder(const CalendarSettingData& settingData)
608 {
609 PickerDate date = settingData.selectedDate;
610 std::vector<std::string> outOrder;
611 bool result = Localization::GetInstance()->GetDateOrder(outOrder);
612 std::map<std::size_t, std::string> order;
613 if (!result || outOrder.size() < DATE_NODE_COUNT) {
614 yearNodeIndex_ = YEAR_NODE_INDEX;
615 monthNodeIndex_ = MONTH_NODE_INDEX;
616 dayNodeIndex_ = DAY_NODE_INDEX;
617 auto num = 0;
618 order[num++] = std::to_string(date.GetYear());
619 order[num++] = (date.GetMonth() < ONE_DIGIT_BOUNDARY ? "0" : "") + std::to_string(date.GetMonth());
620 order[num] = (date.GetDay() < ONE_DIGIT_BOUNDARY ? "0" : "") + std::to_string(date.GetDay());
621 } else {
622 size_t index = 0;
623 for (size_t i = 0; i < outOrder.size(); ++i) {
624 if (outOrder[i] == "year") {
625 yearNodeIndex_ = static_cast<int32_t>(i + index);
626 order[i] = std::to_string(date.GetYear());
627 }
628 if (outOrder[i] == "month") {
629 monthNodeIndex_ = static_cast<int32_t>(i + index);
630 order[i] = (date.GetMonth() < ONE_DIGIT_BOUNDARY ? "0" : "") + std::to_string(date.GetMonth());
631 }
632 if (outOrder[i] == "day") {
633 dayNodeIndex_ = static_cast<int32_t>(i + index);
634 order[i] = (date.GetDay() < ONE_DIGIT_BOUNDARY ? "0" : "") + std::to_string(date.GetDay());
635 }
636 index++;
637 }
638 }
639
640 return order;
641 }
642 } // namespace OHOS::Ace::NG
643