• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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