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 "core/components/picker/picker_base_component.h"
17 
18 #include "base/i18n/localization.h"
19 #include "core/components/picker/picker_base_element.h"
20 #include "core/components/picker/render_picker_base.h"
21 #include "core/components/triangle/triangle_component.h"
22 
23 namespace OHOS::Ace {
24 
25 const char PickerBaseComponent::PICKER_YEAR_COLUMN[] = "year";
26 const char PickerBaseComponent::PICKER_MONTH_COLUMN[] = "month";
27 const char PickerBaseComponent::PICKER_DAY_COLUMN[] = "day";
28 const char PickerBaseComponent::PICKER_HOUR_COLUMN[] = "hour";
29 const char PickerBaseComponent::PICKER_MINUTE_COLUMN[] = "minute";
30 const char PickerBaseComponent::PICKER_SECOND_COLUMN[] = "second";
31 const char PickerBaseComponent::PICKER_TEXT_COLUMN[] = "text";
32 const char PickerBaseComponent::PICKER_MONTHDAY_COLUMN[] = "monthDay";
33 const char PickerBaseComponent::PICKER_AMPM_COLUMN[] = "amPm";
34 
CreateRenderNode()35 RefPtr<RenderNode> PickerBaseComponent::CreateRenderNode()
36 {
37     return RenderPickerBase::Create();
38 }
39 
CreateElement()40 RefPtr<Element> PickerBaseComponent::CreateElement()
41 {
42     auto element = AceType::MakeRefPtr<PickerBaseElement>();
43     element->SetAutoAccessibility(false);
44     return element;
45 }
46 
ClearColumns()47 void PickerBaseComponent::ClearColumns()
48 {
49     auto accessibilityManager = accessibilityManager_.Upgrade();
50     if (accessibilityManager) {
51         for (const auto& column : columns_) {
52             accessibilityManager->RemoveAccessibilityNodeById(column->GetNodeId());
53             column->SetNodeId(-1); // reset to invalidate id.
54         }
55     } else {
56         LOGE("accessibility manager is null.");
57     }
58     columns_.clear();
59 }
60 
AppendColumn(const RefPtr<PickerColumnComponent> & column)61 void PickerBaseComponent::AppendColumn(const RefPtr<PickerColumnComponent>& column)
62 {
63     columns_.emplace_back(column);
64 }
65 
SetNeedVibrate(bool needVibrate)66 void PickerBaseComponent::SetNeedVibrate(bool needVibrate)
67 {
68     if (needVibrate_ == needVibrate) {
69         return;
70     }
71     needVibrate_ = needVibrate;
72     for (auto& column : columns_) {
73         column->SetNeedVibrate(needVibrate_);
74     }
75 }
76 
GetColumn(const std::string & tag) const77 RefPtr<PickerColumnComponent> PickerBaseComponent::GetColumn(const std::string& tag) const
78 {
79     auto iter = std::find_if(columns_.begin(), columns_.end(),
80         [&tag](const RefPtr<PickerColumnComponent>& column) { return column->GetColumnTag() == tag; });
81     return (iter == columns_.end()) ? nullptr : *iter;
82 }
83 
RemoveColumn(const std::string & tag)84 void PickerBaseComponent::RemoveColumn(const std::string& tag)
85 {
86     auto column = GetColumn(tag);
87     auto accessibilityManager = accessibilityManager_.Upgrade();
88     if (accessibilityManager && column) {
89         accessibilityManager->RemoveAccessibilityNodeById(column->GetNodeId());
90         column->SetNodeId(-1); // reset to invalidate id.
91     } else {
92         LOGE("accessibility manager is null or can not get the column.");
93     }
94     columns_.erase(std::remove_if(
95         columns_.begin(),
96         columns_.end(),
97         [tag](const RefPtr<PickerColumnComponent>& col) { return col->GetColumnTag() == tag; }),
98         columns_.end());
99 }
100 
SetFinishCallback(const ColumnFinishCallback & value)101 void PickerBaseComponent::SetFinishCallback(const ColumnFinishCallback& value)
102 {
103     for (const auto& column : columns_) {
104         column->SetFinishCallback(value);
105     }
106 }
107 
SetChangeCallback(const ColumnChangeCallback & value)108 void PickerBaseComponent::SetChangeCallback(const ColumnChangeCallback& value)
109 {
110     for (const auto& column : columns_) {
111         column->SetChangeCallback(value);
112     }
113 }
114 
ShowDialog(const RefPtr<StackElement> & stack,bool disableTouchEvent)115 void PickerBaseComponent::ShowDialog(const RefPtr<StackElement>& stack, bool disableTouchEvent)
116 {
117     if (!isDialog_) {
118         return;
119     }
120 
121     if (dialogShowed_) {
122         LOGW("dialog is showed already.");
123         return;
124     }
125 
126     if (!stack) {
127         LOGE("stack is null.");
128         return;
129     }
130 
131     stack_ = stack;
132     if (!stack_->PushDialog(AceType::Claim(this), disableTouchEvent)) {
133         LOGE("push dialog failed!");
134         return;
135     }
136     dialogShowed_ = true;
137 }
138 
HideDialog()139 bool PickerBaseComponent::HideDialog()
140 {
141     CloseDialog();
142     if (!isDialog_) {
143         return false;
144     }
145 
146     if (!dialogShowed_) {
147         LOGW("dialog not show.");
148         return false;
149     }
150 
151     if (!stack_) {
152         LOGE("stack is null.");
153         return false;
154     }
155 
156     if (!stack_->PopDialog()) {
157         LOGE("pop dialog failed!");
158         return false;
159     }
160     dialogShowed_ = false;
161     ClearAccessibilityNodes();
162     return true;
163 }
164 
OpenDialog(const DialogProperties & properties)165 void PickerBaseComponent::OpenDialog(const DialogProperties& properties)
166 {
167     if (!isCreateDialogComponent_) {
168         return;
169     }
170 
171     auto container = Container::Current();
172     if (!container) {
173         return;
174     }
175     auto context = AceType::DynamicCast<PipelineContext>(container->GetPipelineContext());
176     if (!context) {
177         return;
178     }
179 
180     auto executor = context->GetTaskExecutor();
181     if (!executor) {
182         return;
183     }
184 
185     executor->PostTask(
186         [context, dialogProperties = properties, weak = WeakClaim(this)]() mutable {
187             const auto& picker = weak.Upgrade();
188             if (context && picker) {
189                 picker->dialogComponent_ = context->ShowDialog(dialogProperties, false, picker->GetDialogName());
190             }
191         },
192         TaskExecutor::TaskType::UI, "ArkUIDialogShowPicker");
193 }
194 
CloseDialog()195 void PickerBaseComponent::CloseDialog()
196 {
197     if (!isCreateDialogComponent_) {
198         return;
199     }
200 
201     auto container = Container::Current();
202     if (!container) {
203         return;
204     }
205     auto context = AceType::DynamicCast<PipelineContext>(container->GetPipelineContext());
206     if (!context) {
207         return;
208     }
209     const auto& lastStack = context->GetLastStack();
210     if (!lastStack) {
211         return;
212     }
213     auto executor = context->GetTaskExecutor();
214     if (!executor) {
215         return;
216     }
217     executor->PostTask(
218         [lastStack, dialogComponent = dialogComponent_]() {
219             if (!lastStack || !dialogComponent) {
220                 return;
221             }
222             auto dialogId = dialogComponent->GetDialogId();
223             lastStack->PopDialog(dialogId);
224         },
225         TaskExecutor::TaskType::UI, "ArkUIDialogClosePicker");
226 }
227 
OnTitleBuilding()228 void PickerBaseComponent::OnTitleBuilding()
229 {
230     SetHasLunar(false);
231 
232     auto theme = GetTheme();
233     if (!theme) {
234         LOGE("theme is null.");
235         return;
236     }
237     SetHasTitle(theme->GetShowButtons());
238     SetHasButtons(theme->GetShowButtons());
239 }
240 
InitializeTitle(std::list<RefPtr<Component>> & outChildren)241 void PickerBaseComponent::InitializeTitle(std::list<RefPtr<Component>>& outChildren)
242 {
243     if (!theme_) {
244         LOGE("theme is null.");
245         return;
246     }
247     if ((isDialog_ || isCreateDialogComponent_) && hasTitle_) {
248         auto triangle = AceType::MakeRefPtr<TriangleComponent>();
249         triangle->SetPadding(8.0_vp); // all padding
250         triangle->SetWidth(25.0_vp); // left padding + it width + right padding = 8dp + 9dp + 8dp
251         triangle->SetHeight(22.0_vp); // top padding + it height + bottom padding = 8dp + 6dp + 8dp
252         triangle->SetColor(theme_->GetTitleStyle().GetTextColor());
253         RefPtr<RowComponent> row = AceType::MakeRefPtr<RowComponent>(FlexAlign::CENTER,
254             FlexAlign::CENTER, std::list<RefPtr<Component>>());
255         title_->SetTextStyle(theme_->GetTitleStyle());
256         RefPtr<BoxComponent> titleBox = AceType::MakeRefPtr<BoxComponent>();
257         titleBox->SetChild(title_);
258         if (!GetHasTriangle()) {
259             row->AppendChild(AceType::MakeRefPtr<FlexItemComponent>(0.0, 1.0, 0.0, titleBox));
260         } else if (GetTextDirection() != TextDirection::RTL) {
261             row->AppendChild(AceType::MakeRefPtr<FlexItemComponent>(0.0, 1.0, 0.0, titleBox));
262             row->AppendChild(triangle);
263         } else {
264             row->AppendChild(triangle);
265             row->AppendChild(AceType::MakeRefPtr<FlexItemComponent>(0.0, 1.0, 0.0, titleBox));
266         }
267         auto titleComposed = GenerateAccessibilityComposed("picker-title", row, titleAccessibility_);
268         outChildren.emplace_back(titleComposed);
269 
270         RefPtr<BoxComponent> spaceBox = AceType::MakeRefPtr<BoxComponent>();
271         spaceBox->SetWidth(theme_->GetTitleBottomPadding().Value(), theme_->GetTitleBottomPadding().Unit());
272         spaceBox->SetHeight(theme_->GetTitleBottomPadding().Value(), theme_->GetTitleBottomPadding().Unit());
273         outChildren.emplace_back(spaceBox);
274     }
275 }
276 
InitializeColumns(std::list<RefPtr<Component>> & outChildren,const RefPtr<AccessibilityManager> & accessibilityManager)277 void PickerBaseComponent::InitializeColumns(
278     std::list<RefPtr<Component>>& outChildren, const RefPtr<AccessibilityManager>& accessibilityManager)
279 {
280     if (!theme_) {
281         LOGE("theme is null.");
282         return;
283     }
284 
285     std::list<RefPtr<Component>> columns;
286     for (const auto& column : columns_) {
287         column->SetTheme(theme_->clone());
288         column->SetTextDirection(GetTextDirection());
289         column->SetInDialog(isDialog_);
290         column->SetFixHeight(GetColumnHeight());
291         column->SetDefaultHeight(GetDefaultHeight());
292         auto id = column->GetNodeId();
293         if (id < 0) {
294             id = accessibilityManager->GenerateNextAccessibilityId();
295             // picker and picker-view accessibility parentNode different.
296             static const char* tag = "picker-column";
297             if (isDialog_) {
298                 accessibilityManager->CreateSpecializedNode(tag, id, rootAccessibilityId_);
299             } else {
300                 accessibilityManager->CreateSpecializedNode(tag, id, GetNodeId());
301             }
302             column->SetNodeId(id);
303         }
304         columns.emplace_back(column);
305     }
306     RefPtr<RowComponent> row = AceType::MakeRefPtr<RowComponent>(FlexAlign::FLEX_START, FlexAlign::FLEX_START, columns);
307     outChildren.emplace_back(row);
308 }
309 
InitializeChildAccessibility(const RefPtr<AccessibilityManager> & accessibilityManager)310 void PickerBaseComponent::InitializeChildAccessibility(const RefPtr<AccessibilityManager>& accessibilityManager)
311 {
312     if (!hasLunar_) {
313         if (lunarAccessibility_) {
314             accessibilityManager->RemoveAccessibilityNodes(lunarAccessibility_);
315             lunarAccessibility_ = nullptr;
316         }
317         if (switchAccessibility_) {
318             accessibilityManager->RemoveAccessibilityNodes(switchAccessibility_);
319             switchAccessibility_ = nullptr;
320         }
321         return;
322     }
323 }
324 
ClearAccessibilityNodes()325 void PickerBaseComponent::ClearAccessibilityNodes()
326 {
327     auto accessibilityManager = accessibilityManager_.Upgrade();
328     if (!accessibilityManager) {
329         LOGE("accessibilityManager is null");
330         return;
331     }
332 
333     if (rootAccessibility_) {
334         accessibilityManager->RemoveAccessibilityNodes(rootAccessibility_);
335         rootAccessibility_ = nullptr;
336         lunarAccessibility_ = nullptr;
337         switchAccessibility_ = nullptr;
338         titleAccessibility_ = nullptr;
339         cancelAccessibility_ = nullptr;
340         okAccessibility_ = nullptr;
341     }
342 
343     for (const auto& column : columns_) {
344         column->SetNodeId(-1); // reset id.
345     }
346 #if defined(PREVIEW)
347     if (accessibilityManager) {
348         auto node = accessibilityManager->GetAccessibilityNodeById(GetPickerBaseId());
349         if (node) {
350             node->SetZIndexToChild(0);
351         }
352     }
353 #endif
354 }
355 
GenerateAccessibilityComposed(const std::string & name,const RefPtr<Component> & child,RefPtr<AccessibilityNode> & node)356 RefPtr<Component> PickerBaseComponent::GenerateAccessibilityComposed(
357     const std::string& name, const RefPtr<Component>& child, RefPtr<AccessibilityNode>& node)
358 {
359     auto accessibilityManager = accessibilityManager_.Upgrade();
360     if (!accessibilityManager) {
361         return child;
362     }
363 
364     if (!node) {
365         int32_t parentNodeId = -1;
366         int32_t composedId = accessibilityManager->GenerateNextAccessibilityId();
367         if (isDialog_) {
368             parentNodeId = rootAccessibilityId_;
369         } else {
370             parentNodeId = GetNodeId();
371         }
372         node = accessibilityManager->CreateSpecializedNode(name, composedId, parentNodeId);
373     }
374     return child;
375 }
376 
InitializeLunar(std::list<RefPtr<Component>> & outChildren,const RefPtr<ThemeManager> & themeManager)377 void PickerBaseComponent::InitializeLunar(
378     std::list<RefPtr<Component>>& outChildren, const RefPtr<ThemeManager>& themeManager)
379 {
380     if (!theme_) {
381         LOGE("theme is null");
382         return;
383     }
384 
385     if (hasLunar_) {
386         RefPtr<BoxComponent> spaceBox = AceType::MakeRefPtr<BoxComponent>();
387         spaceBox->SetWidth(theme_->GetButtonTopPadding().Value(), theme_->GetButtonTopPadding().Unit());
388         spaceBox->SetHeight(theme_->GetButtonTopPadding().Value(), theme_->GetButtonTopPadding().Unit());
389         outChildren.emplace_back(spaceBox);
390         std::wstring lunarString { 0x663E, 0x793A, 0x519C, 0x5386 }; // the unicode encoding of chinese string of lunar.
391         RefPtr<TextComponent> lunarText = AceType::MakeRefPtr<TextComponent>(StringUtils::ToString(lunarString));
392         auto lunarStyle = theme_->GetOptionStyle(false, false);
393         if (GetIsDialog()) {
394             lunarStyle.SetLineHeight(theme_->GetLunarHeight());
395         }
396         lunarText->SetTextStyle(lunarStyle);
397         auto checkboxTheme = themeManager->GetTheme<CheckboxTheme>();
398         lunar_ = AceType::MakeRefPtr<CheckboxComponent>(checkboxTheme);
399         lunar_->SetHorizontalPadding(Dimension(0.0));
400         lunar_->SetHotZoneVerticalPadding(Dimension(0.0));
401         auto lunarSwitchComposed = GenerateAccessibilityComposed("lunar-switch", lunar_, switchAccessibility_);
402         RefPtr<BoxComponent> lunarBox = AceType::MakeRefPtr<BoxComponent>();
403         lunarBox->SetChild(lunarSwitchComposed);
404         lunarBox->SetWidth(theme_->GetLunarWidth().Value(), theme_->GetLunarWidth().Unit());
405         lunarBox->SetHeight(theme_->GetLunarHeight().Value(), theme_->GetLunarHeight().Unit());
406 
407         std::list<RefPtr<Component>> lunarChildren;
408         FlexAlign mainAlign = FlexAlign::AUTO;
409         if (GetTextDirection() == TextDirection::RTL) {
410             mainAlign = FlexAlign::FLEX_END;
411             lunarChildren.emplace_back(lunarText);
412             lunarChildren.emplace_back(lunarBox);
413         } else {
414             mainAlign = FlexAlign::FLEX_START;
415             lunarChildren.emplace_back(lunarBox);
416             lunarChildren.emplace_back(lunarText);
417         }
418         RefPtr<RowComponent> lunarRow =
419             AceType::MakeRefPtr<RowComponent>(mainAlign, FlexAlign::CENTER, lunarChildren);
420         RefPtr<DisplayComponent> display = AceType::MakeRefPtr<DisplayComponent>();
421         display->SetChild(lunarRow);
422         outChildren.emplace_back(display);
423     }
424 
425     if (GetSubsidiary() && GetMasterHasLunar()) {
426         RefPtr<BoxComponent> spaceBox = AceType::MakeRefPtr<BoxComponent>();
427         spaceBox->SetWidth(theme_->GetButtonTopPadding().Value(), theme_->GetButtonTopPadding().Unit());
428         spaceBox->SetHeight(theme_->GetButtonTopPadding().Value() + theme_->GetLunarHeight().Value(),
429             theme_->GetButtonTopPadding().Unit());
430         outChildren.emplace_back(spaceBox);
431     }
432 }
433 
InitializeButtons(std::list<RefPtr<Component>> & outChildren,const RefPtr<ThemeManager> & themeManager)434 void PickerBaseComponent::InitializeButtons(
435     std::list<RefPtr<Component>>& outChildren, const RefPtr<ThemeManager>& themeManager)
436 {
437     auto dialogTheme = themeManager->GetTheme<DialogTheme>();
438     if (!theme_ || !dialogTheme) {
439         LOGE("theme is null.");
440         return;
441     }
442 
443     auto buttonTheme = AceType::DynamicCast<ButtonTheme>(themeManager->GetTheme(ButtonTheme::TypeId()));
444     if (!buttonTheme) {
445         return;
446     }
447     auto buttonTextStyle = buttonTheme->GetTextStyle();
448     auto buttonFocusColor = theme_->GetFocusColor();
449     buttonTextStyle.SetTextColor(buttonFocusColor);
450 
451     if (isDialog_ || isCreateDialogComponent_) {
452         RefPtr<BoxComponent> topPaddingBox = AceType::MakeRefPtr<BoxComponent>();
453         topPaddingBox->SetWidth(theme_->GetButtonTopPadding().Value(), theme_->GetButtonTopPadding().Unit());
454         topPaddingBox->SetHeight(theme_->GetButtonTopPadding().Value(), theme_->GetButtonTopPadding().Unit());
455         outChildren.emplace_back(topPaddingBox);
456 
457         auto cancelButton = ButtonBuilder::Build(themeManager,
458             Localization::GetInstance()->GetEntryLetters("common.cancel"), buttonTextStyle, buttonFocusColor, true);
459         cancelButton->SetBackgroundColor(dialogTheme->GetButtonBackgroundColor());
460         cancelButton->SetClickedColor(dialogTheme->GetButtonClickedColor());
461         cancelButton->SetClickedEventId(onCancelClickId_);
462         cancelButton->SetType(ButtonType::CAPSULE);
463         cancelButton->SetHeight(theme_->GetButtonHeight());
464         auto cancelComposed = GenerateAccessibilityComposed("picker-button", cancelButton, cancelAccessibility_);
465         if (cancelAccessibility_) {
466             cancelAccessibility_->SetText(Localization::GetInstance()->GetEntryLetters("common.cancel"));
467         }
468 
469         auto okButton = ButtonBuilder::Build(themeManager, Localization::GetInstance()->GetEntryLetters("common.ok"),
470             buttonTextStyle, buttonFocusColor, true);
471         okButton->SetBackgroundColor(dialogTheme->GetButtonBackgroundColor());
472         okButton->SetClickedColor(dialogTheme->GetButtonClickedColor());
473         okButton->SetClickedEventId(onOkClickId_);
474         okButton->SetType(ButtonType::CAPSULE);
475         okButton->SetHeight(theme_->GetButtonHeight());
476         auto okComposed = GenerateAccessibilityComposed("picker-button", okButton, okAccessibility_);
477         if (okAccessibility_) {
478             okAccessibility_->SetText(Localization::GetInstance()->GetEntryLetters("common.ok"));
479         }
480 
481         auto dividerBox = AceType::MakeRefPtr<BoxComponent>();
482         dividerBox->SetWidth(dialogTheme->GetDividerWidth().Value(), dialogTheme->GetDividerWidth().Unit());
483         dividerBox->SetHeight(dialogTheme->GetDividerHeight().Value(), dialogTheme->GetDividerHeight().Unit());
484         auto backDecoration = AceType::MakeRefPtr<Decoration>();
485         backDecoration->SetBackgroundColor(dialogTheme->GetDividerColor());
486         dividerBox->SetBackDecoration(backDecoration);
487         dividerBox->SetMargin(dialogTheme->GetDividerPadding());
488 
489         std::list<RefPtr<Component>> buttons;
490         RefPtr<RowComponent> row =
491             AceType::MakeRefPtr<RowComponent>(FlexAlign::SPACE_AROUND, FlexAlign::FLEX_START, buttons);
492         row->SetTextDirection(GetTextDirection());
493         row->AppendChild(AceType::MakeRefPtr<FlexItemComponent>(1.0, 1.0, 0.0, cancelComposed));
494         row->AppendChild(AceType::MakeRefPtr<FlexItemComponent>(0.0, 0.0, 0.0, dividerBox));
495         row->AppendChild(AceType::MakeRefPtr<FlexItemComponent>(1.0, 1.0, 0.0, okComposed));
496         row->SetStretchToParent(true);
497 
498         auto display = AceType::MakeRefPtr<DisplayComponent>();
499         display->SetChild(row);
500         outChildren.emplace_back(display);
501     }
502 }
503 
InitializeContainer(const std::list<RefPtr<Component>> & outChildren)504 void PickerBaseComponent::InitializeContainer(const std::list<RefPtr<Component>>& outChildren)
505 {
506     if (!theme_) {
507         LOGE("theme is null.");
508         return;
509     }
510 
511     RefPtr<ColumnComponent> outColumn =
512         AceType::MakeRefPtr<ColumnComponent>(FlexAlign::CENTER, FlexAlign::FLEX_START, outChildren);
513     RefPtr<BoxComponent> box = AceType::MakeRefPtr<BoxComponent>();
514     box->SetDeliverMinToChild(false);
515     box->SetAlignment(Alignment::CENTER);
516     if (GetIsDialog()) {
517         RefPtr<FocusCollaborationComponent> collaboration = AceType::MakeRefPtr<FocusCollaborationComponent>();
518         collaboration->InsertChild(0, outColumn);
519         box->SetChild(collaboration);
520     } else {
521         box->SetChild(outColumn);
522     }
523 
524     RefPtr<BoxComponent> outBox = AceType::MakeRefPtr<BoxComponent>();
525     outBox->SetDeliverMinToChild(false);
526     outBox->SetAlignment(Alignment::CENTER);
527     outBox->SetChild(box);
528     if (GetTextDirection() == TextDirection::RTL) {
529         outColumn->SetCrossAxisAlign(FlexAlign::FLEX_END);
530         box->SetAlignment(Alignment::CENTER_RIGHT);
531     }
532     // picker need build outer composed component but picker-view don't need.
533     if (isDialog_) {
534         if (GetSubsidiary()) {
535             auto edge = theme_->GetPopupEdge();
536             edge.SetTop(0.0_vp);
537             edge.SetBottom(0.0_vp);
538             auto temp = AceType::MakeRefPtr<Decoration>();
539             temp->SetBackgroundColor(Color::TRANSPARENT);
540             box->SetBackDecoration(temp);
541             box->SetPadding(edge);
542             outBox->SetBackDecoration(temp);
543         } else {
544             box->SetBackDecoration(theme_->GetPopupDecoration(false));
545             box->SetPadding(theme_->GetPopupEdge());
546             outBox->SetBackDecoration(theme_->GetPopupDecoration(true));
547         }
548         SetChild(outBox);
549     } else {
550         SetChild(outBox);
551     }
552 }
553 
Initialize(const RefPtr<AccessibilityManager> & accessibilityManager,const RefPtr<ThemeManager> & themeManager)554 void PickerBaseComponent::Initialize(
555     const RefPtr<AccessibilityManager>& accessibilityManager, const RefPtr<ThemeManager>& themeManager)
556 {
557     if (!themeManager) {
558         return;
559     }
560 
561     if (!theme_) {
562         theme_ = themeManager->GetTheme<PickerTheme>();
563     }
564     accessibilityManager_ = accessibilityManager;
565     OnColumnsBuilding();
566     OnTitleBuilding();
567 
568     // picker need build rootAccessibilityNode but picker-view don't need.
569     if (!rootAccessibility_ && isDialog_) {
570         rootAccessibilityId_ = accessibilityManager->GenerateNextAccessibilityId();
571 #if defined(PREVIEW)
572         rootAccessibility_ = accessibilityManager->CreateAccessibilityNode(
573             "picker-dialog", rootAccessibilityId_, GetPickerBaseId(), -1);
574 #else
575         rootAccessibility_ = accessibilityManager->CreateSpecializedNode("picker-dialog", rootAccessibilityId_, -1);
576 #endif
577     }
578     std::list<RefPtr<Component>> outChildren;
579     InitializeTitle(outChildren);
580     InitializeColumns(outChildren, accessibilityManager);
581     InitializeLunar(outChildren, themeManager);
582     InitializeButtons(outChildren, themeManager);
583     InitializeContainer(outChildren);
584     InitializeChildAccessibility(accessibilityManager);
585 }
586 
587 } // namespace OHOS::Ace
588