1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "frameworks/bridge/declarative_frontend/jsview/js_calendar_picker.h"
17
18 #include "base/log/ace_scoring_log.h"
19 #include "base/utils/date_util.h"
20 #include "bridge/common/utils/engine_helper.h"
21 #include "bridge/declarative_frontend/engine/functions/js_function.h"
22 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
23 #include "bridge/declarative_frontend/jsview/js_utils.h"
24 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
25 #include "bridge/declarative_frontend/jsview/models/calendar_picker_model_impl.h"
26 #include "core/components/calendar/calendar_theme.h"
27 #include "core/components/dialog/dialog_theme.h"
28 #include "core/components_ng/base/view_abstract_model.h"
29 #include "core/components_ng/base/view_stack_processor.h"
30 #include "core/components_ng/pattern/calendar_picker/calendar_picker_model_ng.h"
31 #include "core/pipeline_ng/pipeline_context.h"
32 #include "core/common/resource/resource_object.h"
33 #include "core/common/resource/resource_parse_utils.h"
34
35 namespace OHOS::Ace {
36 std::unique_ptr<CalendarPickerModel> CalendarPickerModel::instance_ = nullptr;
37 std::once_flag CalendarPickerModel::onceFlag_;
38
GetInstance()39 CalendarPickerModel* CalendarPickerModel::GetInstance()
40 {
41 std::call_once(onceFlag_, []() {
42 #ifdef NG_BUILD
43 instance_.reset(new NG::CalendarPickerModelNG());
44 #else
45 if (Container::IsCurrentUseNewPipeline()) {
46 instance_.reset(new NG::CalendarPickerModelNG());
47 } else {
48 instance_.reset(new Framework::CalendarPickerModelImpl());
49 }
50 #endif
51 });
52
53 return instance_.get();
54 }
55 } // namespace OHOS::Ace
56
57 namespace OHOS::Ace::Framework {
58 namespace {
ParseFontOfButtonStyle(const JSRef<JSObject> & pickerButtonParamObject,ButtonInfo & buttonInfo)59 void ParseFontOfButtonStyle(const JSRef<JSObject>& pickerButtonParamObject, ButtonInfo& buttonInfo)
60 {
61 CalcDimension fontSize;
62 JSRef<JSVal> sizeProperty = pickerButtonParamObject->GetProperty("fontSize");
63 if (JSViewAbstract::ParseJsDimensionVpNG(sizeProperty, fontSize) && fontSize.Unit() != DimensionUnit::PERCENT &&
64 GreatOrEqual(fontSize.Value(), 0.0)) {
65 if (JSViewAbstract::ParseJsDimensionFp(sizeProperty, fontSize)) {
66 buttonInfo.fontSize = fontSize;
67 }
68 }
69 Color fontColor;
70 if (JSViewAbstract::ParseJsColor(pickerButtonParamObject->GetProperty("fontColor"), fontColor)) {
71 buttonInfo.fontColor = fontColor;
72 }
73 auto fontWeight = pickerButtonParamObject->GetProperty("fontWeight");
74 if (fontWeight->IsString() || fontWeight->IsNumber()) {
75 buttonInfo.fontWeight = ConvertStrToFontWeight(fontWeight->ToString(), FontWeight::MEDIUM);
76 }
77 JSRef<JSVal> style = pickerButtonParamObject->GetProperty("fontStyle");
78 if (style->IsNumber()) {
79 auto value = style->ToNumber<int32_t>();
80 if (value >= 0 && value < static_cast<int32_t>(FontStyle::NONE)) {
81 buttonInfo.fontStyle = static_cast<FontStyle>(value);
82 }
83 }
84 JSRef<JSVal> family = pickerButtonParamObject->GetProperty("fontFamily");
85 std::vector<std::string> fontFamilies;
86 if (JSViewAbstract::ParseJsFontFamilies(family, fontFamilies)) {
87 buttonInfo.fontFamily = fontFamilies;
88 }
89 }
90
ParseButtonStyle(const JSRef<JSObject> & pickerButtonParamObject)91 ButtonInfo ParseButtonStyle(const JSRef<JSObject>& pickerButtonParamObject)
92 {
93 ButtonInfo buttonInfo;
94 if (pickerButtonParamObject->GetProperty("type")->IsNumber()) {
95 auto buttonTypeIntValue = pickerButtonParamObject->GetProperty("type")->ToNumber<int32_t>();
96 if (buttonTypeIntValue == static_cast<int32_t>(ButtonType::CAPSULE) ||
97 buttonTypeIntValue == static_cast<int32_t>(ButtonType::CIRCLE) ||
98 buttonTypeIntValue == static_cast<int32_t>(ButtonType::ARC) ||
99 buttonTypeIntValue == static_cast<int32_t>(ButtonType::NORMAL) ||
100 buttonTypeIntValue == static_cast<int32_t>(ButtonType::ROUNDED_RECTANGLE)) {
101 buttonInfo.type = static_cast<ButtonType>(buttonTypeIntValue);
102 }
103 }
104 if (pickerButtonParamObject->GetProperty("style")->IsNumber()) {
105 auto styleModeIntValue = pickerButtonParamObject->GetProperty("style")->ToNumber<int32_t>();
106 if (styleModeIntValue >= static_cast<int32_t>(ButtonStyleMode::NORMAL) &&
107 styleModeIntValue <= static_cast<int32_t>(ButtonStyleMode::TEXT)) {
108 buttonInfo.buttonStyle = static_cast<ButtonStyleMode>(styleModeIntValue);
109 }
110 }
111 if (pickerButtonParamObject->GetProperty("role")->IsNumber()) {
112 auto buttonRoleIntValue = pickerButtonParamObject->GetProperty("role")->ToNumber<int32_t>();
113 if (buttonRoleIntValue >= static_cast<int32_t>(ButtonRole::NORMAL) &&
114 buttonRoleIntValue <= static_cast<int32_t>(ButtonRole::ERROR)) {
115 buttonInfo.role = static_cast<ButtonRole>(buttonRoleIntValue);
116 }
117 }
118 ParseFontOfButtonStyle(pickerButtonParamObject, buttonInfo);
119 Color backgroundColor;
120 if (JSViewAbstract::ParseJsColor(pickerButtonParamObject->GetProperty("backgroundColor"), backgroundColor)) {
121 buttonInfo.backgroundColor = backgroundColor;
122 }
123 auto radius = ParseBorderRadiusAttr(pickerButtonParamObject->GetProperty("borderRadius"));
124 if (radius.has_value()) {
125 buttonInfo.borderRadius = radius.value();
126 }
127
128 auto primaryValue = pickerButtonParamObject->GetProperty("primary");
129 if (primaryValue->IsBoolean()) {
130 buttonInfo.isPrimary = primaryValue->ToBoolean();
131 }
132
133 return buttonInfo;
134 }
135
ParseButtonStyles(const JSRef<JSObject> & paramObject)136 std::vector<ButtonInfo> ParseButtonStyles(const JSRef<JSObject>& paramObject)
137 {
138 std::vector<ButtonInfo> buttonInfos;
139 auto acceptButtonStyle = paramObject->GetProperty("acceptButtonStyle");
140 if (acceptButtonStyle->IsObject()) {
141 auto acceptButtonStyleParamObject = JSRef<JSObject>::Cast(acceptButtonStyle);
142 buttonInfos.emplace_back(ParseButtonStyle(acceptButtonStyleParamObject));
143 buttonInfos[0].isAcceptButton = true;
144 } else {
145 ButtonInfo buttonInfo;
146 buttonInfos.emplace_back(buttonInfo);
147 }
148 auto cancelButtonStyle = paramObject->GetProperty("cancelButtonStyle");
149 if (cancelButtonStyle->IsObject()) {
150 auto cancelButtonStyleParamObject = JSRef<JSObject>::Cast(cancelButtonStyle);
151 buttonInfos.emplace_back(ParseButtonStyle(cancelButtonStyleParamObject));
152 }
153
154 return buttonInfos;
155 }
156 } // namespace
157
GetMSByDate(const std::string & date)158 double GetMSByDate(const std::string& date)
159 {
160 auto json = JsonUtil::ParseJsonString(date);
161 if (!json || json->IsNull()) {
162 return 0.0f;
163 }
164
165 std::tm dateTime {};
166 auto year = json->GetValue("year");
167 if (year && year->IsNumber()) {
168 dateTime.tm_year = year->GetInt() - 1900; // local date start from 1900
169 }
170 auto month = json->GetValue("month");
171 if (month && month->IsNumber()) {
172 dateTime.tm_mon = month->GetInt() - 1;
173 }
174 auto day = json->GetValue("day");
175 if (day && day->IsNumber()) {
176 dateTime.tm_mday = day->GetInt();
177 }
178 auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
179 auto local = std::localtime(&now);
180 CHECK_NULL_RETURN(local, 0.0f);
181 dateTime.tm_hour = local->tm_hour;
182 dateTime.tm_min = local->tm_min;
183 dateTime.tm_sec = local->tm_sec;
184 return Date::GetMilliSecondsByDateTime(dateTime);
185 }
186
JSBind(BindingTarget globalObj)187 void JSCalendarPicker::JSBind(BindingTarget globalObj)
188 {
189 JSClass<JSCalendarPicker>::Declare("CalendarPicker");
190 JSClass<JSCalendarPicker>::StaticMethod("create", &JSCalendarPicker::Create, MethodOptions::NONE);
191 JSClass<JSCalendarPicker>::StaticMethod("edgeAlign", &JSCalendarPicker::SetEdgeAlign);
192 JSClass<JSCalendarPicker>::StaticMethod("textStyle", &JSCalendarPicker::SetTextStyle);
193 JSClass<JSCalendarPicker>::StaticMethod("onChange", &JSCalendarPicker::SetOnChange);
194 JSClass<JSCalendarPicker>::StaticMethod("border", &JSCalendarPicker::SetBorder);
195 JSClass<JSCalendarPicker>::StaticMethod("padding", &JSCalendarPicker::JsPadding);
196 JSClass<JSCalendarPicker>::StaticMethod("height", &JSCalendarPicker::JsHeight);
197 JSClass<JSCalendarPicker>::StaticMethod("borderColor", &JSCalendarPicker::JsBorderColor);
198 JSClass<JSCalendarPicker>::StaticMethod("borderRadius", &JSCalendarPicker::JsBorderRadius);
199 JSClass<JSCalendarPicker>::StaticMethod("markToday", &JSCalendarPicker::JsMarkToday);
200 JSClass<JSCalendarPicker>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
201 JSClass<JSCalendarPicker>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
202 JSClass<JSCalendarPicker>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
203 JSClass<JSCalendarPicker>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
204 JSClass<JSCalendarPicker>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
205 JSClass<JSCalendarPicker>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
206 JSClass<JSCalendarPicker>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
207 JSClass<JSCalendarPicker>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
208 JSClass<JSCalendarPicker>::InheritAndBind<JSViewAbstract>(globalObj);
209 }
210
SetBorder(const JSCallbackInfo & info)211 void JSCalendarPicker::SetBorder(const JSCallbackInfo& info)
212 {
213 if (!info[0]->IsObject()) {
214 CalendarPickerModel::GetInstance()->ClearBorder();
215 return;
216 }
217 JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
218 auto valueWidth = object->GetProperty("width");
219 CalcDimension value;
220 if (ParseJsDimensionVpNG(valueWidth, value) || valueWidth->IsObject()) {
221 ParseBorderWidth(valueWidth);
222 } else {
223 CalendarPickerModel::GetInstance()->ClearBorderWidth();
224 }
225
226 // use default value when undefined.
227 ParseCalendarPickerBorderColor(object->GetProperty("color"));
228
229 auto valueRadius = object->GetProperty("radius");
230 if (!valueRadius->IsUndefined()) {
231 ParseBorderRadius(valueRadius);
232 }
233 // use default value when undefined.
234 ParseBorderStyle(object->GetProperty("style"));
235
236 info.ReturnSelf();
237 }
238
ParseCalendarPickerBorderColor(const JSRef<JSVal> & args)239 void JSCalendarPicker::ParseCalendarPickerBorderColor(const JSRef<JSVal>& args)
240 {
241 auto pipelineContext = PipelineContext::GetCurrentContext();
242 CHECK_NULL_VOID(pipelineContext);
243 RefPtr<CalendarTheme> theme = pipelineContext->GetTheme<CalendarTheme>();
244 CHECK_NULL_VOID(theme);
245 if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
246 ViewAbstractModel::GetInstance()->SetBorderColor(theme->GetEntryBorderColor());
247 } else {
248 JSViewAbstract::ParseBorderColor(args);
249 }
250 }
251
SetEdgeAlign(const JSCallbackInfo & info)252 void JSCalendarPicker::SetEdgeAlign(const JSCallbackInfo& info)
253 {
254 NG::CalendarEdgeAlign alignType = NG::CalendarEdgeAlign::EDGE_ALIGN_END;
255 DimensionOffset offset;
256 if (info[0]->IsNumber()) {
257 alignType = static_cast<NG::CalendarEdgeAlign>(info[0]->ToNumber<int32_t>());
258 }
259
260 if (!info[1]->IsObject()) {
261 CalendarPickerModel::GetInstance()->SetEdgeAlign(alignType, offset);
262 return;
263 }
264 auto offsetObj = JSRef<JSObject>::Cast(info[1]);
265 auto dxValue = offsetObj->GetProperty("dx");
266 auto dyValue = offsetObj->GetProperty("dy");
267
268 CalcDimension dx;
269 CalcDimension dy;
270
271 if (SystemProperties::ConfigChangePerform()) {
272 RefPtr<ResourceObject> dxResObj;
273 RefPtr<ResourceObject> dyResObj;
274 ParseJsDimensionVp(dxValue, dx, dxResObj);
275 ParseJsDimensionVp(dyValue, dy, dyResObj);
276 offset = DimensionOffset(dx, dy);
277
278 if (dxResObj || dyResObj) {
279 std::vector<RefPtr<ResourceObject>> resArray = { dxResObj, dyResObj };
280 CalendarPickerModel::GetInstance()->ParseEdgeAlignResObj(resArray);
281 } else {
282 CalendarPickerModel::GetInstance()->CalendarPickerRemoveResObj("CalendarPicker.EdgeAlign");
283 }
284 } else {
285 ParseJsDimensionVp(dxValue, dx);
286 ParseJsDimensionVp(dyValue, dy);
287 offset = DimensionOffset(dx, dy);
288 }
289
290 CalendarPickerModel::GetInstance()->SetEdgeAlign(alignType, offset);
291 }
292
SetTextStyle(const JSCallbackInfo & info)293 void JSCalendarPicker::SetTextStyle(const JSCallbackInfo& info)
294 {
295 auto pipeline = PipelineBase::GetCurrentContext();
296 CHECK_NULL_VOID(pipeline);
297 RefPtr<CalendarTheme> calendarTheme = pipeline->GetTheme<CalendarTheme>();
298 CHECK_NULL_VOID(calendarTheme);
299 NG::PickerTextStyle textStyle;
300 textStyle.fontSize = calendarTheme->GetEntryFontSize();
301 textStyle.textColor = calendarTheme->GetEntryFontColor();
302 textStyle.fontWeight = FontWeight::NORMAL;
303 if (info[0]->IsObject()) {
304 JSCalendarPicker::ParseTextStyle(info[0], textStyle);
305 }
306 CalendarPickerModel::GetInstance()->SetTextStyle(textStyle);
307 }
308
SetOnChange(const JSCallbackInfo & info)309 void JSCalendarPicker::SetOnChange(const JSCallbackInfo& info)
310 {
311 if (!info[0]->IsFunction()) {
312 return;
313 }
314
315 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
316 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
317 auto onChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
318 const std::string& info) {
319 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
320 ACE_SCORING_EVENT("CalendarPicker.onChange");
321 PipelineContext::SetCallBackNode(node);
322 auto dateObj = JSDate::New(GetMSByDate(info));
323 func->ExecuteJS(1, &dateObj);
324 };
325 CalendarPickerModel::GetInstance()->SetOnChange(std::move(onChange));
326 }
327
JsPadding(const JSCallbackInfo & info)328 void JSCalendarPicker::JsPadding(const JSCallbackInfo& info)
329 {
330 NG::PaddingProperty padding;
331 if (info[0]->IsObject()) {
332 CommonCalcDimension commonCalcDimension;
333 JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(info[0]);
334 JSViewAbstract::ParseCommonMarginOrPaddingCorner(paddingObj, commonCalcDimension);
335 if (commonCalcDimension.left.has_value() || commonCalcDimension.right.has_value() ||
336 commonCalcDimension.top.has_value() || commonCalcDimension.bottom.has_value()) {
337 padding = SetPaddings(commonCalcDimension.top, commonCalcDimension.bottom, commonCalcDimension.left,
338 commonCalcDimension.right);
339 CalendarPickerModel::GetInstance()->SetPadding(padding);
340 return;
341 }
342 }
343
344 CalcDimension length(-1);
345 if (ParseJsDimensionVpNG(info[0], length) && length.IsNonNegative()) {
346 padding.SetEdges(NG::CalcLength(length));
347 CalendarPickerModel::GetInstance()->SetPadding(padding);
348 } else {
349 CalendarPickerModel::GetInstance()->ClearPadding();
350 }
351 }
352
JsHeight(const JSCallbackInfo & info)353 void JSCalendarPicker::JsHeight(const JSCallbackInfo& info)
354 {
355 auto jsValue = info[0];
356 CalcDimension value;
357 if (ParseJsDimensionVpNG(jsValue, value) && value.IsValid()) {
358 JSViewAbstract::JsHeight(info);
359 return;
360 }
361
362 LayoutCalPolicy policy = LayoutCalPolicy::NO_MATCH;
363 if (jsValue->IsObject()) {
364 JSRef<JSObject> object = JSRef<JSObject>::Cast(jsValue);
365 CHECK_NULL_VOID(!object->IsEmpty());
366 JSRef<JSVal> layoutPolicy = object->GetProperty("id_");
367 CHECK_NULL_VOID(!layoutPolicy->IsEmpty());
368 if (layoutPolicy->IsString()) {
369 policy = ParseLayoutPolicy(layoutPolicy->ToString());
370 }
371 }
372 ViewAbstractModel::GetInstance()->UpdateLayoutPolicyProperty(policy, false);
373 CalendarPickerModel::GetInstance()->ClearHeight();
374 }
375
JsBorderColor(const JSCallbackInfo & info)376 void JSCalendarPicker::JsBorderColor(const JSCallbackInfo& info)
377 {
378 Color borderColor;
379 auto jsValue = info[0];
380 if (ParseJsColor(jsValue, borderColor) || jsValue->IsObject()) {
381 JSViewAbstract::JsBorderColor(info);
382 } else {
383 CalendarPickerModel::GetInstance()->ClearBorderColor();
384 }
385 }
386
JsBorderRadius(const JSCallbackInfo & info)387 void JSCalendarPicker::JsBorderRadius(const JSCallbackInfo& info)
388 {
389 auto jsValue = info[0];
390 CalcDimension value;
391 if (ParseJsDimensionVpNG(jsValue, value) || jsValue->IsObject()) {
392 JSViewAbstract::JsBorderRadius(info);
393 } else {
394 CalendarPickerModel::GetInstance()->ClearBorderRadius();
395 }
396 }
397
SetPaddings(const std::optional<CalcDimension> & top,const std::optional<CalcDimension> & bottom,const std::optional<CalcDimension> & left,const std::optional<CalcDimension> & right)398 NG::PaddingProperty JSCalendarPicker::SetPaddings(const std::optional<CalcDimension>& top,
399 const std::optional<CalcDimension>& bottom, const std::optional<CalcDimension>& left,
400 const std::optional<CalcDimension>& right)
401 {
402 NG::PaddingProperty paddings;
403 if (top.has_value()) {
404 if (top.value().Unit() == DimensionUnit::CALC) {
405 paddings.top =
406 NG::CalcLength(top.value().IsNonNegative() ? top.value().CalcValue() : CalcDimension().CalcValue());
407 } else {
408 paddings.top = NG::CalcLength(top.value().IsNonNegative() ? top.value() : CalcDimension());
409 }
410 }
411 if (bottom.has_value()) {
412 if (bottom.value().Unit() == DimensionUnit::CALC) {
413 paddings.bottom = NG::CalcLength(
414 bottom.value().IsNonNegative() ? bottom.value().CalcValue() : CalcDimension().CalcValue());
415 } else {
416 paddings.bottom = NG::CalcLength(bottom.value().IsNonNegative() ? bottom.value() : CalcDimension());
417 }
418 }
419 if (left.has_value()) {
420 if (left.value().Unit() == DimensionUnit::CALC) {
421 paddings.left =
422 NG::CalcLength(left.value().IsNonNegative() ? left.value().CalcValue() : CalcDimension().CalcValue());
423 } else {
424 paddings.left = NG::CalcLength(left.value().IsNonNegative() ? left.value() : CalcDimension());
425 }
426 }
427 if (right.has_value()) {
428 if (right.value().Unit() == DimensionUnit::CALC) {
429 paddings.right =
430 NG::CalcLength(right.value().IsNonNegative() ? right.value().CalcValue() : CalcDimension().CalcValue());
431 } else {
432 paddings.right = NG::CalcLength(right.value().IsNonNegative() ? right.value() : CalcDimension());
433 }
434 }
435
436 return paddings;
437 }
438
ParseSelectedDateObject(const JSCallbackInfo & info,const JSRef<JSObject> & selectedObject)439 void JSCalendarPicker::ParseSelectedDateObject(const JSCallbackInfo& info, const JSRef<JSObject>& selectedObject)
440 {
441 JSRef<JSVal> changeEventVal = selectedObject->GetProperty("changeEvent");
442 if (!changeEventVal->IsFunction()) {
443 return;
444 }
445 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
446 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
447 auto changeEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
448 const std::string& info) {
449 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
450 ACE_SCORING_EVENT("DatePicker.SelectedDateTimeChangeEvent");
451 PipelineContext::SetCallBackNode(node);
452 auto dateObj = JSDate::New(GetMSByDate(info));
453 func->ExecuteJS(1, &dateObj);
454 };
455 CalendarPickerModel::GetInstance()->SetChangeEvent(std::move(changeEvent));
456 }
457
ParseDisabledDateRange(const JSRef<JSVal> & disabledDateRangeVal,NG::CalendarSettingData & settingData)458 void JSCalendarPicker::ParseDisabledDateRange(
459 const JSRef<JSVal>& disabledDateRangeVal, NG::CalendarSettingData& settingData)
460 {
461 if (disabledDateRangeVal->IsUndefined() || disabledDateRangeVal->IsNull() || !disabledDateRangeVal->IsArray()) {
462 return;
463 }
464
465 JSRef<JSArray> array = JSRef<JSArray>::Cast(disabledDateRangeVal);
466 for (size_t i = 0; i < array->Length(); i++) {
467 JSRef<JSVal> dateRangeValue = array->GetValueAt(i);
468 if (!dateRangeValue->IsObject()) {
469 continue;
470 }
471 auto dateRangeObj = JSRef<JSObject>::Cast(dateRangeValue);
472 auto startValue = dateRangeObj->GetProperty("start");
473 auto endValue = dateRangeObj->GetProperty("end");
474 if (startValue->IsObject() && endValue->IsObject()) {
475 auto startDate = ParseDate(startValue, false);
476 auto endDate = ParseDate(endValue, false);
477 if (startDate.GetYear() == 0 || endDate.GetYear() == 0 || endDate < startDate) {
478 continue;
479 }
480 std::pair<PickerDate, PickerDate> pickerDateRange;
481 pickerDateRange.first = startDate;
482 pickerDateRange.second = endDate;
483 settingData.disabledDateRange.emplace_back(pickerDateRange);
484 }
485 }
486 }
487
ParseHintRadius(JSRef<JSObject> & obj,NG::CalendarSettingData & settingData,CalcDimension & dayRadius)488 void JSCalendarPicker::ParseHintRadius(JSRef<JSObject>& obj, NG::CalendarSettingData& settingData,
489 CalcDimension& dayRadius)
490 {
491 RefPtr<CalendarTheme> calendarTheme = GetTheme<CalendarTheme>();
492 CHECK_NULL_VOID(calendarTheme);
493 if (SystemProperties::ConfigChangePerform()) {
494 RefPtr<ResourceObject> hintRadiusResObj;
495 if (!ParseJsDimensionVpNG(obj->GetProperty("hintRadius"), dayRadius, hintRadiusResObj)) {
496 dayRadius = calendarTheme->GetCalendarDayRadius();
497 }
498
499 if (hintRadiusResObj) {
500 settingData.dayRadiusResObj = hintRadiusResObj;
501 }
502 } else {
503 if (!ParseJsDimensionVpNG(obj->GetProperty("hintRadius"), dayRadius)) {
504 dayRadius = calendarTheme->GetCalendarDayRadius();
505 }
506 }
507 }
508
Create(const JSCallbackInfo & info)509 void JSCalendarPicker::Create(const JSCallbackInfo& info)
510 {
511 NG::CalendarSettingData settingData;
512 RefPtr<CalendarTheme> calendarTheme = GetTheme<CalendarTheme>();
513 CHECK_NULL_VOID(calendarTheme);
514 CalcDimension dayRadius;
515 if (info[0]->IsObject()) {
516 auto obj = JSRef<JSObject>::Cast(info[0]);
517 ParseHintRadius(obj, settingData, dayRadius);
518
519 auto selected = obj->GetProperty("selected");
520 auto parseSelectedDate = ParseDate(selected);
521 if (selected->IsObject() && parseSelectedDate.GetYear() != 0) {
522 JSRef<JSObject> selectedDateObj = JSRef<JSObject>::Cast(selected);
523 JSRef<JSVal> changeEventVal = selectedDateObj->GetProperty("changeEvent");
524 if (!changeEventVal->IsUndefined() && changeEventVal->IsFunction()) {
525 ParseSelectedDateObject(info, selectedDateObj);
526 settingData.selectedDate = ParseDate(selectedDateObj->GetProperty("value"));
527 } else {
528 settingData.selectedDate = parseSelectedDate;
529 }
530 }
531 auto disabledDateRange = obj->GetProperty("disabledDateRange");
532 ParseDisabledDateRange(disabledDateRange, settingData);
533 PickerDate::SortAndMergeDisabledDateRange(settingData.disabledDateRange);
534 auto startDate = obj->GetProperty("start");
535 auto endDate = obj->GetProperty("end");
536 auto parseStartDate = ParseDate(startDate, false);
537 auto parseEndDate = ParseDate(endDate, false);
538 if (parseEndDate.GetYear() > 0 && parseStartDate.ToDays() > parseEndDate.ToDays()) {
539 parseStartDate = PickerDate();
540 parseEndDate = PickerDate();
541 }
542 settingData.startDate = parseStartDate;
543 settingData.endDate = parseEndDate;
544 } else {
545 dayRadius = calendarTheme->GetCalendarDayRadius();
546 }
547 settingData.dayRadius = dayRadius;
548 CalendarPickerModel::GetInstance()->Create(settingData);
549 }
550
ParseTextStyle(const JSRef<JSObject> & paramObj,NG::PickerTextStyle & textStyle)551 void JSCalendarPicker::ParseTextStyle(const JSRef<JSObject>& paramObj, NG::PickerTextStyle& textStyle)
552 {
553 auto fontColor = paramObj->GetProperty("color");
554 auto fontStyle = paramObj->GetProperty("font");
555
556 Color color;
557 if (ParseJsColor(fontColor, color, textStyle.textColorResObj)) {
558 textStyle.textColor = color;
559 textStyle.textColorSetByUser = true;
560 }
561
562 if (!fontStyle->IsObject()) {
563 return;
564 }
565 JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(fontStyle);
566 auto fontSize = fontObj->GetProperty("size");
567 auto fontWeight = fontObj->GetProperty("weight");
568 if (fontSize->IsNull() || fontSize->IsUndefined()) {
569 textStyle.fontSize = Dimension(-1);
570 } else {
571 CalcDimension size;
572 if (!ParseJsDimensionFpNG(fontSize, size, textStyle.fontSizeResObj) || size.Unit() == DimensionUnit::PERCENT) {
573 textStyle.fontSize = Dimension(-1);
574 } else {
575 textStyle.fontSize = size;
576 }
577 }
578
579 if (!fontWeight->IsNull() && !fontWeight->IsUndefined()) {
580 std::string weight;
581 if (fontWeight->IsNumber()) {
582 weight = std::to_string(fontWeight->ToNumber<int32_t>());
583 } else {
584 ParseJsString(fontWeight, weight);
585 }
586 textStyle.fontWeight = ConvertStrToFontWeight(weight);
587 }
588 }
589
ParseDate(const JSRef<JSVal> & dateVal,bool useCurrentDate)590 PickerDate JSCalendarPicker::ParseDate(const JSRef<JSVal>& dateVal, bool useCurrentDate)
591 {
592 auto pickerDate = useCurrentDate ? PickerDate::Current() : PickerDate();
593 if (!dateVal->IsObject()) {
594 return pickerDate;
595 }
596 auto dateObj = JSRef<JSObject>::Cast(dateVal);
597 auto yearFuncJsVal = dateObj->GetProperty("getFullYear");
598 auto monthFuncJsVal = dateObj->GetProperty("getMonth");
599 auto dateFuncJsVal = dateObj->GetProperty("getDate");
600 if (!(yearFuncJsVal->IsFunction() && monthFuncJsVal->IsFunction() && dateFuncJsVal->IsFunction())) {
601 return pickerDate;
602 }
603 auto yearFunc = JSRef<JSFunc>::Cast(yearFuncJsVal);
604 auto monthFunc = JSRef<JSFunc>::Cast(monthFuncJsVal);
605 auto dateFunc = JSRef<JSFunc>::Cast(dateFuncJsVal);
606 JSRef<JSVal> year = yearFunc->Call(dateObj);
607 JSRef<JSVal> month = monthFunc->Call(dateObj);
608 JSRef<JSVal> date = dateFunc->Call(dateObj);
609
610 if (year->IsNumber() && month->IsNumber() && date->IsNumber()) {
611 pickerDate.SetYear(year->ToNumber<int32_t>());
612 pickerDate.SetMonth(month->ToNumber<int32_t>() + 1); // 0-11 means 1 to 12 months
613 pickerDate.SetDay(date->ToNumber<int32_t>());
614 }
615 return pickerDate;
616 }
617
JsMarkToday(const JSCallbackInfo & info)618 void JSCalendarPicker::JsMarkToday(const JSCallbackInfo& info)
619 {
620 bool isMarkToday = false;
621 if (info[0]->IsBoolean()) {
622 isMarkToday = info[0]->ToBoolean();
623 }
624 CalendarPickerModel::GetInstance()->SetMarkToday(isMarkToday);
625 }
626
JSBind(BindingTarget globalObj)627 void JSCalendarPickerDialog::JSBind(BindingTarget globalObj)
628 {
629 JSClass<JSCalendarPickerDialog>::Declare("CalendarPickerDialog");
630 JSClass<JSCalendarPickerDialog>::StaticMethod("show", &JSCalendarPickerDialog::Show);
631 JSClass<JSCalendarPickerDialog>::Bind<>(globalObj);
632 }
633
Show(const JSCallbackInfo & info)634 void JSCalendarPickerDialog::Show(const JSCallbackInfo& info)
635 {
636 auto scopedDelegate = EngineHelper::GetCurrentDelegateSafely();
637 CHECK_NULL_VOID(scopedDelegate);
638 if (!info[0]->IsObject()) {
639 return;
640 }
641
642 if (Container::IsCurrentUseNewPipeline()) {
643 auto paramObject = JSRef<JSObject>::Cast(info[0]);
644 auto buttonInfos = ParseButtonStyles(paramObject);
645 auto dialogEvent = ChangeDialogEvent(info);
646 auto dialogCancelEvent = DialogCancelEvent(info);
647 auto dialogLifeCycleEvent = LifeCycleDialogEvent(info);
648 CalendarPickerDialogShow(paramObject, dialogEvent, dialogCancelEvent, dialogLifeCycleEvent, buttonInfos);
649 }
650 }
651
ChangeDialogEvent(const JSCallbackInfo & info)652 std::map<std::string, NG::DialogEvent> JSCalendarPickerDialog::ChangeDialogEvent(const JSCallbackInfo& info)
653 {
654 std::map<std::string, NG::DialogEvent> dialogEvent;
655 if (!info[0]->IsObject()) {
656 return dialogEvent;
657 }
658 auto paramObject = JSRef<JSObject>::Cast(info[0]);
659 auto onChange = paramObject->GetProperty("onChange");
660 if (!onChange->IsUndefined() && onChange->IsFunction()) {
661 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onChange));
662 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
663 auto changeId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
664 const std::string& info) {
665 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
666 ACE_SCORING_EVENT("CalendarDialog.onChange");
667 PipelineContext::SetCallBackNode(node);
668 auto dateObj = JSDate::New(GetMSByDate(info));
669 func->ExecuteJS(1, &dateObj);
670 };
671 dialogEvent["changeId"] = changeId;
672 }
673 auto onAccept = paramObject->GetProperty("onAccept");
674 if (!onAccept->IsUndefined() && onAccept->IsFunction()) {
675 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAccept));
676 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
677 auto acceptId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
678 const std::string& info) {
679 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
680 ACE_SCORING_EVENT("CalendarDialog.onAccept");
681 PipelineContext::SetCallBackNode(node);
682 auto dateObj = JSDate::New(GetMSByDate(info));
683 func->ExecuteJS(1, &dateObj);
684 };
685 dialogEvent["acceptId"] = acceptId;
686 }
687 return dialogEvent;
688 }
689
DialogCancelEvent(const JSCallbackInfo & info)690 std::map<std::string, NG::DialogGestureEvent> JSCalendarPickerDialog::DialogCancelEvent(const JSCallbackInfo& info)
691 {
692 std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent;
693 if (!info[0]->IsObject()) {
694 return dialogCancelEvent;
695 }
696 auto paramObject = JSRef<JSObject>::Cast(info[0]);
697 auto onCancel = paramObject->GetProperty("onCancel");
698 if (!onCancel->IsUndefined() && onCancel->IsFunction()) {
699 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCancel));
700 auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
701 auto cancelId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
702 const GestureEvent& /* info */) {
703 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
704 ACE_SCORING_EVENT("CalendarDialog.onCancel");
705 PipelineContext::SetCallBackNode(node);
706 func->Execute();
707 };
708 dialogCancelEvent["cancelId"] = cancelId;
709 }
710 return dialogCancelEvent;
711 }
712
AppearDialogEvent(const JSCallbackInfo & info,std::map<std::string,NG::DialogCancelEvent> & dialogLifeCycleEvent)713 void AppearDialogEvent(const JSCallbackInfo& info, std::map<std::string, NG::DialogCancelEvent>& dialogLifeCycleEvent)
714 {
715 if (!info[0]->IsObject()) {
716 return;
717 }
718 auto paramObject = JSRef<JSObject>::Cast(info[0]);
719 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
720 auto onDidAppear = paramObject->GetProperty("onDidAppear");
721 if (!onDidAppear->IsUndefined() && onDidAppear->IsFunction()) {
722 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidAppear));
723 auto didAppearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
724 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
725 ACE_SCORING_EVENT("CalendarDialog.onDidAppear");
726 PipelineContext::SetCallBackNode(node);
727 func->Execute();
728 };
729 dialogLifeCycleEvent["didAppearId"] = didAppearId;
730 }
731 auto onWillAppear = paramObject->GetProperty("onWillAppear");
732 if (!onWillAppear->IsUndefined() && onWillAppear->IsFunction()) {
733 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillAppear));
734 auto willAppearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
735 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
736 ACE_SCORING_EVENT("CalendarDialog.onWillAppear");
737 PipelineContext::SetCallBackNode(node);
738 func->Execute();
739 };
740 dialogLifeCycleEvent["willAppearId"] = willAppearId;
741 }
742 }
743
DisappearDialogEvent(const JSCallbackInfo & info,std::map<std::string,NG::DialogCancelEvent> & dialogLifeCycleEvent)744 void DisappearDialogEvent(
745 const JSCallbackInfo& info, std::map<std::string, NG::DialogCancelEvent>& dialogLifeCycleEvent)
746 {
747 if (!info[0]->IsObject()) {
748 return;
749 }
750 auto paramObject = JSRef<JSObject>::Cast(info[0]);
751 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
752 auto onDidDisappear = paramObject->GetProperty("onDidDisappear");
753 if (!onDidDisappear->IsUndefined() && onDidDisappear->IsFunction()) {
754 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidDisappear));
755 auto didDisappearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
756 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
757 ACE_SCORING_EVENT("CalendarDialog.onDidDisappear");
758 PipelineContext::SetCallBackNode(node);
759 func->Execute();
760 };
761 dialogLifeCycleEvent["didDisappearId"] = didDisappearId;
762 }
763 auto onWillDisappear = paramObject->GetProperty("onWillDisappear");
764 if (!onWillDisappear->IsUndefined() && onWillDisappear->IsFunction()) {
765 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDisappear));
766 auto willDisappearId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
767 node = targetNode]() {
768 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
769 ACE_SCORING_EVENT("CalendarDialog.onWillDisappear");
770 PipelineContext::SetCallBackNode(node);
771 func->Execute();
772 };
773 dialogLifeCycleEvent["willDisappearId"] = willDisappearId;
774 }
775 }
776
LifeCycleDialogEvent(const JSCallbackInfo & info)777 std::map<std::string, NG::DialogCancelEvent> JSCalendarPickerDialog::LifeCycleDialogEvent(const JSCallbackInfo& info)
778 {
779 std::map<std::string, NG::DialogCancelEvent> dialogLifeCycleEvent;
780 if (!info[0]->IsObject()) {
781 return dialogLifeCycleEvent;
782 }
783 AppearDialogEvent(info, dialogLifeCycleEvent);
784 DisappearDialogEvent(info, dialogLifeCycleEvent);
785 return dialogLifeCycleEvent;
786 }
787
ParseDate(const JSRef<JSVal> & dateVal,bool useCurrentDate)788 PickerDate JSCalendarPickerDialog::ParseDate(const JSRef<JSVal>& dateVal, bool useCurrentDate)
789 {
790 auto pickerDate = useCurrentDate ? PickerDate::Current() : PickerDate();
791 if (!dateVal->IsObject()) {
792 return pickerDate;
793 }
794 auto dateObj = JSRef<JSObject>::Cast(dateVal);
795
796 auto yearFuncJsVal = dateObj->GetProperty("getFullYear");
797 auto monthFuncJsVal = dateObj->GetProperty("getMonth");
798 auto dateFuncJsVal = dateObj->GetProperty("getDate");
799 if (!(yearFuncJsVal->IsFunction() && monthFuncJsVal->IsFunction() && dateFuncJsVal->IsFunction())) {
800 return pickerDate;
801 }
802 auto yearFunc = JSRef<JSFunc>::Cast(yearFuncJsVal);
803 auto monthFunc = JSRef<JSFunc>::Cast(monthFuncJsVal);
804 auto dateFunc = JSRef<JSFunc>::Cast(dateFuncJsVal);
805 JSRef<JSVal> year = yearFunc->Call(dateObj);
806 JSRef<JSVal> month = monthFunc->Call(dateObj);
807 JSRef<JSVal> date = dateFunc->Call(dateObj);
808
809 if (year->IsNumber() && month->IsNumber() && date->IsNumber()) {
810 pickerDate.SetYear(year->ToNumber<int32_t>());
811 pickerDate.SetMonth(month->ToNumber<int32_t>() + 1); // 0-11 means 1 to 12 months
812 pickerDate.SetDay(date->ToNumber<int32_t>());
813 }
814 return pickerDate;
815 }
816
ParseDisabledDateRange(const JSRef<JSVal> & disabledDateRangeVal,NG::CalendarSettingData & settingData)817 void JSCalendarPickerDialog::ParseDisabledDateRange(
818 const JSRef<JSVal>& disabledDateRangeVal, NG::CalendarSettingData& settingData)
819 {
820 if (disabledDateRangeVal->IsUndefined() || disabledDateRangeVal->IsNull() || !disabledDateRangeVal->IsArray()) {
821 return;
822 }
823
824 JSRef<JSArray> array = JSRef<JSArray>::Cast(disabledDateRangeVal);
825 for (size_t i = 0; i < array->Length(); i++) {
826 JSRef<JSVal> dateRangeValue = array->GetValueAt(i);
827 auto dateRangeObj = JSRef<JSObject>::Cast(dateRangeValue);
828 auto startValue = dateRangeObj->GetProperty("start");
829 auto endValue = dateRangeObj->GetProperty("end");
830 if (startValue->IsObject() && endValue->IsObject()) {
831 auto startDate = ParseDate(startValue);
832 auto endDate = ParseDate(endValue);
833 if (startDate.GetYear() == 0 || endDate.GetYear() == 0 || endDate < startDate)
834 continue;
835 std::pair<PickerDate, PickerDate> pickerDateRange;
836 pickerDateRange.first = startDate;
837 pickerDateRange.second = endDate;
838 settingData.disabledDateRange.emplace_back(pickerDateRange);
839 }
840 }
841 }
842
CalendarPickerDialogShow(const JSRef<JSObject> & paramObj,const std::map<std::string,NG::DialogEvent> & dialogEvent,const std::map<std::string,NG::DialogGestureEvent> & dialogCancelEvent,const std::map<std::string,NG::DialogCancelEvent> & dialogLifeCycleEvent,const std::vector<ButtonInfo> & buttonInfos)843 void JSCalendarPickerDialog::CalendarPickerDialogShow(const JSRef<JSObject>& paramObj,
844 const std::map<std::string, NG::DialogEvent>& dialogEvent,
845 const std::map<std::string, NG::DialogGestureEvent>& dialogCancelEvent,
846 const std::map<std::string, NG::DialogCancelEvent>& dialogLifeCycleEvent,
847 const std::vector<ButtonInfo>& buttonInfos)
848 {
849 auto container = Container::CurrentSafely();
850 CHECK_NULL_VOID(container);
851 auto pipelineContext = AccessibilityManager::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
852 CHECK_NULL_VOID(pipelineContext);
853 auto executor = pipelineContext->GetTaskExecutor();
854 CHECK_NULL_VOID(executor);
855
856 auto theme = GetTheme<DialogTheme>();
857 CHECK_NULL_VOID(theme);
858 auto calendarTheme = pipelineContext->GetTheme<CalendarTheme>();
859 NG::CalendarSettingData settingData;
860 auto markToday = paramObj->GetProperty("markToday");
861 bool isMarkToday = false;
862 if (markToday->IsBoolean()) {
863 isMarkToday = markToday->ToBoolean();
864 }
865 settingData.markToday = isMarkToday;
866 auto disabledDateRange = paramObj->GetProperty("disabledDateRange");
867 ParseDisabledDateRange(disabledDateRange, settingData);
868 PickerDate::SortAndMergeDisabledDateRange(settingData.disabledDateRange);
869 auto selectedDate = paramObj->GetProperty("selected");
870 auto parseSelectedDate = ParseDate(selectedDate, true);
871
872 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
873 auto startDate = paramObj->GetProperty("start");
874 auto endDate = paramObj->GetProperty("end");
875 auto parseStartDate = ParseDate(startDate);
876 auto parseEndDate = ParseDate(endDate);
877 if (parseEndDate.GetYear() > 0 && parseStartDate.ToDays() > parseEndDate.ToDays()) {
878 parseStartDate = PickerDate();
879 parseEndDate = PickerDate();
880 }
881 settingData.startDate = parseStartDate;
882 settingData.endDate = parseEndDate;
883 parseSelectedDate = PickerDate::AdjustDateToRange(parseSelectedDate, parseStartDate, parseEndDate);
884 }
885
886 if (parseSelectedDate.GetYear() != 0) {
887 settingData.selectedDate = parseSelectedDate;
888 }
889
890 CalcDimension radius;
891 if (ParseJsDimensionVpNG(paramObj->GetProperty("hintRadius"), radius)) {
892 settingData.dayRadius = radius;
893 }
894
895 DialogProperties properties;
896 properties.alignment = theme->GetAlignment();
897 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
898 properties.alignment = DialogAlignment::CENTER;
899 }
900
901 auto backgroundColorValue = paramObj->GetProperty("backgroundColor");
902 Color backgroundColor;
903 if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
904 properties.backgroundColor = backgroundColor;
905 }
906
907 auto backgroundBlurStyle = paramObj->GetProperty("backgroundBlurStyle");
908 if (backgroundBlurStyle->IsNumber()) {
909 auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
910 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
911 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
912 properties.backgroundBlurStyle = blurStyle;
913 }
914 }
915
916 auto shadowValue = paramObj->GetProperty("shadow");
917 Shadow shadow;
918 if ((shadowValue->IsObject() || shadowValue->IsNumber()) && JSViewAbstract::ParseShadowProps(shadowValue, shadow)) {
919 properties.shadow = shadow;
920 }
921
922 properties.customStyle = false;
923 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TWELVE)) {
924 properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
925 NG::BorderRadiusProperty dialogRadius;
926 dialogRadius.SetRadius(calendarTheme->GetDialogBorderRadius());
927 properties.borderRadius = dialogRadius;
928 }
929
930 properties.hoverModeArea = HoverModeAreaType::BOTTOM_SCREEN;
931 JSViewAbstract::SetDialogHoverModeProperties(paramObj, properties);
932 JSViewAbstract::SetDialogBlurStyleOption(paramObj, properties);
933 JSViewAbstract::SetDialogEffectOption(paramObj, properties);
934
935 auto context = AccessibilityManager::DynamicCast<NG::PipelineContext>(pipelineContext);
936 auto overlayManager = context ? context->GetOverlayManager() : nullptr;
937 executor->PostTask(
938 [properties, settingData, dialogEvent, dialogCancelEvent, dialogLifeCycleEvent, buttonInfos,
939 weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
940 auto overlayManager = weak.Upgrade();
941 CHECK_NULL_VOID(overlayManager);
942 overlayManager->ShowCalendarDialog(
943 properties, settingData, dialogEvent, dialogCancelEvent, dialogLifeCycleEvent, buttonInfos);
944 },
945 TaskExecutor::TaskType::UI, "ArkUIDialogShowCalendarPicker",
946 TaskExecutor::GetPriorityTypeWithCheck(PriorityType::VIP));
947 }
948 } // namespace OHOS::Ace::Framework
949