• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "core/components_ng/pattern/calendar_picker/calendar_dialog_view.h"
16 
17 #include <utility>
18 
19 #include "base/i18n/localization.h"
20 #include "base/memory/ace_type.h"
21 #include "base/utils/utils.h"
22 #include "core/components/common/properties/shadow_config.h"
23 #include "core/components/theme/icon_theme.h"
24 #include "core/components/theme/shadow_theme.h"
25 #include "core/components_ng/base/view_stack_processor.h"
26 #include "core/components_ng/pattern/button/button_pattern.h"
27 #include "core/components_ng/pattern/button/button_layout_property.h"
28 #include "core/components_ng/pattern/calendar/calendar_month_pattern.h"
29 #include "core/components_ng/pattern/calendar/calendar_paint_property.h"
30 #include "core/components_ng/pattern/calendar/calendar_pattern.h"
31 #include "core/components_ng/pattern/calendar_picker/calendar_picker_event_hub.h"
32 #include "core/components_ng/pattern/dialog/dialog_view.h"
33 #include "core/components_ng/pattern/divider/divider_pattern.h"
34 #include "core/components_ng/pattern/image/image_pattern.h"
35 #include "core/components_ng/pattern/scroll/scroll_pattern.h"
36 #include "core/components_ng/pattern/text/text_pattern.h"
37 #include "core/components_ng/pattern/text/text_layout_property.h"
38 #include "core/pipeline_ng/pipeline_context.h"
39 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
40 #include "core/common/resource/resource_parse_utils.h"
41 
42 namespace OHOS::Ace::NG {
43 namespace {
44 constexpr int32_t SWIPER_MONTHS_COUNT = 3;
45 constexpr int32_t CURRENT_MONTH_INDEX = 1;
46 constexpr int32_t DAYS_OF_WEEK = 7;
47 constexpr Dimension DIALOG_WIDTH = 336.0_vp;
48 constexpr Dimension CALENDAR_DISTANCE_ADJUST_FOCUSED_EVENT = 4.0_vp;
49 constexpr float WEEK_SPACE = 20.0f;
50 constexpr size_t ACCEPT_BUTTON_INDEX = 0;
51 constexpr size_t CANCEL_BUTTON_INDEX = 1;
52 constexpr size_t CANCEL_BUTTON_FONT_COLOR_INDEX = 0;
53 constexpr size_t CANCEL_BUTTON_BACKGROUND_COLOR_INDEX = 1;
54 constexpr size_t ACCEPT_BUTTON_FONT_COLOR_INDEX = 2;
55 constexpr size_t ACCEPT_BUTTON_BACKGROUND_COLOR_INDEX = 3;
56 } // namespace
57 
CheckOrientationChange()58 bool CalendarDialogView::CheckOrientationChange()
59 {
60     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
61     CHECK_NULL_RETURN(pipeline, true);
62     return (!(SystemProperties::GetDeviceOrientation() == previousOrientation_)
63                 ? Dimension(pipeline->GetRootWidth()).ConvertToVp() < deviceHeightLimit
64                 : Dimension(pipeline->GetRootHeight()).ConvertToVp() < deviceHeightLimit);
65 }
66 
67 DeviceOrientation CalendarDialogView::previousOrientation_ { DeviceOrientation::PORTRAIT };
68 
Show(const DialogProperties & dialogProperties,const CalendarSettingData & settingData,const std::vector<ButtonInfo> & buttonInfos,const std::map<std::string,NG::DialogEvent> & dialogEvent,const std::map<std::string,NG::DialogGestureEvent> & dialogCancelEvent)69 RefPtr<FrameNode> CalendarDialogView::Show(const DialogProperties& dialogProperties,
70     const CalendarSettingData& settingData, const std::vector<ButtonInfo>& buttonInfos,
71     const std::map<std::string, NG::DialogEvent>& dialogEvent,
72     const std::map<std::string, NG::DialogGestureEvent>& dialogCancelEvent)
73 {
74     auto contentColumn = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
75         AceType::MakeRefPtr<CalendarDialogPattern>());
76     OperationsToPattern(contentColumn, settingData, dialogProperties, buttonInfos);
77     auto layoutProperty = contentColumn->GetLayoutProperty();
78     CHECK_NULL_RETURN(layoutProperty, nullptr);
79 
80     auto textDirection = layoutProperty->GetLayoutDirection();
81     if (settingData.entryNode.Upgrade() != nullptr) {
82         auto entryNode = settingData.entryNode.Upgrade();
83         textDirection = entryNode->GetLayoutProperty()->GetNonAutoLayoutDirection();
84         layoutProperty->UpdateLayoutDirection(textDirection);
85     }
86 
87     auto calendarNode = CreateCalendarNode(contentColumn, settingData, dialogEvent);
88     CHECK_NULL_RETURN(calendarNode, nullptr);
89     auto calendarLayoutProperty = calendarNode->GetLayoutProperty();
90     CHECK_NULL_RETURN(calendarLayoutProperty, nullptr);
91     calendarLayoutProperty->UpdateLayoutDirection(textDirection);
92 
93     auto weekFrameNode = CreateWeekNode(calendarNode);
94     CHECK_NULL_RETURN(weekFrameNode, nullptr);
95 
96     auto titleNode = CreateTitleNode(calendarNode, contentColumn);
97     CHECK_NULL_RETURN(titleNode, nullptr);
98     auto titleLayoutProperty = titleNode->GetLayoutProperty();
99     CHECK_NULL_RETURN(titleLayoutProperty, nullptr);
100     titleLayoutProperty->UpdateLayoutDirection(textDirection);
101 
102     auto scrollFrameNode = CreateScrollNode();
103     CHECK_NULL_RETURN(weekFrameNode, nullptr);
104 
105     calendarNode->MountToParent(scrollFrameNode);
106     titleNode->MountToParent(contentColumn);
107     weekFrameNode->MountToParent(contentColumn);
108     scrollFrameNode->MountToParent(contentColumn);
109 
110     auto dialogNode = DialogView::CreateDialogNode(dialogProperties, contentColumn);
111     CHECK_NULL_RETURN(dialogNode, nullptr);
112     auto dialogLayoutProperty = dialogNode->GetLayoutProperty();
113     CHECK_NULL_RETURN(dialogLayoutProperty, nullptr);
114     auto calendarTextDirection = calendarLayoutProperty->GetNonAutoLayoutDirection();
115     auto dialogTextDirection = dialogLayoutProperty->GetNonAutoLayoutDirection();
116     SetWeekTextDirection(dialogTextDirection, calendarTextDirection, weekFrameNode);
117     dialogLayoutProperty->UpdateLayoutDirection(textDirection);
118     CreateChildNode(contentColumn, dialogNode, dialogProperties);
119     if (!settingData.entryNode.Upgrade()) {
120         auto contentRow =
121             CreateOptionsNode(dialogNode, calendarNode, dialogEvent, std::move(dialogCancelEvent), buttonInfos);
122         contentRow->MountToParent(contentColumn);
123         UpdateDialogDefaultFocus(contentRow, contentColumn);
124     }
125 
126     contentColumn->MarkModifyDone();
127     calendarNode->MarkModifyDone();
128     dialogNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
129     return dialogNode;
130 }
131 
SetWeekTextDirection(const TextDirection & dialogDirection,const TextDirection & calendarDirection,const RefPtr<FrameNode> & weekNode)132 void CalendarDialogView::SetWeekTextDirection(const TextDirection& dialogDirection,
133     const TextDirection& calendarDirection, const RefPtr<FrameNode>& weekNode)
134 {
135     std::vector<std::string> weekNumbers = Localization::GetInstance()->GetWeekdays(true);
136     for (int32_t column = 0; column < DAYS_OF_WEEK; column++) {
137         auto textWeekNode = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG,
138             ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
139         CHECK_NULL_VOID(textWeekNode);
140         int32_t weekId = 0;
141         if (calendarDirection == TextDirection::RTL
142             && dialogDirection != TextDirection::RTL) {
143             weekId = (DAYS_OF_WEEK - 1) - (column % DAYS_OF_WEEK);
144         } else {
145             weekId = column % DAYS_OF_WEEK;
146         }
147         if (weekId < 0) {
148             continue;
149         }
150         std::string weekContent { weekNumbers[weekId] };
151         auto textLayoutProperty = textWeekNode->GetLayoutProperty<TextLayoutProperty>();
152         CHECK_NULL_VOID(textLayoutProperty);
153         textLayoutProperty->UpdateContent(weekContent);
154         textLayoutProperty->UpdateTextAlign(TextAlign::CENTER);
155         textWeekNode->MountToParent(weekNode);
156     }
157 }
158 
CreateChildNode(const RefPtr<FrameNode> & contentColumn,const RefPtr<FrameNode> & dialogNode,const DialogProperties & dialogProperties)159 void CalendarDialogView::CreateChildNode(const RefPtr<FrameNode>& contentColumn,
160     const RefPtr<FrameNode>& dialogNode, const DialogProperties& dialogProperties)
161 {
162     auto layoutProperty = contentColumn->GetLayoutProperty();
163     CHECK_NULL_VOID(layoutProperty);
164     auto pipelineContext = dialogNode->GetContext();
165     CHECK_NULL_VOID(pipelineContext);
166     RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
167     RefPtr<DialogTheme> dialogTheme = pipelineContext->GetTheme<DialogTheme>();
168     CHECK_NULL_VOID(theme);
169     PaddingProperty padding;
170     padding.top = CalcLength(theme->GetCalendarTitleRowTopPadding());
171     padding.bottom = CalcLength(theme->GetCalendarTitleRowTopPadding() - CALENDAR_DISTANCE_ADJUST_FOCUSED_EVENT);
172     layoutProperty->UpdatePadding(padding);
173     auto childNode = AceType::DynamicCast<FrameNode>(dialogNode->GetFirstChild());
174     CHECK_NULL_VOID(childNode);
175     auto renderContext = childNode->GetRenderContext();
176     CHECK_NULL_VOID(renderContext);
177     if (dialogProperties.customStyle) {
178         layoutProperty->UpdateUserDefinedIdealSize(CalcSize(NG::CalcLength(DIALOG_WIDTH), std::nullopt));
179         BorderRadiusProperty radius;
180         radius.SetRadius(theme->GetDialogBorderRadius());
181         renderContext->UpdateBorderRadius(radius);
182         auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
183         if (shadowTheme) {
184             auto colorMode = pipelineContext->GetColorMode();
185             renderContext->UpdateBackShadow(shadowTheme->GetShadow(ShadowStyle::OuterDefaultSM, colorMode));
186         }
187     }
188     UpdateBackgroundStyle(renderContext, dialogProperties, theme, childNode);
189 }
190 
OperationsToPattern(const RefPtr<FrameNode> & frameNode,const CalendarSettingData & settingData,const DialogProperties & dialogProperties,const std::vector<ButtonInfo> & buttonInfos)191 void CalendarDialogView::OperationsToPattern(
192     const RefPtr<FrameNode>& frameNode, const CalendarSettingData& settingData,
193     const DialogProperties& dialogProperties, const std::vector<ButtonInfo>& buttonInfos)
194 {
195     auto pattern = frameNode->GetPattern<CalendarDialogPattern>();
196     CHECK_NULL_VOID(pattern);
197     pattern->SetEntryNode(settingData.entryNode);
198     pattern->SetDialogOffset(OffsetF(dialogProperties.offset.GetX().Value(), dialogProperties.offset.GetY().Value()));
199     pattern->SetCurrentButtonInfo(buttonInfos);
200     pattern->SetCurrentSettingData(settingData);
201     SetPreviousOrientation();
202     pattern->InitSurfaceChangedCallback();
203     DisableResetOptionButtonColor(pattern, buttonInfos);
204 }
205 
DisableResetOptionButtonColor(const RefPtr<CalendarDialogPattern> & calendarDialogPattern,const std::vector<ButtonInfo> & buttonInfos)206 void CalendarDialogView::DisableResetOptionButtonColor(
207     const RefPtr<CalendarDialogPattern>& calendarDialogPattern, const std::vector<ButtonInfo>& buttonInfos)
208 {
209     CHECK_NULL_VOID(calendarDialogPattern);
210     size_t fontColorIndex = 0;
211     size_t backgoundColorIndex = 0;
212     for (size_t index = 0; index < buttonInfos.size(); index++) {
213         if (index == 0) {
214             fontColorIndex = ACCEPT_BUTTON_FONT_COLOR_INDEX;
215             backgoundColorIndex = ACCEPT_BUTTON_BACKGROUND_COLOR_INDEX;
216         } else {
217             fontColorIndex = CANCEL_BUTTON_FONT_COLOR_INDEX;
218             backgoundColorIndex = CANCEL_BUTTON_BACKGROUND_COLOR_INDEX;
219         }
220 
221         if (buttonInfos[index].role.has_value() || buttonInfos[index].buttonStyle.has_value() ||
222             buttonInfos[index].fontColor.has_value()) {
223             calendarDialogPattern->SetOptionsButtonUpdateColorFlags(fontColorIndex, false);
224         }
225 
226         if (buttonInfos[index].role.has_value() || buttonInfos[index].buttonStyle.has_value() ||
227             buttonInfos[index].backgroundColor.has_value()) {
228             calendarDialogPattern->SetOptionsButtonUpdateColorFlags(backgoundColorIndex, false);
229         }
230     }
231 }
232 
SetTitleIdealSize(const RefPtr<CalendarTheme> & theme,const RefPtr<LinearLayoutProperty> & layoutProps)233 void CalendarDialogView::SetTitleIdealSize(
234     const RefPtr<CalendarTheme>& theme, const RefPtr<LinearLayoutProperty>& layoutProps)
235 {
236     auto pipeline = PipelineBase::GetCurrentContext();
237     CHECK_NULL_VOID(pipeline);
238     auto fontSizeScale = pipeline->GetFontScale();
239     if (fontSizeScale < theme->GetCalendarPickerLargeScale() || CheckOrientationChange()) {
240         layoutProps->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(theme->GetCalendarTitleRowHeight())));
241     } else if (fontSizeScale >= theme->GetCalendarPickerLargerScale()) {
242         layoutProps->UpdateUserDefinedIdealSize(
243             CalcSize(std::nullopt, CalcLength(theme->GetCalendarTitleLargerRowHeight())));
244     } else {
245         layoutProps->UpdateUserDefinedIdealSize(
246             CalcSize(std::nullopt, CalcLength(theme->GetCalendarTitleLargeRowHeight())));
247     }
248 }
249 
AddButtonAccessAbility(RefPtr<FrameNode> & leftYearArrowNode,RefPtr<FrameNode> & leftDayArrowNode,RefPtr<FrameNode> & rightDayArrowNode,RefPtr<FrameNode> & rightYearArrowNode,RefPtr<CalendarTheme> theme)250 void AddButtonAccessAbility(RefPtr<FrameNode>& leftYearArrowNode, RefPtr<FrameNode>& leftDayArrowNode,
251     RefPtr<FrameNode>& rightDayArrowNode, RefPtr<FrameNode>& rightYearArrowNode, RefPtr<CalendarTheme> theme)
252 {
253     CHECK_NULL_VOID(theme);
254     CHECK_NULL_VOID(leftYearArrowNode);
255     auto leftYearProperty = leftYearArrowNode->GetAccessibilityProperty<AccessibilityProperty>();
256     CHECK_NULL_VOID(leftYearProperty);
257     leftYearProperty->SetAccessibilityText(theme->GetCalendarTheme().preYear);
258     CHECK_NULL_VOID(leftDayArrowNode);
259     auto leftDayProperty = leftDayArrowNode->GetAccessibilityProperty<AccessibilityProperty>();
260     CHECK_NULL_VOID(leftDayProperty);
261     leftDayProperty->SetAccessibilityText(theme->GetCalendarTheme().preMonth);
262     CHECK_NULL_VOID(rightDayArrowNode);
263     auto rightDayProperty = rightDayArrowNode->GetAccessibilityProperty<AccessibilityProperty>();
264     CHECK_NULL_VOID(rightDayProperty);
265     rightDayProperty->SetAccessibilityText(theme->GetCalendarTheme().nextMonth);
266     CHECK_NULL_VOID(rightYearArrowNode);
267     auto rightYearProperty = rightYearArrowNode->GetAccessibilityProperty<AccessibilityProperty>();
268     CHECK_NULL_VOID(rightYearProperty);
269     rightYearProperty->SetAccessibilityText(theme->GetCalendarTheme().nextYear);
270 }
271 
CreateTitleNode(const RefPtr<FrameNode> & calendarNode,const RefPtr<FrameNode> & calendarDialogNode)272 RefPtr<FrameNode> CalendarDialogView::CreateTitleNode(const RefPtr<FrameNode>& calendarNode,
273     const RefPtr<FrameNode>& calendarDialogNode)
274 {
275     auto titleRow = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
276         AceType::MakeRefPtr<LinearLayoutPattern>(false));
277     CHECK_NULL_RETURN(titleRow, nullptr);
278     auto layoutProps = titleRow->GetLayoutProperty<LinearLayoutProperty>();
279     CHECK_NULL_RETURN(layoutProps, nullptr);
280     auto pipelineContext = calendarNode->GetContextRefPtr();
281     CHECK_NULL_RETURN(pipelineContext, nullptr);
282     RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
283     CHECK_NULL_RETURN(theme, nullptr);
284     layoutProps->UpdateMainAxisAlign(FlexAlign::AUTO);
285     layoutProps->UpdateCrossAxisAlign(FlexAlign::CENTER);
286     layoutProps->UpdateMeasureType(MeasureType::MATCH_PARENT_MAIN_AXIS);
287     MarginProperty margin;
288     margin.left = CalcLength(theme->GetCalendarTitleRowLeftRightPadding());
289     margin.right = CalcLength(theme->GetCalendarTitleRowLeftRightPadding());
290     layoutProps->UpdateMargin(margin);
291     SetTitleIdealSize(theme, layoutProps);
292 
293     // left year arrow
294     auto leftYearArrowNode =
295         CreateTitleImageNode(calendarNode, InternalResource::ResourceId::IC_PUBLIC_DOUBLE_ARROW_LEFT_SVG);
296     leftYearArrowNode->MountToParent(titleRow);
297 
298     // left day arrow
299     auto leftDayArrowNode = CreateTitleImageNode(calendarNode, InternalResource::ResourceId::IC_PUBLIC_ARROW_LEFT_SVG);
300     leftDayArrowNode->MountToParent(titleRow);
301 
302     // text
303     auto calendarPattern = calendarNode->GetPattern<CalendarPattern>();
304     CHECK_NULL_RETURN(calendarPattern, nullptr);
305     auto textTitleNode =
306         FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, calendarPattern->GetTitleId(), AceType::MakeRefPtr<TextPattern>());
307     CHECK_NULL_RETURN(textTitleNode, nullptr);
308     auto textLayoutProperty = textTitleNode->GetLayoutProperty<TextLayoutProperty>();
309     CHECK_NULL_RETURN(textLayoutProperty, nullptr);
310     UpdateTextLayoutProperty(textLayoutProperty, theme);
311     textTitleNode->MarkModifyDone();
312     textTitleNode->MountToParent(titleRow);
313 
314     // right day arrow
315     auto rightDayArrowNode =
316         CreateTitleImageNode(calendarNode, InternalResource::ResourceId::IC_PUBLIC_ARROW_RIGHT_SVG);
317     rightDayArrowNode->MountToParent(titleRow);
318 
319     // right year arrow
320     auto rightYearArrowNode =
321         CreateTitleImageNode(calendarNode, InternalResource::ResourceId::IC_PUBLIC_DOUBLE_ARROW_RIGHT_SVG);
322     rightYearArrowNode->MountToParent(titleRow);
323     AddButtonAccessAbility(leftYearArrowNode, leftDayArrowNode, rightDayArrowNode, rightYearArrowNode, theme);
324 
325     auto pattern = calendarDialogNode->GetPattern<CalendarDialogPattern>();
326     CHECK_NULL_RETURN(pattern, nullptr);
327     pattern->SetTitleNode(textTitleNode);
328     return titleRow;
329 }
330 
CreateWeekNode(const RefPtr<FrameNode> & calendarNode)331 RefPtr<FrameNode> CalendarDialogView::CreateWeekNode(const RefPtr<FrameNode>& calendarNode)
332 {
333     auto weekFrameNode = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
334         AceType::MakeRefPtr<LinearLayoutPattern>(false));
335     CHECK_NULL_RETURN(weekFrameNode, nullptr);
336     auto pipelineContext = PipelineContext::GetCurrentContext();
337     CHECK_NULL_RETURN(pipelineContext, nullptr);
338     RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
339     CHECK_NULL_RETURN(theme, nullptr);
340     auto weekLayoutProperty = weekFrameNode->GetLayoutProperty<LinearLayoutProperty>();
341     CHECK_NULL_RETURN(weekLayoutProperty, nullptr);
342     auto swiperNode = calendarNode->GetChildren().front();
343     CHECK_NULL_RETURN(swiperNode, nullptr);
344     auto monthFrameNode = AceType::DynamicCast<FrameNode>(swiperNode->GetChildren().front());
345     CHECK_NULL_RETURN(monthFrameNode, nullptr);
346     auto calendarPaintProperty = monthFrameNode->GetPaintProperty<CalendarPaintProperty>();
347     CHECK_NULL_RETURN(calendarPaintProperty, nullptr);
348     MarginProperty margin;
349     margin.top = CalcLength(theme->GetDistanceBetweenTitleAndDate().ConvertToPx() + WEEK_SPACE);
350     weekLayoutProperty->UpdateMargin(margin);
351     return weekFrameNode;
352 }
353 
CreateTitleImageNode(const RefPtr<FrameNode> & calendarNode,const InternalResource::ResourceId & resourceId)354 RefPtr<FrameNode> CalendarDialogView::CreateTitleImageNode(
355     const RefPtr<FrameNode>& calendarNode, const InternalResource::ResourceId& resourceId)
356 {
357     auto pipelineContext = calendarNode->GetContext();
358     CHECK_NULL_RETURN(pipelineContext, nullptr);
359     RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
360     CHECK_NULL_RETURN(theme, nullptr);
361     CalcSize idealSize = { CalcLength(theme->GetEntryArrowWidth()), CalcLength(theme->GetEntryArrowWidth()) };
362     MeasureProperty layoutConstraint = { .selfIdealSize = idealSize };
363     BorderRadiusProperty borderRadius;
364     Dimension radius =
365         Dimension((theme->GetCalendarImageWidthHeight().Value()) / 2, (theme->GetCalendarImageWidthHeight()).Unit());
366     borderRadius.SetRadius(radius);
367 
368     // Create button node
369     auto buttonNode = FrameNode::GetOrCreateFrameNode(V2::BUTTON_ETS_TAG,
370         ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ButtonPattern>(); });
371     CHECK_NULL_RETURN(buttonNode, nullptr);
372     auto buttonLayoutProperty = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
373     CHECK_NULL_RETURN(buttonLayoutProperty, nullptr);
374     buttonLayoutProperty->UpdateType(ButtonType::CIRCLE);
375     buttonLayoutProperty->UpdateUserDefinedIdealSize(
376         CalcSize(CalcLength(theme->GetCalendarImageWidthHeight()), CalcLength(theme->GetCalendarImageWidthHeight())));
377     auto buttonRenderContext = buttonNode->GetRenderContext();
378     CHECK_NULL_RETURN(buttonRenderContext, nullptr);
379     buttonRenderContext->UpdateBorderRadius(borderRadius);
380     MarginProperty margin;
381     if (resourceId == InternalResource::ResourceId::IC_PUBLIC_DOUBLE_ARROW_LEFT_SVG) {
382         margin.right = CalcLength(theme->GetCalendarTitleImagePadding());
383     } else if (resourceId == InternalResource::ResourceId::IC_PUBLIC_DOUBLE_ARROW_RIGHT_SVG) {
384         margin.left = CalcLength(theme->GetCalendarTitleImagePadding());
385     }
386     buttonLayoutProperty->UpdateMargin(margin);
387 
388     // Create image node
389     auto imageNode = FrameNode::CreateFrameNode(
390         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
391     CHECK_NULL_RETURN(imageNode, nullptr);
392     auto imageRenderContext = imageNode->GetRenderContext();
393     CHECK_NULL_RETURN(imageRenderContext, nullptr);
394     imageRenderContext->UpdateBorderRadius(borderRadius);
395     auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
396     CHECK_NULL_RETURN(imageLayoutProperty, nullptr);
397     ImageSourceInfo imageSourceInfo;
398     imageSourceInfo.SetResourceId(resourceId, theme->GetEntryArrowColor());
399     imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
400     imageLayoutProperty->UpdateCalcLayoutProperty(layoutConstraint);
401     imageNode->SetDraggable(false);
402     imageNode->MarkModifyDone();
403     imageNode->MountToParent(buttonNode);
404 
405     buttonNode->MarkModifyDone();
406     return buttonNode;
407 }
408 
SetCalendarIdealSize(const RefPtr<CalendarTheme> & theme,const RefPtr<LayoutProperty> & calendarLayoutProperty,const Dimension & weekHeight)409 void CalendarDialogView::SetCalendarIdealSize(const RefPtr<CalendarTheme>& theme,
410     const RefPtr<LayoutProperty>& calendarLayoutProperty, const Dimension& weekHeight)
411 {
412     auto pipeline = PipelineBase::GetCurrentContext();
413     CHECK_NULL_VOID(pipeline);
414     auto fontSizeScale = pipeline->GetFontScale();
415     if (fontSizeScale < theme->GetCalendarPickerLargeScale() || CheckOrientationChange()) {
416         calendarLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt,
417             CalcLength(theme->GetCalendarContainerHeight() + CALENDAR_DISTANCE_ADJUST_FOCUSED_EVENT - weekHeight)));
418     } else if (fontSizeScale >= theme->GetCalendarPickerLargerScale()) {
419         calendarLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt,
420             CalcLength(theme->GetCalendarLargerContainerHeight()
421             + CALENDAR_DISTANCE_ADJUST_FOCUSED_EVENT - weekHeight)));
422     } else {
423         calendarLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt,
424             CalcLength(theme->GetCalendarLargeContainerHeight()
425             + CALENDAR_DISTANCE_ADJUST_FOCUSED_EVENT - weekHeight)));
426     }
427 }
428 
CreateCalendarNode(const RefPtr<FrameNode> & calendarDialogNode,const CalendarSettingData & settingData,const std::map<std::string,NG::DialogEvent> & dialogEvent)429 RefPtr<FrameNode> CalendarDialogView::CreateCalendarNode(const RefPtr<FrameNode>& calendarDialogNode,
430     const CalendarSettingData& settingData, const std::map<std::string, NG::DialogEvent>& dialogEvent)
431 {
432     int32_t calendarNodeId = ElementRegister::GetInstance()->MakeUniqueId();
433     auto calendarNode = FrameNode::GetOrCreateFrameNode(
434         V2::CALENDAR_ETS_TAG, calendarNodeId, []() { return AceType::MakeRefPtr<CalendarPattern>(); });
435     CHECK_NULL_RETURN(calendarNode, nullptr);
436 
437     auto textDirection = calendarNode->GetLayoutProperty()->GetNonAutoLayoutDirection();
438     if (settingData.entryNode.Upgrade() != nullptr) {
439         auto entryNode = settingData.entryNode.Upgrade();
440         textDirection = entryNode->GetLayoutProperty()->GetNonAutoLayoutDirection();
441     }
442 
443     auto swiperNode = CreateCalendarSwiperNode();
444     CHECK_NULL_RETURN(swiperNode, nullptr);
445     auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
446     CHECK_NULL_RETURN(swiperLayoutProperty, nullptr);
447     swiperLayoutProperty->UpdateLayoutDirection(textDirection);
448     swiperNode->MountToParent(calendarNode);
449 
450     InitOnRequestDataEvent(calendarDialogNode, calendarNode);
451     auto calendarPattern = calendarNode->GetPattern<CalendarPattern>();
452     CHECK_NULL_RETURN(calendarPattern, nullptr);
453     PickerDate date = settingData.selectedDate;
454     calendarPattern->SetSelectedDay(date);
455     CalendarMonth currentMonth { .year = date.GetYear(), .month = date.GetMonth() };
456     UpdateCalendarMonthData(calendarDialogNode, calendarNode, currentMonth);
457     calendarPattern->SetStartDate(settingData.startDate);
458     calendarPattern->SetEndDate(settingData.endDate);
459     calendarPattern->SetMarkToday(settingData.markToday);
460     calendarPattern->SetDisabledDateRange(settingData.disabledDateRange);
461 
462     CalendarDay calendarDay;
463     PickerDate today = PickerDate::Current();
464     calendarDay.month.year = static_cast<int32_t>(today.GetYear());
465     calendarDay.month.month = static_cast<int32_t>(today.GetMonth());
466     calendarDay.day = static_cast<int32_t>(today.GetDay());
467     calendarPattern->SetCalendarDay(calendarDay);
468 
469     DialogEvent changeEvent = GetChangeEvent(settingData, calendarDialogNode, dialogEvent); // do not check nullptr
470     for (int32_t i = 0; i < SWIPER_MONTHS_COUNT; i++) {
471         auto monthFrameNode = CreateCalendarMonthNode(calendarNodeId, settingData, changeEvent);
472         CHECK_NULL_RETURN(monthFrameNode, nullptr);
473         auto monthLayoutProperty = monthFrameNode->GetLayoutProperty();
474         CHECK_NULL_RETURN(monthLayoutProperty, nullptr);
475         if (i == CURRENT_MONTH_INDEX) {
476             auto currentPattern = monthFrameNode->GetPattern<CalendarMonthPattern>();
477             CHECK_NULL_RETURN(currentPattern, nullptr);
478             currentPattern->SetIsFirstEnter(true);
479         }
480         monthLayoutProperty->UpdateLayoutDirection(textDirection);
481         monthFrameNode->MountToParent(swiperNode);
482         monthFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
483     }
484 
485     InitCalendarProperty(calendarNode);
486     swiperNode->MarkModifyDone();
487     return calendarNode;
488 }
489 
InitCalendarProperty(const RefPtr<FrameNode> & calendarNode)490 void CalendarDialogView::InitCalendarProperty(const RefPtr<FrameNode>& calendarNode)
491 {
492     auto pipelineContext = calendarNode->GetContext();
493     CHECK_NULL_VOID(pipelineContext);
494     auto calendarLayoutProperty = calendarNode->GetLayoutProperty();
495     CHECK_NULL_VOID(calendarLayoutProperty);
496     RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
497     CHECK_NULL_VOID(theme);
498     MarginProperty margin = {
499         .left = CalcLength(theme->GetDistanceBetweenContainterAndDate() - CALENDAR_DISTANCE_ADJUST_FOCUSED_EVENT),
500         .right = CalcLength(theme->GetDistanceBetweenContainterAndDate() - CALENDAR_DISTANCE_ADJUST_FOCUSED_EVENT)
501     };
502     calendarLayoutProperty->UpdateMargin(margin);
503     auto swiperNode = calendarNode->GetChildren().front();
504     CHECK_NULL_VOID(swiperNode);
505     auto calendarMonthNode = swiperNode->GetChildAtIndex(CURRENT_MONTH_INDEX);
506     CHECK_NULL_VOID(calendarMonthNode);
507     auto calendarMonthFrameNode = AceType::DynamicCast<FrameNode>(calendarMonthNode);
508     CHECK_NULL_VOID(calendarMonthFrameNode);
509     auto calendarPaintProperty = calendarMonthFrameNode->GetPaintProperty<CalendarPaintProperty>();
510     auto gregorianDayHeight = calendarPaintProperty->GetGregorianCalendarHeightValue({}).ConvertToPx() <= 0
511                     ? theme->GetCalendarTheme().gregorianCalendarHeight
512                     : calendarPaintProperty->GetGregorianCalendarHeightValue({});
513     auto monthPattern = calendarMonthFrameNode->GetPattern<CalendarMonthPattern>();
514     CHECK_NULL_VOID(monthPattern);
515     if (monthPattern->IsLargeSize(theme)) {
516         gregorianDayHeight = monthPattern->GetDaySize(theme);
517     }
518     SetCalendarIdealSize(theme, calendarLayoutProperty, gregorianDayHeight);
519 }
520 
CreateScrollNode()521 RefPtr<FrameNode> CalendarDialogView::CreateScrollNode()
522 {
523     auto scrollNode = FrameNode::GetOrCreateFrameNode(V2::SCROLL_ETS_TAG,
524         ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ScrollPattern>(); });
525     CHECK_NULL_RETURN(scrollNode, nullptr);
526     auto props = scrollNode->GetLayoutProperty<ScrollLayoutProperty>();
527     CHECK_NULL_RETURN(props, nullptr);
528     props->UpdateScrollEnabled(true);
529     props->UpdateAxis(Axis::VERTICAL);
530     props->UpdateAlignment(Alignment::TOP_CENTER);
531     scrollNode->MarkModifyDone();
532     return scrollNode;
533 }
534 
CreateCalendarSwiperNode()535 RefPtr<FrameNode> CalendarDialogView::CreateCalendarSwiperNode()
536 {
537     auto swiperNode = FrameNode::GetOrCreateFrameNode(V2::SWIPER_ETS_TAG,
538         ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<SwiperPattern>(); });
539     CHECK_NULL_RETURN(swiperNode, nullptr);
540     auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
541     CHECK_NULL_RETURN(swiperLayoutProperty, nullptr);
542     swiperLayoutProperty->UpdateIndex(CURRENT_MONTH_INDEX);
543     swiperLayoutProperty->UpdateShowIndicator(false);
544     swiperLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
545     swiperLayoutProperty->UpdateLoop(true);
546     swiperLayoutProperty->UpdateDisableSwipe(false);
547     return swiperNode;
548 }
549 
CreateCalendarMonthNode(int32_t calendarNodeId,const CalendarSettingData & settingData,const DialogEvent & changeEvent)550 RefPtr<FrameNode> CalendarDialogView::CreateCalendarMonthNode(int32_t calendarNodeId,
551     const CalendarSettingData& settingData, const DialogEvent& changeEvent)
552 {
553     auto monthFrameNode = FrameNode::GetOrCreateFrameNode(V2::CALENDAR_ETS_TAG,
554         ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<CalendarMonthPattern>(); });
555     CHECK_NULL_RETURN(monthFrameNode, nullptr);
556     ViewStackProcessor::GetInstance()->Push(monthFrameNode);
557     SetCalendarPaintProperties(settingData);
558     ViewStackProcessor::GetInstance()->Finish();
559     auto monthPattern = monthFrameNode->GetPattern<CalendarMonthPattern>();
560     CHECK_NULL_RETURN(monthPattern, nullptr);
561 
562     if (settingData.dayRadiusResObj) {
563         auto&& updateFunc = [monthPattern, monthFrameNode](const RefPtr<ResourceObject>& resObj) {
564             CalcDimension dayRadius;
565             ResourceParseUtils::ParseResDimensionVpNG(resObj, dayRadius);
566             monthPattern->UpdateDayRadius(dayRadius);
567         };
568         monthPattern->AddResObj("CalendarDayRadius", settingData.dayRadiusResObj, std::move(updateFunc));
569     }
570 
571     monthPattern->SetCalendarDialogFlag(true);
572     auto calendarEventHub = monthPattern->GetOrCreateEventHub<CalendarEventHub>();
573     CHECK_NULL_RETURN(calendarEventHub, nullptr);
574     auto selectedChangeEvent = [calendarNodeId, changeEvent, settingData](const std::string& callbackInfo) {
575         OnSelectedChangeEvent(calendarNodeId, callbackInfo, std::move(changeEvent), settingData);
576     };
577     calendarEventHub->SetSelectedChangeEvent(std::move(selectedChangeEvent));
578 
579     auto monthLayoutProperty = monthFrameNode->GetLayoutProperty<LayoutProperty>();
580     CHECK_NULL_RETURN(monthLayoutProperty, nullptr);
581     auto pipelineContext = monthFrameNode->GetContext();
582     CHECK_NULL_RETURN(pipelineContext, nullptr);
583     RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
584     CHECK_NULL_RETURN(theme, nullptr);
585     monthLayoutProperty->UpdateUserDefinedIdealSize(
586         CalcSize(CalcLength(1, DimensionUnit::PERCENT),
587         CalcLength(theme->GetCalendarContainerHeight() + CALENDAR_DISTANCE_ADJUST_FOCUSED_EVENT)));
588     return monthFrameNode;
589 }
590 
UpdateCalendarMonthData(const RefPtr<FrameNode> & calendarDialogNode,const RefPtr<FrameNode> & calendarNode,const CalendarMonth & currentMonth)591 void CalendarDialogView::UpdateCalendarMonthData(const RefPtr<FrameNode>& calendarDialogNode,
592     const RefPtr<FrameNode>& calendarNode, const CalendarMonth& currentMonth)
593 {
594     CHECK_NULL_VOID(calendarNode);
595     CHECK_NULL_VOID(calendarDialogNode);
596     auto calendarPattern = calendarNode->GetPattern<CalendarPattern>();
597     CHECK_NULL_VOID(calendarPattern);
598     auto calendarDialogPattern = calendarDialogNode->GetPattern<CalendarDialogPattern>();
599     CHECK_NULL_VOID(calendarDialogPattern);
600 
601     CalendarData calendarData;
602     calendarDialogPattern->GetCalendarMonthData(currentMonth.year, currentMonth.month, calendarData.currentData);
603     calendarPattern->SetCurrentMonthData(calendarData.currentData);
604     calendarDialogPattern->GetCalendarMonthData(calendarDialogPattern->GetLastMonth(currentMonth).year,
605         calendarDialogPattern->GetLastMonth(currentMonth).month, calendarData.preData);
606     calendarPattern->SetPreMonthData(calendarData.preData);
607     calendarDialogPattern->GetCalendarMonthData(calendarDialogPattern->GetNextMonth(currentMonth).year,
608         calendarDialogPattern->GetNextMonth(currentMonth).month, calendarData.nextData);
609     calendarPattern->SetNextMonthData(calendarData.nextData);
610 }
611 
SetDialogChange(const RefPtr<FrameNode> & frameNode,DialogEvent && onChange)612 void CalendarDialogView::SetDialogChange(const RefPtr<FrameNode>& frameNode, DialogEvent&& onChange)
613 {
614     CHECK_NULL_VOID(frameNode);
615     auto eventHub = frameNode->GetOrCreateEventHub<CalendarEventHub>();
616     CHECK_NULL_VOID(eventHub);
617     eventHub->SetDialogChange(std::move(onChange));
618 }
619 
SetDialogAcceptEvent(const RefPtr<FrameNode> & frameNode,DialogEvent && onAccept)620 void CalendarDialogView::SetDialogAcceptEvent(const RefPtr<FrameNode>& frameNode, DialogEvent&& onAccept)
621 {
622     CHECK_NULL_VOID(frameNode);
623     auto eventHub = frameNode->GetOrCreateEventHub<CalendarEventHub>();
624     CHECK_NULL_VOID(eventHub);
625     eventHub->SetDialogAcceptEvent(std::move(onAccept));
626 }
627 
CreateButtonNode(bool isConfirm,const std::vector<ButtonInfo> & buttonInfos)628 RefPtr<FrameNode> CalendarDialogView::CreateButtonNode(bool isConfirm, const std::vector<ButtonInfo>& buttonInfos)
629 {
630     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
631     CHECK_NULL_RETURN(pipeline, nullptr);
632     auto dialogTheme = pipeline->GetTheme<DialogTheme>();
633     auto pickerTheme = pipeline->GetTheme<PickerTheme>();
634     auto calendarTheme = pipeline->GetTheme<CalendarTheme>();
635     CHECK_NULL_RETURN(calendarTheme, nullptr);
636     auto buttonNode = FrameNode::GetOrCreateFrameNode(V2::BUTTON_ETS_TAG,
637         ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ButtonPattern>(); });
638     CHECK_NULL_RETURN(buttonNode, nullptr);
639     auto textNode = FrameNode::CreateFrameNode(
640         V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
641     CHECK_NULL_RETURN(textNode, nullptr);
642     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
643     CHECK_NULL_RETURN(textLayoutProperty, nullptr);
644     textLayoutProperty->UpdateContent(isConfirm ? dialogTheme->GetConfirmText() : dialogTheme->GetCancelText());
645 
646     auto fontSizeScale = pipeline->GetFontScale();
647     auto fontSize = pickerTheme->GetOptionStyle(false, false).GetFontSize();
648     if (fontSizeScale < calendarTheme->GetCalendarPickerLargeScale() || CheckOrientationChange()) {
649         textLayoutProperty->UpdateFontSize(fontSize);
650     } else {
651         fontSizeScale = fontSizeScale > calendarTheme->GetCalendarPickerLargeScale()
652                             ? calendarTheme->GetCalendarPickerLargeScale()
653                             : fontSizeScale;
654         textLayoutProperty->UpdateFontSize(fontSize * fontSizeScale);
655     }
656 
657     textLayoutProperty->UpdateTextColor(pickerTheme->GetOptionStyle(true, false).GetTextColor());
658     textLayoutProperty->UpdateFontWeight(pickerTheme->GetOptionStyle(true, false).GetFontWeight());
659     textNode->MountToParent(buttonNode);
660 
661     UpdateButtonLayoutProperty(buttonNode, isConfirm, buttonInfos, pipeline);
662     auto buttonEventHub = buttonNode->GetOrCreateEventHub<ButtonEventHub>();
663     CHECK_NULL_RETURN(buttonEventHub, nullptr);
664     buttonEventHub->SetStateEffect(true);
665 
666     auto buttonRenderContext = buttonNode->GetRenderContext();
667     auto defaultBGColor =
668         calendarTheme->GetIsButtonTransparent() ? Color::TRANSPARENT : calendarTheme->GetDialogButtonBackgroundColor();
669     buttonRenderContext->UpdateBackgroundColor(defaultBGColor);
670     auto buttonLayoutProperty = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
671     CHECK_NULL_RETURN(buttonLayoutProperty, nullptr);
672     auto index = isConfirm ? ACCEPT_BUTTON_INDEX : CANCEL_BUTTON_INDEX;
673     UpdateButtonStyles(buttonInfos, index, buttonLayoutProperty, buttonRenderContext);
674     UpdateButtonDefaultFocus(buttonInfos, buttonNode, isConfirm);
675     buttonNode->MarkModifyDone();
676     return buttonNode;
677 }
678 
UpdateButtonLayoutProperty(const RefPtr<FrameNode> & buttonNode,bool isConfirm,const std::vector<ButtonInfo> & buttonInfos,const RefPtr<PipelineContext> & pipeline)679 void CalendarDialogView::UpdateButtonLayoutProperty(const RefPtr<FrameNode>& buttonNode, bool isConfirm,
680     const std::vector<ButtonInfo>& buttonInfos, const RefPtr<PipelineContext>& pipeline)
681 {
682     auto dialogTheme = pipeline->GetTheme<DialogTheme>();
683     auto pickerTheme = pipeline->GetTheme<PickerTheme>();
684     auto calendarTheme = pipeline->GetTheme<CalendarTheme>();
685     auto buttonLayoutProperty = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
686     CHECK_NULL_VOID(buttonLayoutProperty);
687     auto index = isConfirm ? ACCEPT_BUTTON_INDEX : CANCEL_BUTTON_INDEX;
688     if (index < buttonInfos.size() &&
689         (buttonInfos[index].role.has_value() || buttonInfos[index].buttonStyle.has_value() ||
690             buttonInfos[index].fontSize.has_value() || buttonInfos[index].fontColor.has_value() ||
691             buttonInfos[index].fontWeight.has_value() || buttonInfos[index].fontStyle.has_value() ||
692             buttonInfos[index].fontFamily.has_value())) {
693         buttonLayoutProperty->UpdateLabel(isConfirm ? dialogTheme->GetConfirmText() : dialogTheme->GetCancelText());
694     }
695     buttonLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT_MAIN_AXIS);
696     if (buttonNode->GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
697         buttonLayoutProperty->UpdateType(ButtonType::ROUNDED_RECTANGLE);
698     } else {
699         buttonLayoutProperty->UpdateType(ButtonType::CAPSULE);
700     }
701 
702     buttonLayoutProperty->UpdateFlexShrink(1.0);
703     CalcLength width;
704     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
705         width = CalcLength(1.0, DimensionUnit::PERCENT);
706     } else {
707         width = CalcLength(pickerTheme->GetButtonWidth());
708     }
709 
710     auto fontSizeScale = pipeline->GetFontScale();
711     if (fontSizeScale >= calendarTheme->GetCalendarPickerLargerScale() &&
712         (!(GetPreviousOrientation() == SystemProperties::GetDeviceOrientation())
713                 ? Dimension(pipeline->GetRootWidth()).ConvertToVp() >= deviceHeightLimit
714                 : Dimension(pipeline->GetRootHeight()).ConvertToVp() >= deviceHeightLimit)) {
715         buttonLayoutProperty->UpdateUserDefinedIdealSize(
716             CalcSize(width, CalcLength(calendarTheme->GetCalendarActionLargeRowHeight())));
717     } else {
718         buttonLayoutProperty->UpdateUserDefinedIdealSize(
719             CalcSize(width, CalcLength(calendarTheme->GetCalendarActionRowHeight())));
720     }
721 }
722 
UpdateButtonStyles(const std::vector<ButtonInfo> & buttonInfos,size_t index,const RefPtr<ButtonLayoutProperty> & buttonLayoutProperty,const RefPtr<RenderContext> & buttonRenderContext)723 void CalendarDialogView::UpdateButtonStyles(const std::vector<ButtonInfo>& buttonInfos, size_t index,
724     const RefPtr<ButtonLayoutProperty>& buttonLayoutProperty, const RefPtr<RenderContext>& buttonRenderContext)
725 {
726     if (index >= buttonInfos.size()) {
727         return;
728     }
729     CHECK_NULL_VOID(buttonLayoutProperty);
730     CHECK_NULL_VOID(buttonRenderContext);
731     auto buttonTheme = PipelineBase::GetCurrentContext()->GetTheme<ButtonTheme>();
732     CHECK_NULL_VOID(buttonTheme);
733     if (buttonInfos[index].type.has_value()) {
734         buttonLayoutProperty->UpdateType(buttonInfos[index].type.value());
735     }
736     UpdateButtonStyleAndRole(buttonInfos, index, buttonLayoutProperty, buttonRenderContext, buttonTheme);
737     if (buttonInfos[index].fontSize.has_value()) {
738         buttonLayoutProperty->UpdateFontSize(buttonInfos[index].fontSize.value());
739     }
740     if (buttonInfos[index].fontColor.has_value()) {
741         buttonLayoutProperty->UpdateFontColor(buttonInfos[index].fontColor.value());
742     }
743     if (buttonInfos[index].fontWeight.has_value()) {
744         buttonLayoutProperty->UpdateFontWeight(buttonInfos[index].fontWeight.value());
745     }
746     if (buttonInfos[index].fontStyle.has_value()) {
747         buttonLayoutProperty->UpdateFontStyle(buttonInfos[index].fontStyle.value());
748     }
749     if (buttonInfos[index].fontFamily.has_value()) {
750         buttonLayoutProperty->UpdateFontFamily(buttonInfos[index].fontFamily.value());
751     }
752     if (buttonInfos[index].borderRadius.has_value()) {
753         buttonLayoutProperty->UpdateBorderRadius(buttonInfos[index].borderRadius.value());
754     }
755     if (buttonInfos[index].backgroundColor.has_value()) {
756         buttonRenderContext->UpdateBackgroundColor(buttonInfos[index].backgroundColor.value());
757     }
758 }
759 
UpdateButtonStyleAndRole(const std::vector<ButtonInfo> & buttonInfos,size_t index,const RefPtr<ButtonLayoutProperty> & buttonLayoutProperty,const RefPtr<RenderContext> & buttonRenderContext,const RefPtr<ButtonTheme> & buttonTheme)760 void CalendarDialogView::UpdateButtonStyleAndRole(const std::vector<ButtonInfo>& buttonInfos, size_t index,
761     const RefPtr<ButtonLayoutProperty>& buttonLayoutProperty, const RefPtr<RenderContext>& buttonRenderContext,
762     const RefPtr<ButtonTheme>& buttonTheme)
763 {
764     if (index >= buttonInfos.size()) {
765         return;
766     }
767     CHECK_NULL_VOID(buttonLayoutProperty);
768     CHECK_NULL_VOID(buttonRenderContext);
769     CHECK_NULL_VOID(buttonTheme);
770     if (buttonInfos[index].role.has_value()) {
771         buttonLayoutProperty->UpdateButtonRole(buttonInfos[index].role.value());
772         ButtonStyleMode buttonStyleMode;
773         if (buttonInfos[index].buttonStyle.has_value()) {
774             buttonStyleMode = buttonInfos[index].buttonStyle.value();
775         } else {
776             buttonStyleMode = buttonLayoutProperty->GetButtonStyle().value_or(ButtonStyleMode::EMPHASIZE);
777         }
778         auto bgColor = buttonTheme->GetBgColor(buttonStyleMode, buttonInfos[index].role.value());
779         auto textColor = buttonTheme->GetTextColor(buttonStyleMode, buttonInfos[index].role.value());
780         buttonRenderContext->UpdateBackgroundColor(bgColor);
781         buttonLayoutProperty->UpdateFontColor(textColor);
782     }
783     if (buttonInfos[index].buttonStyle.has_value()) {
784         buttonLayoutProperty->UpdateButtonStyle(buttonInfos[index].buttonStyle.value());
785         ButtonRole buttonRole = buttonLayoutProperty->GetButtonRole().value_or(ButtonRole::NORMAL);
786         auto bgColor = buttonTheme->GetBgColor(buttonInfos[index].buttonStyle.value(), buttonRole);
787         auto textColor = buttonTheme->GetTextColor(buttonInfos[index].buttonStyle.value(), buttonRole);
788         buttonRenderContext->UpdateBackgroundColor(bgColor);
789         buttonLayoutProperty->UpdateFontColor(textColor);
790     }
791 }
792 
CreateConfirmNode(const RefPtr<FrameNode> & calendarNode,DialogEvent & acceptEvent,const std::vector<ButtonInfo> & buttonInfos)793 RefPtr<FrameNode> CalendarDialogView::CreateConfirmNode(
794     const RefPtr<FrameNode>& calendarNode, DialogEvent& acceptEvent, const std::vector<ButtonInfo>& buttonInfos)
795 {
796     CHECK_NULL_RETURN(calendarNode, nullptr);
797     auto buttonConfirmNode = CreateButtonNode(true, buttonInfos);
798 
799     auto eventConfirmHub = buttonConfirmNode->GetOrCreateGestureEventHub();
800     CHECK_NULL_RETURN(eventConfirmHub, nullptr);
801     SetDialogAcceptEvent(calendarNode, std::move(acceptEvent));
802     auto clickCallback = [weak = WeakPtr<FrameNode>(calendarNode)](const GestureEvent& /* info */) {
803         auto calendarNode = weak.Upgrade();
804         CHECK_NULL_VOID(calendarNode);
805         auto calendarPattern = calendarNode->GetPattern<CalendarPattern>();
806         CHECK_NULL_VOID(calendarPattern);
807         auto str = calendarPattern->GetSelectDate();
808         auto calendarEventHub = calendarNode->GetOrCreateEventHub<CalendarEventHub>();
809         CHECK_NULL_VOID(calendarEventHub);
810         calendarEventHub->FireDialogAcceptEvent(str);
811     };
812     eventConfirmHub->AddClickEvent(AceType::MakeRefPtr<NG::ClickEvent>(std::move(clickCallback)));
813 
814     return buttonConfirmNode;
815 }
816 
CreateCancelNode(const NG::DialogGestureEvent & cancelEvent,const std::vector<ButtonInfo> & buttonInfos)817 RefPtr<FrameNode> CalendarDialogView::CreateCancelNode(
818     const NG::DialogGestureEvent& cancelEvent, const std::vector<ButtonInfo>& buttonInfos)
819 {
820     auto buttonCancelNode = CreateButtonNode(false, buttonInfos);
821 
822     auto eventCancelHub = buttonCancelNode->GetOrCreateGestureEventHub();
823     CHECK_NULL_RETURN(eventCancelHub, nullptr);
824     eventCancelHub->AddClickEvent(AceType::MakeRefPtr<NG::ClickEvent>(std::move(cancelEvent)));
825 
826     return buttonCancelNode;
827 }
828 
CreateDividerNode()829 RefPtr<FrameNode> CalendarDialogView::CreateDividerNode()
830 {
831     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
832     CHECK_NULL_RETURN(pipeline, nullptr);
833     auto dialogTheme = pipeline->GetTheme<DialogTheme>();
834     RefPtr<CalendarTheme> theme = pipeline->GetTheme<CalendarTheme>();
835     auto dividerNode = FrameNode::GetOrCreateFrameNode(V2::DIVIDER_ETS_TAG,
836         ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<DividerPattern>(); });
837     auto dividerRenderContext = dividerNode->GetRenderContext();
838     CHECK_NULL_RETURN(dividerRenderContext, nullptr);
839     dividerRenderContext->UpdateBackgroundColor(Color::TRANSPARENT);
840 
841     auto dividerLayoutProperty = dividerNode->GetLayoutProperty<DividerLayoutProperty>();
842     CHECK_NULL_RETURN(dividerLayoutProperty, nullptr);
843     dividerLayoutProperty->UpdateVertical(true);
844     auto dividerRenderProperty = dividerNode->GetPaintProperty<DividerRenderProperty>();
845     CHECK_NULL_RETURN(dividerRenderProperty, nullptr);
846     dividerRenderProperty->UpdateDividerColor(
847         theme->GetIsDividerTransparent() ? Color::TRANSPARENT : theme->GetDialogDividerColor());
848 
849     dividerNode->GetLayoutProperty()->UpdateUserDefinedIdealSize(
850         CalcSize(CalcLength(dialogTheme->GetDividerWidth()), CalcLength(theme->GetEntryArrowWidth())));
851 
852     dividerNode->MarkModifyDone();
853 
854     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
855         auto dividerWrapper = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG,
856             ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<LinearLayoutPattern>(false));
857         CHECK_NULL_RETURN(dividerWrapper, nullptr);
858         auto layoutProps = dividerWrapper->GetLayoutProperty<LinearLayoutProperty>();
859         CHECK_NULL_RETURN(layoutProps, nullptr);
860         layoutProps->UpdateMainAxisAlign(FlexAlign::SPACE_AROUND);
861         layoutProps->UpdateMeasureType(MeasureType::MATCH_PARENT_MAIN_AXIS);
862         layoutProps->UpdateUserDefinedIdealSize(CalcSize(
863             CalcLength(dialogTheme->GetActionsPadding().Bottom()), CalcLength(theme->GetCalendarActionRowHeight())));
864         dividerNode->MountToParent(dividerWrapper);
865         return dividerWrapper;
866     }
867     return dividerNode;
868 }
869 
CreateOptionsNode(const RefPtr<FrameNode> & dialogNode,const RefPtr<FrameNode> & dateNode,const std::map<std::string,NG::DialogEvent> & dialogEvent,const std::map<std::string,NG::DialogGestureEvent> & dialogCancelEvent,const std::vector<ButtonInfo> & buttonInfos)870 RefPtr<FrameNode> CalendarDialogView::CreateOptionsNode(
871     const RefPtr<FrameNode>& dialogNode, const RefPtr<FrameNode>& dateNode,
872     const std::map<std::string, NG::DialogEvent>& dialogEvent,
873     const std::map<std::string, NG::DialogGestureEvent>& dialogCancelEvent, const std::vector<ButtonInfo>& buttonInfos)
874 {
875     auto contentRow = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
876         AceType::MakeRefPtr<LinearLayoutPattern>(false));
877     CHECK_NULL_RETURN(contentRow, nullptr);
878     auto pipelineContext = contentRow->GetContextRefPtr();
879     CHECK_NULL_RETURN(pipelineContext, nullptr);
880     UpdateOptionLayoutProps(contentRow, pipelineContext);
881 
882     auto cancelIter = dialogCancelEvent.find("cancelId");
883     DialogGestureEvent cancelEvent = nullptr;
884     if (cancelIter != dialogCancelEvent.end()) {
885         cancelEvent = cancelIter->second;
886     }
887     auto buttonCancelNode = CreateCancelNode(cancelEvent, buttonInfos);
888     auto acceptIter = dialogEvent.find("acceptId");
889     DialogEvent acceptEvent = (acceptIter != dialogEvent.end()) ? acceptIter->second : nullptr;
890     auto buttonConfirmNode = CreateConfirmNode(dateNode, acceptEvent, buttonInfos);
891 
892     buttonCancelNode->MountToParent(contentRow);
893     buttonConfirmNode->MountToParent(contentRow);
894     UpdateDefaultFocusByButtonInfo(contentRow, buttonConfirmNode, buttonCancelNode);
895 
896     auto event = [weakDialogNode = WeakPtr<FrameNode>(dialogNode),
897                  weakPipelineContext = WeakPtr<PipelineContext>(pipelineContext)](const GestureEvent& /* info */) {
898         auto dialogNode = weakDialogNode.Upgrade();
899         CHECK_NULL_VOID(dialogNode);
900         auto pipelineContext = weakPipelineContext.Upgrade();
901         CHECK_NULL_VOID(pipelineContext);
902         auto overlayManager = pipelineContext->GetOverlayManager();
903         CHECK_NULL_VOID(overlayManager);
904         overlayManager->CloseDialog(dialogNode);
905     };
906     for (const auto& child : contentRow->GetChildren()) {
907         auto firstChild = AceType::DynamicCast<FrameNode>(child);
908         auto gesturHub = firstChild->GetOrCreateGestureEventHub();
909         auto onClick = AceType::MakeRefPtr<NG::ClickEvent>(event);
910         gesturHub->AddClickEvent(onClick);
911     }
912     contentRow->AddChild(CreateDividerNode(), 1);
913     return contentRow;
914 }
915 
UpdateOptionLayoutProps(const RefPtr<FrameNode> & contentRow,const RefPtr<PipelineContext> & pipelineContext)916 void CalendarDialogView::UpdateOptionLayoutProps(
917     const RefPtr<FrameNode>& contentRow, const RefPtr<PipelineContext>& pipelineContext)
918 {
919     auto layoutProps = contentRow->GetLayoutProperty<LinearLayoutProperty>();
920     CHECK_NULL_VOID(layoutProps);
921     RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
922     CHECK_NULL_VOID(theme);
923     layoutProps->UpdateMainAxisAlign(FlexAlign::SPACE_BETWEEN);
924     layoutProps->UpdateMeasureType(MeasureType::MATCH_PARENT_MAIN_AXIS);
925     MarginProperty margin;
926     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
927         margin.top = CalcLength(theme->GetCalendarActionRowTopPadding() - CALENDAR_DISTANCE_ADJUST_FOCUSED_EVENT);
928     } else {
929         margin.top = CalcLength(theme->GetCalendarActionRowTopPadding() + CALENDAR_DISTANCE_ADJUST_FOCUSED_EVENT);
930     }
931     margin.left = CalcLength(theme->GetCalendarActionRowBottomLeftRightPadding());
932     margin.right = CalcLength(theme->GetCalendarActionRowBottomLeftRightPadding());
933     margin.bottom = CalcLength(theme->GetCalendarTitleRowTopPadding() + CALENDAR_DISTANCE_ADJUST_FOCUSED_EVENT);
934     layoutProps->UpdateMargin(margin);
935     layoutProps->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(theme->GetCalendarActionRowHeight())));
936 }
937 
SetCalendarPaintProperties(const CalendarSettingData & settingData)938 void CalendarDialogView::SetCalendarPaintProperties(const CalendarSettingData& settingData)
939 {
940     auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck();
941     CHECK_NULL_VOID(pipelineContext);
942     RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
943     CHECK_NULL_VOID(theme);
944 
945     auto fontSizeScale = pipelineContext->GetFontScale();
946     Dimension defaultDayRadius;
947     auto fontSize = theme->GetCalendarDayFontSize();
948     if (fontSizeScale < theme->GetCalendarPickerLargeScale() || CheckOrientationChange()) {
949         ACE_UPDATE_PAINT_PROPERTY(CalendarPaintProperty, DayHeight, theme->GetCalendarPickerDayWidthOrHeight());
950         ACE_UPDATE_PAINT_PROPERTY(CalendarPaintProperty, DayWidth, theme->GetCalendarPickerDayWidthOrHeight());
951         ACE_UPDATE_PAINT_PROPERTY(CalendarPaintProperty, DayFontSize, fontSize);
952         ACE_UPDATE_PAINT_PROPERTY(CalendarPaintProperty, WeekHeight, theme->GetCalendarPickerDayWidthOrHeight());
953         ACE_UPDATE_PAINT_PROPERTY(CalendarPaintProperty, WeekWidth, theme->GetCalendarPickerDayWidthOrHeight());
954         ACE_UPDATE_PAINT_PROPERTY(CalendarPaintProperty, WeekFontSize, fontSize);
955         defaultDayRadius = theme->GetCalendarDayRadius();
956     } else {
957         fontSizeScale = fontSizeScale > theme->GetCalendarPickerLargerScale() ? theme->GetCalendarPickerLargerScale()
958                                                                               : fontSizeScale;
959         ACE_UPDATE_PAINT_PROPERTY(CalendarPaintProperty, DayHeight, theme->GetCalendarPickerDayLargeWidthOrHeight());
960         ACE_UPDATE_PAINT_PROPERTY(CalendarPaintProperty, DayWidth, theme->GetCalendarPickerDayLargeWidthOrHeight());
961         ACE_UPDATE_PAINT_PROPERTY(CalendarPaintProperty, DayFontSize, fontSize * fontSizeScale);
962         ACE_UPDATE_PAINT_PROPERTY(CalendarPaintProperty, WeekHeight, theme->GetCalendarPickerDayLargeWidthOrHeight());
963         ACE_UPDATE_PAINT_PROPERTY(CalendarPaintProperty, WeekWidth, theme->GetCalendarPickerDayLargeWidthOrHeight());
964         ACE_UPDATE_PAINT_PROPERTY(CalendarPaintProperty, WeekFontSize, fontSize * fontSizeScale);
965         defaultDayRadius = theme->GetCalendarPickerDayLargeWidthOrHeight() / 2;
966     }
967 
968     if (AceApplicationInfo::GetInstance().GetLanguage() != "zh") {
969         ACE_UPDATE_PAINT_PROPERTY(CalendarPaintProperty, WeekFontSize, theme->GetCalendarSmallDayFontSize());
970     }
971 
972     if (settingData.dayRadius.has_value() && NonNegative(settingData.dayRadius.value().ConvertToPx()) &&
973         LessOrEqual(settingData.dayRadius.value().ConvertToPx(), defaultDayRadius.ConvertToPx())) {
974         ACE_UPDATE_PAINT_PROPERTY(CalendarPaintProperty, DayRadius, settingData.dayRadius.value());
975     } else {
976         ACE_UPDATE_PAINT_PROPERTY(CalendarPaintProperty, DayRadius, defaultDayRadius);
977     }
978 }
979 
InitOnRequestDataEvent(const RefPtr<FrameNode> & calendarDialogNode,const RefPtr<FrameNode> & calendarNode)980 void CalendarDialogView::InitOnRequestDataEvent(
981     const RefPtr<FrameNode>& calendarDialogNode, const RefPtr<FrameNode>& calendarNode)
982 {
983     auto callback = [calendarDialogNodeWeak = WeakPtr<FrameNode>(calendarDialogNode),
984                     calendarNodeWeak = WeakPtr<FrameNode>(calendarNode)](const std::string& info) {
985         auto calendarNode = calendarNodeWeak.Upgrade();
986         CHECK_NULL_VOID(calendarNode);
987         auto calendarDialogNode = calendarDialogNodeWeak.Upgrade();
988         CHECK_NULL_VOID(calendarDialogNode);
989         auto jsonInfo = JsonUtil::ParseJsonString(info);
990         CalendarMonth currentMonth { .year = jsonInfo->GetInt("year"), .month = jsonInfo->GetInt("month") };
991         UpdateCalendarMonthData(calendarDialogNode, calendarNode, currentMonth);
992 
993         calendarNode->MarkModifyDone();
994         calendarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
995     };
996     auto eventHub = calendarNode->GetOrCreateEventHub<CalendarEventHub>();
997     CHECK_NULL_VOID(eventHub);
998     eventHub->SetOnRequestDataEvent(std::move(callback));
999 }
1000 
OnSelectedChangeEvent(int32_t calendarNodeId,const std::string & callbackInfo,const DialogEvent & onChange,const CalendarSettingData & settingData)1001 void CalendarDialogView::OnSelectedChangeEvent(int32_t calendarNodeId, const std::string& callbackInfo,
1002     const DialogEvent& onChange, const CalendarSettingData& settingData)
1003 {
1004     auto calendarNode = FrameNode::GetOrCreateFrameNode(
1005         V2::CALENDAR_ETS_TAG, calendarNodeId, []() { return AceType::MakeRefPtr<CalendarPattern>(); });
1006     CHECK_NULL_VOID(calendarNode);
1007     auto calendarPattern = calendarNode->GetPattern<CalendarPattern>();
1008     CHECK_NULL_VOID(calendarPattern);
1009     auto currentMonthData = calendarPattern->GetCurrentMonthData();
1010     auto jsonInfo = JsonUtil::ParseJsonString(callbackInfo);
1011     CalendarMonth selectedMonth { .year = jsonInfo->GetInt("year"), .month = jsonInfo->GetInt("month") };
1012     if (currentMonthData.year != selectedMonth.year || currentMonthData.month != selectedMonth.month) {
1013         return;
1014     }
1015 
1016     if (onChange) {
1017         onChange(callbackInfo);
1018     }
1019     PickerDate selectedDay(selectedMonth.year, selectedMonth.month, jsonInfo->GetInt("day"));
1020     calendarPattern->SetSelectedDay(selectedDay);
1021     calendarNode->MarkModifyDone();
1022 
1023     auto entryNode = settingData.entryNode.Upgrade();
1024     CHECK_NULL_VOID(entryNode);
1025     auto eventHub = entryNode->GetOrCreateEventHub<CalendarPickerEventHub>();
1026     CHECK_NULL_VOID(eventHub);
1027     eventHub->UpdateOnChangeEvent(callbackInfo);
1028 }
1029 
UpdateBackgroundStyle(const RefPtr<RenderContext> & renderContext,const DialogProperties & dialogProperties,const RefPtr<CalendarTheme> & calendarTheme,const RefPtr<FrameNode> & dialogNode)1030 void CalendarDialogView::UpdateBackgroundStyle(const RefPtr<RenderContext>& renderContext,
1031     const DialogProperties& dialogProperties, const RefPtr<CalendarTheme>& calendarTheme,
1032     const RefPtr<FrameNode>& dialogNode)
1033 {
1034     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN) && renderContext->IsUniRenderEnabled()) {
1035         CHECK_NULL_VOID(calendarTheme);
1036         auto contentRenderContext = dialogNode->GetRenderContext();
1037         CHECK_NULL_VOID(contentRenderContext);
1038         auto pipeLineContext = dialogNode->GetContext();
1039         CHECK_NULL_VOID(pipeLineContext);
1040         BlurStyleOption styleOption;
1041         if (dialogProperties.blurStyleOption.has_value()) {
1042             styleOption = dialogProperties.blurStyleOption.value();
1043             if (styleOption.policy == BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) {
1044                 pipeLineContext->AddWindowFocusChangedCallback(dialogNode->GetId());
1045             } else {
1046                 pipeLineContext->RemoveWindowFocusChangedCallback(dialogNode->GetId());
1047             }
1048         }
1049         styleOption.blurStyle = static_cast<BlurStyle>(
1050             dialogProperties.backgroundBlurStyle.value_or(calendarTheme->GetCalendarPickerDialogBlurStyle()));
1051         if (dialogProperties.blurStyleOption.has_value() && contentRenderContext->GetBackgroundEffect().has_value()) {
1052             contentRenderContext->UpdateBackgroundEffect(std::nullopt);
1053         }
1054         renderContext->UpdateBackBlurStyle(styleOption);
1055         if (dialogProperties.effectOption.has_value()) {
1056             if (dialogProperties.effectOption->policy == BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) {
1057                 pipeLineContext->AddWindowFocusChangedCallback(dialogNode->GetId());
1058             } else {
1059                 pipeLineContext->RemoveWindowFocusChangedCallback(dialogNode->GetId());
1060             }
1061             if (contentRenderContext->GetBackBlurStyle().has_value()) {
1062                 contentRenderContext->UpdateBackBlurStyle(std::nullopt);
1063             }
1064             // Clear and re-render to avoid previous impact, when using backgroundEffect
1065             contentRenderContext->UpdateBackgroundEffect(std::nullopt);
1066             contentRenderContext->UpdateBackgroundEffect(dialogProperties.effectOption.value());
1067         }
1068         // Clear and re-render to avoid previous impact
1069         // Because when policy is BlurStyleActivePolicy.ALWAYS_INACTIVE, the background color shows inactiveColor
1070         renderContext->ResetBackgroundColor();
1071         renderContext->UpdateBackgroundColor(dialogProperties.backgroundColor.value_or(Color::TRANSPARENT));
1072     }
1073 }
1074 
UpdateButtonDefaultFocus(const std::vector<ButtonInfo> & buttonInfos,const RefPtr<FrameNode> & buttonNode,bool isConfirm)1075 void CalendarDialogView::UpdateButtonDefaultFocus(const std::vector<ButtonInfo>& buttonInfos,
1076     const RefPtr<FrameNode>& buttonNode, bool isConfirm)
1077 {
1078     bool setDefaultFocus = false;
1079     if (buttonInfos.size() > CANCEL_BUTTON_INDEX) {
1080         if (buttonInfos[ACCEPT_BUTTON_INDEX].isPrimary && buttonInfos[CANCEL_BUTTON_INDEX].isPrimary) {
1081             return;
1082         }
1083         auto index = isConfirm ? ACCEPT_BUTTON_INDEX : CANCEL_BUTTON_INDEX;
1084         if (buttonInfos[index].isPrimary) {
1085             setDefaultFocus = true;
1086         }
1087     } else if (buttonInfos.size() == CANCEL_BUTTON_INDEX) {
1088         bool isAcceptButtonPrimary = (buttonInfos[0].isAcceptButton && isConfirm && buttonInfos[0].isPrimary);
1089         bool isCancelButtonPrimary = (!buttonInfos[0].isAcceptButton && !isConfirm && buttonInfos[0].isPrimary);
1090         if (isAcceptButtonPrimary || isCancelButtonPrimary) {
1091             setDefaultFocus = true;
1092         }
1093     }
1094     if (setDefaultFocus && buttonNode) {
1095         auto focusHub = buttonNode->GetOrCreateFocusHub();
1096         if (focusHub) {
1097             focusHub->SetIsDefaultFocus(true);
1098         }
1099     }
1100 }
1101 
UpdateDialogDefaultFocus(const RefPtr<FrameNode> & contentRow,const RefPtr<FrameNode> & contentColumn)1102 void CalendarDialogView::UpdateDialogDefaultFocus(const RefPtr<FrameNode>& contentRow,
1103     const RefPtr<FrameNode>& contentColumn)
1104 {
1105     auto contentRowFocusHub = contentRow->GetOrCreateFocusHub();
1106     CHECK_NULL_VOID(contentRowFocusHub);
1107     if (contentRowFocusHub->IsDefaultFocus()) {
1108         auto contentColumnFocusHub = contentColumn->GetOrCreateFocusHub();
1109         CHECK_NULL_VOID(contentColumnFocusHub);
1110         contentColumnFocusHub->SetIsDefaultFocus(true);
1111     }
1112 }
1113 
UpdateDefaultFocusByButtonInfo(const RefPtr<FrameNode> & optionsNode,const RefPtr<FrameNode> & accept,const RefPtr<FrameNode> & cancel)1114 void CalendarDialogView::UpdateDefaultFocusByButtonInfo(const RefPtr<FrameNode>& optionsNode,
1115     const RefPtr<FrameNode>& accept, const RefPtr<FrameNode>& cancel)
1116 {
1117     auto acceptFocusHub = accept->GetOrCreateFocusHub();
1118     CHECK_NULL_VOID(acceptFocusHub);
1119     auto cancelFocusHub = cancel->GetOrCreateFocusHub();
1120     CHECK_NULL_VOID(cancelFocusHub);
1121     if (acceptFocusHub->IsDefaultFocus() || cancelFocusHub->IsDefaultFocus()) {
1122         auto optionsNodeFocusHub = optionsNode->GetOrCreateFocusHub();
1123         CHECK_NULL_VOID(optionsNodeFocusHub);
1124         optionsNodeFocusHub->SetIsDefaultFocus(true);
1125     }
1126 }
1127 
UpdateIdealSize(const RefPtr<CalendarTheme> & calendarTheme,const RefPtr<LinearLayoutProperty> & layoutProps,const RefPtr<LayoutProperty> & calendarLayoutProperty,const RefPtr<FrameNode> & calendarNode)1128 void CalendarDialogView::UpdateIdealSize(const RefPtr<CalendarTheme>& calendarTheme,
1129     const RefPtr<LinearLayoutProperty>& layoutProps, const RefPtr<LayoutProperty>& calendarLayoutProperty,
1130     const RefPtr<FrameNode>& calendarNode)
1131 {
1132     SetTitleIdealSize(calendarTheme, layoutProps);
1133     auto swiperNode = calendarNode->GetChildren().front();
1134     CHECK_NULL_VOID(swiperNode);
1135     auto calendarMonthNode = swiperNode->GetChildAtIndex(CURRENT_MONTH_INDEX);
1136     CHECK_NULL_VOID(calendarMonthNode);
1137     auto calendarMonthFrameNode = AceType::DynamicCast<FrameNode>(calendarMonthNode);
1138     CHECK_NULL_VOID(calendarMonthFrameNode);
1139     auto calendarPaintProperty = calendarMonthFrameNode->GetPaintProperty<CalendarPaintProperty>();
1140     auto gregorianDayHeight = calendarPaintProperty->GetGregorianCalendarHeightValue({}).ConvertToPx() <= 0
1141                     ? calendarTheme->GetCalendarTheme().gregorianCalendarHeight
1142                     : calendarPaintProperty->GetGregorianCalendarHeightValue({});
1143     auto monthPattern = calendarMonthFrameNode->GetPattern<CalendarMonthPattern>();
1144     CHECK_NULL_VOID(monthPattern);
1145     if (monthPattern->IsLargeSize(calendarTheme)) {
1146         gregorianDayHeight = monthPattern->GetDaySize(calendarTheme);
1147     }
1148     SetCalendarIdealSize(calendarTheme, calendarLayoutProperty, gregorianDayHeight);
1149 }
1150 
UpdatePaintProperties(const RefPtr<FrameNode> & monthFrameNode,const CalendarSettingData & settingData)1151 void CalendarDialogView::UpdatePaintProperties(
1152     const RefPtr<FrameNode>& monthFrameNode, const CalendarSettingData& settingData)
1153 {
1154     auto pipelineContext = monthFrameNode->GetContext();
1155     CHECK_NULL_VOID(pipelineContext);
1156     RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
1157     CHECK_NULL_VOID(theme);
1158 
1159     auto fontSizeScale = pipelineContext->GetFontScale();
1160     Dimension defaultDayRadius;
1161     auto fontSize = theme->GetCalendarDayFontSize();
1162     if (fontSizeScale < theme->GetCalendarPickerLargeScale() || CheckOrientationChange()) {
1163         ACE_UPDATE_NODE_PAINT_PROPERTY(
1164             CalendarPaintProperty, DayHeight, theme->GetCalendarPickerDayWidthOrHeight(), monthFrameNode);
1165         ACE_UPDATE_NODE_PAINT_PROPERTY(
1166             CalendarPaintProperty, DayWidth, theme->GetCalendarPickerDayWidthOrHeight(), monthFrameNode);
1167         ACE_UPDATE_NODE_PAINT_PROPERTY(CalendarPaintProperty, DayFontSize, fontSize, monthFrameNode);
1168         ACE_UPDATE_NODE_PAINT_PROPERTY(
1169             CalendarPaintProperty, WeekHeight, theme->GetCalendarPickerDayWidthOrHeight(), monthFrameNode);
1170         ACE_UPDATE_NODE_PAINT_PROPERTY(
1171             CalendarPaintProperty, WeekWidth, theme->GetCalendarPickerDayWidthOrHeight(), monthFrameNode);
1172         ACE_UPDATE_NODE_PAINT_PROPERTY(CalendarPaintProperty, WeekFontSize, fontSize, monthFrameNode);
1173         defaultDayRadius = theme->GetCalendarDayRadius();
1174     } else {
1175         fontSizeScale = fontSizeScale > theme->GetCalendarPickerLargerScale() ? theme->GetCalendarPickerLargerScale()
1176                                                                               : fontSizeScale;
1177         ACE_UPDATE_NODE_PAINT_PROPERTY(
1178             CalendarPaintProperty, DayHeight, theme->GetCalendarPickerDayLargeWidthOrHeight(), monthFrameNode);
1179         ACE_UPDATE_NODE_PAINT_PROPERTY(
1180             CalendarPaintProperty, DayWidth, theme->GetCalendarPickerDayLargeWidthOrHeight(), monthFrameNode);
1181         ACE_UPDATE_NODE_PAINT_PROPERTY(CalendarPaintProperty, DayFontSize, fontSize * fontSizeScale, monthFrameNode);
1182         ACE_UPDATE_NODE_PAINT_PROPERTY(
1183             CalendarPaintProperty, WeekHeight, theme->GetCalendarPickerDayLargeWidthOrHeight(), monthFrameNode);
1184         ACE_UPDATE_NODE_PAINT_PROPERTY(
1185             CalendarPaintProperty, WeekWidth, theme->GetCalendarPickerDayLargeWidthOrHeight(), monthFrameNode);
1186         ACE_UPDATE_NODE_PAINT_PROPERTY(CalendarPaintProperty, WeekFontSize, fontSize * fontSizeScale, monthFrameNode);
1187         defaultDayRadius = theme->GetCalendarPickerDayLargeWidthOrHeight() / 2;
1188     }
1189 
1190     if (AceApplicationInfo::GetInstance().GetLanguage() != "zh") {
1191         ACE_UPDATE_NODE_PAINT_PROPERTY(
1192             CalendarPaintProperty, WeekFontSize, theme->GetCalendarSmallDayFontSize(), monthFrameNode);
1193     }
1194 
1195     if (settingData.dayRadius.has_value() && NonNegative(settingData.dayRadius.value().ConvertToPx()) &&
1196         LessOrEqual(settingData.dayRadius.value().ConvertToPx(), defaultDayRadius.ConvertToPx())) {
1197         ACE_UPDATE_NODE_PAINT_PROPERTY(CalendarPaintProperty, DayRadius, settingData.dayRadius.value(), monthFrameNode);
1198     } else {
1199         ACE_UPDATE_NODE_PAINT_PROPERTY(CalendarPaintProperty, DayRadius, defaultDayRadius, monthFrameNode);
1200     }
1201 }
1202 
UpdateButtons(const RefPtr<FrameNode> & buttonNode,size_t buttonIndex,std::vector<ButtonInfo> & buttonInfos)1203 void CalendarDialogView::UpdateButtons(
1204     const RefPtr<FrameNode>& buttonNode, size_t buttonIndex, std::vector<ButtonInfo>& buttonInfos)
1205 {
1206     auto pipelineContext = buttonNode->GetContextRefPtr();
1207     CHECK_NULL_VOID(pipelineContext);
1208     auto calendarTheme = pipelineContext->GetTheme<CalendarTheme>();
1209     CHECK_NULL_VOID(calendarTheme);
1210     auto pickerTheme = pipelineContext->GetTheme<PickerTheme>();
1211     CHECK_NULL_VOID(pickerTheme);
1212     auto textNode = AceType::DynamicCast<FrameNode>(buttonNode->GetFirstChild());
1213     CHECK_NULL_VOID(textNode);
1214     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
1215     CHECK_NULL_VOID(textLayoutProperty);
1216     auto fontSizeScale = pipelineContext->GetFontScale();
1217     auto fontSize = pickerTheme->GetOptionStyle(false, false).GetFontSize();
1218     if (fontSizeScale < calendarTheme->GetCalendarPickerLargeScale() || CheckOrientationChange()) {
1219         textLayoutProperty->UpdateFontSize(fontSize);
1220     } else {
1221         fontSizeScale = fontSizeScale > calendarTheme->GetCalendarPickerLargeScale()
1222                             ? calendarTheme->GetCalendarPickerLargeScale()
1223                             : fontSizeScale;
1224         textLayoutProperty->UpdateFontSize(fontSize * fontSizeScale);
1225     }
1226 
1227     CalendarDialogView::UpdateButtonLayoutProperty(buttonNode, buttonIndex, buttonInfos, pipelineContext);
1228     auto buttonLayoutProperty = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
1229     CHECK_NULL_VOID(buttonLayoutProperty);
1230     CalendarDialogView::UpdateButtonStyles(
1231         buttonInfos, buttonIndex, buttonLayoutProperty, buttonNode->GetRenderContext());
1232     buttonNode->MarkModifyDone();
1233 }
1234 
GetChangeEvent(const CalendarSettingData & settingData,const RefPtr<FrameNode> & frameNode,const std::map<std::string,NG::DialogEvent> & dialogEvent)1235 DialogEvent CalendarDialogView::GetChangeEvent(const CalendarSettingData& settingData,
1236     const RefPtr<FrameNode>& frameNode, const std::map<std::string, NG::DialogEvent>& dialogEvent)
1237 {
1238     auto changeIter = dialogEvent.find("changeId");
1239     DialogEvent changeEvent = changeIter == dialogEvent.end() ? nullptr : changeIter->second;
1240     CHECK_NULL_RETURN(!settingData.entryNode.Upgrade(), changeEvent);
1241     changeEvent = [weak = WeakPtr<FrameNode>(frameNode), changeEvent](const std::string& info) -> void {
1242         ReportChangeEvent(weak.Upgrade(), "CalendarPickerDialog", "onChange", info);
1243         CHECK_NULL_VOID(changeEvent);
1244         changeEvent(info);
1245     };
1246     return changeEvent;
1247 }
1248 
CanReportChangeEvent(PickerDate & pickerDate,const PickerDate & newPickerDate)1249 bool CalendarDialogView::CanReportChangeEvent(PickerDate& pickerDate, const PickerDate& newPickerDate)
1250 {
1251     auto year = newPickerDate.GetYear();
1252     auto month = newPickerDate.GetMonth();
1253     auto day = newPickerDate.GetDay();
1254     if ((pickerDate.GetYear() == year) && (pickerDate.GetMonth() == month) && (pickerDate.GetDay() == day)) {
1255         return false;
1256     }
1257     pickerDate.SetYear(year);
1258     pickerDate.SetMonth(month);
1259     pickerDate.SetDay(day);
1260     return true;
1261 }
1262 
GetReportChangeEventDate(PickerDate & pickerDate,const std::string & eventData)1263 bool CalendarDialogView::GetReportChangeEventDate(PickerDate& pickerDate, const std::string& eventData)
1264 {
1265     auto dataJson = JsonUtil::ParseJsonString(eventData);
1266     CHECK_NULL_RETURN(dataJson, false);
1267     pickerDate.SetYear(dataJson->GetUInt("year"));
1268     pickerDate.SetMonth(dataJson->GetUInt("month"));
1269     pickerDate.SetDay(dataJson->GetUInt("day"));
1270     return true;
1271 }
1272 
ReportChangeEvent(const RefPtr<FrameNode> & frameNode,const std::string & compName,const std::string & eventName,const std::string & eventData)1273 bool CalendarDialogView::ReportChangeEvent(const RefPtr<FrameNode>& frameNode, const std::string& compName,
1274     const std::string& eventName, const std::string& eventData)
1275 {
1276     CHECK_NULL_RETURN(frameNode, false);
1277     auto wrapperNode = frameNode->GetParent();
1278     CHECK_NULL_RETURN(wrapperNode, false);
1279     auto dialogNode = wrapperNode->GetParent();
1280     CHECK_NULL_RETURN(dialogNode, false);
1281     auto pattern = frameNode->GetPattern<CalendarDialogPattern>();
1282     CHECK_NULL_RETURN(pattern, false);
1283     PickerDate pickerDate;
1284     CHECK_NULL_RETURN(GetReportChangeEventDate(pickerDate, eventData), false);
1285     CHECK_NULL_RETURN(pattern->CanReportChangeEvent(pickerDate), false);
1286     return ReportChangeEvent(dialogNode->GetId(), compName, eventName, pickerDate);
1287 }
1288 
ReportChangeEvent(int32_t nodeId,const std::string & compName,const std::string & eventName,const PickerDate & pickerDate)1289 bool CalendarDialogView::ReportChangeEvent(int32_t nodeId, const std::string& compName,
1290     const std::string& eventName, const PickerDate& pickerDate)
1291 {
1292     auto params = JsonUtil::Create();
1293     CHECK_NULL_RETURN(params, false);
1294     params->Put("year", static_cast<int32_t>(pickerDate.GetYear()));
1295     params->Put("month", static_cast<int32_t>(pickerDate.GetMonth()));
1296     params->Put("day", static_cast<int32_t>(pickerDate.GetDay()));
1297     auto value = JsonUtil::Create();
1298     CHECK_NULL_RETURN(value, false);
1299     value->Put("nodeId", nodeId);
1300     value->Put(compName.c_str(), eventName.c_str());
1301     value->Put("params", params);
1302     UiSessionManager::GetInstance()->ReportComponentChangeEvent("event", value->ToString());
1303     return true;
1304 }
1305 
UpdateTextLayoutProperty(const RefPtr<TextLayoutProperty> & textLayoutProperty,RefPtr<CalendarTheme> & theme)1306 void CalendarDialogView::UpdateTextLayoutProperty(const RefPtr<TextLayoutProperty>& textLayoutProperty,
1307     RefPtr<CalendarTheme>& theme)
1308 {
1309     textLayoutProperty->UpdateContent(u"");
1310     MarginProperty textMargin;
1311     textMargin.left = CalcLength(theme->GetCalendarTitleTextPadding());
1312     textMargin.right = CalcLength(theme->GetCalendarTitleTextPadding());
1313     textLayoutProperty->UpdateMargin(textMargin);
1314     textLayoutProperty->UpdateFontSize(theme->GetCalendarTitleFontSize());
1315     textLayoutProperty->UpdateTextColor(theme->GetCalendarTitleFontColor());
1316     textLayoutProperty->UpdateFontWeight(FontWeight::MEDIUM);
1317     textLayoutProperty->UpdateMaxLines(1);
1318     textLayoutProperty->UpdateLayoutWeight(1);
1319     textLayoutProperty->UpdateTextAlign(TextAlign::CENTER);
1320 }
1321 } // namespace OHOS::Ace::NG
1322