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
ClearBorderColor()359 void CalendarPickerModelNG::ClearBorderColor()
360 {
361 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
362 CHECK_NULL_VOID(frameNode);
363 auto pipelineContext = frameNode->GetContext();
364 CHECK_NULL_VOID(pipelineContext);
365 RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
366 CHECK_NULL_VOID(theme);
367 BorderColorProperty borderColor;
368 borderColor.SetColor(theme->GetEntryBorderColor());
369 frameNode->GetRenderContext()->UpdateBorderColor(borderColor);
370 }
371
ClearBorderRadius()372 void CalendarPickerModelNG::ClearBorderRadius()
373 {
374 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
375 CHECK_NULL_VOID(frameNode);
376 auto pipelineContext = frameNode->GetContext();
377 CHECK_NULL_VOID(pipelineContext);
378 RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
379 CHECK_NULL_VOID(theme);
380 BorderRadiusProperty borderRadius;
381 borderRadius.SetRadius(theme->GetEntryBorderRadius());
382 frameNode->GetRenderContext()->UpdateBorderRadius(borderRadius);
383 }
384
ClearHeight()385 void CalendarPickerModelNG::ClearHeight()
386 {
387 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
388 CHECK_NULL_VOID(frameNode);
389 auto pipelineContext = frameNode->GetContext();
390 CHECK_NULL_VOID(pipelineContext);
391 RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
392 CHECK_NULL_VOID(theme);
393 frameNode->GetLayoutProperty()->UpdateUserDefinedIdealSize(
394 CalcSize(std::nullopt, CalcLength(theme->GetEntryHeight())));
395 }
396
ClearBorder()397 void CalendarPickerModelNG::ClearBorder()
398 {
399 ClearBorderWidth();
400 ClearBorderRadius();
401 ClearBorderColor();
402 }
403
ClearBorderWidth()404 void CalendarPickerModelNG::ClearBorderWidth()
405 {
406 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
407 CHECK_NULL_VOID(frameNode);
408 auto pipelineContext = frameNode->GetContext();
409 CHECK_NULL_VOID(pipelineContext);
410 RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
411 CHECK_NULL_VOID(theme);
412 BorderWidthProperty borderWidth;
413 borderWidth.SetBorderWidth(theme->GetEntryBorderWidth());
414 frameNode->GetLayoutProperty()->UpdateBorderWidth(borderWidth);
415 }
416
ClearPadding()417 void CalendarPickerModelNG::ClearPadding()
418 {
419 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
420 CHECK_NULL_VOID(frameNode);
421 auto pickerPattern = frameNode->GetPattern<CalendarPickerPattern>();
422 CHECK_NULL_VOID(pickerPattern);
423 if (!pickerPattern->HasContentNode()) {
424 return;
425 }
426 auto contentNode = AceType::DynamicCast<FrameNode>(frameNode->GetFirstChild());
427 CHECK_NULL_VOID(contentNode);
428 auto linearLayoutProperty = contentNode->GetLayoutProperty();
429 CHECK_NULL_VOID(linearLayoutProperty);
430 auto pipelineContext = frameNode->GetContext();
431 CHECK_NULL_VOID(pipelineContext);
432 RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
433 CHECK_NULL_VOID(theme);
434 PaddingProperty padding;
435 padding.top = CalcLength(theme->GetEntryDateTopBottomMargin());
436 padding.left = CalcLength(theme->GetEntryDateLeftRightMargin());
437 padding.right = CalcLength(theme->GetEntryDateLeftRightMargin());
438 padding.bottom = CalcLength(theme->GetEntryDateTopBottomMargin());
439 linearLayoutProperty->UpdatePadding(padding);
440 }
441
GetCalendarTheme()442 RefPtr<CalendarTheme> GetCalendarTheme()
443 {
444 auto pipeline = PipelineBase::GetCurrentContextSafely();
445 CHECK_NULL_RETURN(pipeline, nullptr);
446 return pipeline->GetTheme<CalendarTheme>();
447 }
448
GetTextStyle(FrameNode * frameNode)449 PickerTextStyle CalendarPickerModelNG::GetTextStyle(FrameNode* frameNode)
450 {
451 PickerTextStyle textStyle;
452 CHECK_NULL_RETURN(frameNode, textStyle);
453 auto calendarTheme = GetCalendarTheme();
454 CHECK_NULL_RETURN(calendarTheme, textStyle);
455 auto calendarPickerProperty = frameNode->GetLayoutProperty<CalendarPickerLayoutProperty>();
456 CHECK_NULL_RETURN(calendarPickerProperty, textStyle);
457 textStyle.textColor =
458 calendarPickerProperty->HasColor() ? calendarPickerProperty->GetColor() : calendarTheme->GetEntryFontColor();
459 textStyle.fontSize = calendarPickerProperty->HasFontSize() ? calendarPickerProperty->GetFontSize()
460 : calendarTheme->GetEntryFontSize();
461 textStyle.fontWeight =
462 calendarPickerProperty->HasWeight() ? calendarPickerProperty->GetWeight() : FontWeight::NORMAL;
463 return textStyle;
464 }
465
GetEdgeAlignType(FrameNode * frameNode)466 CalendarEdgeAlign CalendarPickerModelNG::GetEdgeAlignType(FrameNode* frameNode)
467 {
468 CHECK_NULL_RETURN(frameNode, CalendarEdgeAlign::EDGE_ALIGN_END);
469 auto layoutProperty = frameNode->GetLayoutProperty<CalendarPickerLayoutProperty>();
470 CHECK_NULL_RETURN(layoutProperty, CalendarEdgeAlign::EDGE_ALIGN_END);
471 return layoutProperty->GetDialogAlignType().value_or(CalendarEdgeAlign::EDGE_ALIGN_END);
472 }
473
GetEdgeOffset(FrameNode * frameNode)474 DimensionOffset CalendarPickerModelNG::GetEdgeOffset(FrameNode* frameNode)
475 {
476 DimensionOffset offsetDimension(0.0_vp, 0.0_vp);
477 CHECK_NULL_RETURN(frameNode, offsetDimension);
478 auto layoutProperty = frameNode->GetLayoutProperty<CalendarPickerLayoutProperty>();
479 CHECK_NULL_RETURN(layoutProperty, offsetDimension);
480 return layoutProperty->GetDialogOffset().value_or(offsetDimension);
481 }
482
SetEdgeAlign(FrameNode * frameNode,const CalendarEdgeAlign & alignType,const DimensionOffset & offset)483 void CalendarPickerModelNG::SetEdgeAlign(
484 FrameNode* frameNode, const CalendarEdgeAlign& alignType, const DimensionOffset& offset)
485 {
486 auto layoutProperty = frameNode->GetLayoutProperty<CalendarPickerLayoutProperty>();
487 CHECK_NULL_VOID(layoutProperty);
488 auto pickerPattern = frameNode->GetPattern<CalendarPickerPattern>();
489 CHECK_NULL_VOID(pickerPattern);
490 pickerPattern->SetCalendarEdgeAlign(alignType);
491 pickerPattern->SetCalendarDialogOffset(offset);
492
493 ACE_UPDATE_NODE_LAYOUT_PROPERTY(CalendarPickerLayoutProperty, DialogAlignType, alignType, frameNode);
494 ACE_UPDATE_NODE_LAYOUT_PROPERTY(CalendarPickerLayoutProperty, DialogOffset, offset, frameNode);
495 }
496
SetPadding(FrameNode * frameNode,const PaddingProperty & padding)497 void CalendarPickerModelNG::SetPadding(FrameNode* frameNode, const PaddingProperty& padding)
498 {
499 CHECK_NULL_VOID(frameNode);
500 auto pickerPattern = frameNode->GetPattern<CalendarPickerPattern>();
501 CHECK_NULL_VOID(pickerPattern);
502 if (!pickerPattern->HasContentNode()) {
503 return;
504 }
505 auto contentNode = AceType::DynamicCast<FrameNode>(frameNode->GetFirstChild());
506 CHECK_NULL_VOID(contentNode);
507 auto linearLayoutProperty = contentNode->GetLayoutProperty();
508 CHECK_NULL_VOID(linearLayoutProperty);
509 linearLayoutProperty->UpdatePadding(padding);
510 }
511
ClearPadding(FrameNode * frameNode)512 void CalendarPickerModelNG::ClearPadding(FrameNode* frameNode)
513 {
514 CHECK_NULL_VOID(frameNode);
515 auto pickerPattern = frameNode->GetPattern<CalendarPickerPattern>();
516 CHECK_NULL_VOID(pickerPattern);
517 if (!pickerPattern->HasContentNode()) {
518 return;
519 }
520 auto contentNode = AceType::DynamicCast<FrameNode>(frameNode->GetFirstChild());
521 CHECK_NULL_VOID(contentNode);
522 auto linearLayoutProperty = contentNode->GetLayoutProperty();
523 CHECK_NULL_VOID(linearLayoutProperty);
524 auto pipelineContext = frameNode->GetContext();
525 CHECK_NULL_VOID(pipelineContext);
526 RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
527 CHECK_NULL_VOID(theme);
528 PaddingProperty padding;
529 padding.top = CalcLength(theme->GetEntryDateTopBottomMargin());
530 padding.left = CalcLength(theme->GetEntryDateLeftRightMargin());
531 padding.right = CalcLength(theme->GetEntryDateLeftRightMargin());
532 padding.bottom = CalcLength(theme->GetEntryDateTopBottomMargin());
533 linearLayoutProperty->UpdatePadding(padding);
534 }
535
ClearHeight(FrameNode * frameNode)536 void CalendarPickerModelNG::ClearHeight(FrameNode* frameNode)
537 {
538 CHECK_NULL_VOID(frameNode);
539 auto pipelineContext = frameNode->GetContext();
540 CHECK_NULL_VOID(pipelineContext);
541 RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
542 CHECK_NULL_VOID(theme);
543 ViewAbstract::SetHeight(frameNode, CalcLength(theme->GetEntryHeight()));
544 }
545
ClearBorderColor(FrameNode * frameNode)546 void CalendarPickerModelNG::ClearBorderColor(FrameNode* frameNode)
547 {
548 CHECK_NULL_VOID(frameNode);
549 auto pipelineContext = frameNode->GetContext();
550 CHECK_NULL_VOID(pipelineContext);
551 RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
552 CHECK_NULL_VOID(theme);
553 BorderColorProperty borderColor;
554 borderColor.SetColor(theme->GetEntryBorderColor());
555 frameNode->GetRenderContext()->UpdateBorderColor(borderColor);
556 }
557
ClearBorderRadius(FrameNode * frameNode)558 void CalendarPickerModelNG::ClearBorderRadius(FrameNode* frameNode)
559 {
560 CHECK_NULL_VOID(frameNode);
561 auto pipelineContext = frameNode->GetContext();
562 CHECK_NULL_VOID(pipelineContext);
563 RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
564 CHECK_NULL_VOID(theme);
565 BorderRadiusProperty borderRadius;
566 borderRadius.SetRadius(theme->GetEntryBorderRadius());
567 frameNode->GetRenderContext()->UpdateBorderRadius(borderRadius);
568 }
569
ClearBorderWidth(FrameNode * frameNode)570 void CalendarPickerModelNG::ClearBorderWidth(FrameNode* frameNode)
571 {
572 CHECK_NULL_VOID(frameNode);
573 auto pipelineContext = frameNode->GetContext();
574 CHECK_NULL_VOID(pipelineContext);
575 RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
576 CHECK_NULL_VOID(theme);
577 BorderWidthProperty borderWidth;
578 borderWidth.SetBorderWidth(theme->GetEntryBorderWidth());
579 frameNode->GetLayoutProperty()->UpdateBorderWidth(borderWidth);
580 }
581
SetHintRadiusWithNode(FrameNode * frameNode,Dimension & radius)582 void CalendarPickerModelNG::SetHintRadiusWithNode(FrameNode* frameNode, Dimension& radius)
583 {
584 CHECK_NULL_VOID(frameNode);
585 auto pickerPattern = frameNode->GetPattern<CalendarPickerPattern>();
586 CHECK_NULL_VOID(pickerPattern);
587 auto calendarDate = pickerPattern->GetCalendarData();
588 calendarDate.dayRadius = radius;
589 pickerPattern->SetCalendarData(calendarDate);
590 }
591
SetSelectDateWithNode(FrameNode * frameNode,uint32_t year,uint32_t month,uint32_t day)592 void CalendarPickerModelNG::SetSelectDateWithNode(FrameNode* frameNode, uint32_t year, uint32_t month, uint32_t day)
593 {
594 CHECK_NULL_VOID(frameNode);
595 auto pickerPattern = frameNode->GetPattern<CalendarPickerPattern>();
596 CHECK_NULL_VOID(pickerPattern);
597 auto calendarDate = pickerPattern->GetCalendarData();
598 if (year > 0) {
599 calendarDate.selectedDate.SetYear(year);
600 auto yearNode = CalendarPickerModelNG::GetYearNode(frameNode);
601 if (yearNode) {
602 auto textLayoutProperty = yearNode->GetLayoutProperty<TextLayoutProperty>();
603 if (textLayoutProperty) {
604 textLayoutProperty->UpdateContent(std::to_string(year));
605 yearNode->MarkModifyDone();
606 yearNode->MarkDirtyNode();
607 }
608 }
609 }
610 if (month > 0) {
611 calendarDate.selectedDate.SetMonth(month);
612 auto monthNode = CalendarPickerModelNG::GetMonthNode(frameNode);
613 if (monthNode) {
614 auto textLayoutProperty = monthNode->GetLayoutProperty<TextLayoutProperty>();
615 if (textLayoutProperty) {
616 auto selectedMonthStr = (month < ONE_DIGIT_BOUNDARY ? "0" : "") + std::to_string(month);
617 textLayoutProperty->UpdateContent(selectedMonthStr);
618 monthNode->MarkModifyDone();
619 monthNode->MarkDirtyNode();
620 }
621 }
622 }
623 if (day > 0) {
624 calendarDate.selectedDate.SetDay(day);
625 auto dayNode = CalendarPickerModelNG::GetDayNode(frameNode);
626 if (dayNode) {
627 auto textLayoutProperty = dayNode->GetLayoutProperty<TextLayoutProperty>();
628 if (textLayoutProperty) {
629 auto selectedDayStr = (day < ONE_DIGIT_BOUNDARY ? "0" : "") + std::to_string(day);
630 textLayoutProperty->UpdateContent(selectedDayStr);
631 dayNode->MarkModifyDone();
632 dayNode->MarkDirtyNode();
633 }
634 }
635 }
636 pickerPattern->SetCalendarData(calendarDate);
637 }
638
GetYearNode(FrameNode * calendarPickerNode)639 RefPtr<FrameNode> CalendarPickerModelNG::GetYearNode(FrameNode* calendarPickerNode)
640 {
641 CHECK_NULL_RETURN(calendarPickerNode, nullptr);
642 auto feedbackNode = calendarPickerNode->GetFirstChild();
643 CHECK_NULL_RETURN(feedbackNode, nullptr);
644 return AceType::DynamicCast<FrameNode>(feedbackNode->GetChildAtIndex(yearNodeIndex_));
645 }
646
GetMonthNode(FrameNode * calendarPickerNode)647 RefPtr<FrameNode> CalendarPickerModelNG::GetMonthNode(FrameNode* calendarPickerNode)
648 {
649 CHECK_NULL_RETURN(calendarPickerNode, nullptr);
650 auto feedbackNode = calendarPickerNode->GetFirstChild();
651 CHECK_NULL_RETURN(feedbackNode, nullptr);
652 return AceType::DynamicCast<FrameNode>(feedbackNode->GetChildAtIndex(monthNodeIndex_));
653 }
654
GetDayNode(FrameNode * calendarPickerNode)655 RefPtr<FrameNode> CalendarPickerModelNG::GetDayNode(FrameNode* calendarPickerNode)
656 {
657 CHECK_NULL_RETURN(calendarPickerNode, nullptr);
658 auto feedbackNode = calendarPickerNode->GetFirstChild();
659 CHECK_NULL_RETURN(feedbackNode, nullptr);
660 return AceType::DynamicCast<FrameNode>(feedbackNode->GetChildAtIndex(dayNodeIndex_));
661 }
662
GetHintRadius(FrameNode * frameNode)663 Dimension CalendarPickerModelNG::GetHintRadius(FrameNode* frameNode)
664 {
665 Dimension defaultRadius(DEFAULT_HINT_RADIUS);
666 CHECK_NULL_RETURN(frameNode, defaultRadius);
667 auto pickerPattern = frameNode->GetPattern<CalendarPickerPattern>();
668 CHECK_NULL_RETURN(pickerPattern, defaultRadius);
669 auto calendarDate = pickerPattern->GetCalendarData();
670 return calendarDate.dayRadius.value_or(defaultRadius);
671 }
672
GetSelectDateWithNode(FrameNode * frameNode)673 PickerDate CalendarPickerModelNG::GetSelectDateWithNode(FrameNode* frameNode)
674 {
675 auto defaultSelectedDate = PickerDate::Current();
676 CHECK_NULL_RETURN(frameNode, defaultSelectedDate);
677 auto pickerPattern = frameNode->GetPattern<CalendarPickerPattern>();
678 CHECK_NULL_RETURN(pickerPattern, defaultSelectedDate);
679 return pickerPattern->GetCalendarData().selectedDate;
680 }
681
SetOnChangeWithNode(FrameNode * frameNode,SelectedChangeEvent && onChange)682 void CalendarPickerModelNG::SetOnChangeWithNode(FrameNode* frameNode, SelectedChangeEvent&& onChange)
683 {
684 CHECK_NULL_VOID(frameNode);
685 auto eventHub = frameNode->GetEventHub<CalendarPickerEventHub>();
686 CHECK_NULL_VOID(eventHub);
687 eventHub->SetOnChangeEvent(std::move(onChange));
688 }
689
GetDateNodeOrder(const CalendarSettingData & settingData)690 std::map<std::size_t, std::string> CalendarPickerModelNG::GetDateNodeOrder(const CalendarSettingData& settingData)
691 {
692 PickerDate date = settingData.selectedDate;
693 std::vector<std::string> outOrder;
694 bool result = Localization::GetInstance()->GetDateOrder(outOrder);
695 std::map<std::size_t, std::string> order;
696 if (!result || outOrder.size() < DATE_NODE_COUNT) {
697 yearNodeIndex_ = YEAR_NODE_INDEX;
698 monthNodeIndex_ = MONTH_NODE_INDEX;
699 dayNodeIndex_ = DAY_NODE_INDEX;
700 auto num = 0;
701 order[num++] = std::to_string(date.GetYear());
702 order[num++] = (date.GetMonth() < ONE_DIGIT_BOUNDARY ? "0" : "") + std::to_string(date.GetMonth());
703 order[num] = (date.GetDay() < ONE_DIGIT_BOUNDARY ? "0" : "") + std::to_string(date.GetDay());
704 } else {
705 size_t index = 0;
706 for (size_t i = 0; i < outOrder.size(); ++i) {
707 if (outOrder[i] == "year") {
708 yearNodeIndex_ = static_cast<int32_t>(i + index);
709 order[i] = std::to_string(date.GetYear());
710 }
711 if (outOrder[i] == "month") {
712 monthNodeIndex_ = static_cast<int32_t>(i + index);
713 order[i] = (date.GetMonth() < ONE_DIGIT_BOUNDARY ? "0" : "") + std::to_string(date.GetMonth());
714 }
715 if (outOrder[i] == "day") {
716 dayNodeIndex_ = static_cast<int32_t>(i + index);
717 order[i] = (date.GetDay() < ONE_DIGIT_BOUNDARY ? "0" : "") + std::to_string(date.GetDay());
718 }
719 index++;
720 }
721 }
722
723 return order;
724 }
725 } // namespace OHOS::Ace::NG
726