1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "frameworks/bridge/common/dom/dom_picker_base.h"
17
18 #include "frameworks/bridge/common/utils/utils.h"
19
20 namespace OHOS::Ace::Framework {
21 namespace {
22
23 const PickerDate DEFAULT_PICKER_DATE(1970, 1, 1);
24 const PickerDate DEFAULT_END_PICKER_DATE(2100, 12, 31);
25 constexpr char PICKER_DATE_SPLITTER = '-';
26 const PickerTime DEFAULT_PICKER_TIME(0, 0, 0);
27 constexpr char PICKER_TIME_SPLITTER = ':';
28
29 } // namespace
30
DOMPickerBase(NodeId nodeId,const std::string & nodeName,bool hasValue)31 DOMPickerBase::DOMPickerBase(NodeId nodeId, const std::string& nodeName, bool hasValue)
32 : DOMNode(nodeId, nodeName), hasValue_(hasValue)
33 {
34 if (!hasValue_) {
35 return;
36 }
37 valuePickerChild_ = AceType::MakeRefPtr<PickerValueComponent>([weak = WeakClaim(this)]() {
38 auto refPtr = weak.Upgrade();
39 if (refPtr) {
40 refPtr->HandleClickCallback();
41 }
42 });
43 pickerId_ = nodeId;
44 }
45
InitializeStyle()46 void DOMPickerBase::InitializeStyle()
47 {
48 ResetInitializedStyle();
49 }
50
ResetInitializedStyle()51 void DOMPickerBase::ResetInitializedStyle()
52 {
53 auto theme = GetTheme<PickerTheme>();
54 if (!theme) {
55 return;
56 }
57 theme_ = theme->clone();
58 if (!theme_ || !valuePickerChild_) {
59 return;
60 }
61 valuePickerChild_->SetTheme(theme_);
62 }
63
GetSpecializedComponent()64 RefPtr<Component> DOMPickerBase::GetSpecializedComponent()
65 {
66 if (!hasValue_) {
67 return basePickerChild_;
68 }
69 return valuePickerChild_;
70 }
71
HandleClickCallback() const72 void DOMPickerBase::HandleClickCallback() const
73 {
74 if (!hasValue_) {
75 return;
76 }
77 ShowDialog();
78 }
79
ShowDialog() const80 void DOMPickerBase::ShowDialog() const
81 {
82 if (!basePickerChild_) {
83 return;
84 }
85 auto context = GetPipelineContext().Upgrade();
86 if (!context) {
87 return;
88 }
89 auto pageStack = context->GetLastStack();
90 if (!pageStack) {
91 return;
92 }
93 basePickerChild_->ShowDialog(pageStack);
94 }
95
GetPickerDate(const std::string & strDate,PickerDate & outDate) const96 bool DOMPickerBase::GetPickerDate(const std::string& strDate, PickerDate& outDate) const
97 {
98 std::string strValue;
99 std::stringstream streamDate(strDate);
100 if (!std::getline(streamDate, strValue, PICKER_DATE_SPLITTER)) {
101 return false;
102 }
103 outDate.SetYear(StringUtils::StringToInt(strValue));
104 if (!std::getline(streamDate, strValue, PICKER_DATE_SPLITTER)) {
105 return false;
106 }
107 outDate.SetMonth(StringUtils::StringToInt(strValue));
108 if (!std::getline(streamDate, strValue, PICKER_DATE_SPLITTER)) {
109 return false;
110 }
111 outDate.SetDay(StringUtils::StringToInt(strValue));
112 return true;
113 }
114
GetPickerTime(const std::string & strDate,PickerTime & outTime) const115 bool DOMPickerBase::GetPickerTime(const std::string& strDate, PickerTime& outTime) const
116 {
117 std::string strValue;
118 std::stringstream streamDate(strDate);
119 if (!std::getline(streamDate, strValue, PICKER_TIME_SPLITTER)) {
120 return false;
121 }
122 outTime.SetHour(StringUtils::StringToInt(strValue));
123 if (!std::getline(streamDate, strValue, PICKER_TIME_SPLITTER)) {
124 return false;
125 }
126 outTime.SetMinute(StringUtils::StringToInt(strValue));
127 // the format time hh:mm is supported, so the time should be set
128 if (std::getline(streamDate, strValue)) {
129 outTime.SetSecond(StringUtils::StringToInt(strValue));
130 }
131 return true;
132 }
133
GetPickerDateTime(const std::string & strDate,PickerDateTime & outDateTime) const134 bool DOMPickerBase::GetPickerDateTime(const std::string& strDate, PickerDateTime& outDateTime) const
135 {
136 std::vector<std::string> strValues;
137 StringUtils::StringSplitter(strDate, PICKER_DATE_SPLITTER, strValues);
138 PickerDate outDate = outDateTime.GetDate();
139 PickerTime outTime = outDateTime.GetTime();
140 if (strValues.size() == 4) { // MM-dd-hh-mm
141 outDate.SetMonth(StringUtils::StringToInt(strValues[0]));
142 outDate.SetDay(StringUtils::StringToInt(strValues[1]));
143 outTime.SetHour(StringUtils::StringToInt(strValues[2]));
144 outTime.SetMinute(StringUtils::StringToInt(strValues[3]));
145 } else if (strValues.size() == 5) { // yyyy-MM-dd-hh-mm
146 outDate.SetYear(StringUtils::StringToInt(strValues[0]));
147 outDate.SetMonth(StringUtils::StringToInt(strValues[1]));
148 outDate.SetDay(StringUtils::StringToInt(strValues[2]));
149 outTime.SetHour(StringUtils::StringToInt(strValues[3]));
150 outTime.SetMinute(StringUtils::StringToInt(strValues[4]));
151 } else {
152 return false;
153 }
154 outDateTime.SetDate(outDate);
155 outDateTime.SetTime(outTime);
156 return true;
157 }
158
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)159 bool DOMPickerBase::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
160 {
161 if (attr.first == DOM_VALUE) {
162 if (!hasValue_) {
163 return false;
164 }
165 std::string strValue = attr.second;
166 strValue.erase(
167 std::remove_if(strValue.begin(), strValue.end(), [](char c) { return c == DOM_PICKER_SPLIT_ARRAY; }),
168 strValue.end());
169 valuePickerChild_->SetText(strValue);
170 return true;
171 }
172
173 if (attr.first == DOM_TYPE) {
174 type_ = attr.second;
175 return true;
176 }
177
178 static const LinearMapNode<void (*)(DOMPickerBase&, const std::string&)> pickerAttrOperators[] = {
179 { DOM_PICKER_COLUMN_COUNT, [](DOMPickerBase& picker, const std::string& val) { picker.SetColumnCount(val); } },
180 { DOM_PICKER_CONTAIN_SECOND, [](DOMPickerBase& picker, const std::string& val) { picker.SetHasSecond(val); } },
181 { DOM_END, [](DOMPickerBase& picker, const std::string& val) { picker.SetEnd(val); } },
182 { DOM_PICKER_HOUR24, [](DOMPickerBase& picker, const std::string& val) { picker.SetHour24(val); } },
183 { DOM_PICKER_PREFIX, [](DOMPickerBase& picker, const std::string& val) { picker.SetPrefix(val); } },
184 { DOM_PICKER_SUFFIX, [](DOMPickerBase& picker, const std::string& val) { picker.SetSuffix(val); } },
185 { DOM_PICKER_SHOW_LUNAR, [](DOMPickerBase& picker, const std::string& val) { picker.SetShowLunar(val); } },
186 { DOM_PICKER_LUNAR, [](DOMPickerBase& picker, const std::string& val) { picker.SetLunar(val); } },
187 { DOM_PICKER_RANGE, [](DOMPickerBase& picker, const std::string& val) { picker.SetRange(val); } },
188 { DOM_SELECTED, [](DOMPickerBase& picker, const std::string& val) { picker.SetSelected(val); } },
189 { DOM_START, [](DOMPickerBase& picker, const std::string& val) { picker.SetStart(val); } },
190 { DOM_PICKER_VIBRATE, [](DOMPickerBase& picker, const std::string& val) { picker.SetVibrate(val); } },
191 };
192 auto it = BinarySearchFindIndex(pickerAttrOperators, ArraySize(pickerAttrOperators), attr.first.c_str());
193 if (it != -1) {
194 if (!basePickerChild_) {
195 storeAttributes_.emplace_back(attr);
196 return true;
197 }
198 pickerAttrOperators[it].value(*this, attr.second);
199 return true;
200 }
201 return false;
202 }
203
AddSpecializedEvent(int32_t pageId,const std::string & event)204 bool DOMPickerBase::AddSpecializedEvent(int32_t pageId, const std::string& event)
205 {
206 static const LinearMapNode<void (*)(RefPtr<PickerBaseComponent>&, const EventMarker&)> pickerEventOperators[] = {
207 { DOM_CANCEL,
208 [](RefPtr<PickerBaseComponent>& picker, const EventMarker& event) { picker->SetOnCancel(event); } },
209 { DOM_CHANGE,
210 [](RefPtr<PickerBaseComponent>& picker, const EventMarker& event) { picker->SetOnChange(event); } },
211 { DOM_PICKER_COLUMN_CHANGE,
212 [](RefPtr<PickerBaseComponent>& picker, const EventMarker& event) { picker->SetOnColumnChange(event); } },
213 };
214 auto it = BinarySearchFindIndex(pickerEventOperators, ArraySize(pickerEventOperators), event.c_str());
215 if (it != -1) {
216 if (!basePickerChild_) {
217 storeEvents_.emplace_back(std::make_pair(pageId, event));
218 return true;
219 }
220 pickerEventOperators[it].value(basePickerChild_, EventMarker(GetNodeIdForEvent(), event, pageId));
221 return true;
222 }
223 return false;
224 }
225
SetSpecializedStyle(const std::pair<std::string,std::string> & style)226 bool DOMPickerBase::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
227 {
228 if (!hasValue_) {
229 return SetOptionStyleOperators(style);
230 }
231 return SetTextStyleOperators(style);
232 }
233
SetOptionStyleOperators(const std::pair<std::string,std::string> & style)234 bool DOMPickerBase::SetOptionStyleOperators(const std::pair<std::string, std::string>& style)
235 {
236 static const LinearMapNode<void (*)(const DOMPickerBase&,
237 const std::string&, TextStyle&, TextStyle&, TextStyle&, TextStyle&)>
238 optionStyleOperators[] = {
239 { DOM_TEXT_COLOR, [](const DOMPickerBase& node, const std::string& val, TextStyle& normal, TextStyle&,
240 TextStyle&, TextStyle&) { normal.SetTextColor(node.ParseColor(val)); } },
241 { DOM_PICKER_DISAPPEAR_COLOR, [](const DOMPickerBase& node, const std::string& val,
242 TextStyle&, TextStyle&, TextStyle&, TextStyle& style) { style.SetTextColor(node.ParseColor(val)); } },
243 { DOM_PICKER_DISAPPEAR_FONT_SIZE, [](const DOMPickerBase& node, const std::string& val,
244 TextStyle&, TextStyle&, TextStyle&, TextStyle& style) {
245 style.SetFontSize(node.ParseDimension(val));
246 style.SetAdaptMaxFontSize(node.ParseDimension(val)); } },
247 { DOM_PICKER_FOCUS_COLOR, [](const DOMPickerBase& node, const std::string& val, TextStyle&, TextStyle&,
248 TextStyle& focus, TextStyle&) { focus.SetTextColor(node.ParseColor(val)); } },
249 { DOM_PICKER_FOCUS_SIZE,
250 [](const DOMPickerBase& node, const std::string& val,
251 TextStyle&, TextStyle&, TextStyle& focus, TextStyle&) {
252 focus.SetFontSize(node.ParseDimension(val));
253 focus.SetAdaptMaxFontSize(node.ParseDimension(val));
254 } },
255 { DOM_TEXT_FONT_FAMILY,
256 [](const DOMPickerBase& node, const std::string& val, TextStyle& normal, TextStyle& select,
257 TextStyle& focus, TextStyle& disappear) {
258 normal.SetFontFamilies(node.ParseFontFamilies(val));
259 select.SetFontFamilies(node.ParseFontFamilies(val));
260 focus.SetFontFamilies(node.ParseFontFamilies(val));
261 disappear.SetFontFamilies(node.ParseFontFamilies(val));
262 } },
263 { DOM_TEXT_FONT_SIZE,
264 [](const DOMPickerBase& node, const std::string& val,
265 TextStyle& normal, TextStyle&, TextStyle&, TextStyle&) {
266 normal.SetFontSize(node.ParseDimension(val));
267 normal.SetAdaptMaxFontSize(node.ParseDimension(val));
268 } },
269 { DOM_PICKER_SELECT_COLOR, [](const DOMPickerBase& node, const std::string& val,
270 TextStyle&, TextStyle& select,
271 TextStyle&, TextStyle&) { select.SetTextColor(node.ParseColor(val)); } },
272 { DOM_PICKER_SELECT_SIZE,
273 [](const DOMPickerBase& node, const std::string& val,
274 TextStyle&, TextStyle& select, TextStyle&, TextStyle&) {
275 select.SetFontSize(node.ParseDimension(val));
276 select.SetAdaptMaxFontSize(node.ParseDimension(val));
277 } },
278 };
279 auto styleIter = BinarySearchFindIndex(optionStyleOperators, ArraySize(optionStyleOperators), style.first.c_str());
280 if (styleIter != -1) {
281 if (!basePickerChild_) {
282 storeStyles_.emplace_back(style);
283 return true;
284 }
285 auto theme = basePickerChild_->GetTheme();
286 auto normalStyle = theme->GetOptionStyle(false, false);
287 auto selectStyle = theme->GetOptionStyle(true, false);
288 auto focusStyle = theme->GetOptionStyle(true, true);
289 auto disappearStyle = theme->GetDisappearOptionStyle();
290 optionStyleOperators[styleIter].value(*this, style.second,
291 normalStyle, selectStyle, focusStyle, disappearStyle);
292 theme->SetOptionStyle(false, false, normalStyle);
293 theme->SetOptionStyle(true, false, selectStyle);
294 theme->SetOptionStyle(true, true, focusStyle);
295 theme->SetDisappearOptionStyle(disappearStyle);
296 return true;
297 }
298 return false;
299 }
300
SetTextBackgroundColor(const std::pair<std::string,std::string> & style)301 bool DOMPickerBase::SetTextBackgroundColor(const std::pair<std::string, std::string>& style)
302 {
303 if (style.first != DOM_BACKGROUND_COLOR) {
304 return false;
305 }
306 auto decoration = theme_->GetOptionDecoration(false);
307 if (!decoration) {
308 return false;
309 }
310 decoration->SetBackgroundColor(ParseColor(style.second));
311 return true;
312 }
313
SetTextStyleOperators(const std::pair<std::string,std::string> & style)314 bool DOMPickerBase::SetTextStyleOperators(const std::pair<std::string, std::string>& style)
315 {
316 static const LinearMapNode<void (*)(
317 const DOMPickerBase&, const std::string&, TextStyle&, TextStyle&, TextStyle&, TextStyle&)>
318 textStyleOperators[] = {
319 { DOM_TEXT_ALLOW_SCALE,
320 [](const DOMPickerBase& node, const std::string& val, TextStyle& normal, TextStyle& focus, TextStyle&,
321 TextStyle&) {
322 normal.SetAllowScale(StringToBool(val));
323 focus.SetAllowScale(StringToBool(val));
324 } },
325 { DOM_PICKER_DISAPPEAR_FONT_SIZE,
326 [](const DOMPickerBase& node, const std::string& val, TextStyle&, TextStyle&, TextStyle&,
327 TextStyle& disappear) {
328 Dimension fontSize = node.ParseDimension(val);
329 if (fontSize.IsValid()) {
330 disappear.SetFontSize(fontSize);
331 disappear.SetAdaptMaxFontSize(fontSize);
332 }
333 } },
334 { DOM_PICKER_FOCUS_SIZE,
335 [](const DOMPickerBase& node, const std::string& val, TextStyle&, TextStyle& focus, TextStyle&,
336 TextStyle&) {
337 Dimension fontSize = node.ParseDimension(val);
338 if (fontSize.IsValid()) {
339 focus.SetFontSize(fontSize);
340 focus.SetAdaptMaxFontSize(fontSize);
341 }
342 } },
343 { DOM_TEXT_FONT_FAMILY,
344 [](const DOMPickerBase& node, const std::string& val, TextStyle& normal, TextStyle& focus, TextStyle&,
345 TextStyle&) {
346 normal.SetFontFamilies(node.ParseFontFamilies(val));
347 focus.SetFontFamilies(node.ParseFontFamilies(val));
348 } },
349 { DOM_TEXT_FONT_SIZE,
350 [](const DOMPickerBase& node, const std::string& val, TextStyle& normal, TextStyle&, TextStyle&,
351 TextStyle&) {
352 Dimension fontSize = node.ParseDimension(val);
353 if (fontSize.IsValid()) {
354 normal.SetFontSize(fontSize);
355 normal.SetAdaptMaxFontSize(fontSize);
356 }
357 } },
358 { DOM_TEXT_FONT_STYLE,
359 [](const DOMPickerBase& node, const std::string& val, TextStyle& normal, TextStyle& focus, TextStyle&,
360 TextStyle&) {
361 normal.SetFontStyle(ConvertStrToFontStyle(val));
362 focus.SetFontStyle(ConvertStrToFontStyle(val));
363 } },
364 { DOM_TEXT_FONT_WEIGHT,
365 [](const DOMPickerBase& node, const std::string& val, TextStyle& normal, TextStyle& focus, TextStyle&,
366 TextStyle&) {
367 normal.SetFontWeight(ConvertStrToFontWeight(val));
368 focus.SetFontWeight(ConvertStrToFontWeight(val));
369 } },
370 { DOM_TEXT_LETTER_SPACING,
371 [](const DOMPickerBase& node, const std::string& val, TextStyle& normal, TextStyle& focus, TextStyle&,
372 TextStyle&) {
373 normal.SetLetterSpacing(node.ParseDimension(val));
374 focus.SetLetterSpacing(node.ParseDimension(val));
375 } },
376 { DOM_TEXT_LINE_HEIGHT,
377 [](const DOMPickerBase& node, const std::string& val, TextStyle& normal, TextStyle& focus, TextStyle&,
378 TextStyle&) {
379 normal.SetLineHeight(node.ParseLineHeight(val));
380 focus.SetLineHeight(node.ParseLineHeight(val));
381 } },
382 { DOM_PICKER_SELECT_SIZE,
383 [](const DOMPickerBase& node, const std::string& val, TextStyle&, TextStyle&, TextStyle& selected,
384 TextStyle&) {
385 Dimension fontSize = node.ParseDimension(val);
386 if (fontSize.IsValid()) {
387 selected.SetFontSize(fontSize);
388 selected.SetAdaptMaxFontSize(fontSize);
389 }
390 } },
391 { DOM_PICKER_TEXT_COLOR,
392 [](const DOMPickerBase& node, const std::string& val, TextStyle& normal, TextStyle& focus, TextStyle&,
393 TextStyle&) {
394 normal.SetTextColor(node.ParseColor(val));
395 focus.SetTextColor(node.ParseColor(val));
396 } },
397 { DOM_TEXT_DECORATION,
398 [](const DOMPickerBase& node, const std::string& val, TextStyle& normal, TextStyle& focus, TextStyle&,
399 TextStyle&) {
400 normal.SetTextDecoration(ConvertStrToTextDecoration(val));
401 focus.SetTextDecoration(ConvertStrToTextDecoration(val));
402 } },
403 };
404 auto operatorIter = BinarySearchFindIndex(textStyleOperators, ArraySize(textStyleOperators), style.first.c_str());
405 if (operatorIter != -1) {
406 if (!basePickerChild_) {
407 storeStyles_.emplace_back(style);
408 return true;
409 }
410 auto theme = basePickerChild_->GetTheme();
411 if (theme) {
412 auto normalStyle = theme->GetOptionStyle(false, false);
413 auto focusStyle = theme->GetOptionStyle(true, true);
414 auto selectedStyle = theme->GetOptionStyle(true, false);
415 auto disappearStyle = theme->GetDisappearOptionStyle();
416
417 textStyleOperators[operatorIter].value(
418 *this, style.second, normalStyle, focusStyle, selectedStyle, disappearStyle);
419 theme->SetOptionStyle(false, false, normalStyle);
420 theme->SetOptionStyle(true, false, selectedStyle); // selected
421 theme->SetOptionStyle(true, true, focusStyle);
422 theme->SetDisappearOptionStyle(disappearStyle);
423 }
424
425 // theme is used only by valuePickerChild_
426 auto normalStyle = theme_->GetOptionStyle(false, false);
427 auto focusStyle = theme_->GetOptionStyle(true, true);
428 auto selectedStyle = theme_->GetOptionStyle(true, false);
429 auto disappearStyle = theme_->GetDisappearOptionStyle();
430 textStyleOperators[operatorIter].value(
431 *this, style.second, normalStyle, focusStyle, selectedStyle, disappearStyle);
432 theme_->SetOptionStyle(false, false, normalStyle);
433 theme_->SetOptionStyle(true, false, normalStyle);
434 theme_->SetOptionStyle(true, true, focusStyle);
435 return true;
436 }
437 if (SetColumnHeight(style)) {
438 return true;
439 }
440 if (SetTextBackgroundColor(style)) {
441 return true;
442 }
443 return false;
444 }
445
CallSpecializedMethod(const std::string & method,const std::string & args)446 void DOMPickerBase::CallSpecializedMethod(const std::string& method, const std::string& args)
447 {
448 if (!basePickerChild_) {
449 return;
450 }
451 if (method == DOM_ROTATION) {
452 auto controller = basePickerChild_->GetRotationController();
453 if (controller) {
454 controller->RequestRotation(true);
455 }
456 }
457 if (!hasValue_) {
458 return;
459 }
460 if (method == DOM_SHOW) {
461 ShowDialog();
462 }
463 }
464
PrepareSpecializedComponent()465 void DOMPickerBase::PrepareSpecializedComponent()
466 {
467 if (valuePickerChild_) {
468 valuePickerChild_->SetTextDirection((IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR));
469 }
470 if (CreatePicker()) {
471 for (const auto& attribute : storeAttributes_) {
472 SetSpecializedAttr(attribute);
473 }
474 for (const auto& oneEvent : storeEvents_) {
475 AddSpecializedEvent(oneEvent.first, oneEvent.second);
476 }
477 for (const auto& oneStyle : storeStyles_) {
478 SetSpecializedStyle(oneStyle);
479 }
480 }
481 storeAttributes_.clear();
482 storeEvents_.clear();
483 storeStyles_.clear();
484 }
485
CompositeComponents()486 void DOMPickerBase::CompositeComponents()
487 {
488 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_DATE &&
489 AceType::InstanceOf<PickerDateComponent>(basePickerChild_)) {
490 auto picker = AceType::DynamicCast<PickerDateComponent>(basePickerChild_);
491 // check invalidate of start and end.
492 const auto& start = picker->GetStartDate();
493 const auto& end = picker->GetEndDate();
494 if (start.GetYear() > end.GetYear() ||
495 (start.GetYear() == end.GetYear() && start.GetMonth() > end.GetMonth()) ||
496 (start.GetYear() == end.GetYear() && start.GetMonth() == end.GetMonth() && start.GetDay() > end.GetDay())) {
497 // invalidate => use default start date and end date.
498 picker->SetStartDate(DEFAULT_PICKER_DATE); // default start date is 1970-1-1 from FA document.
499 picker->SetEndDate(DEFAULT_END_PICKER_DATE); // default end date is 2100-12-31 from FA document.
500 }
501 }
502 if (IsRightToLeft()) {
503 SetAlignment(Alignment::CENTER_RIGHT);
504 }
505 DOMNode::CompositeComponents();
506 }
507
CreatePicker()508 bool DOMPickerBase::CreatePicker()
509 {
510 // The type cannot be dynamically changed.
511 if (basePickerChild_) {
512 return true;
513 }
514
515 // Operator map for type.
516 static const std::unordered_map<std::string, void (*)(RefPtr<PickerBaseComponent>&)> pickerOperators = {
517 { DOM_PICKER_TYPE_TIME,
518 [](RefPtr<PickerBaseComponent>& pickerBase) {
519 pickerBase = AceType::MakeRefPtr<PickerTimeComponent>(); } },
520 { DOM_PICKER_TYPE_DATE,
521 [](RefPtr<PickerBaseComponent>& pickerBase) {
522 pickerBase = AceType::MakeRefPtr<PickerDateComponent>(); } },
523 { DOM_PICKER_TYPE_TEXT,
524 [](RefPtr<PickerBaseComponent>& pickerBase) {
525 pickerBase = AceType::MakeRefPtr<PickerTextComponent>(); } },
526 { DOM_PICKER_TYPE_MULTITEXT,
527 [](RefPtr<PickerBaseComponent>& pickerBase) {
528 pickerBase = AceType::MakeRefPtr<PickerMultiTextComponent>();
529 } },
530 { DOM_PICKER_TYPE_DATETIME,
531 [](RefPtr<PickerBaseComponent>& pickerBase) {
532 pickerBase = AceType::MakeRefPtr<PickerDateTimeComponent>();
533 } },
534 };
535
536 auto operatorIter = pickerOperators.find(type_);
537 if (operatorIter != pickerOperators.end()) {
538 operatorIter->second(basePickerChild_);
539 } else {
540 basePickerChild_ = AceType::MakeRefPtr<PickerTextComponent>();
541 type_ = DOM_PICKER_TYPE_TEXT;
542 }
543
544 if (basePickerChild_) {
545 auto theme = GetTheme<PickerTheme>();
546 basePickerChild_->SetTheme(theme->clone());
547 basePickerChild_->SetTextDirection((IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR));
548 basePickerChild_->SetIsDialog(hasValue_);
549 basePickerChild_->SetNodeId(GetNodeId());
550 #if defined(PREVIEW)
551 basePickerChild_->SetPickerBaseId(pickerId_);
552 #endif
553 return true;
554 }
555
556 return false;
557 }
558
SetColumnHeight(const std::pair<std::string,std::string> & style)559 bool DOMPickerBase::SetColumnHeight(const std::pair<std::string, std::string>& style)
560 {
561 if (style.first != DOM_PICKER_COLUMN_HEIGHT) {
562 return false;
563 }
564
565 if (!hasValue_) {
566 return false;
567 }
568
569 if (!basePickerChild_) {
570 storeStyles_.emplace_back(style);
571 return false;
572 }
573
574 basePickerChild_->SetColumnHeight(StringToDimension(style.second));
575 return true;
576 }
577
SetStart(const std::string & value)578 bool DOMPickerBase::SetStart(const std::string& value)
579 {
580 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_DATE &&
581 AceType::InstanceOf<PickerDateComponent>(basePickerChild_)) {
582 auto picker = AceType::DynamicCast<PickerDateComponent>(basePickerChild_);
583 auto date = DEFAULT_PICKER_DATE;
584 if (GetPickerDate(value, date)) {
585 picker->SetStartDate(date);
586 }
587
588 return true;
589 }
590
591 return false;
592 }
593
SetEnd(const std::string & value)594 bool DOMPickerBase::SetEnd(const std::string& value)
595 {
596 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_DATE &&
597 AceType::InstanceOf<PickerDateComponent>(basePickerChild_)) {
598 auto picker = AceType::DynamicCast<PickerDateComponent>(basePickerChild_);
599 auto date = DEFAULT_PICKER_DATE;
600 if (GetPickerDate(value, date)) {
601 picker->SetEndDate(date);
602 }
603
604 return true;
605 }
606
607 return false;
608 }
609
SetSelected(const std::string & value)610 bool DOMPickerBase::SetSelected(const std::string& value)
611 {
612 return (SetTextSelected(value) || SetDateTimeSelected(value));
613 }
614
SetTextSelected(const std::string & value)615 bool DOMPickerBase::SetTextSelected(const std::string& value)
616 {
617 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_TEXT &&
618 AceType::InstanceOf<PickerTextComponent>(basePickerChild_)) {
619 auto picker = AceType::DynamicCast<PickerTextComponent>(basePickerChild_);
620 picker->SetSelected(StringUtils::StringToInt(value));
621 return true;
622 }
623
624 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_MULTITEXT &&
625 AceType::InstanceOf<PickerMultiTextComponent>(basePickerChild_)) {
626 auto picker = AceType::DynamicCast<PickerMultiTextComponent>(basePickerChild_);
627 std::vector<std::string> out;
628 StringUtils::StringSplitter(value, DOM_PICKER_SPLIT_ARRAY, out);
629 std::vector<uint32_t> selectedIndexes;
630 for (uint32_t index = 0; index < out.size(); ++index) {
631 selectedIndexes.emplace_back(StringUtils::StringToInt(out[index]));
632 }
633 picker->SetSelected(selectedIndexes);
634 return true;
635 }
636
637 return false;
638 }
639
SetDateTimeSelected(const std::string & value)640 bool DOMPickerBase::SetDateTimeSelected(const std::string& value)
641 {
642 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_DATE &&
643 AceType::InstanceOf<PickerDateComponent>(basePickerChild_)) {
644 auto picker = AceType::DynamicCast<PickerDateComponent>(basePickerChild_);
645 auto date = DEFAULT_PICKER_DATE;
646 if (GetPickerDate(value, date)) {
647 picker->SetSelectedDate(date);
648 }
649
650 return true;
651 }
652
653 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_TIME &&
654 AceType::InstanceOf<PickerTimeComponent>(basePickerChild_)) {
655 auto picker = AceType::DynamicCast<PickerTimeComponent>(basePickerChild_);
656 auto time = DEFAULT_PICKER_TIME;
657 if (GetPickerTime(value, time)) {
658 picker->SetSelectedTime(time);
659 }
660 return true;
661 }
662
663 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_DATETIME &&
664 AceType::InstanceOf<PickerDateTimeComponent>(basePickerChild_)) {
665 auto picker = AceType::DynamicCast<PickerDateTimeComponent>(basePickerChild_);
666 auto dateTime = PickerDateTime::Current();
667 if (GetPickerDateTime(value, dateTime)) {
668 picker->SetSelectedDateTime(dateTime);
669 }
670
671 return true;
672 }
673
674 return false;
675 }
676
SetHasSecond(const std::string & value)677 bool DOMPickerBase::SetHasSecond(const std::string& value)
678 {
679 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_TIME &&
680 AceType::InstanceOf<PickerTimeComponent>(basePickerChild_)) {
681 auto picker = AceType::DynamicCast<PickerTimeComponent>(basePickerChild_);
682 picker->SetHasSecond((value == "true")); // bool attribute's value is "true" and "false".
683 return true;
684 }
685
686 return false;
687 }
688
SetRange(const std::string & value)689 bool DOMPickerBase::SetRange(const std::string& value)
690 {
691 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_TEXT &&
692 AceType::InstanceOf<PickerTextComponent>(basePickerChild_)) {
693 auto picker = AceType::DynamicCast<PickerTextComponent>(basePickerChild_);
694 std::vector<std::string> out;
695 StringUtils::StringSplitter(value, DOM_PICKER_SPLIT_ARRAY, out);
696 picker->SetRange(out);
697 return true;
698 }
699
700 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_MULTITEXT &&
701 AceType::InstanceOf<PickerMultiTextComponent>(basePickerChild_)) {
702 auto picker = AceType::DynamicCast<PickerMultiTextComponent>(basePickerChild_);
703 std::vector<std::string> out;
704 StringUtils::StringSplitter(value, DOM_PICKER_SPLIT_ARRAY, out);
705 std::vector<std::vector<std::string>> arrayRange;
706 for (uint32_t index = 0; index < out.size(); ++index) {
707 std::vector<std::string> textRange;
708 StringUtils::StringSplitter(out[index], DOM_PICKER_SPLIT_ITEM, textRange);
709 arrayRange.emplace_back(textRange);
710 }
711 picker->SetRange(arrayRange);
712 return true;
713 }
714
715 return false;
716 }
717
SetColumnCount(const std::string & value)718 bool DOMPickerBase::SetColumnCount(const std::string& value)
719 {
720 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_MULTITEXT &&
721 AceType::InstanceOf<PickerMultiTextComponent>(basePickerChild_)) {
722 auto picker = AceType::DynamicCast<PickerMultiTextComponent>(basePickerChild_);
723 picker->SetColumnCount(StringUtils::StringToInt(value));
724 return true;
725 }
726
727 return false;
728 }
729
SetHour24(const std::string & value)730 bool DOMPickerBase::SetHour24(const std::string& value)
731 {
732 if (basePickerChild_ && (type_ == DOM_PICKER_TYPE_DATETIME || type_ == DOM_PICKER_TYPE_TIME) &&
733 AceType::InstanceOf<PickerTimeComponent>(basePickerChild_)) {
734 auto picker = AceType::DynamicCast<PickerTimeComponent>(basePickerChild_);
735 if (value == "24") {
736 picker->SetHour24(true);
737 } else if (value == "12") {
738 picker->SetHour24(false);
739 }
740 return true;
741 }
742
743 return false;
744 }
745
SetShowLunar(const std::string & value)746 bool DOMPickerBase::SetShowLunar(const std::string& value)
747 {
748 static const char* FALSE = "false";
749 static const char* TRUE = "true";
750
751 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_DATETIME &&
752 AceType::InstanceOf<PickerDateTimeComponent>(basePickerChild_)) {
753 auto picker = AceType::DynamicCast<PickerDateTimeComponent>(basePickerChild_);
754 if (value == TRUE) {
755 picker->SetShowLunar(true);
756 } else if (value == FALSE) {
757 picker->SetShowLunar(false);
758 }
759 return true;
760 }
761
762 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_DATE &&
763 AceType::InstanceOf<PickerDateComponent>(basePickerChild_)) {
764 auto picker = AceType::DynamicCast<PickerDateComponent>(basePickerChild_);
765 if (value == TRUE) {
766 picker->SetShowLunar(true);
767 } else if (value == FALSE) {
768 picker->SetShowLunar(false);
769 }
770 return true;
771 }
772
773 return false;
774 }
775
SetLunar(const std::string & value)776 bool DOMPickerBase::SetLunar(const std::string& value)
777 {
778 static const char* FALSE = "false";
779 static const char* TRUE = "true";
780
781 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_DATETIME &&
782 AceType::InstanceOf<PickerDateTimeComponent>(basePickerChild_)) {
783 auto picker = AceType::DynamicCast<PickerDateTimeComponent>(basePickerChild_);
784 if (value == TRUE) {
785 picker->SetHasLunar(true);
786 } else if (value == FALSE) {
787 picker->SetHasLunar(false);
788 }
789 return true;
790 }
791
792 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_DATE &&
793 AceType::InstanceOf<PickerDateComponent>(basePickerChild_)) {
794 auto picker = AceType::DynamicCast<PickerDateComponent>(basePickerChild_);
795 if (value == TRUE) {
796 picker->SetHasLunar(true);
797 } else if (value == FALSE) {
798 picker->SetHasLunar(false);
799 }
800 return true;
801 }
802
803 return false;
804 }
805
SetPrefix(const std::string & value)806 bool DOMPickerBase::SetPrefix(const std::string& value)
807 {
808 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_TEXT &&
809 AceType::InstanceOf<PickerTextComponent>(basePickerChild_)) {
810 auto picker = AceType::DynamicCast<PickerTextComponent>(basePickerChild_);
811 picker->SetPrefix(value);
812 return true;
813 }
814 return false;
815 }
816
SetSuffix(const std::string & value)817 bool DOMPickerBase::SetSuffix(const std::string& value)
818 {
819 if (basePickerChild_ && type_ == DOM_PICKER_TYPE_TEXT &&
820 AceType::InstanceOf<PickerTextComponent>(basePickerChild_)) {
821 auto picker = AceType::DynamicCast<PickerTextComponent>(basePickerChild_);
822 picker->SetSuffix(value);
823 return true;
824 }
825 return false;
826 }
827
SetVibrate(const std::string & value)828 bool DOMPickerBase::SetVibrate(const std::string& value)
829 {
830 static const char* FALSE = "false";
831 static const char* TRUE = "true";
832
833 if (basePickerChild_) {
834 if (value == TRUE) {
835 basePickerChild_->SetNeedVibrate(true);
836 } else if (value == FALSE) {
837 basePickerChild_->SetNeedVibrate(false);
838 }
839 return true;
840 }
841 return false;
842 }
843
844 } // namespace OHOS::Ace::Framework
845