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