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