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