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