1 /*
2 * Copyright (c) 2021-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 "bridge/declarative_frontend/jsview/js_datepicker.h"
17
18 #include <utility>
19
20 #include "base/log/ace_scoring_log.h"
21 #include "base/utils/utils.h"
22 #include "bridge/common/utils/engine_helper.h"
23 #include "bridge/declarative_frontend/engine/functions/js_event_function.h"
24 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
25 #include "bridge/declarative_frontend/jsview/js_utils.h"
26 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
27 #include "bridge/declarative_frontend/jsview/models/picker_model_impl.h"
28 #include "bridge/declarative_frontend/jsview/models/timepicker_model_impl.h"
29 #include "bridge/declarative_frontend/view_stack_processor.h"
30 #include "core/components/picker/picker_data.h"
31 #include "core/components/picker/picker_date_component.h"
32 #include "core/components/picker/picker_theme.h"
33 #include "core/components/picker/picker_time_component.h"
34 #include "core/components_ng/base/view_stack_processor.h"
35 #include "core/components_ng/pattern/picker/datepicker_model_ng.h"
36 #include "core/components_ng/pattern/time_picker/timepicker_model.h"
37 #include "core/components_ng/pattern/time_picker/timepicker_model_ng.h"
38 #include "core/components_v2/inspector/inspector_constants.h"
39 #include "core/event/ace_event_helper.h"
40 #include "core/pipeline_ng/pipeline_context.h"
41 #include "core/common/resource/resource_object.h"
42 #include "core/common/resource/resource_parse_utils.h"
43
44 namespace OHOS::Ace {
45 namespace {
46 const DimensionOffset DATEPICKER_OFFSET_DEFAULT_TOP = DimensionOffset(0.0_vp, 40.0_vp);
47 const std::vector<DialogAlignment> DIALOG_ALIGNMENT = { DialogAlignment::TOP, DialogAlignment::CENTER,
48 DialogAlignment::BOTTOM, DialogAlignment::DEFAULT, DialogAlignment::TOP_START, DialogAlignment::TOP_END,
49 DialogAlignment::CENTER_START, DialogAlignment::CENTER_END, DialogAlignment::BOTTOM_START,
50 DialogAlignment::BOTTOM_END };
51 const std::vector<HoverModeAreaType> HOVER_MODE_AREA_TYPE = { HoverModeAreaType::TOP_SCREEN,
52 HoverModeAreaType::BOTTOM_SCREEN };
53 const char TIMEPICKER_OPTIONS_HOUR[] = "hour";
54 const char TIMEPICKER_OPTIONS_MINUTE[] = "minute";
55 const char TIMEPICKER_OPTIONS_SECOND[] = "second";
56 const std::string TIMEPICKER_OPTIONS_NUMERIC_VAL = "numeric";
57 const std::string TIMEPICKER_OPTIONS_TWO_DIGIT_VAL = "2-digit";
58 } // namespace
59
60 std::unique_ptr<DatePickerModel> DatePickerModel::datePickerInstance_ = nullptr;
61 std::unique_ptr<DatePickerDialogModel> DatePickerDialogModel::datePickerDialogInstance_ = nullptr;
62 std::unique_ptr<TimePickerModel> TimePickerModel::timePickerInstance_ = nullptr;
63 std::unique_ptr<TimePickerDialogModel> TimePickerDialogModel::timePickerDialogInstance_ = nullptr;
64 std::once_flag DatePickerModel::onceFlag_;
65 std::once_flag DatePickerDialogModel::onceFlag_;
66 std::once_flag TimePickerModel::onceFlag_;
67 std::once_flag TimePickerDialogModel::onceFlag_;
68
GetInstance()69 DatePickerModel* DatePickerModel::GetInstance()
70 {
71 std::call_once(onceFlag_, []() {
72 #ifdef NG_BUILD
73 datePickerInstance_.reset(new NG::DatePickerModelNG());
74 #else
75 if (Container::IsCurrentUseNewPipeline()) {
76 datePickerInstance_.reset(new NG::DatePickerModelNG());
77 } else {
78 datePickerInstance_.reset(new Framework::DatePickerModelImpl());
79 }
80 #endif
81 });
82
83 return datePickerInstance_.get();
84 }
85
GetInstance()86 DatePickerDialogModel* DatePickerDialogModel::GetInstance()
87 {
88 std::call_once(onceFlag_, []() {
89 #ifdef NG_BUILD
90 datePickerDialogInstance_.reset(new NG::DatePickerDialogModelNG());
91 #else
92 if (Container::IsCurrentUseNewPipeline()) {
93 datePickerDialogInstance_.reset(new NG::DatePickerDialogModelNG());
94 } else {
95 datePickerDialogInstance_.reset(new Framework::DatePickerDialogModelImpl());
96 }
97 #endif
98 });
99
100 return datePickerDialogInstance_.get();
101 }
102
GetInstance()103 TimePickerModel* TimePickerModel::GetInstance()
104 {
105 std::call_once(onceFlag_, []() {
106 #ifdef NG_BUILD
107 timePickerInstance_.reset(new NG::TimePickerModelNG());
108 #else
109 if (Container::IsCurrentUseNewPipeline()) {
110 timePickerInstance_.reset(new NG::TimePickerModelNG());
111 } else {
112 timePickerInstance_.reset(new Framework::TimePickerModelImpl());
113 }
114 #endif
115 });
116
117 return timePickerInstance_.get();
118 }
119
GetInstance()120 TimePickerDialogModel* TimePickerDialogModel::GetInstance()
121 {
122 std::call_once(onceFlag_, []() {
123 #ifdef NG_BUILD
124 timePickerDialogInstance_.reset(new NG::TimePickerDialogModelNG());
125 #else
126 if (Container::IsCurrentUseNewPipeline()) {
127 timePickerDialogInstance_.reset(new NG::TimePickerDialogModelNG());
128 } else {
129 timePickerDialogInstance_.reset(new Framework::TimePickerDialogModelImpl());
130 }
131 #endif
132 });
133
134 return timePickerDialogInstance_.get();
135 }
136 } // namespace OHOS::Ace
137
138 namespace OHOS::Ace::Framework {
139 namespace {
DatePickerChangeEventToJSValue(const DatePickerChangeEvent & eventInfo)140 JSRef<JSVal> DatePickerChangeEventToJSValue(const DatePickerChangeEvent& eventInfo)
141 {
142 JSRef<JSObject> obj = JSRef<JSObject>::New();
143 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(eventInfo.GetSelectedStr());
144 if (!argsPtr) {
145 return JSRef<JSVal>::Cast(obj);
146 }
147 std::vector<std::string> keys = { "year", "month", "day", "hour", "minute", "second" };
148 for (auto iter = keys.begin(); iter != keys.end(); iter++) {
149 const std::string key = *iter;
150 const auto value = argsPtr->GetValue(key);
151 if (!value || value->ToString().empty()) {
152 continue;
153 }
154 obj->SetProperty<int32_t>(key.c_str(), value->GetInt());
155 }
156 return JSRef<JSVal>::Cast(obj);
157 }
158
DatePickerDateChangeEventToJSValue(const DatePickerChangeEvent & eventInfo)159 JSRef<JSVal> DatePickerDateChangeEventToJSValue(const DatePickerChangeEvent& eventInfo)
160 {
161 JSRef<JSObject> obj = JSRef<JSObject>::New();
162 std::unique_ptr<JsonValue> argsPtr = JsonUtil::ParseJsonString(eventInfo.GetSelectedStr());
163 if (!argsPtr) {
164 return JSRef<JSVal>::Cast(obj);
165 }
166 auto dateObj = JSDatePickerDialog::GetDateObj(argsPtr);
167 return JSRef<JSVal>::Cast(dateObj);
168 }
169
ParseFontOfButtonStyle(const JSRef<JSObject> & pickerButtonParamObject,ButtonInfo & buttonInfo)170 void ParseFontOfButtonStyle(const JSRef<JSObject>& pickerButtonParamObject, ButtonInfo& buttonInfo)
171 {
172 CalcDimension fontSize;
173 JSRef<JSVal> sizeProperty = pickerButtonParamObject->GetProperty("fontSize");
174 if (JSViewAbstract::ParseJsDimensionVpNG(sizeProperty, fontSize) && fontSize.Unit() != DimensionUnit::PERCENT &&
175 GreatOrEqual(fontSize.Value(), 0.0)) {
176 if (JSViewAbstract::ParseJsDimensionFp(sizeProperty, fontSize)) {
177 buttonInfo.fontSize = fontSize;
178 }
179 }
180 Color fontColor;
181 if (JSViewAbstract::ParseJsColor(pickerButtonParamObject->GetProperty("fontColor"), fontColor)) {
182 buttonInfo.fontColor = fontColor;
183 }
184 auto fontWeight = pickerButtonParamObject->GetProperty("fontWeight");
185 if (fontWeight->IsString() || fontWeight->IsNumber()) {
186 buttonInfo.fontWeight = ConvertStrToFontWeight(fontWeight->ToString(), FontWeight::MEDIUM);
187 }
188 JSRef<JSVal> style = pickerButtonParamObject->GetProperty("fontStyle");
189 if (style->IsNumber()) {
190 auto value = style->ToNumber<int32_t>();
191 if (value >= 0 && value < static_cast<int32_t>(FontStyle::NONE)) {
192 buttonInfo.fontStyle = static_cast<FontStyle>(value);
193 }
194 }
195 JSRef<JSVal> family = pickerButtonParamObject->GetProperty("fontFamily");
196 std::vector<std::string> fontFamilies;
197 if (JSViewAbstract::ParseJsFontFamilies(family, fontFamilies)) {
198 buttonInfo.fontFamily = fontFamilies;
199 }
200 }
201
ParseButtonStyle(const JSRef<JSObject> & pickerButtonParamObject)202 ButtonInfo ParseButtonStyle(const JSRef<JSObject>& pickerButtonParamObject)
203 {
204 ButtonInfo buttonInfo;
205 if (pickerButtonParamObject->GetProperty("type")->IsNumber()) {
206 auto buttonTypeIntValue = pickerButtonParamObject->GetProperty("type")->ToNumber<int32_t>();
207 if (buttonTypeIntValue == static_cast<int32_t>(ButtonType::CAPSULE) ||
208 buttonTypeIntValue == static_cast<int32_t>(ButtonType::CIRCLE) ||
209 buttonTypeIntValue == static_cast<int32_t>(ButtonType::ARC) ||
210 buttonTypeIntValue == static_cast<int32_t>(ButtonType::NORMAL) ||
211 buttonTypeIntValue == static_cast<int32_t>(ButtonType::ROUNDED_RECTANGLE)) {
212 buttonInfo.type = static_cast<ButtonType>(buttonTypeIntValue);
213 }
214 }
215 if (pickerButtonParamObject->GetProperty("style")->IsNumber()) {
216 auto styleModeIntValue = pickerButtonParamObject->GetProperty("style")->ToNumber<int32_t>();
217 if (styleModeIntValue >= static_cast<int32_t>(ButtonStyleMode::NORMAL) &&
218 styleModeIntValue <= static_cast<int32_t>(ButtonStyleMode::TEXT)) {
219 buttonInfo.buttonStyle = static_cast<ButtonStyleMode>(styleModeIntValue);
220 }
221 }
222 if (pickerButtonParamObject->GetProperty("role")->IsNumber()) {
223 auto buttonRoleIntValue = pickerButtonParamObject->GetProperty("role")->ToNumber<int32_t>();
224 if (buttonRoleIntValue >= static_cast<int32_t>(ButtonRole::NORMAL) &&
225 buttonRoleIntValue <= static_cast<int32_t>(ButtonRole::ERROR)) {
226 buttonInfo.role = static_cast<ButtonRole>(buttonRoleIntValue);
227 }
228 }
229 ParseFontOfButtonStyle(pickerButtonParamObject, buttonInfo);
230 Color backgroundColor;
231 if (JSViewAbstract::ParseJsColor(pickerButtonParamObject->GetProperty("backgroundColor"), backgroundColor)) {
232 buttonInfo.backgroundColor = backgroundColor;
233 }
234 auto radius = ParseBorderRadiusAttr(pickerButtonParamObject->GetProperty("borderRadius"));
235 if (radius.has_value()) {
236 buttonInfo.borderRadius = radius.value();
237 }
238
239 auto primaryValue = pickerButtonParamObject->GetProperty("primary");
240 if (primaryValue->IsBoolean()) {
241 buttonInfo.isPrimary = primaryValue->ToBoolean();
242 }
243
244 return buttonInfo;
245 }
246
ParseButtonStyles(const JSRef<JSObject> & paramObject)247 std::vector<ButtonInfo> ParseButtonStyles(const JSRef<JSObject>& paramObject)
248 {
249 std::vector<ButtonInfo> buttonInfos;
250 auto acceptButtonStyle = paramObject->GetProperty("acceptButtonStyle");
251 if (acceptButtonStyle->IsObject()) {
252 auto acceptButtonStyleParamObject = JSRef<JSObject>::Cast(acceptButtonStyle);
253 buttonInfos.emplace_back(ParseButtonStyle(acceptButtonStyleParamObject));
254 buttonInfos[0].isAcceptButton = true;
255 } else {
256 ButtonInfo buttonInfo;
257 buttonInfos.emplace_back(buttonInfo);
258 }
259 auto cancelButtonStyle = paramObject->GetProperty("cancelButtonStyle");
260 if (cancelButtonStyle->IsObject()) {
261 auto cancelButtonStyleParamObject = JSRef<JSObject>::Cast(cancelButtonStyle);
262 buttonInfos.emplace_back(ParseButtonStyle(cancelButtonStyleParamObject));
263 }
264
265 return buttonInfos;
266 }
267
ParseDatePickerHoverMode(PickerDialogInfo & pickerDialog,const JSRef<JSObject> & paramObject)268 void ParseDatePickerHoverMode(PickerDialogInfo& pickerDialog, const JSRef<JSObject>& paramObject)
269 {
270 auto enableHoverModeValue = paramObject->GetProperty("enableHoverMode");
271 if (enableHoverModeValue->IsBoolean()) {
272 pickerDialog.enableHoverMode = enableHoverModeValue->ToBoolean();
273 }
274
275 auto hoverModeAreaValue = paramObject->GetProperty("hoverModeArea");
276 pickerDialog.hoverModeArea = HoverModeAreaType::BOTTOM_SCREEN;
277 if (hoverModeAreaValue->IsNumber()) {
278 auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
279 if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
280 pickerDialog.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
281 }
282 }
283 }
284
ParseDatePickerBlurStyleOption(PickerDialogInfo & pickerDialog,const JSRef<JSObject> & paramObject)285 void ParseDatePickerBlurStyleOption(PickerDialogInfo& pickerDialog, const JSRef<JSObject>& paramObject)
286 {
287 auto blurStyleValue = paramObject->GetProperty("backgroundBlurStyleOptions");
288 if (blurStyleValue->IsObject()) {
289 if (!pickerDialog.blurStyleOption.has_value()) {
290 pickerDialog.blurStyleOption.emplace();
291 }
292 JSViewAbstract::ParseBlurStyleOption(blurStyleValue, pickerDialog.blurStyleOption.value());
293 }
294 }
295
ParseDatePickerEffectOption(PickerDialogInfo & pickerDialog,const JSRef<JSObject> & paramObject)296 void ParseDatePickerEffectOption(PickerDialogInfo& pickerDialog, const JSRef<JSObject>& paramObject)
297 {
298 auto effectOptionValue = paramObject->GetProperty("backgroundEffect");
299 if (effectOptionValue->IsObject()) {
300 if (!pickerDialog.effectOption.has_value()) {
301 pickerDialog.effectOption.emplace();
302 }
303 JSViewAbstract::ParseEffectOption(effectOptionValue, pickerDialog.effectOption.value());
304 }
305 }
306 } // namespace
307
JSBind(BindingTarget globalObj)308 void JSDatePicker::JSBind(BindingTarget globalObj)
309 {
310 JSClass<JSDatePicker>::Declare("DatePicker");
311 MethodOptions opt = MethodOptions::NONE;
312 JSClass<JSDatePicker>::StaticMethod("create", &JSDatePicker::Create, opt);
313 JSClass<JSDatePicker>::StaticMethod("lunar", &JSDatePicker::SetLunar);
314 JSClass<JSDatePicker>::StaticMethod("canLoop", &JSDatePicker::SetCanLoop);
315 JSClass<JSDatePicker>::StaticMethod("onChange", &JSDatePicker::OnChange);
316 JSClass<JSDatePicker>::StaticMethod("onDateChange", &JSDatePicker::OnDateChange);
317 JSClass<JSDatePicker>::StaticMethod("backgroundColor", &JSDatePicker::PickerBackgroundColor);
318 JSClass<JSDatePicker>::StaticMethod("opacity", &JSDatePicker::JsOpacity);
319 // keep compatible, need remove after
320 JSClass<JSDatePicker>::StaticMethod("useMilitaryTime", &JSDatePicker::UseMilitaryTime);
321 JSClass<JSDatePicker>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
322 JSClass<JSDatePicker>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
323 JSClass<JSDatePicker>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
324 JSClass<JSDatePicker>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
325 JSClass<JSDatePicker>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
326 JSClass<JSDatePicker>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
327 JSClass<JSDatePicker>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
328 JSClass<JSDatePicker>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
329 JSClass<JSDatePicker>::StaticMethod("disappearTextStyle", &JSDatePicker::SetDisappearTextStyle);
330 JSClass<JSDatePicker>::StaticMethod("textStyle", &JSDatePicker::SetTextStyle);
331 JSClass<JSDatePicker>::StaticMethod("selectedTextStyle", &JSDatePicker::SetSelectedTextStyle);
332 JSClass<JSDatePicker>::StaticMethod("enableHapticFeedback", &JSDatePicker::SetEnableHapticFeedback);
333 JSClass<JSDatePicker>::StaticMethod("digitalCrownSensitivity", &JSDatePicker::SetDigitalCrownSensitivity);
334 JSClass<JSDatePicker>::InheritAndBind<JSViewAbstract>(globalObj);
335 }
336
SetDigitalCrownSensitivity(const JSCallbackInfo & info)337 void JSDatePicker::SetDigitalCrownSensitivity(const JSCallbackInfo& info)
338 {
339 int32_t value = OHOS::Ace::NG::DEFAULT_CROWNSENSITIVITY;
340 if (info.Length() >= 1 && info[0]->IsNumber()) {
341 value = info[0]->ToNumber<int32_t>();
342 }
343 DatePickerModel::GetInstance()->SetDigitalCrownSensitivity(value);
344 }
345
Create(const JSCallbackInfo & info)346 void JSDatePicker::Create(const JSCallbackInfo& info)
347 {
348 DatePickerType pickerType = DatePickerType::DATE;
349 JSRef<JSObject> paramObject;
350 if (info.Length() >= 1 && info[0]->IsObject()) {
351 paramObject = JSRef<JSObject>::Cast(info[0]);
352 auto type = paramObject->GetProperty("type");
353 if (type->IsNumber()) {
354 pickerType = static_cast<DatePickerType>(type->ToNumber<int32_t>());
355 }
356 }
357 switch (pickerType) {
358 case DatePickerType::TIME: {
359 CreateTimePicker(info, paramObject);
360 break;
361 }
362 case DatePickerType::DATE: {
363 CreateDatePicker(info, paramObject);
364 break;
365 }
366 default: {
367 break;
368 }
369 }
370 }
371
SetLunar(bool isLunar)372 void JSDatePicker::SetLunar(bool isLunar)
373 {
374 DatePickerModel::GetInstance()->SetShowLunar(isLunar);
375 }
376
SetCanLoop(const JSCallbackInfo & info)377 void JSDatePicker::SetCanLoop(const JSCallbackInfo& info)
378 {
379 bool value = true;
380 if (info.Length() >= 1 && info[0]->IsBoolean()) {
381 value = info[0]->ToBoolean();
382 }
383 DatePickerModel::GetInstance()->SetCanLoop(value);
384 }
385
UseMilitaryTime(bool isUseMilitaryTime)386 void JSDatePicker::UseMilitaryTime(bool isUseMilitaryTime)
387 {
388 DatePickerModel::GetInstance()->SetHour24(isUseMilitaryTime);
389 }
390
ParseTextProperties(const JSRef<JSObject> & paramObj,NG::PickerTextProperties & result)391 void JSDatePicker::ParseTextProperties(const JSRef<JSObject>& paramObj, NG::PickerTextProperties& result)
392 {
393 auto disappearProperty = paramObj->GetProperty("disappearTextStyle");
394 auto normalProperty = paramObj->GetProperty("textStyle");
395 auto selectedProperty = paramObj->GetProperty("selectedTextStyle");
396
397 if (!disappearProperty->IsNull() && disappearProperty->IsObject()) {
398 JSRef<JSObject> disappearObj = JSRef<JSObject>::Cast(disappearProperty);
399 JSDatePicker::ParseTextStyle(disappearObj, result.disappearTextStyle_, "disappearTextStyle");
400 }
401
402 if (!normalProperty->IsNull() && normalProperty->IsObject()) {
403 JSRef<JSObject> noramlObj = JSRef<JSObject>::Cast(normalProperty);
404 JSDatePicker::ParseTextStyle(noramlObj, result.normalTextStyle_, "textStyle");
405 }
406
407 if (!selectedProperty->IsNull() && selectedProperty->IsObject()) {
408 JSRef<JSObject> selectedObj = JSRef<JSObject>::Cast(selectedProperty);
409 JSDatePicker::ParseTextStyle(selectedObj, result.selectedTextStyle_, "selectedTextStyle");
410 }
411 }
412
IsUserDefinedFontFamily(const std::string & pos)413 void JSDatePicker::IsUserDefinedFontFamily(const std::string& pos)
414 {
415 if (pos == "disappearTextStyle") {
416 DatePickerModel::GetInstance()->HasUserDefinedDisappearFontFamily(true);
417 } else if (pos == "textStyle") {
418 DatePickerModel::GetInstance()->HasUserDefinedNormalFontFamily(true);
419 } else if (pos == "selectedTextStyle") {
420 DatePickerModel::GetInstance()->HasUserDefinedSelectedFontFamily(true);
421 } else if (pos == "disappearTextStyleTime") {
422 TimePickerModel::GetInstance()->HasUserDefinedDisappearFontFamily(true);
423 } else if (pos == "textStyleTime") {
424 TimePickerModel::GetInstance()->HasUserDefinedNormalFontFamily(true);
425 } else if (pos == "selectedTextStyleTime") {
426 TimePickerModel::GetInstance()->HasUserDefinedSelectedFontFamily(true);
427 }
428 }
429
ParseTextStyleFontSize(const JSRef<JSVal> & fontSize,NG::PickerTextStyle & textStyle)430 void JSDatePicker::ParseTextStyleFontSize(const JSRef<JSVal>& fontSize, NG::PickerTextStyle& textStyle)
431 {
432 if (fontSize->IsNull() || fontSize->IsUndefined()) {
433 textStyle.fontSize = Dimension(-1);
434 } else {
435 CalcDimension size;
436 if (!ParseJsDimensionFp(fontSize, size, textStyle.fontSizeResObj) || size.Unit() == DimensionUnit::PERCENT) {
437 textStyle.fontSize = Dimension(-1);
438 } else {
439 textStyle.fontSize = size;
440 }
441 }
442 }
443
ParseTextStyle(const JSRef<JSObject> & paramObj,NG::PickerTextStyle & textStyle,const std::string & pos)444 void JSDatePicker::ParseTextStyle(
445 const JSRef<JSObject>& paramObj, NG::PickerTextStyle& textStyle, const std::string& pos)
446 {
447 auto fontColor = paramObj->GetProperty("color");
448 auto fontOptions = paramObj->GetProperty("font");
449
450 Color textColor;
451 if (JSViewAbstract::ParseJsColor(fontColor, textColor, textStyle.textColorResObj)) {
452 textStyle.textColor = textColor;
453 textStyle.textColorSetByUser = true;
454 }
455
456 if (!fontOptions->IsObject()) {
457 return;
458 }
459 JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(fontOptions);
460 auto fontSize = fontObj->GetProperty("size");
461 auto fontWeight = fontObj->GetProperty("weight");
462 auto fontFamily = fontObj->GetProperty("family");
463 auto fontStyle = fontObj->GetProperty("style");
464
465 ParseTextStyleFontSize(fontSize, textStyle);
466
467 if (!fontWeight->IsNull() && !fontWeight->IsUndefined()) {
468 std::string weight;
469 if (fontWeight->IsNumber()) {
470 weight = std::to_string(fontWeight->ToNumber<int32_t>());
471 } else {
472 ParseJsString(fontWeight, weight);
473 }
474 textStyle.fontWeight = ConvertStrToFontWeight(weight);
475 }
476
477 if (!fontFamily->IsNull() && !fontFamily->IsUndefined()) {
478 std::vector<std::string> families;
479 if (ParseJsFontFamilies(fontFamily, families, textStyle.fontFamilyResObj)) {
480 textStyle.fontFamily = families;
481 IsUserDefinedFontFamily(pos);
482 }
483 }
484
485 if (fontStyle->IsNumber()) {
486 auto style = fontStyle->ToNumber<int32_t>();
487 if (style < 0 || style > 1) {
488 return;
489 }
490 textStyle.fontStyle = static_cast<FontStyle>(style);
491 }
492 }
493
SetDisappearTextStyle(const JSCallbackInfo & info)494 void JSDatePicker::SetDisappearTextStyle(const JSCallbackInfo& info)
495 {
496 auto theme = GetTheme<PickerTheme>();
497 CHECK_NULL_VOID(theme);
498 NG::PickerTextStyle textStyle;
499 if (info[0]->IsObject()) {
500 JSDatePicker::ParseTextStyle(info[0], textStyle, "disappearTextStyle");
501 }
502 DatePickerModel::GetInstance()->SetDisappearTextStyle(theme, textStyle);
503 }
504
SetTextStyle(const JSCallbackInfo & info)505 void JSDatePicker::SetTextStyle(const JSCallbackInfo& info)
506 {
507 auto theme = GetTheme<PickerTheme>();
508 CHECK_NULL_VOID(theme);
509 NG::PickerTextStyle textStyle;
510 if (info[0]->IsObject()) {
511 JSDatePicker::ParseTextStyle(info[0], textStyle, "textStyle");
512 }
513 DatePickerModel::GetInstance()->SetNormalTextStyle(theme, textStyle);
514 }
515
SetEnableHapticFeedback(const JSCallbackInfo & info)516 void JSDatePicker::SetEnableHapticFeedback(const JSCallbackInfo& info)
517 {
518 bool isEnableHapticFeedback = true;
519 if (info[0]->IsBoolean()) {
520 isEnableHapticFeedback = info[0]->ToBoolean();
521 }
522 DatePickerModel::GetInstance()->SetEnableHapticFeedback(isEnableHapticFeedback);
523 }
524
SetSelectedTextStyle(const JSCallbackInfo & info)525 void JSDatePicker::SetSelectedTextStyle(const JSCallbackInfo& info)
526 {
527 auto theme = GetTheme<PickerTheme>();
528 CHECK_NULL_VOID(theme);
529 NG::PickerTextStyle textStyle;
530 if (info[0]->IsObject()) {
531 JSDatePicker::ParseTextStyle(info[0], textStyle, "selectedTextStyle");
532 }
533 DatePickerModel::GetInstance()->SetSelectedTextStyle(theme, textStyle);
534 if (textStyle.textColor.has_value() && theme->IsCircleDial()) {
535 DatePickerModel::GetInstance()->UpdateUserSetSelectColor();
536 }
537 }
538
JsOpacity(const JSCallbackInfo & info)539 void JSDatePicker::JsOpacity(const JSCallbackInfo& info)
540 {
541 JSViewAbstract::JsOpacity(info);
542 DatePickerModel::GetInstance()->HasUserDefinedOpacity();
543 }
544
OnChange(const JSCallbackInfo & info)545 void JSDatePicker::OnChange(const JSCallbackInfo& info)
546 {
547 if (!info[0]->IsFunction()) {
548 return;
549 }
550
551 auto jsFunc = AceType::MakeRefPtr<JsEventFunction<DatePickerChangeEvent, 1>>(
552 JSRef<JSFunc>::Cast(info[0]), DatePickerChangeEventToJSValue);
553 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
554 auto onChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
555 const BaseEventInfo* info) {
556 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
557 ACE_SCORING_EVENT("datePicker.onChange");
558 PipelineContext::SetCallBackNode(node);
559 const auto* eventInfo = TypeInfoHelper::DynamicCast<DatePickerChangeEvent>(info);
560 func->Execute(*eventInfo);
561 };
562 DatePickerModel::GetInstance()->SetOnChange(std::move(onChange));
563 }
564
OnDateChange(const JSCallbackInfo & info)565 void JSDatePicker::OnDateChange(const JSCallbackInfo& info)
566 {
567 if (!info[0]->IsFunction()) {
568 return;
569 }
570 auto jsFunc = AceType::MakeRefPtr<JsEventFunction<DatePickerChangeEvent, 1>>(
571 JSRef<JSFunc>::Cast(info[0]), DatePickerDateChangeEventToJSValue);
572 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
573 auto onDateChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
574 const BaseEventInfo* info) {
575 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
576 ACE_SCORING_EVENT("datePicker.onDateChange");
577 PipelineContext::SetCallBackNode(node);
578 const auto* eventInfo = TypeInfoHelper::DynamicCast<DatePickerChangeEvent>(info);
579 func->Execute(*eventInfo);
580 };
581 DatePickerModel::GetInstance()->SetOnDateChange(std::move(onDateChange));
582 }
583
OnChange(const JSCallbackInfo & info)584 void JSTimePicker::OnChange(const JSCallbackInfo& info)
585 {
586 if (!info[0]->IsFunction()) {
587 return;
588 }
589
590 auto jsFunc = AceType::MakeRefPtr<JsEventFunction<DatePickerChangeEvent, 1>>(
591 JSRef<JSFunc>::Cast(info[0]), DatePickerChangeEventToJSValue);
592 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
593 auto onChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
594 const BaseEventInfo* index) {
595 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
596 ACE_SCORING_EVENT("datePicker.onChange");
597 PipelineContext::SetCallBackNode(node);
598 const auto* eventInfo = TypeInfoHelper::DynamicCast<DatePickerChangeEvent>(index);
599 func->Execute(*eventInfo);
600 };
601 TimePickerModel::GetInstance()->SetOnChange(std::move(onChange));
602 }
603
OnEnterSelectedArea(const JSCallbackInfo & info)604 void JSTimePicker::OnEnterSelectedArea(const JSCallbackInfo& info)
605 {
606 if (!info[0]->IsFunction()) {
607 return;
608 }
609
610 auto jsFunc = AceType::MakeRefPtr<JsEventFunction<DatePickerChangeEvent, 1>>(
611 JSRef<JSFunc>::Cast(info[0]), DatePickerChangeEventToJSValue);
612 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
613 auto onEnterSelectedArea = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
614 const BaseEventInfo* index) {
615 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
616 ACE_SCORING_EVENT("datePicker.onEnterSelectedArea");
617 PipelineContext::SetCallBackNode(node);
618 const auto* eventInfo = TypeInfoHelper::DynamicCast<DatePickerChangeEvent>(index);
619 func->Execute(*eventInfo);
620 };
621 TimePickerModel::GetInstance()->SetOnEnterSelectedArea(std::move(onEnterSelectedArea));
622 }
623
PickerBackgroundColor(const JSCallbackInfo & info)624 void JSDatePicker::PickerBackgroundColor(const JSCallbackInfo& info)
625 {
626 JSViewAbstract::JsBackgroundColor(info);
627
628 if (info.Length() < 1) {
629 return;
630 }
631 Color backgroundColor;
632 if (!ParseJsColor(info[0], backgroundColor)) {
633 return;
634 }
635 DatePickerModel::GetInstance()->SetBackgroundColor(backgroundColor);
636 }
637
ParseDate(const JSRef<JSVal> & dateVal)638 PickerDate JSDatePicker::ParseDate(const JSRef<JSVal>& dateVal)
639 {
640 auto pickerDate = PickerDate();
641 if (!dateVal->IsObject()) {
642 return pickerDate;
643 }
644 auto dateObj = JSRef<JSObject>::Cast(dateVal);
645 auto yearFuncJsVal = dateObj->GetProperty("getFullYear");
646 auto monthFuncJsVal = dateObj->GetProperty("getMonth");
647 auto dateFuncJsVal = dateObj->GetProperty("getDate");
648 if (!(yearFuncJsVal->IsFunction() && monthFuncJsVal->IsFunction() && dateFuncJsVal->IsFunction())) {
649 return pickerDate;
650 }
651 auto yearFunc = JSRef<JSFunc>::Cast(yearFuncJsVal);
652 auto monthFunc = JSRef<JSFunc>::Cast(monthFuncJsVal);
653 auto dateFunc = JSRef<JSFunc>::Cast(dateFuncJsVal);
654 JSRef<JSVal> year = yearFunc->Call(dateObj);
655 JSRef<JSVal> month = monthFunc->Call(dateObj);
656 JSRef<JSVal> date = dateFunc->Call(dateObj);
657
658 if (year->IsNumber() && month->IsNumber() && date->IsNumber()) {
659 pickerDate.SetYear(year->ToNumber<int32_t>());
660 pickerDate.SetMonth(month->ToNumber<int32_t>() + 1); // 0-11 means 1 to 12 months
661 pickerDate.SetDay(date->ToNumber<int32_t>());
662 }
663 return pickerDate;
664 }
665
ParseTime(const JSRef<JSVal> & timeVal)666 PickerTime JSDatePicker::ParseTime(const JSRef<JSVal>& timeVal)
667 {
668 auto pickerTime = PickerTime();
669 if (!timeVal->IsObject()) {
670 return pickerTime;
671 }
672 auto timeObj = JSRef<JSObject>::Cast(timeVal);
673 auto hourFuncJsVal = timeObj->GetProperty("getHours");
674 auto minuteFuncJsVal = timeObj->GetProperty("getMinutes");
675 auto secondFuncJsVal = timeObj->GetProperty("getSeconds");
676 if (!(hourFuncJsVal->IsFunction() && minuteFuncJsVal->IsFunction() && secondFuncJsVal->IsFunction())) {
677 return pickerTime;
678 }
679 auto hourFunc = JSRef<JSFunc>::Cast(hourFuncJsVal);
680 auto minuteFunc = JSRef<JSFunc>::Cast(minuteFuncJsVal);
681 auto secondFunc = JSRef<JSFunc>::Cast(secondFuncJsVal);
682 JSRef<JSVal> hour = hourFunc->Call(timeObj);
683 JSRef<JSVal> minute = minuteFunc->Call(timeObj);
684 JSRef<JSVal> second = secondFunc->Call(timeObj);
685
686 if (hour->IsNumber() && minute->IsNumber() && second->IsNumber()) {
687 pickerTime.SetHour(hour->ToNumber<int32_t>());
688 pickerTime.SetMinute(minute->ToNumber<int32_t>());
689 pickerTime.SetSecond(second->ToNumber<int32_t>());
690 }
691 return pickerTime;
692 }
693
ParseSelectedDateTimeObject(const JSCallbackInfo & info,const JSRef<JSObject> & selectedObject,bool isDatePicker)694 void ParseSelectedDateTimeObject(const JSCallbackInfo& info, const JSRef<JSObject>& selectedObject, bool isDatePicker)
695 {
696 JSRef<JSVal> changeEventVal = selectedObject->GetProperty("changeEvent");
697 if (changeEventVal->IsUndefined() || !changeEventVal->IsFunction()) {
698 return;
699 }
700 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
701 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
702 auto changeEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
703 node = targetNode, isDatePicker](const BaseEventInfo* info) {
704 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
705 ACE_SCORING_EVENT("DatePicker.SelectedDateTimeChangeEvent");
706 const auto* eventInfo = TypeInfoHelper::DynamicCast<DatePickerChangeEvent>(info);
707 CHECK_NULL_VOID(eventInfo);
708 auto selectedStr = eventInfo->GetSelectedStr();
709 auto sourceJson = JsonUtil::ParseJsonString(selectedStr);
710 if (!sourceJson || sourceJson->IsNull()) {
711 return;
712 }
713
714 auto dateObj = JSDatePickerDialog::GetDateObj(sourceJson, isDatePicker);
715 PipelineContext::SetCallBackNode(node);
716 func->ExecuteJS(1, &dateObj);
717 };
718 if (isDatePicker) {
719 DatePickerModel::GetInstance()->SetChangeEvent(std::move(changeEvent));
720 } else {
721 TimePickerModel::GetInstance()->SetChangeEvent(std::move(changeEvent));
722 }
723 }
724
CreateDatePicker(const JSCallbackInfo & info,const JSRef<JSObject> & paramObj)725 void JSDatePicker::CreateDatePicker(const JSCallbackInfo& info, const JSRef<JSObject>& paramObj)
726 {
727 JSRef<JSVal> startDate;
728 JSRef<JSVal> endDate;
729 JSRef<JSVal> selectedDate;
730 JSRef<JSVal> mode;
731 if (!paramObj->IsUndefined()) {
732 startDate = paramObj->GetProperty("start");
733 endDate = paramObj->GetProperty("end");
734 selectedDate = paramObj->GetProperty("selected");
735 mode = paramObj->GetProperty("mode");
736 }
737 ParseStartEndDate(startDate, endDate);
738
739 PickerDate parseSelectedDate = PickerDate::Current();
740 if (selectedDate->IsObject()) {
741 JSRef<JSObject> selectedDateObj = JSRef<JSObject>::Cast(selectedDate);
742 JSRef<JSVal> changeEventVal = selectedDateObj->GetProperty("changeEvent");
743 if (!changeEventVal->IsUndefined() && changeEventVal->IsFunction()) {
744 ParseSelectedDateTimeObject(info, selectedDateObj, true);
745 parseSelectedDate = ParseDate(selectedDateObj->GetProperty("value"));
746 } else {
747 parseSelectedDate = ParseDate(selectedDate);
748 }
749 }
750 DatePickerModel::GetInstance()->SetSelectedDate(parseSelectedDate);
751
752 ParseDatePickerMode(mode);
753 SetDefaultAttributes();
754 }
755
SetDefaultAttributes()756 void JSDatePicker::SetDefaultAttributes()
757 {
758 auto theme = GetTheme<PickerTheme>();
759 CHECK_NULL_VOID(theme);
760 NG::PickerTextStyle textStyle;
761 auto selectedStyle = theme->GetOptionStyle(true, false);
762 textStyle.fontSize = selectedStyle.GetFontSize();
763 textStyle.fontWeight = selectedStyle.GetFontWeight();
764 DatePickerModel::GetInstance()->SetSelectedTextStyle(theme, textStyle);
765
766 auto disappearStyle = theme->GetDisappearOptionStyle();
767 textStyle.fontSize = disappearStyle.GetFontSize();
768 textStyle.fontWeight = disappearStyle.GetFontWeight();
769 DatePickerModel::GetInstance()->SetDisappearTextStyle(theme, textStyle);
770
771 auto normalStyle = theme->GetOptionStyle(false, false);
772 textStyle.fontSize = normalStyle.GetFontSize();
773 textStyle.fontWeight = normalStyle.GetFontWeight();
774 DatePickerModel::GetInstance()->SetNormalTextStyle(theme, textStyle);
775 }
776
ParseDatePickerMode(JSRef<JSVal> mode)777 void JSDatePicker::ParseDatePickerMode(JSRef<JSVal> mode)
778 {
779 auto datePickerMode = DatePickerMode::DATE;
780 if (!mode->IsNull() && mode->IsNumber()) {
781 auto parseMode = mode->ToNumber<int32_t>();
782 if (parseMode >= static_cast<int32_t>(DatePickerMode::DATE) &&
783 parseMode <= static_cast<int32_t>(DatePickerMode::MONTH_AND_DAY)) {
784 datePickerMode = static_cast<DatePickerMode>(parseMode);
785 }
786 }
787 DatePickerModel::GetInstance()->SetMode(datePickerMode);
788 }
789
ParseStartEndDate(JSRef<JSVal> startDate,JSRef<JSVal> endDate)790 void JSDatePicker::ParseStartEndDate(JSRef<JSVal> startDate, JSRef<JSVal> endDate)
791 {
792 auto theme = GetTheme<PickerTheme>();
793 CHECK_NULL_VOID(theme);
794 auto parseStartDate = ParseDate(startDate);
795 auto parseEndDate = ParseDate(endDate);
796 if (parseStartDate.GetYear() <= 0) {
797 parseStartDate = theme->GetDefaultStartDate();
798 }
799 if (parseEndDate.GetYear() <= 0) {
800 parseEndDate = theme->GetDefaultEndDate();
801 }
802 auto startDays = parseStartDate.ToDays();
803 auto endDays = parseEndDate.ToDays();
804 if (startDays > endDays) {
805 parseStartDate = theme->GetDefaultStartDate();
806 parseEndDate = theme->GetDefaultEndDate();
807 }
808 DatePickerModel::GetInstance()->CreateDatePicker(theme);
809 if (startDate->IsObject()) {
810 DatePickerModel::GetInstance()->SetStartDate(parseStartDate);
811 }
812 if (endDate->IsObject()) {
813 DatePickerModel::GetInstance()->SetEndDate(parseEndDate);
814 }
815 }
816
CreateTimePicker(const JSCallbackInfo & info,const JSRef<JSObject> & paramObj)817 void JSDatePicker::CreateTimePicker(const JSCallbackInfo& info, const JSRef<JSObject>& paramObj)
818 {
819 auto theme = GetTheme<PickerTheme>();
820 CHECK_NULL_VOID(theme);
821 DatePickerModel::GetInstance()->CreateTimePicker(theme);
822 auto selectedTime = paramObj->GetProperty("selected");
823 if (selectedTime->IsObject()) {
824 JSRef<JSObject> selectedTimeObj = JSRef<JSObject>::Cast(selectedTime);
825 JSRef<JSVal> changeEventVal = selectedTimeObj->GetProperty("changeEvent");
826 if (!changeEventVal->IsUndefined() && changeEventVal->IsFunction()) {
827 ParseSelectedDateTimeObject(info, selectedTimeObj, true);
828 auto parseSelectedTime = ParseTime(selectedTimeObj->GetProperty("value"));
829 DatePickerModel::GetInstance()->SetSelectedTime(parseSelectedTime);
830 } else {
831 DatePickerModel::GetInstance()->SetSelectedTime(ParseTime(selectedTime));
832 }
833 }
834 }
835
JSBind(BindingTarget globalObj)836 void JSDatePickerDialog::JSBind(BindingTarget globalObj)
837 {
838 JSClass<JSDatePickerDialog>::Declare("DatePickerDialog");
839 JSClass<JSDatePickerDialog>::StaticMethod("show", &JSDatePickerDialog::Show);
840
841 JSClass<JSDatePickerDialog>::Bind<>(globalObj);
842 }
843
DatePickerDialogAppearEvent(const JSCallbackInfo & info,PickerDialogEvent & pickerDialogEvent)844 void DatePickerDialogAppearEvent(const JSCallbackInfo& info, PickerDialogEvent& pickerDialogEvent)
845 {
846 std::function<void()> didAppearEvent;
847 std::function<void()> willAppearEvent;
848 if (info.Length() == 0 || !info[0]->IsObject()) {
849 return;
850 }
851 auto paramObject = JSRef<JSObject>::Cast(info[0]);
852 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
853 auto onDidAppear = paramObject->GetProperty("onDidAppear");
854 if (!onDidAppear->IsUndefined() && onDidAppear->IsFunction()) {
855 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidAppear));
856 didAppearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode]() {
857 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
858 ACE_SCORING_EVENT("DatePickerDialog.onDidAppear");
859 PipelineContext::SetCallBackNode(node);
860 func->Execute();
861 };
862 }
863 auto onWillAppear = paramObject->GetProperty("onWillAppear");
864 if (!onWillAppear->IsUndefined() && onWillAppear->IsFunction()) {
865 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillAppear));
866 willAppearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode]() {
867 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
868 ACE_SCORING_EVENT("DatePickerDialog.onWillAppear");
869 PipelineContext::SetCallBackNode(node);
870 func->Execute();
871 };
872 }
873 pickerDialogEvent.onDidAppear = std::move(didAppearEvent);
874 pickerDialogEvent.onWillAppear = std::move(willAppearEvent);
875 }
876
DatePickerDialogDisappearEvent(const JSCallbackInfo & info,PickerDialogEvent & pickerDialogEvent)877 void DatePickerDialogDisappearEvent(const JSCallbackInfo& info, PickerDialogEvent& pickerDialogEvent)
878 {
879 std::function<void()> didDisappearEvent;
880 std::function<void()> willDisappearEvent;
881 if (info.Length() == 0 || !info[0]->IsObject()) {
882 return;
883 }
884 auto paramObject = JSRef<JSObject>::Cast(info[0]);
885 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
886 auto onDidDisappear = paramObject->GetProperty("onDidDisappear");
887 if (!onDidDisappear->IsUndefined() && onDidDisappear->IsFunction()) {
888 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidDisappear));
889 didDisappearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode]() {
890 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
891 ACE_SCORING_EVENT("DatePickerDialog.onDidDisappear");
892 PipelineContext::SetCallBackNode(node);
893 func->Execute();
894 };
895 }
896 auto onWillDisappear = paramObject->GetProperty("onWillDisappear");
897 if (!onWillDisappear->IsUndefined() && onWillDisappear->IsFunction()) {
898 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDisappear));
899 willDisappearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode]() {
900 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
901 ACE_SCORING_EVENT("DatePickerDialog.onWillDisappear");
902 PipelineContext::SetCallBackNode(node);
903 func->Execute();
904 };
905 }
906 pickerDialogEvent.onDidDisappear = std::move(didDisappearEvent);
907 pickerDialogEvent.onWillDisappear = std::move(willDisappearEvent);
908 }
909
GetDateChangeEvent(const JSRef<JSObject> & paramObject,const JSCallbackInfo & info,const DatePickerType & pickerType,const WeakPtr<NG::FrameNode> & frameNode)910 std::function<void(const std::string&)> JSDatePickerDialog::GetDateChangeEvent(const JSRef<JSObject>& paramObject,
911 const JSCallbackInfo& info, const DatePickerType& pickerType, const WeakPtr<NG::FrameNode>& frameNode)
912 {
913 std::function<void(const std::string&)> dateChangeEvent;
914 auto onDateChange = paramObject->GetProperty("onDateChange");
915 if (!onDateChange->IsUndefined() && onDateChange->IsFunction()) {
916 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDateChange));
917 dateChangeEvent = [execCtx = info.GetExecutionContext(), type = pickerType, func = std::move(jsFunc),
918 node = frameNode](const std::string& info) {
919 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
920 ACE_SCORING_EVENT("DatePickerDialog.onDateChange");
921 auto selectedJson = JsonUtil::ParseJsonString(info);
922 if (!selectedJson || selectedJson->IsNull()) {
923 return;
924 }
925 auto dateObj = GetDateObj(selectedJson);
926 PipelineContext::SetCallBackNode(node);
927 func->ExecuteJS(1, &dateObj);
928 };
929 }
930 return dateChangeEvent;
931 }
932
GetDateAcceptEvent(const JSRef<JSObject> & paramObject,const JSCallbackInfo & info,const DatePickerType & pickerType,const WeakPtr<NG::FrameNode> & frameNode)933 std::function<void(const std::string&)> JSDatePickerDialog::GetDateAcceptEvent(const JSRef<JSObject>& paramObject,
934 const JSCallbackInfo& info, const DatePickerType& pickerType, const WeakPtr<NG::FrameNode>& frameNode)
935 {
936 std::function<void(const std::string&)> dateAcceptEvent;
937 auto onDateAccept = paramObject->GetProperty("onDateAccept");
938 if (!onDateAccept->IsUndefined() && onDateAccept->IsFunction()) {
939 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDateAccept));
940 dateAcceptEvent = [execCtx = info.GetExecutionContext(), type = pickerType, func = std::move(jsFunc),
941 node = frameNode](const std::string& info) {
942 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
943 ACE_SCORING_EVENT("DatePickerDialog.onDateAccept");
944 auto selectedJson = JsonUtil::ParseJsonString(info);
945 if (!selectedJson || selectedJson->IsNull()) {
946 return;
947 }
948 auto dateObj = GetDateObj(selectedJson);
949 PipelineContext::SetCallBackNode(node);
950 func->ExecuteJS(1, &dateObj);
951 };
952 }
953 return dateAcceptEvent;
954 }
955
GetDateObj(const std::unique_ptr<JsonValue> & selectedJson,bool isDatePicker)956 JsiRef<JsiValue> JSDatePickerDialog::GetDateObj(const std::unique_ptr<JsonValue>& selectedJson, bool isDatePicker)
957 {
958 std::tm dateTime {};
959 auto year = selectedJson->GetValue("year");
960 if (year && year->IsNumber()) {
961 dateTime.tm_year = year->GetInt() - 1900; // local date start from 1900
962 }
963 auto month = selectedJson->GetValue("month");
964 if (month && month->IsNumber()) {
965 dateTime.tm_mon = month->GetInt();
966 }
967 auto day = selectedJson->GetValue("day");
968 if (day && day->IsNumber()) {
969 dateTime.tm_mday = day->GetInt();
970 }
971 auto hour = selectedJson->GetValue("hour");
972 if (hour && hour->IsNumber()) {
973 dateTime.tm_hour = hour->GetInt();
974 }
975 auto minute = selectedJson->GetValue("minute");
976 if (minute && minute->IsNumber()) {
977 dateTime.tm_min = minute->GetInt();
978 }
979 auto second = selectedJson->GetValue("second");
980 if (second && second->IsNumber()) {
981 dateTime.tm_sec = second->GetInt();
982 }
983
984 dateTime.tm_isdst = -1; // Auto considering daylight saving time
985 if (!isDatePicker) {
986 auto milliseconds = Date::GetMilliSecondsByDateTime(dateTime);
987 auto dateObj = JSDate::New(milliseconds);
988 return dateObj;
989 }
990
991 auto timestamp = std::chrono::system_clock::from_time_t(std::mktime(&dateTime));
992 auto duration = timestamp.time_since_epoch();
993 auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
994 auto dateObj = JSDate::New(milliseconds);
995 return dateObj;
996 }
997
GetChangeEvent(const JSRef<JSObject> & paramObject,const JSCallbackInfo & info,const DatePickerType & pickerType,const WeakPtr<NG::FrameNode> & frameNode)998 std::function<void(const std::string&)> JSDatePickerDialog::GetChangeEvent(const JSRef<JSObject>& paramObject,
999 const JSCallbackInfo& info, const DatePickerType& pickerType, const WeakPtr<NG::FrameNode>& frameNode)
1000 {
1001 std::function<void(const std::string&)> changeEvent;
1002 auto onChange = paramObject->GetProperty("onChange");
1003 if (!onChange->IsUndefined() && onChange->IsFunction()) {
1004 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onChange));
1005 changeEvent = [execCtx = info.GetExecutionContext(), type = pickerType, func = std::move(jsFunc),
1006 node = frameNode](const std::string& info) {
1007 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1008 std::vector<std::string> keys;
1009 keys = { "year", "month", "day" };
1010 ACE_SCORING_EVENT("DatePickerDialog.onChange");
1011 PipelineContext::SetCallBackNode(node);
1012 func->Execute(keys, info);
1013 };
1014 }
1015 return changeEvent;
1016 }
1017
GetAcceptEvent(const JSRef<JSObject> & paramObject,const JSCallbackInfo & info,const WeakPtr<NG::FrameNode> & frameNode)1018 std::function<void(const std::string&)> JSDatePickerDialog::GetAcceptEvent(
1019 const JSRef<JSObject>& paramObject, const JSCallbackInfo& info, const WeakPtr<NG::FrameNode>& frameNode)
1020 {
1021 std::function<void(const std::string&)> acceptEvent;
1022 auto onAccept = paramObject->GetProperty("onAccept");
1023 if (!onAccept->IsUndefined() && onAccept->IsFunction()) {
1024 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAccept));
1025 acceptEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode](
1026 const std::string& info) {
1027 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1028 std::vector<std::string> keys = { "year", "month", "day", "hour", "minute", "second" };
1029 ACE_SCORING_EVENT("DatePickerDialog.onAccept");
1030 PipelineContext::SetCallBackNode(node);
1031 func->Execute(keys, info);
1032 };
1033 }
1034 return acceptEvent;
1035 }
1036
GetCancelEvent(const JSRef<JSObject> & paramObject,const JSCallbackInfo & info,const WeakPtr<NG::FrameNode> & frameNode)1037 std::function<void()> JSDatePickerDialog::GetCancelEvent(
1038 const JSRef<JSObject>& paramObject, const JSCallbackInfo& info, const WeakPtr<NG::FrameNode>& frameNode)
1039 {
1040 std::function<void()> cancelEvent;
1041 auto onCancel = paramObject->GetProperty("onCancel");
1042 if (!onCancel->IsUndefined() && onCancel->IsFunction()) {
1043 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCancel));
1044 cancelEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = frameNode]() {
1045 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1046 ACE_SCORING_EVENT("DatePickerDialog.onCancel");
1047 PipelineContext::SetCallBackNode(node);
1048 func->Execute();
1049 };
1050 }
1051 return cancelEvent;
1052 }
1053
UpdateLunarSwitchSettingData(const JSRef<JSObject> & paramObject,NG::DatePickerSettingData & settingData)1054 void JSDatePickerDialog::UpdateLunarSwitchSettingData(
1055 const JSRef<JSObject>& paramObject, NG::DatePickerSettingData& settingData)
1056 {
1057 auto selectedColorValue = paramObject->GetProperty("selectedColor");
1058 auto unselectedColorValue = paramObject->GetProperty("unselectedColor");
1059 auto strokeColorValue = paramObject->GetProperty("strokeColor");
1060 Color selectedColor;
1061 if (JSViewAbstract::ParseJsColor(selectedColorValue, selectedColor)) {
1062 settingData.checkboxSettingData.selectedColor = selectedColor;
1063 }
1064 Color unselectedColor;
1065 if (JSViewAbstract::ParseJsColor(unselectedColorValue, unselectedColor)) {
1066 settingData.checkboxSettingData.unselectedColor = unselectedColor;
1067 }
1068 Color strokeColor;
1069 if (JSViewAbstract::ParseJsColor(strokeColorValue, strokeColor)) {
1070 settingData.checkboxSettingData.strokeColor = strokeColor;
1071 }
1072 }
1073
UpdateDatePickerSettingData(const JSRef<JSObject> & paramObject,NG::DatePickerSettingData & settingData)1074 void JSDatePickerDialog::UpdateDatePickerSettingData(
1075 const JSRef<JSObject>& paramObject, NG::DatePickerSettingData& settingData)
1076 {
1077 auto lunar = paramObject->GetProperty("lunar");
1078 auto lunarSwitch = paramObject->GetProperty("lunarSwitch");
1079 auto sTime = paramObject->GetProperty("showTime");
1080 auto useMilitary = paramObject->GetProperty("useMilitaryTime");
1081 settingData.isLunar = lunar->ToBoolean();
1082 settingData.lunarswitch = lunarSwitch->ToBoolean();
1083 if (settingData.lunarswitch) {
1084 auto lunarSwitchStyle = paramObject->GetProperty("lunarSwitchStyle");
1085 if ((!lunarSwitchStyle->IsUndefined()) && lunarSwitchStyle->IsObject()) {
1086 auto style = JSRef<JSObject>::Cast(lunarSwitchStyle);
1087 UpdateLunarSwitchSettingData(style, settingData);
1088 }
1089 }
1090 auto enableHapticFeedbackValue = paramObject->GetProperty("enableHapticFeedback");
1091 if (enableHapticFeedbackValue->IsBoolean()) {
1092 settingData.isEnableHapticFeedback = enableHapticFeedbackValue->ToBoolean();
1093 }
1094 settingData.showTime = sTime->ToBoolean();
1095 settingData.useMilitary = useMilitary->ToBoolean();
1096
1097 auto mode = paramObject->GetProperty("mode");
1098 auto datePickerMode = DatePickerMode::DATE;
1099 if (!mode->IsNull() && mode->IsNumber()) {
1100 auto parseMode = mode->ToNumber<int32_t>();
1101 if (parseMode >= static_cast<int32_t>(DatePickerMode::DATE) &&
1102 parseMode <= static_cast<int32_t>(DatePickerMode::MONTH_AND_DAY)) {
1103 datePickerMode = static_cast<DatePickerMode>(parseMode);
1104 }
1105 }
1106 settingData.mode = datePickerMode;
1107 auto isLoop = paramObject->GetProperty("canLoop");
1108 if (isLoop->IsBoolean()) {
1109 settingData.canLoop = isLoop->ToBoolean();
1110 } else {
1111 settingData.canLoop = true;
1112 }
1113
1114 auto dateTimeOptionsValue = paramObject->GetProperty("dateTimeOptions");
1115 if (dateTimeOptionsValue->IsObject()) {
1116 auto dateTimeOptionsObj = JSRef<JSObject>::Cast(dateTimeOptionsValue);
1117 JSDatePickerDialog::ParseDateTimeOptions(dateTimeOptionsObj, settingData.dateTimeOptions);
1118 }
1119 JSDatePicker::ParseTextProperties(paramObject, settingData.properties);
1120 }
1121
UpdatePickerDialogTimeInfo(const JSRef<JSObject> & paramObject,PickerDialogInfo & pickerDialog)1122 void JSDatePickerDialog::UpdatePickerDialogTimeInfo(const JSRef<JSObject>& paramObject, PickerDialogInfo& pickerDialog)
1123 {
1124 auto theme = GetTheme<PickerTheme>();
1125 CHECK_NULL_VOID(theme);
1126
1127 auto startDate = paramObject->GetProperty("start");
1128 if (startDate->IsObject()) {
1129 pickerDialog.isStartDate = true;
1130 }
1131 auto endDate = paramObject->GetProperty("end");
1132 if (endDate->IsObject()) {
1133 pickerDialog.isEndDate = true;
1134 }
1135 auto selectedDate = paramObject->GetProperty("selected");
1136 if (selectedDate->IsObject()) {
1137 pickerDialog.isSelectedDate = true;
1138 }
1139 auto parseStartDate = ParseDate(startDate);
1140 auto parseEndDate = ParseDate(endDate);
1141 if (parseStartDate.GetYear() <= 0) {
1142 parseStartDate = theme->GetDefaultStartDate();
1143 }
1144 if (parseEndDate.GetYear() <= 0) {
1145 parseEndDate = theme->GetDefaultEndDate();
1146 }
1147 auto startDays = parseStartDate.ToDays();
1148 auto endDays = parseEndDate.ToDays();
1149 if (startDays > endDays) {
1150 parseStartDate = theme->GetDefaultStartDate();
1151 parseEndDate = theme->GetDefaultEndDate();
1152 }
1153 pickerDialog.parseStartDate = parseStartDate;
1154 pickerDialog.parseEndDate = parseEndDate;
1155 pickerDialog.parseSelectedDate = ParseDate(selectedDate);
1156 pickerDialog.pickerTime = ParseTime(selectedDate);
1157 }
1158
UpdatePickerDialogPositionInfo(const JSRef<JSObject> & paramObject,PickerDialogInfo & pickerDialog)1159 void JSDatePickerDialog::UpdatePickerDialogPositionInfo(
1160 const JSRef<JSObject>& paramObject, PickerDialogInfo& pickerDialog)
1161 {
1162 // Parse alignment
1163 auto alignmentValue = paramObject->GetProperty("alignment");
1164 if (alignmentValue->IsNumber()) {
1165 auto alignment = alignmentValue->ToNumber<int32_t>();
1166 if (alignment >= 0 && alignment < static_cast<int32_t>(DIALOG_ALIGNMENT.size())) {
1167 pickerDialog.alignment = DIALOG_ALIGNMENT[alignment];
1168 }
1169 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1170 if (alignment == static_cast<int32_t>(DialogAlignment::TOP) ||
1171 alignment == static_cast<int32_t>(DialogAlignment::TOP_START) ||
1172 alignment == static_cast<int32_t>(DialogAlignment::TOP_END)) {
1173 pickerDialog.offset = DATEPICKER_OFFSET_DEFAULT_TOP;
1174 }
1175 }
1176 }
1177
1178 // Parse offset
1179 auto offsetValue = paramObject->GetProperty("offset");
1180 if (offsetValue->IsObject()) {
1181 auto offsetObj = JSRef<JSObject>::Cast(offsetValue);
1182 CalcDimension dx;
1183 auto dxValue = offsetObj->GetProperty("dx");
1184 ParseJsDimensionVp(dxValue, dx);
1185 CalcDimension dy;
1186 auto dyValue = offsetObj->GetProperty("dy");
1187 ParseJsDimensionVp(dyValue, dy);
1188 pickerDialog.offset = DimensionOffset(dx, dy);
1189 }
1190 }
1191
UpdatePickerDialogInfo(const JSRef<JSObject> & paramObject,PickerDialogInfo & pickerDialog)1192 void JSDatePickerDialog::UpdatePickerDialogInfo(const JSRef<JSObject>& paramObject, PickerDialogInfo& pickerDialog)
1193 {
1194 UpdatePickerDialogTimeInfo(paramObject, pickerDialog);
1195 UpdatePickerDialogPositionInfo(paramObject, pickerDialog);
1196 // Parse maskRect.
1197 auto maskRectValue = paramObject->GetProperty("maskRect");
1198 DimensionRect maskRect;
1199 if (JSViewAbstract::ParseJsDimensionRect(maskRectValue, maskRect)) {
1200 pickerDialog.maskRect = maskRect;
1201 }
1202
1203 auto backgroundColorValue = paramObject->GetProperty("backgroundColor");
1204 Color backgroundColor;
1205 if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
1206 pickerDialog.backgroundColor = backgroundColor;
1207 }
1208
1209 auto backgroundBlurStyle = paramObject->GetProperty("backgroundBlurStyle");
1210 if (backgroundBlurStyle->IsNumber()) {
1211 auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
1212 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
1213 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
1214 pickerDialog.backgroundBlurStyle = blurStyle;
1215 }
1216 }
1217
1218 auto shadowValue = paramObject->GetProperty("shadow");
1219 Shadow shadow;
1220 if ((shadowValue->IsObject() || shadowValue->IsNumber()) && JSViewAbstract::ParseShadowProps(shadowValue, shadow)) {
1221 pickerDialog.shadow = shadow;
1222 }
1223
1224 ParseDatePickerHoverMode(pickerDialog, paramObject);
1225 ParseDatePickerBlurStyleOption(pickerDialog, paramObject);
1226 ParseDatePickerEffectOption(pickerDialog, paramObject);
1227 }
1228
Show(const JSCallbackInfo & info)1229 void JSDatePickerDialog::Show(const JSCallbackInfo& info)
1230 {
1231 auto scopedDelegate = EngineHelper::GetCurrentDelegateSafely();
1232 CHECK_NULL_VOID(scopedDelegate);
1233 if (!info[0]->IsObject()) {
1234 return;
1235 }
1236
1237 auto paramObject = info[0]->IsEmpty() ? (JSRef<JSObject>::New()) : JSRef<JSObject>::Cast(info[0]);
1238 DatePickerType pickerType = DatePickerType::DATE;
1239 auto type = paramObject->GetProperty("type");
1240 if (type->IsNumber()) {
1241 pickerType = static_cast<DatePickerType>(type->ToNumber<int32_t>());
1242 }
1243 std::function<void()> cancelEvent;
1244 std::function<void(const std::string&)> acceptEvent;
1245 std::function<void(const std::string&)> changeEvent;
1246 std::function<void(const std::string&)> dateChangeEvent;
1247 std::function<void(const std::string&)> dateAcceptEvent;
1248 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1249 changeEvent = GetChangeEvent(paramObject, info, pickerType, frameNode);
1250 acceptEvent = GetAcceptEvent(paramObject, info, frameNode);
1251 cancelEvent = GetCancelEvent(paramObject, info, frameNode);
1252 dateChangeEvent = GetDateChangeEvent(paramObject, info, pickerType, frameNode);
1253 dateAcceptEvent = GetDateAcceptEvent(paramObject, info, pickerType, frameNode);
1254 NG::DatePickerSettingData settingData;
1255 UpdateDatePickerSettingData(paramObject, settingData);
1256 PickerDialogInfo pickerDialog;
1257 UpdatePickerDialogInfo(paramObject, pickerDialog);
1258
1259 auto buttonInfos = ParseButtonStyles(paramObject);
1260 PickerDialogEvent pickerDialogEvent { nullptr, nullptr, nullptr, nullptr };
1261 DatePickerDialogAppearEvent(info, pickerDialogEvent);
1262 DatePickerDialogDisappearEvent(info, pickerDialogEvent);
1263 DatePickerDialogModel::GetInstance()->SetDatePickerDialogShow(pickerDialog, settingData, std::move(cancelEvent),
1264 std::move(acceptEvent), std::move(changeEvent), std::move(dateAcceptEvent), std::move(dateChangeEvent),
1265 pickerType, pickerDialogEvent, buttonInfos);
1266 }
1267
DatePickerDialogShow(const JSRef<JSObject> & paramObj,const std::map<std::string,NG::DialogEvent> & dialogEvent,const std::map<std::string,NG::DialogGestureEvent> & dialogCancelEvent)1268 void JSDatePickerDialog::DatePickerDialogShow(const JSRef<JSObject>& paramObj,
1269 const std::map<std::string, NG::DialogEvent>& dialogEvent,
1270 const std::map<std::string, NG::DialogGestureEvent>& dialogCancelEvent)
1271 {
1272 auto container = Container::CurrentSafely();
1273 if (!container) {
1274 return;
1275 }
1276 auto pipelineContext = AccessibilityManager::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
1277 if (!pipelineContext) {
1278 return;
1279 }
1280
1281 auto executor = pipelineContext->GetTaskExecutor();
1282 if (!executor) {
1283 return;
1284 }
1285
1286 NG::DatePickerSettingData settingData;
1287 auto startDate = paramObj->GetProperty("start");
1288 auto endDate = paramObj->GetProperty("end");
1289 auto selectedDate = paramObj->GetProperty("selected");
1290 auto lunar = paramObj->GetProperty("lunar");
1291 auto sTime = paramObj->GetProperty("showTime");
1292 auto useMilitary = paramObj->GetProperty("useMilitaryTime");
1293 settingData.isLunar = lunar->ToBoolean();
1294 settingData.showTime = sTime->ToBoolean();
1295 settingData.useMilitary = useMilitary->ToBoolean();
1296 auto parseStartDate = ParseDate(startDate);
1297 auto parseEndDate = ParseDate(endDate);
1298 auto parseSelectedDate = ParseDate(selectedDate);
1299
1300 auto theme = GetTheme<DialogTheme>();
1301 CHECK_NULL_VOID(theme);
1302
1303 DialogProperties properties;
1304 properties.alignment = theme->GetAlignment();
1305 if (properties.alignment == DialogAlignment::BOTTOM &&
1306 Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_ELEVEN)) {
1307 properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
1308 }
1309 properties.customStyle = false;
1310 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1311 properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
1312 }
1313
1314 std::map<std::string, PickerDate> datePickerProperty;
1315 std::map<std::string, PickerTime> timePickerProperty;
1316 if (startDate->IsObject()) {
1317 settingData.datePickerProperty["start"] = parseStartDate;
1318 }
1319 if (endDate->IsObject()) {
1320 settingData.datePickerProperty["end"] = parseEndDate;
1321 }
1322 if (selectedDate->IsObject()) {
1323 settingData.datePickerProperty["selected"] = parseSelectedDate;
1324 settingData.timePickerProperty["selected"] = ParseTime(selectedDate);
1325 }
1326 auto enableHapticFeedbackValue = paramObj->GetProperty("enableHapticFeedback");
1327 if (enableHapticFeedbackValue->IsBoolean()) {
1328 settingData.isEnableHapticFeedback = enableHapticFeedbackValue->ToBoolean();
1329 }
1330
1331 JSDatePicker::ParseTextProperties(paramObj, settingData.properties);
1332 auto context = AccessibilityManager::DynamicCast<NG::PipelineContext>(pipelineContext);
1333 auto overlayManager = context ? context->GetOverlayManager() : nullptr;
1334 executor->PostTask(
1335 [properties, settingData, dialogEvent, dialogCancelEvent, weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
1336 auto overlayManager = weak.Upgrade();
1337 CHECK_NULL_VOID(overlayManager);
1338 overlayManager->ShowDateDialog(properties, settingData, dialogEvent, dialogCancelEvent);
1339 },
1340 TaskExecutor::TaskType::UI, "ArkUIDialogShowDatePicker",
1341 TaskExecutor::GetPriorityTypeWithCheck(PriorityType::VIP));
1342 }
1343
CreateDatePicker(RefPtr<Component> & component,const JSRef<JSObject> & paramObj)1344 void JSDatePickerDialog::CreateDatePicker(RefPtr<Component>& component, const JSRef<JSObject>& paramObj)
1345 {
1346 auto datePicker = AceType::MakeRefPtr<PickerDateComponent>();
1347 auto startDate = paramObj->GetProperty("start");
1348 auto endDate = paramObj->GetProperty("end");
1349 auto selectedDate = paramObj->GetProperty("selected");
1350 auto lunar = paramObj->GetProperty("lunar");
1351 bool isLunar = lunar->ToBoolean();
1352 auto parseStartDate = ParseDate(startDate);
1353 auto parseEndDate = ParseDate(endDate);
1354 auto parseSelectedDate = ParseDate(selectedDate);
1355 auto startDays = parseStartDate.ToDays();
1356 auto endDays = parseEndDate.ToDays();
1357 if (startDays > endDays) {
1358 parseStartDate.SetYear(0);
1359 parseEndDate.SetYear(0);
1360 }
1361 if (startDate->IsObject()) {
1362 datePicker->SetStartDate(parseStartDate);
1363 }
1364 if (endDate->IsObject()) {
1365 datePicker->SetEndDate(parseEndDate);
1366 }
1367 if (selectedDate->IsObject()) {
1368 datePicker->SetSelectedDate(parseSelectedDate);
1369 }
1370 datePicker->SetIsDialog(true);
1371 datePicker->SetIsCreateDialogComponent(true);
1372 datePicker->SetShowLunar(isLunar);
1373
1374 component = datePicker;
1375 }
1376
CreateTimePicker(RefPtr<Component> & component,const JSRef<JSObject> & paramObj)1377 void JSDatePickerDialog::CreateTimePicker(RefPtr<Component>& component, const JSRef<JSObject>& paramObj)
1378 {
1379 auto timePicker = AceType::MakeRefPtr<PickerTimeComponent>();
1380 auto selectedTime = paramObj->GetProperty("selected");
1381 auto useMilitaryTime = paramObj->GetProperty("useMilitaryTime");
1382 bool isUseMilitaryTime = useMilitaryTime->ToBoolean();
1383 if (selectedTime->IsObject()) {
1384 timePicker->SetSelectedTime(ParseTime(selectedTime));
1385 }
1386 timePicker->SetIsDialog(true);
1387 timePicker->SetIsCreateDialogComponent(true);
1388 timePicker->SetHour24(isUseMilitaryTime);
1389 component = timePicker;
1390 }
1391
ParseDate(const JSRef<JSVal> & dateVal)1392 PickerDate JSDatePickerDialog::ParseDate(const JSRef<JSVal>& dateVal)
1393 {
1394 auto pickerDate = PickerDate();
1395 if (!dateVal->IsObject()) {
1396 return pickerDate;
1397 }
1398 auto dateObj = JSRef<JSObject>::Cast(dateVal);
1399 auto yearFuncJsVal = dateObj->GetProperty("getFullYear");
1400 auto monthFuncJsVal = dateObj->GetProperty("getMonth");
1401 auto dateFuncJsVal = dateObj->GetProperty("getDate");
1402 if (!(yearFuncJsVal->IsFunction() && monthFuncJsVal->IsFunction() && dateFuncJsVal->IsFunction())) {
1403 return pickerDate;
1404 }
1405 auto yearFunc = JSRef<JSFunc>::Cast(yearFuncJsVal);
1406 auto monthFunc = JSRef<JSFunc>::Cast(monthFuncJsVal);
1407 auto dateFunc = JSRef<JSFunc>::Cast(dateFuncJsVal);
1408 JSRef<JSVal> year = yearFunc->Call(dateObj);
1409 JSRef<JSVal> month = monthFunc->Call(dateObj);
1410 JSRef<JSVal> date = dateFunc->Call(dateObj);
1411
1412 if (year->IsNumber() && month->IsNumber() && date->IsNumber()) {
1413 pickerDate.SetYear(year->ToNumber<int32_t>());
1414 pickerDate.SetMonth(month->ToNumber<int32_t>() + 1); // 0-11 means 1 to 12 months
1415 pickerDate.SetDay(date->ToNumber<int32_t>());
1416 }
1417 return pickerDate;
1418 }
1419
ParseTime(const JSRef<JSVal> & timeVal)1420 PickerTime JSDatePickerDialog::ParseTime(const JSRef<JSVal>& timeVal)
1421 {
1422 auto pickerTime = PickerTime();
1423 if (!timeVal->IsObject()) {
1424 return pickerTime;
1425 }
1426 auto timeObj = JSRef<JSObject>::Cast(timeVal);
1427 auto hourFuncJsVal = timeObj->GetProperty("getHours");
1428 auto minuteFuncJsVal = timeObj->GetProperty("getMinutes");
1429 auto secondFuncJsVal = timeObj->GetProperty("getSeconds");
1430 if (!(hourFuncJsVal->IsFunction() && minuteFuncJsVal->IsFunction() && secondFuncJsVal->IsFunction())) {
1431 return pickerTime;
1432 }
1433 auto hourFunc = JSRef<JSFunc>::Cast(hourFuncJsVal);
1434 auto minuteFunc = JSRef<JSFunc>::Cast(minuteFuncJsVal);
1435 auto secondFunc = JSRef<JSFunc>::Cast(secondFuncJsVal);
1436 JSRef<JSVal> hour = hourFunc->Call(timeObj);
1437 JSRef<JSVal> minute = minuteFunc->Call(timeObj);
1438 JSRef<JSVal> second = secondFunc->Call(timeObj);
1439
1440 if (hour->IsNumber() && minute->IsNumber() && second->IsNumber()) {
1441 pickerTime.SetHour(hour->ToNumber<int32_t>());
1442 pickerTime.SetMinute(minute->ToNumber<int32_t>());
1443 pickerTime.SetSecond(second->ToNumber<int32_t>());
1444 }
1445 return pickerTime;
1446 }
1447
ParseDateTimeOptions(const JSRef<JSObject> & paramObj,DateTimeType & dateTimeOptions)1448 void JSDatePickerDialog::ParseDateTimeOptions(const JSRef<JSObject>& paramObj, DateTimeType& dateTimeOptions)
1449 {
1450 dateTimeOptions.hourType = ZeroPrefixType::AUTO;
1451 dateTimeOptions.minuteType = ZeroPrefixType::AUTO;
1452 dateTimeOptions.secondType = ZeroPrefixType::AUTO;
1453
1454 auto hourValue = paramObj->GetProperty(TIMEPICKER_OPTIONS_HOUR);
1455 if (hourValue->IsString()) {
1456 std::string hour = hourValue->ToString();
1457 if (hour == TIMEPICKER_OPTIONS_TWO_DIGIT_VAL) {
1458 dateTimeOptions.hourType = ZeroPrefixType::SHOW;
1459 } else if (hour == TIMEPICKER_OPTIONS_NUMERIC_VAL) {
1460 dateTimeOptions.hourType = ZeroPrefixType::HIDE;
1461 }
1462 }
1463 auto minuteValue = paramObj->GetProperty(TIMEPICKER_OPTIONS_MINUTE);
1464 if (minuteValue->IsString()) {
1465 dateTimeOptions.minuteType = ZeroPrefixType::SHOW;
1466 std::string minute = minuteValue->ToString();
1467 if (minute == TIMEPICKER_OPTIONS_NUMERIC_VAL) {
1468 dateTimeOptions.minuteType = ZeroPrefixType::HIDE;
1469 }
1470 }
1471 }
1472
JSBind(BindingTarget globalObj)1473 void JSTimePicker::JSBind(BindingTarget globalObj)
1474 {
1475 JSClass<JSTimePicker>::Declare("TimePicker");
1476 MethodOptions opt = MethodOptions::NONE;
1477 JSClass<JSTimePicker>::StaticMethod("create", &JSTimePicker::Create, opt);
1478 JSClass<JSTimePicker>::StaticMethod("onChange", &JSTimePicker::OnChange);
1479 JSClass<JSTimePicker>::StaticMethod("backgroundColor", &JSTimePicker::PickerBackgroundColor);
1480 JSClass<JSTimePicker>::StaticMethod("loop", &JSTimePicker::Loop);
1481 JSClass<JSTimePicker>::StaticMethod("useMilitaryTime", &JSTimePicker::UseMilitaryTime);
1482 JSClass<JSTimePicker>::StaticMethod("enableHapticFeedback", &JSTimePicker::EnableHapticFeedback);
1483 JSClass<JSTimePicker>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
1484 JSClass<JSTimePicker>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
1485 JSClass<JSTimePicker>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
1486 JSClass<JSTimePicker>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
1487 JSClass<JSTimePicker>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
1488 JSClass<JSTimePicker>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
1489 JSClass<JSTimePicker>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
1490 JSClass<JSTimePicker>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
1491 JSClass<JSTimePicker>::StaticMethod("disappearTextStyle", &JSTimePicker::SetDisappearTextStyle);
1492 JSClass<JSTimePicker>::StaticMethod("textStyle", &JSTimePicker::SetTextStyle);
1493 JSClass<JSTimePicker>::StaticMethod("selectedTextStyle", &JSTimePicker::SetSelectedTextStyle);
1494 JSClass<JSTimePicker>::StaticMethod("dateTimeOptions", &JSTimePicker::DateTimeOptions);
1495 JSClass<JSTimePicker>::StaticMethod("opacity", &JSTimePicker::JsOpacity);
1496 JSClass<JSTimePicker>::StaticMethod("enableCascade", &JSTimePicker::EnableCascade);
1497 JSClass<JSTimePicker>::StaticMethod("onEnterSelectedArea", &JSTimePicker::OnEnterSelectedArea);
1498 JSClass<JSTimePicker>::StaticMethod("digitalCrownSensitivity", &JSTimePicker::SetDigitalCrownSensitivity);
1499 JSClass<JSTimePicker>::InheritAndBind<JSViewAbstract>(globalObj);
1500 }
1501
SetDigitalCrownSensitivity(const JSCallbackInfo & info)1502 void JSTimePicker::SetDigitalCrownSensitivity(const JSCallbackInfo& info)
1503 {
1504 int32_t value = OHOS::Ace::NG::DEFAULT_CROWNSENSITIVITY;
1505 if (info[0]->IsNumber()) {
1506 value = info[0]->ToNumber<int32_t>();
1507 }
1508 TimePickerModel::GetInstance()->SetDigitalCrownSensitivity(value);
1509 }
1510
Create(const JSCallbackInfo & info)1511 void JSTimePicker::Create(const JSCallbackInfo& info)
1512 {
1513 JSRef<JSObject> paramObject = JSRef<JSObject>::New();
1514 if (info.Length() >= 1 && info[0]->IsObject()) {
1515 paramObject = JSRef<JSObject>::Cast(info[0]);
1516 }
1517 CreateTimePicker(info, paramObject);
1518 }
1519
JsOpacity(const JSCallbackInfo & info)1520 void JSTimePicker::JsOpacity(const JSCallbackInfo& info)
1521 {
1522 JSViewAbstract::JsOpacity(info);
1523 TimePickerModel::GetInstance()->HasUserDefinedOpacity();
1524 }
1525
Loop(const JSCallbackInfo & info)1526 void JSTimePicker::Loop(const JSCallbackInfo& info)
1527 {
1528 bool isLoop = true;
1529 if (info[0]->IsBoolean()) {
1530 isLoop = info[0]->ToBoolean();
1531 }
1532 TimePickerModel::GetInstance()->SetWheelModeEnabled(isLoop);
1533 }
1534
EnableHapticFeedback(const JSCallbackInfo & info)1535 void JSTimePicker::EnableHapticFeedback(const JSCallbackInfo& info)
1536 {
1537 bool isEnableHapticFeedback = true;
1538 if (info[0]->IsBoolean()) {
1539 isEnableHapticFeedback = info[0]->ToBoolean();
1540 }
1541 TimePickerModel::GetInstance()->SetIsEnableHapticFeedback(isEnableHapticFeedback);
1542 }
1543
UseMilitaryTime(bool isUseMilitaryTime)1544 void JSTimePicker::UseMilitaryTime(bool isUseMilitaryTime)
1545 {
1546 TimePickerModel::GetInstance()->SetHour24(isUseMilitaryTime);
1547 }
1548
EnableCascade(const JSCallbackInfo & info)1549 void JSTimePicker::EnableCascade(const JSCallbackInfo& info)
1550 {
1551 bool isEnableCascade = false;
1552 if (info[0]->IsBoolean()) {
1553 isEnableCascade = info[0]->ToBoolean();
1554 }
1555 TimePickerModel::GetInstance()->SetEnableCascade(isEnableCascade);
1556 }
1557
DateTimeOptions(const JSCallbackInfo & info)1558 void JSTimePicker::DateTimeOptions(const JSCallbackInfo& info)
1559 {
1560 JSRef<JSObject> paramObject;
1561 ZeroPrefixType hourType = ZeroPrefixType::AUTO;
1562 ZeroPrefixType minuteType = ZeroPrefixType::AUTO;
1563 ZeroPrefixType secondType = ZeroPrefixType::AUTO;
1564 if (info.Length() >= 1 && info[0]->IsObject()) {
1565 paramObject = JSRef<JSObject>::Cast(info[0]);
1566 auto hourValue = paramObject->GetProperty(TIMEPICKER_OPTIONS_HOUR);
1567 if (hourValue->IsString()) {
1568 std::string hour = hourValue->ToString();
1569 if (hour == TIMEPICKER_OPTIONS_TWO_DIGIT_VAL) {
1570 hourType = ZeroPrefixType::SHOW;
1571 } else if (hour == TIMEPICKER_OPTIONS_NUMERIC_VAL) {
1572 hourType = ZeroPrefixType::HIDE;
1573 }
1574 }
1575 auto minuteValue = paramObject->GetProperty(TIMEPICKER_OPTIONS_MINUTE);
1576 if (minuteValue->IsString()) {
1577 minuteType = ZeroPrefixType::SHOW;
1578 std::string minute = minuteValue->ToString();
1579 if (minute == TIMEPICKER_OPTIONS_NUMERIC_VAL) {
1580 minuteType = ZeroPrefixType::HIDE;
1581 }
1582 }
1583 auto secondValue = paramObject->GetProperty(TIMEPICKER_OPTIONS_SECOND);
1584 if (secondValue->IsString()) {
1585 secondType = ZeroPrefixType::SHOW;
1586 std::string second = secondValue->ToString();
1587 if (second == TIMEPICKER_OPTIONS_NUMERIC_VAL) {
1588 secondType = ZeroPrefixType::HIDE;
1589 }
1590 }
1591 }
1592 TimePickerModel::GetInstance()->SetDateTimeOptions(hourType, minuteType, secondType);
1593 }
1594
PickerBackgroundColor(const JSCallbackInfo & info)1595 void JSTimePicker::PickerBackgroundColor(const JSCallbackInfo& info)
1596 {
1597 JSViewAbstract::JsBackgroundColor(info);
1598
1599 if (info.Length() < 1) {
1600 return;
1601 }
1602 Color backgroundColor;
1603 if (!ParseJsColor(info[0], backgroundColor)) {
1604 return;
1605 }
1606 TimePickerModel::GetInstance()->SetBackgroundColor(backgroundColor);
1607 }
1608
SetDisappearTextStyle(const JSCallbackInfo & info)1609 void JSTimePicker::SetDisappearTextStyle(const JSCallbackInfo& info)
1610 {
1611 auto theme = GetTheme<PickerTheme>();
1612 CHECK_NULL_VOID(theme);
1613 NG::PickerTextStyle textStyle;
1614 if (info[0]->IsObject()) {
1615 JSDatePicker::ParseTextStyle(info[0], textStyle, "disappearTextStyleTime");
1616 }
1617 TimePickerModel::GetInstance()->SetDisappearTextStyle(theme, textStyle);
1618 }
1619
SetTextStyle(const JSCallbackInfo & info)1620 void JSTimePicker::SetTextStyle(const JSCallbackInfo& info)
1621 {
1622 auto theme = GetTheme<PickerTheme>();
1623 CHECK_NULL_VOID(theme);
1624 NG::PickerTextStyle textStyle;
1625 if (info[0]->IsObject()) {
1626 JSDatePicker::ParseTextStyle(info[0], textStyle, "textStyleTime");
1627 }
1628 TimePickerModel::GetInstance()->SetNormalTextStyle(theme, textStyle);
1629 }
1630
SetSelectedTextStyle(const JSCallbackInfo & info)1631 void JSTimePicker::SetSelectedTextStyle(const JSCallbackInfo& info)
1632 {
1633 auto theme = GetTheme<PickerTheme>();
1634 CHECK_NULL_VOID(theme);
1635 NG::PickerTextStyle textStyle;
1636 if (info[0]->IsObject()) {
1637 JSDatePicker::ParseTextStyle(info[0], textStyle, "selectedTextStyleTime");
1638 }
1639 TimePickerModel::GetInstance()->SetSelectedTextStyle(theme, textStyle);
1640 if (textStyle.textColor.has_value() && theme->IsCircleDial()) {
1641 TimePickerModel::GetInstance()->UpdateUserSetSelectColor();
1642 }
1643 }
1644
CreateTimePicker(const JSCallbackInfo & info,const JSRef<JSObject> & paramObj)1645 void JSTimePicker::CreateTimePicker(const JSCallbackInfo& info, const JSRef<JSObject>& paramObj)
1646 {
1647 auto startTime = paramObj->GetProperty("start");
1648 auto endTime = paramObj->GetProperty("end");
1649 auto selectedTime = paramObj->GetProperty("selected");
1650 auto theme = GetTheme<PickerTheme>();
1651 CHECK_NULL_VOID(theme);
1652 auto parseStartTime = ParseTime(startTime, theme->GetDefaultStartTime(), true);
1653 auto parseEndTime = ParseTime(endTime, theme->GetDefaultEndTime(), true);
1654 if (parseStartTime.ToMinutes() > parseEndTime.ToMinutes()) {
1655 parseStartTime = theme->GetDefaultStartTime();
1656 parseEndTime = theme->GetDefaultEndTime();
1657 }
1658 auto formatValue = paramObj->GetProperty("format");
1659 bool showSecond = false;
1660 if (formatValue->IsNumber()) {
1661 auto displayedFormat = static_cast<TimePickerFormat>(formatValue->ToNumber<int32_t>());
1662 if (displayedFormat == TimePickerFormat::HOUR_MINUTE_SECOND) {
1663 showSecond = true;
1664 }
1665 }
1666 TimePickerModel::GetInstance()->CreateTimePicker(theme, showSecond);
1667 TimePickerModel::GetInstance()->SetStartTime(parseStartTime);
1668 TimePickerModel::GetInstance()->SetEndTime(parseEndTime);
1669 if (selectedTime->IsObject()) {
1670 JSRef<JSObject> selectedTimeObj = JSRef<JSObject>::Cast(selectedTime);
1671 JSRef<JSVal> changeEventVal = selectedTimeObj->GetProperty("changeEvent");
1672 if (!changeEventVal->IsUndefined() && changeEventVal->IsFunction()) {
1673 ParseSelectedDateTimeObject(info, selectedTimeObj, false);
1674 auto parseSelectedTime = ParseTime(selectedTimeObj->GetProperty("value"));
1675 TimePickerModel::GetInstance()->SetSelectedTime(parseSelectedTime);
1676 } else {
1677 TimePickerModel::GetInstance()->SetSelectedTime(ParseTime(selectedTime));
1678 }
1679 }
1680 SetDefaultAttributes();
1681 }
1682
SetDefaultAttributes()1683 void JSTimePicker::SetDefaultAttributes()
1684 {
1685 auto theme = GetTheme<PickerTheme>();
1686 CHECK_NULL_VOID(theme);
1687 NG::PickerTextStyle textStyle;
1688 auto selectedStyle = theme->GetOptionStyle(true, false);
1689 textStyle.fontSize = selectedStyle.GetFontSize();
1690 textStyle.fontWeight = selectedStyle.GetFontWeight();
1691 TimePickerModel::GetInstance()->SetSelectedTextStyle(theme, textStyle);
1692
1693 auto disappearStyle = theme->GetDisappearOptionStyle();
1694 textStyle.fontSize = disappearStyle.GetFontSize();
1695 textStyle.fontWeight = disappearStyle.GetFontWeight();
1696 TimePickerModel::GetInstance()->SetDisappearTextStyle(theme, textStyle);
1697
1698 auto normalStyle = theme->GetOptionStyle(false, false);
1699 textStyle.fontSize = normalStyle.GetFontSize();
1700 textStyle.fontWeight = normalStyle.GetFontWeight();
1701 TimePickerModel::GetInstance()->SetNormalTextStyle(theme, textStyle);
1702 }
1703
ParseTime(const JSRef<JSVal> & timeVal,PickerTime defaultTime,bool startEndCheckValue)1704 PickerTime JSTimePicker::ParseTime(const JSRef<JSVal>& timeVal, PickerTime defaultTime, bool startEndCheckValue)
1705 {
1706 auto pickerTime = startEndCheckValue ? defaultTime : PickerTime::Current();
1707 if (!timeVal->IsObject()) {
1708 return pickerTime;
1709 }
1710 auto timeObj = JSRef<JSObject>::Cast(timeVal);
1711 auto yearFuncJsVal = timeObj->GetProperty("getFullYear");
1712 if (yearFuncJsVal->IsFunction()) {
1713 auto yearFunc = JSRef<JSFunc>::Cast(yearFuncJsVal);
1714 JSRef<JSVal> year = yearFunc->Call(timeObj);
1715 if (year->IsNumber() && LessOrEqual(year->ToNumber<int32_t>(), 0)) {
1716 return pickerTime;
1717 }
1718 }
1719
1720 auto hourFuncJsVal = timeObj->GetProperty("getHours");
1721 auto minuteFuncJsVal = timeObj->GetProperty("getMinutes");
1722 auto secondFuncJsVal = timeObj->GetProperty("getSeconds");
1723 if (!(hourFuncJsVal->IsFunction() && minuteFuncJsVal->IsFunction() && secondFuncJsVal->IsFunction())) {
1724 return pickerTime;
1725 }
1726 auto hourFunc = JSRef<JSFunc>::Cast(hourFuncJsVal);
1727 auto minuteFunc = JSRef<JSFunc>::Cast(minuteFuncJsVal);
1728 auto secondFunc = JSRef<JSFunc>::Cast(secondFuncJsVal);
1729 JSRef<JSVal> hour = hourFunc->Call(timeObj);
1730 JSRef<JSVal> minute = minuteFunc->Call(timeObj);
1731 JSRef<JSVal> second = secondFunc->Call(timeObj);
1732
1733 if (hour->IsNumber() && minute->IsNumber() && second->IsNumber()) {
1734 pickerTime.SetHour(hour->ToNumber<int32_t>());
1735 pickerTime.SetMinute(minute->ToNumber<int32_t>());
1736 pickerTime.SetSecond(second->ToNumber<int32_t>());
1737 }
1738 return pickerTime;
1739 }
1740
JSBind(BindingTarget globalObj)1741 void JSTimePickerDialog::JSBind(BindingTarget globalObj)
1742 {
1743 JSClass<JSTimePickerDialog>::Declare("TimePickerDialog");
1744 JSClass<JSTimePickerDialog>::StaticMethod("show", &JSTimePickerDialog::Show);
1745
1746 JSClass<JSTimePickerDialog>::Bind<>(globalObj);
1747 }
1748
TimePickerDialogAppearEvent(const JSCallbackInfo & info,TimePickerDialogEvent & timePickerDialogEvent)1749 void TimePickerDialogAppearEvent(const JSCallbackInfo& info, TimePickerDialogEvent& timePickerDialogEvent)
1750 {
1751 std::function<void()> didAppearEvent;
1752 std::function<void()> willAppearEvent;
1753 if (info.Length() == 0 || !info[0]->IsObject()) {
1754 return;
1755 }
1756 auto paramObject = JSRef<JSObject>::Cast(info[0]);
1757 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1758 auto onDidAppear = paramObject->GetProperty("onDidAppear");
1759 if (!onDidAppear->IsUndefined() && onDidAppear->IsFunction()) {
1760 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidAppear));
1761 didAppearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1762 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1763 ACE_SCORING_EVENT("DatePickerDialog.onDidAppear");
1764 PipelineContext::SetCallBackNode(node);
1765 func->Execute();
1766 };
1767 }
1768 auto onWillAppear = paramObject->GetProperty("onWillAppear");
1769 if (!onWillAppear->IsUndefined() && onWillAppear->IsFunction()) {
1770 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillAppear));
1771 willAppearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1772 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1773 ACE_SCORING_EVENT("DatePickerDialog.onWillAppear");
1774 PipelineContext::SetCallBackNode(node);
1775 func->Execute();
1776 };
1777 }
1778 timePickerDialogEvent.onDidAppear = std::move(didAppearEvent);
1779 timePickerDialogEvent.onWillAppear = std::move(willAppearEvent);
1780 }
1781
TimePickerDialogDisappearEvent(const JSCallbackInfo & info,TimePickerDialogEvent & timePickerDialogEvent)1782 void TimePickerDialogDisappearEvent(const JSCallbackInfo& info, TimePickerDialogEvent& timePickerDialogEvent)
1783 {
1784 std::function<void()> didDisappearEvent;
1785 std::function<void()> willDisappearEvent;
1786 if (info.Length() == 0 || !info[0]->IsObject()) {
1787 return;
1788 }
1789 auto paramObject = JSRef<JSObject>::Cast(info[0]);
1790 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1791 auto onDidDisappear = paramObject->GetProperty("onDidDisappear");
1792 if (!onDidDisappear->IsUndefined() && onDidDisappear->IsFunction()) {
1793 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidDisappear));
1794 didDisappearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1795 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1796 ACE_SCORING_EVENT("DatePickerDialog.onDidDisappear");
1797 PipelineContext::SetCallBackNode(node);
1798 func->Execute();
1799 };
1800 }
1801 auto onWillDisappear = paramObject->GetProperty("onWillDisappear");
1802 if (!onWillDisappear->IsUndefined() && onWillDisappear->IsFunction()) {
1803 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDisappear));
1804 willDisappearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1805 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1806 ACE_SCORING_EVENT("DatePickerDialog.onWillDisappear");
1807 PipelineContext::SetCallBackNode(node);
1808 func->Execute();
1809 };
1810 }
1811 timePickerDialogEvent.onDidDisappear = std::move(didDisappearEvent);
1812 timePickerDialogEvent.onWillDisappear = std::move(willDisappearEvent);
1813 }
1814
Show(const JSCallbackInfo & info)1815 void JSTimePickerDialog::Show(const JSCallbackInfo& info)
1816 {
1817 auto scopedDelegate = EngineHelper::GetCurrentDelegateSafely();
1818 CHECK_NULL_VOID(scopedDelegate);
1819 if (!info[0]->IsObject()) {
1820 return;
1821 }
1822 auto paramObject = info[0]->IsEmpty() ? (JSRef<JSObject>::New()) : JSRef<JSObject>::Cast(info[0]);
1823 std::function<void()> cancelEvent;
1824 std::function<void(const std::string&)> acceptEvent;
1825 std::function<void(const std::string&)> changeEvent;
1826 std::function<void(const std::string&)> enterEvent;
1827 WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1828 auto onChange = paramObject->GetProperty("onChange");
1829 if (!onChange->IsUndefined() && onChange->IsFunction()) {
1830 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onChange));
1831 changeEvent = [execCtx = info.GetExecutionContext(), type = DatePickerType::TIME, func = std::move(jsFunc),
1832 node = targetNode](const std::string& info) {
1833 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1834 std::vector<std::string> keys;
1835 keys = { "year", "month", "day", "hour", "minute", "second" };
1836 ACE_SCORING_EVENT("DatePickerDialog.onChange");
1837 PipelineContext::SetCallBackNode(node);
1838 func->Execute(keys, info);
1839 };
1840 }
1841 auto onEnterSelectedArea = paramObject->GetProperty("onEnterSelectedArea");
1842 if (!onEnterSelectedArea->IsUndefined() && onEnterSelectedArea->IsFunction()) {
1843 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onEnterSelectedArea));
1844 enterEvent = [execCtx = info.GetExecutionContext(), type = DatePickerType::TIME, func = std::move(jsFunc),
1845 node = targetNode](const std::string& info) {
1846 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1847 std::vector<std::string> keys;
1848 keys = { "year", "month", "day", "hour", "minute", "second" };
1849 ACE_SCORING_EVENT("DatePickerDialog.onEnterSelectedArea");
1850 PipelineContext::SetCallBackNode(node);
1851 func->Execute(keys, info);
1852 };
1853 }
1854 auto onAccept = paramObject->GetProperty("onAccept");
1855 if (!onAccept->IsUndefined() && onAccept->IsFunction()) {
1856 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAccept));
1857 acceptEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1858 const std::string& info) {
1859 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1860 std::vector<std::string> keys = { "year", "month", "day", "hour", "minute", "second" };
1861 ACE_SCORING_EVENT("DatePickerDialog.onAccept");
1862 PipelineContext::SetCallBackNode(node);
1863 func->Execute(keys, info);
1864 };
1865 }
1866 auto onCancel = paramObject->GetProperty("onCancel");
1867 if (!onCancel->IsUndefined() && onCancel->IsFunction()) {
1868 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCancel));
1869 cancelEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1870 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1871 ACE_SCORING_EVENT("DatePickerDialog.onCancel");
1872 PipelineContext::SetCallBackNode(node);
1873 func->Execute();
1874 };
1875 }
1876 auto startTime = paramObject->GetProperty("start");
1877 auto endTime = paramObject->GetProperty("end");
1878 auto selectedTime = paramObject->GetProperty("selected");
1879 auto useMilitaryTime = paramObject->GetProperty("useMilitaryTime");
1880 auto enableCascade = paramObject->GetProperty("enableCascade");
1881 NG::TimePickerSettingData settingData;
1882 PickerDialogInfo pickerDialog;
1883 settingData.isUseMilitaryTime = useMilitaryTime->ToBoolean();
1884 settingData.isEnableCascade = enableCascade->ToBoolean();
1885 pickerDialog.isUseMilitaryTime = useMilitaryTime->ToBoolean();
1886 pickerDialog.isEnableCascade = enableCascade->ToBoolean();
1887 auto theme = GetTheme<PickerTheme>();
1888 CHECK_NULL_VOID(theme);
1889 auto parseStartTime = ParseTime(startTime, theme->GetDefaultStartTime(), true);
1890 auto parseEndTime = ParseTime(endTime, theme->GetDefaultEndTime(), true);
1891 if (parseStartTime.ToMinutes() > parseEndTime.ToMinutes()) {
1892 parseStartTime = theme->GetDefaultStartTime();
1893 parseEndTime = theme->GetDefaultEndTime();
1894 }
1895 pickerDialog.parseStartTime = parseStartTime;
1896 pickerDialog.parseEndTime = parseEndTime;
1897
1898 if (selectedTime->IsObject()) {
1899 PickerDate dialogTitleDate = ParseDate(selectedTime);
1900 if (dialogTitleDate.GetYear() != 0) {
1901 settingData.dialogTitleDate = dialogTitleDate;
1902 pickerDialog.isSelectedTime = true;
1903 pickerDialog.pickerTime = ParseTime(selectedTime);
1904 }
1905 }
1906 JSDatePicker::ParseTextProperties(paramObject, settingData.properties);
1907 auto dateTimeOptionsValue = paramObject->GetProperty("dateTimeOptions");
1908 if (dateTimeOptionsValue->IsObject()) {
1909 auto dateTimeOptionsObj = JSRef<JSObject>::Cast(dateTimeOptionsValue);
1910 JSDatePickerDialog::ParseDateTimeOptions(dateTimeOptionsObj, settingData.dateTimeOptions);
1911 }
1912
1913 // Parse alignment
1914 auto alignmentValue = paramObject->GetProperty("alignment");
1915 if (alignmentValue->IsNumber()) {
1916 auto alignment = alignmentValue->ToNumber<int32_t>();
1917 if (alignment >= 0 && alignment < static_cast<int32_t>(DIALOG_ALIGNMENT.size())) {
1918 pickerDialog.alignment = DIALOG_ALIGNMENT[alignment];
1919 }
1920 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1921 if (alignment == static_cast<int32_t>(DialogAlignment::TOP) ||
1922 alignment == static_cast<int32_t>(DialogAlignment::TOP_START) ||
1923 alignment == static_cast<int32_t>(DialogAlignment::TOP_END)) {
1924 pickerDialog.offset = DATEPICKER_OFFSET_DEFAULT_TOP;
1925 }
1926 }
1927 }
1928
1929 // Parse offset
1930 auto offsetValue = paramObject->GetProperty("offset");
1931 if (offsetValue->IsObject()) {
1932 auto offsetObj = JSRef<JSObject>::Cast(offsetValue);
1933 CalcDimension dx;
1934 auto dxValue = offsetObj->GetProperty("dx");
1935 JSAlertDialog::ParseJsDimensionVp(dxValue, dx);
1936 CalcDimension dy;
1937 auto dyValue = offsetObj->GetProperty("dy");
1938 JSAlertDialog::ParseJsDimensionVp(dyValue, dy);
1939 pickerDialog.offset = DimensionOffset(dx, dy);
1940 }
1941
1942 // Parse maskRect.
1943 auto maskRectValue = paramObject->GetProperty("maskRect");
1944 DimensionRect maskRect;
1945 if (JSViewAbstract::ParseJsDimensionRect(maskRectValue, maskRect)) {
1946 pickerDialog.maskRect = maskRect;
1947 }
1948
1949 auto backgroundColorValue = paramObject->GetProperty("backgroundColor");
1950 Color backgroundColor;
1951 if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
1952 pickerDialog.backgroundColor = backgroundColor;
1953 }
1954
1955 auto backgroundBlurStyle = paramObject->GetProperty("backgroundBlurStyle");
1956 if (backgroundBlurStyle->IsNumber()) {
1957 auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
1958 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
1959 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
1960 pickerDialog.backgroundBlurStyle = blurStyle;
1961 }
1962 }
1963
1964 ParseDatePickerHoverMode(pickerDialog, paramObject);
1965 ParseDatePickerBlurStyleOption(pickerDialog, paramObject);
1966 ParseDatePickerEffectOption(pickerDialog, paramObject);
1967
1968 auto buttonInfos = ParseButtonStyles(paramObject);
1969
1970 auto shadowValue = paramObject->GetProperty("shadow");
1971 Shadow shadow;
1972 if ((shadowValue->IsObject() || shadowValue->IsNumber()) && JSViewAbstract::ParseShadowProps(shadowValue, shadow)) {
1973 pickerDialog.shadow = shadow;
1974 }
1975 auto formatValue = paramObject->GetProperty("format");
1976 bool showSecond = false;
1977 if (formatValue->IsNumber()) {
1978 auto displayedFormat = static_cast<TimePickerFormat>(formatValue->ToNumber<int32_t>());
1979 if (displayedFormat == TimePickerFormat::HOUR_MINUTE_SECOND) {
1980 showSecond = true;
1981 }
1982 }
1983 settingData.showSecond = showSecond;
1984 auto enableHapticFeedbackValue = paramObject->GetProperty("enableHapticFeedback");
1985 bool isEnableHapticFeedback = true;
1986 if (enableHapticFeedbackValue->IsBoolean()) {
1987 isEnableHapticFeedback = enableHapticFeedbackValue->ToBoolean();
1988 }
1989 settingData.isEnableHapticFeedback = isEnableHapticFeedback;
1990 TimePickerDialogEvent timePickerDialogEvent { nullptr, nullptr, nullptr, nullptr };
1991 TimePickerDialogAppearEvent(info, timePickerDialogEvent);
1992 TimePickerDialogDisappearEvent(info, timePickerDialogEvent);
1993 TimePickerDialogModel::GetInstance()->SetTimePickerDialogShow(pickerDialog, settingData, std::move(cancelEvent),
1994 std::move(acceptEvent), std::move(changeEvent), std::move(enterEvent), timePickerDialogEvent, buttonInfos);
1995 }
1996
TimePickerDialogShow(const JSRef<JSObject> & paramObj,const std::map<std::string,NG::DialogEvent> & dialogEvent,const std::map<std::string,NG::DialogGestureEvent> & dialogCancelEvent)1997 void JSTimePickerDialog::TimePickerDialogShow(const JSRef<JSObject>& paramObj,
1998 const std::map<std::string, NG::DialogEvent>& dialogEvent,
1999 const std::map<std::string, NG::DialogGestureEvent>& dialogCancelEvent)
2000 {
2001 auto container = Container::CurrentSafely();
2002 CHECK_NULL_VOID(container);
2003
2004 auto pipelineContext = AccessibilityManager::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
2005 CHECK_NULL_VOID(pipelineContext);
2006
2007 auto executor = pipelineContext->GetTaskExecutor();
2008 CHECK_NULL_VOID(executor);
2009
2010 auto theme = JSAlertDialog::GetTheme<DialogTheme>();
2011 CHECK_NULL_VOID(theme);
2012
2013 auto selectedTime = paramObj->GetProperty("selected");
2014 auto useMilitaryTime = paramObj->GetProperty("useMilitaryTime");
2015 auto enableCascade = paramObj->GetProperty("enableCascade");
2016 NG::TimePickerSettingData settingData;
2017 settingData.isUseMilitaryTime = useMilitaryTime->ToBoolean();
2018 settingData.isEnableCascade = enableCascade->ToBoolean();
2019
2020 DialogProperties properties;
2021 properties.alignment = theme->GetAlignment();
2022 if (properties.alignment == DialogAlignment::BOTTOM &&
2023 Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
2024 properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
2025 }
2026
2027 auto enableHapticFeedbackValue = paramObj->GetProperty("enableHapticFeedback");
2028 bool isEnableHapticFeedback = true;
2029 if (enableHapticFeedbackValue->IsBoolean()) {
2030 isEnableHapticFeedback = enableHapticFeedbackValue->ToBoolean();
2031 }
2032 settingData.isEnableHapticFeedback = isEnableHapticFeedback;
2033
2034 properties.customStyle = false;
2035 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
2036 properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
2037 }
2038
2039 std::map<std::string, PickerTime> timePickerProperty;
2040 if (selectedTime->IsObject()) {
2041 settingData.dialogTitleDate = ParseDate(selectedTime);
2042 timePickerProperty["selected"] = ParseTime(selectedTime);
2043 }
2044 JSDatePicker::ParseTextProperties(paramObj, settingData.properties);
2045
2046 auto context = AccessibilityManager::DynamicCast<NG::PipelineContext>(pipelineContext);
2047 auto overlayManager = context ? context->GetOverlayManager() : nullptr;
2048 executor->PostTask(
2049 [properties, settingData, timePickerProperty, dialogEvent, dialogCancelEvent,
2050 weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
2051 auto overlayManager = weak.Upgrade();
2052 CHECK_NULL_VOID(overlayManager);
2053 overlayManager->ShowTimeDialog(properties, settingData, timePickerProperty, dialogEvent, dialogCancelEvent);
2054 },
2055 TaskExecutor::TaskType::UI, "ArkUIDialogShowTimePicker",
2056 TaskExecutor::GetPriorityTypeWithCheck(PriorityType::VIP));
2057 }
2058
CreateTimePicker(RefPtr<Component> & component,const JSRef<JSObject> & paramObj)2059 void JSTimePickerDialog::CreateTimePicker(RefPtr<Component>& component, const JSRef<JSObject>& paramObj)
2060 {
2061 auto timePicker = AceType::MakeRefPtr<PickerTimeComponent>();
2062 auto selectedTime = paramObj->GetProperty("selected");
2063 auto useMilitaryTime = paramObj->GetProperty("useMilitaryTime");
2064 auto enableCascade = paramObj->GetProperty("enableCascade");
2065 bool isUseMilitaryTime = useMilitaryTime->ToBoolean();
2066 bool isEnableCascade = enableCascade->ToBoolean();
2067 if (selectedTime->IsObject()) {
2068 timePicker->SetSelectedTime(ParseTime(selectedTime));
2069 }
2070 timePicker->SetIsDialog(true);
2071 timePicker->SetIsCreateDialogComponent(true);
2072 timePicker->SetHour24(isUseMilitaryTime);
2073 timePicker->SetEnableCascade(isEnableCascade);
2074 component = timePicker;
2075 }
2076
ParseTime(const JSRef<JSVal> & timeVal,PickerTime defaultTime,bool startEndCheckValue)2077 PickerTime JSTimePickerDialog::ParseTime(const JSRef<JSVal>& timeVal, PickerTime defaultTime, bool startEndCheckValue)
2078 {
2079 auto pickerTime = startEndCheckValue ? defaultTime : PickerTime();
2080 if (!timeVal->IsObject()) {
2081 return pickerTime;
2082 }
2083 auto timeObj = JSRef<JSObject>::Cast(timeVal);
2084 auto yearFuncJsVal = timeObj->GetProperty("getFullYear");
2085 if (yearFuncJsVal->IsFunction()) {
2086 auto yearFunc = JSRef<JSFunc>::Cast(yearFuncJsVal);
2087 JSRef<JSVal> year = yearFunc->Call(timeObj);
2088 if (year->IsNumber() && LessOrEqual(year->ToNumber<int32_t>(), 0)) {
2089 return pickerTime;
2090 }
2091 }
2092 auto hourFuncJsVal = timeObj->GetProperty("getHours");
2093 auto minuteFuncJsVal = timeObj->GetProperty("getMinutes");
2094 auto secondFuncJsVal = timeObj->GetProperty("getSeconds");
2095 if (!(hourFuncJsVal->IsFunction() && minuteFuncJsVal->IsFunction() && secondFuncJsVal->IsFunction())) {
2096 return pickerTime;
2097 }
2098 auto hourFunc = JSRef<JSFunc>::Cast(hourFuncJsVal);
2099 auto minuteFunc = JSRef<JSFunc>::Cast(minuteFuncJsVal);
2100 auto secondFunc = JSRef<JSFunc>::Cast(secondFuncJsVal);
2101 JSRef<JSVal> hour = hourFunc->Call(timeObj);
2102 JSRef<JSVal> minute = minuteFunc->Call(timeObj);
2103 JSRef<JSVal> second = secondFunc->Call(timeObj);
2104
2105 if (hour->IsNumber() && minute->IsNumber() && second->IsNumber()) {
2106 pickerTime.SetHour(hour->ToNumber<int32_t>());
2107 pickerTime.SetMinute(minute->ToNumber<int32_t>());
2108 pickerTime.SetSecond(second->ToNumber<int32_t>());
2109 }
2110 return pickerTime;
2111 }
2112
ParseDate(const JSRef<JSVal> & dateVal)2113 PickerDate JSTimePickerDialog::ParseDate(const JSRef<JSVal>& dateVal)
2114 {
2115 auto pickerDate = PickerDate();
2116 if (!dateVal->IsObject()) {
2117 return pickerDate;
2118 }
2119 auto dateObj = JSRef<JSObject>::Cast(dateVal);
2120 auto yearFuncJsVal = dateObj->GetProperty("getFullYear");
2121 auto monthFuncJsVal = dateObj->GetProperty("getMonth");
2122 auto dateFuncJsVal = dateObj->GetProperty("getDate");
2123 if (!(yearFuncJsVal->IsFunction() && monthFuncJsVal->IsFunction() && dateFuncJsVal->IsFunction())) {
2124 return pickerDate;
2125 }
2126 auto yearFunc = JSRef<JSFunc>::Cast(yearFuncJsVal);
2127 auto monthFunc = JSRef<JSFunc>::Cast(monthFuncJsVal);
2128 auto dateFunc = JSRef<JSFunc>::Cast(dateFuncJsVal);
2129 JSRef<JSVal> year = yearFunc->Call(dateObj);
2130 JSRef<JSVal> month = monthFunc->Call(dateObj);
2131 JSRef<JSVal> date = dateFunc->Call(dateObj);
2132
2133 if (year->IsNumber() && month->IsNumber() && date->IsNumber()) {
2134 pickerDate.SetYear(year->ToNumber<int32_t>());
2135 pickerDate.SetMonth(month->ToNumber<int32_t>() + 1); // 0-11 means 1 to 12 months
2136 pickerDate.SetDay(date->ToNumber<int32_t>());
2137 }
2138 return pickerDate;
2139 }
2140 } // namespace OHOS::Ace::Framework
2141