1 /*
2  * Copyright (c) 2021 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/navigation_bar/navigation_bar_component.h"
17 
18 #include "core/components/display/display_component.h"
19 #include "core/components/flex/flex_item_component.h"
20 #include "core/components/navigation_bar/navigation_bar_element.h"
21 #include "core/components/padding/padding_component.h"
22 #include "core/components/transform/transform_component.h"
23 #ifdef WEARABLE_PRODUCT
24 #include "core/components/box/box_component.h"
25 #include "core/components/button/button_theme.h"
26 #include "core/components/flex/flex_item_component.h"
27 #include "core/components/image/image_component.h"
28 #include "core/components/text/text_component.h"
29 #endif
30 
31 namespace OHOS::Ace {
32 namespace {
33 
34 #ifndef WEARABLE_PRODUCT
35 constexpr double MIDDLE_ZONE_FLEX_GROW = 1.0;
36 constexpr double MIDDLE_ZONE_FLEX_SHRINK = 1.0;
37 // only for default
38 constexpr double LOGO_PADDING_RIGHT_VALUE = 16.0;
39 // only for tv
40 constexpr double TV_PADDING_BETWEEN_TITLE_AND_SUBTITLE = 12.0;
41 constexpr double WATCH_BAR_PADDING_BOTTOM = 8.0;
42 #endif
43 
44 // only for watch
45 constexpr double WATCH_TITLE_LINE_PADDING_VALUE = 52.0;
46 const Dimension WATCH_TITLE_LINE_PADDING(WATCH_TITLE_LINE_PADDING_VALUE, DimensionUnit::VP);
47 constexpr double WATCH_SUBTITLE_LINE_PADDING_VALUE = 26.0;
48 const Dimension WATCH_SUBTITLE_LINE_PADDING(WATCH_SUBTITLE_LINE_PADDING_VALUE, DimensionUnit::VP);
49 constexpr double WATCH_TITLE_PADDING_TOP = 20.0;
50 constexpr double WATCH_SUBTITLE_PADDING_TOP = 2.0;
51 constexpr double WATCH_PADDING_BETWEEN_LOGO_AND_SUBTITLE = 8.0;
52 constexpr Dimension WATCH_TITLE_MIN_SIZE = 16.0_fp;
53 constexpr Dimension WATCH_SUBTITLE_MIN_SIZE = 13.0_fp;
54 
BuildWatchTitleText(const std::string & value,const Color & color,const Dimension & fontSize,bool subtitle)55 RefPtr<TextComponent> BuildWatchTitleText(
56     const std::string& value, const Color& color, const Dimension& fontSize, bool subtitle)
57 {
58     auto text = AceType::MakeRefPtr<TextComponent>(value);
59     TextStyle textStyle;
60     textStyle.SetTextColor(color);
61     textStyle.SetFontSize(fontSize);
62     textStyle.SetAllowScale(false);
63     textStyle.SetFontWeight(FontWeight::W500);
64     if (subtitle) {
65         textStyle.SetMaxLines(1);
66         textStyle.SetAdaptMaxFontSize(fontSize);
67         textStyle.SetAdaptMinFontSize(WATCH_SUBTITLE_MIN_SIZE);
68     } else {
69         textStyle.SetMaxLines(2);
70         textStyle.SetAdaptMaxFontSize(fontSize);
71         textStyle.SetAdaptMinFontSize(WATCH_TITLE_MIN_SIZE);
72     }
73 
74     textStyle.SetTextOverflow(TextOverflow::ELLIPSIS);
75     text->SetTextStyle(textStyle);
76     return text;
77 }
78 
79 } // namespace
80 
NavigationBarComponent(const ComposeId & id,const std::string & name)81 NavigationBarComponent::NavigationBarComponent(const ComposeId& id, const std::string& name)
82     : ComposedComponent(id, name), data_(AceType::MakeRefPtr<NavigationBarData>())
83 {}
84 
CreateElement()85 RefPtr<Element> NavigationBarComponent::CreateElement()
86 {
87     return AceType::MakeRefPtr<NavigationBarElement>(GetId());
88 }
89 
90 #ifndef WEARABLE_PRODUCT
BuildTitle(double padding)91 RefPtr<Component> PhoneTitleBarBuilder::BuildTitle(double padding)
92 {
93     RefPtr<ColumnComponent> titleContainer = AceType::MakeRefPtr<ColumnComponent>(
94         FlexAlign::FLEX_START, FlexAlign::FLEX_START, std::list<RefPtr<Component>>());
95     titleContainer->SetTextDirection(direction_);
96     titleContainer->SetMainAxisSize(MainAxisSize::MIN);
97     if (padding > 0) {
98         titleContainer->AppendChild(BuildPadding(padding, true));
99     }
100 
101     if (selectPopup_) {
102         BuildSelectPopup(titleContainer);
103     } else if (!title_.empty()) {
104         auto titleText = BuildTitleText(title_, titleColor_, titleFontSize_, FontWeight::W500);
105         auto transform = AceType::MakeRefPtr<TransformComponent>();
106         transform->SetChild(titleText);
107         transform->SetOriginDimension(DimensionOffset(Offset(0.0, 0.0)));
108         titleComposed_ = GenerateAccessibilityComposed(StringUtils::StringToInt(id_), "titleText", transform);
109         titleContainer->AppendChild(titleComposed_);
110     }
111     if (!subTitle_.empty()) {
112         titleContainer->AppendChild(BuildPadding(2, true));
113         auto subTitleText = BuildTitleText(subTitle_, subTitleColor_, subTitleFontSize_, FontWeight::W400);
114         auto display = AceType::MakeRefPtr<DisplayComponent>(subTitleText);
115         subTitleComposed_ = GenerateAccessibilityComposed(StringUtils::StringToInt(id_), "subTitleText", display);
116         titleContainer->AppendChild(subTitleComposed_);
117     }
118 
119     return AceType::MakeRefPtr<FlexItemComponent>(MIDDLE_ZONE_FLEX_GROW, MIDDLE_ZONE_FLEX_SHRINK, 0.0, titleContainer);
120 }
121 
BuildTabBar(const RefPtr<ComponentGroup> & parent)122 void TabBarBuilder::BuildTabBar(const RefPtr<ComponentGroup>& parent)
123 {
124     tabBar_->InitNavigationBarStyle();
125     RefPtr<BoxComponent> box = AceType::MakeRefPtr<BoxComponent>();
126     box->SetChild(tabBar_);
127     box->SetDeliverMinToChild(false);
128     parent->AppendChild(
129         AceType::MakeRefPtr<FlexItemComponent>(MIDDLE_ZONE_FLEX_GROW, MIDDLE_ZONE_FLEX_SHRINK, 0.0, box));
130 }
131 
MoveMenuItemsToBar(const RefPtr<ComponentGroup> & container)132 void TitleBarMenuBuilder::MoveMenuItemsToBar(const RefPtr<ComponentGroup>& container)
133 {
134     menu_->ClearOptions();
135     uint32_t showInBarSize = 0;
136     bool hasRoom = true;
137     uint32_t mostShowInBarSize = theme_->GetMostMenuItemCountInBar();
138 
139     bool needAddPadding = false;
140     for (const auto& menuItem : allMenuItems_) {
141         hasRoom = hasRoom && ((showInBarSize < mostShowInBarSize - 1) ||
142                     (showInBarSize == mostShowInBarSize - 1 && allMenuItems_.size() == mostShowInBarSize) ||
143                     (showInBarSize < mostShowInBarSize && SystemProperties::GetDeviceType() == DeviceType::TV));
144         if (menuItem->GetShowInNavigationBar() == ShowInNavigationBar::SHOW && hasRoom) {
145             showInBarSize++;
146             auto menuItemIcon = menuItem->GetIcon();
147             if (!menuItemIcon) {
148                 LOGW("navigation bar menu item icon empty");
149                 continue;
150             }
151 
152             IconImage menuIcon(menuItemIcon->GetSrc(), menuIconSize_, menuIconSize_, imageFill_);
153             auto optionButton = BuildIconButton(theme_, menuZoneSize_, menuZoneSize_, menuIcon);
154             if (theme_->GetMenuItemPadding().Value() > 0.0 && needAddPadding) {
155                 container->AppendChild(BuildPadding(theme_->GetMenuItemPadding().Value()));
156             }
157             container->AppendChild(
158                 GenerateAccessibilityComposed(StringUtils::StringToInt(id_), "optionButton", optionButton));
159             needAddPadding = true;
160 
161             NavigationBarComponent::MenuItemInBar menuItemInBar { menuItem->GetValue(),
162                 BackEndEventManager<void(const ClickInfo&)>::GetInstance().GetAvailableMarker(), optionButton };
163             menuItemsInBar_.emplace(menuItemInBar.clickEvent.GetData().eventId, menuItemInBar);
164         } else {
165             menu_->AppendOption(menuItem);
166         }
167     }
168 }
169 
AddCollapseMenu(const RefPtr<ComponentGroup> & container)170 void TitleBarMenuBuilder::AddCollapseMenu(const RefPtr<ComponentGroup>& container)
171 {
172     IconImage moreIcon(theme_->GetMoreResourceId(), menuIconSize_, menuIconSize_);
173     moreIcon.image->SetImageFill(theme_->GetMenuIconColor());
174     moreButton_ = BuildIconButton(theme_, menuZoneSize_, menuZoneSize_, moreIcon);
175     container->AppendChild(GenerateAccessibilityComposed(StringUtils::StringToInt(id_), "moreButton", moreButton_));
176     container->AppendChild(menu_);
177 }
178 
AddMenu(const RefPtr<ComponentGroup> & container,bool canCollapse)179 bool TitleBarMenuBuilder::AddMenu(const RefPtr<ComponentGroup>& container, bool canCollapse)
180 {
181     if (menu_) {
182         MoveMenuItemsToBar(container);
183         if (menu_->GetOptionCount() > 0 && canCollapse) {
184             AddCollapseMenu(container);
185         }
186         return true;
187     }
188     return false;
189 }
190 
BuildSelectPopup(const RefPtr<ComponentGroup> & parent)191 void PhoneTitleBarBuilder::BuildSelectPopup(const RefPtr<ComponentGroup>& parent)
192 {
193     RefPtr<BoxComponent> selectBox = AceType::MakeRefPtr<BoxComponent>();
194     if (!selectPopup_->IsFontSet()) {
195         selectPopup_->SetFontSize(titleFontSize_);
196     }
197     selectPopup_->SetInnerPadding(Edge());
198     selectPopup_->SetClickedColor(Color::TRANSPARENT);
199     selectBox->SetChild(selectPopup_);
200 
201     auto transform = AceType::MakeRefPtr<TransformComponent>();
202     transform->SetChild(selectBox);
203     transform->SetOriginDimension(DimensionOffset(Offset(0.0, 0.0)));
204     titleComposed_ = GenerateAccessibilityComposed(StringUtils::StringToInt(id_), "select", transform);
205     parent->AppendChild(titleComposed_);
206 }
207 
BuildTitleZone(const RefPtr<ComponentGroup> & parent,double padding)208 void PhoneTitleBarBuilder::BuildTitleZone(const RefPtr<ComponentGroup>& parent, double padding)
209 {
210     if (tabBar_) {
211         if (parent->GetChildren().empty()) {
212             padding_.SetLeft(Dimension(0, DimensionUnit::VP));
213         }
214         BuildTabBar(parent);
215     } else {
216         parent->AppendChild(BuildTitle(padding));
217     }
218 }
219 
Build()220 RefPtr<Component> EmphasizeTitleBarBuilder::Build()
221 {
222     RefPtr<RowComponent> menuContainer =
223         AceType::MakeRefPtr<RowComponent>(FlexAlign::FLEX_END, FlexAlign::CENTER, std::list<RefPtr<Component>>());
224     menuContainer->SetTextDirection(direction_);
225     auto menusBox = AceType::MakeRefPtr<BoxComponent>();
226     menusBox->SetHeight(theme_->GetHeight().Value(), theme_->GetHeight().Unit());
227     menusBox->SetChild(menuContainer);
228     AddMenu(menuContainer);
229     RefPtr<ColumnComponent> columnContainer =
230         AceType::MakeRefPtr<ColumnComponent>(FlexAlign::FLEX_START, FlexAlign::STRETCH, std::list<RefPtr<Component>>());
231     columnContainer->SetTextDirection(direction_);
232     columnContainer->SetCrossAxisSize(CrossAxisSize::MAX);
233     columnContainer->AppendChild(BuildTitle());
234 
235     RefPtr<CollapsingNavigationBarComponent> collapsingNavigationBar =
236         AceType::MakeRefPtr<CollapsingNavigationBarComponent>(AceType::Claim(this));
237     collapsingNavigationBar->AppendChild(menusBox);
238     collapsingNavigationBar->AppendChild(columnContainer);
239     collapsingNavigationBar->SetMinHeight(theme_->GetHeight());
240 
241     if (!subTitle_.empty() && !tabBar_) {
242         height_ = Dimension(134, DimensionUnit::VP);
243     }
244     if (tabBar_) {
245         padding_.SetLeft(Dimension(0, DimensionUnit::VP));
246     }
247     return TitleBarBuilder::BuildContainer(collapsingNavigationBar);
248 }
249 
BuildStartZone(const RefPtr<RowComponent> & parent)250 void NormalTitleBarBuilder::BuildStartZone(const RefPtr<RowComponent>& parent)
251 {
252     if (!startIconSrc_.empty()) {
253         IconImage startIcon(startIconSrc_, menuIconSize_, menuIconSize_, imageFill_);
254         auto startButton = BuildIconButton(theme_, menuZoneSize_, menuZoneSize_, startIcon, startClickMarker_);
255         parent->AppendChild(GenerateAccessibilityComposed(StringUtils::StringToInt(id_), "startButton", startButton));
256         parent->AppendChild(BuildPadding(theme_->GetTitleMinPadding().Value()));
257         padding_.SetLeft(theme_->GetDefaultPaddingStart());
258     } else if (backEnabled_) {
259         IconImage backIcon(theme_->GetBackResourceId(), menuIconSize_, menuIconSize_);
260         backIcon.image->SetTextDirection(direction_);
261         backIcon.image->SetMatchTextDirection(true);
262         backIcon.image->SetColor(theme_->GetMenuIconColor());
263         auto backButton = BuildIconButton(theme_, menuZoneSize_, menuZoneSize_, backIcon, backClickMarker_);
264         parent->AppendChild(GenerateAccessibilityComposed(StringUtils::StringToInt(id_), "backButton", backButton));
265         parent->AppendChild(BuildPadding(theme_->GetTitleMinPadding().Value()));
266         padding_.SetLeft(theme_->GetDefaultPaddingStart());
267     }
268 }
269 
BuildLogo(const RefPtr<RowComponent> & parent)270 void NormalTitleBarBuilder::BuildLogo(const RefPtr<RowComponent>& parent)
271 {
272     if (!logoSrc_.empty()) {
273         auto logoSize = theme_->GetLogoIconSize();
274         IconImage logoIconImage(logoSrc_, logoSize, logoSize, imageFill_);
275         parent->AppendChild(GenerateAccessibilityComposed(StringUtils::StringToInt(id_), "image", logoIconImage.image));
276         parent->AppendChild(BuildPadding(LOGO_PADDING_RIGHT_VALUE));
277         padding_.SetLeft(theme_->GetDefaultPaddingStart());
278     }
279 }
280 
BuildEndZone(const RefPtr<RowComponent> & parent)281 void NormalTitleBarBuilder::BuildEndZone(const RefPtr<RowComponent>& parent)
282 {
283     parent->AppendChild(BuildPadding(theme_->GetTitleMinPadding().Value()));
284     if (!endIconSrc_.empty()) {
285         IconImage endIcon(endIconSrc_, menuIconSize_, menuIconSize_, imageFill_);
286         auto endButton = BuildIconButton(theme_, menuZoneSize_, menuZoneSize_, endIcon, endClickMarker_);
287         parent->AppendChild(GenerateAccessibilityComposed(StringUtils::StringToInt(id_), "endButton", endButton));
288         padding_.SetRight(theme_->GetDefaultPaddingEnd());
289     } else if (AddMenu(parent)) {
290         padding_.SetRight(theme_->GetDefaultPaddingEnd());
291     } else {
292         padding_.SetRight(theme_->GetMaxPaddingStart() - theme_->GetTitleMinPadding());
293     }
294 }
295 
Build()296 RefPtr<Component> NormalTitleBarBuilder::Build()
297 {
298     if (!theme_) {
299         LOGW("theme is null");
300         return nullptr;
301     }
302     padding_.SetLeft(theme_->GetMaxPaddingStart());
303     padding_.SetRight(theme_->GetMaxPaddingEnd());
304 
305     RefPtr<RowComponent> container =
306         AceType::MakeRefPtr<RowComponent>(FlexAlign::FLEX_START, FlexAlign::CENTER, std::list<RefPtr<Component>>());
307     container->SetTextDirection(direction_);
308     container->SetUpdateType(UpdateType::REBUILD);
309 
310     if (backEnabled_) {
311         titleFontSize_ = Dimension(20, DimensionUnit::VP);
312     }
313 
314     BuildStartZone(container);
315     BuildLogo(container);
316     BuildTitleZone(container);
317     BuildEndZone(container);
318     return TitleBarBuilder::BuildContainer(container);
319 }
320 
BindDefaultBackEvent(const WeakPtr<PipelineContext> & weakContext)321 void NormalTitleBarBuilder::BindDefaultBackEvent(const WeakPtr<PipelineContext>& weakContext)
322 {
323     if (!backClickMarker_.IsEmpty()) {
324         return;
325     }
326     backClickMarker_ = BackEndEventManager<void(const ClickInfo&)>::GetInstance().GetAvailableMarker();
327     BackEndEventManager<void(const ClickInfo&)>::GetInstance().BindBackendEvent(
328         backClickMarker_, [weakContext](const ClickInfo& clickInfo) {
329             auto context = weakContext.Upgrade();
330             if (!context) {
331                 LOGW("context is empty");
332                 return;
333             }
334             context->CallRouterBackToPopPage();
335         });
336 }
337 
BuildTitle(const RefPtr<ComponentGroup> & parent)338 void TVTitleBarBuilder::BuildTitle(const RefPtr<ComponentGroup>& parent)
339 {
340     if (!title_.empty()) {
341         if (!titleFontSize_.IsValid()) {
342             titleFontSize_ = theme_->GetTitleFontSize();
343         }
344         auto titleText = BuildTitleText(title_, titleColor_, titleFontSize_, FontWeight::W500);
345         parent->AppendChild(GenerateAccessibilityComposed(StringUtils::StringToInt(id_), "titleText", titleText));
346     }
347 }
348 
BuildSubTitle(const RefPtr<ComponentGroup> & parent,const RefPtr<ComponentGroup> & leftContainer)349 void TVTitleBarBuilder::BuildSubTitle(const RefPtr<ComponentGroup>& parent, const RefPtr<ComponentGroup>& leftContainer)
350 {
351     if (!subTitle_.empty()) {
352         if (menu_) {
353             leftContainer->AppendChild(BuildPadding(TV_PADDING_BETWEEN_TITLE_AND_SUBTITLE));
354             auto subTitleText = BuildTitleText(subTitle_, subTitleColor_, subTitleFontSize_, FontWeight::W400);
355             leftContainer->AppendChild(
356                 GenerateAccessibilityComposed(StringUtils::StringToInt(id_), "subTitleText", subTitleText));
357             parent->AppendChild(AceType::MakeRefPtr<FlexItemComponent>(
358                 MIDDLE_ZONE_FLEX_GROW, MIDDLE_ZONE_FLEX_SHRINK, 0.0, leftContainer));
359         } else {
360             parent->AppendChild(AceType::MakeRefPtr<FlexItemComponent>(
361                 MIDDLE_ZONE_FLEX_GROW, MIDDLE_ZONE_FLEX_SHRINK, 0.0, leftContainer));
362             auto subTitleText = BuildTitleText(subTitle_, subTitleColor_, subTitleFontSize_, FontWeight::W400);
363             parent->AppendChild(
364                 GenerateAccessibilityComposed(StringUtils::StringToInt(id_), "subTitleText", subTitleText));
365         }
366     } else {
367         parent->AppendChild(
368             AceType::MakeRefPtr<FlexItemComponent>(MIDDLE_ZONE_FLEX_GROW, MIDDLE_ZONE_FLEX_SHRINK, 0.0, leftContainer));
369     }
370 }
371 
Build()372 RefPtr<Component> TVTitleBarBuilder::Build()
373 {
374     RefPtr<RowComponent> container =
375         AceType::MakeRefPtr<RowComponent>(FlexAlign::FLEX_START, FlexAlign::FLEX_END, std::list<RefPtr<Component>>());
376     container->SetTextDirection(direction_);
377     RefPtr<RowComponent> leftContainer =
378         AceType::MakeRefPtr<RowComponent>(FlexAlign::FLEX_START, FlexAlign::FLEX_END, std::list<RefPtr<Component>>());
379     leftContainer->SetTextDirection(direction_);
380 
381     BuildTitle(leftContainer);
382     BuildSubTitle(container, leftContainer);
383     AddMenu(container, false);
384 
385     padding_.SetLeft(theme_->GetMaxPaddingStart());
386     padding_.SetRight(theme_->GetMaxPaddingEnd());
387     padding_.SetBottom(Dimension(WATCH_BAR_PADDING_BOTTOM, DimensionUnit::VP));
388 
389     auto boxContainer = BuildContainer(container);
390     boxContainer->SetAlignment(Alignment::BOTTOM_CENTER);
391     return boxContainer;
392 }
393 
394 #endif
395 
BuildTitle(const RefPtr<ComponentGroup> & parent)396 void WatchTitleBarBuilder::BuildTitle(const RefPtr<ComponentGroup>& parent)
397 {
398     parent->AppendChild(BuildPadding(WATCH_TITLE_PADDING_TOP, true));
399     if (!titleFontSize_.IsValid()) {
400         titleFontSize_ = theme_->GetTitleFontSize();
401     }
402 
403     auto titleBox = AceType::MakeRefPtr<BoxComponent>();
404     titleBox->SetPadding(
405         Edge(WATCH_TITLE_LINE_PADDING.Value(), 0.0, WATCH_TITLE_LINE_PADDING.Value(), 0.0, DimensionUnit::VP));
406     auto titleText = BuildWatchTitleText(title_, titleColor_, titleFontSize_, false);
407     titleBox->SetChild(GenerateAccessibilityComposed(StringUtils::StringToInt(id_), "titleText", titleText));
408     parent->AppendChild(titleBox);
409 }
410 
BuildSubTitle(const RefPtr<ComponentGroup> & parent)411 void WatchTitleBarBuilder::BuildSubTitle(const RefPtr<ComponentGroup>& parent)
412 {
413     if (!subTitle_.empty()) {
414         parent->AppendChild(BuildPadding(WATCH_SUBTITLE_PADDING_TOP, true));
415 
416         auto subTitleBox = AceType::MakeRefPtr<BoxComponent>();
417         subTitleBox->SetPadding(Edge(
418             WATCH_SUBTITLE_LINE_PADDING.Value(), 0.0, WATCH_SUBTITLE_LINE_PADDING.Value(), 0.0, DimensionUnit::VP));
419         if (!logoSrc_.empty()) {
420             RefPtr<RowComponent> subContainer = AceType::MakeRefPtr<RowComponent>(
421                 FlexAlign::FLEX_START, FlexAlign::CENTER, std::list<RefPtr<Component>>());
422             subContainer->SetTextDirection(direction_);
423             BuildLogo(subContainer);
424             subContainer->AppendChild(BuildPadding(WATCH_PADDING_BETWEEN_LOGO_AND_SUBTITLE));
425             auto subTitleText = BuildWatchTitleText(subTitle_, subTitleColor_, subTitleFontSize_, true);
426             auto subTitleFlex = AceType::MakeRefPtr<FlexItemComponent>(
427                 1, 1, 0, GenerateAccessibilityComposed(StringUtils::StringToInt(id_), "subTitleText", subTitleText));
428             subContainer->AppendChild(subTitleFlex);
429             subContainer->SetMainAxisSize(MainAxisSize::MIN);
430             subTitleBox->SetChild(subContainer);
431         } else {
432             auto subTitleText = BuildWatchTitleText(subTitle_, subTitleColor_, subTitleFontSize_, true);
433             subTitleBox->SetChild(
434                 GenerateAccessibilityComposed(StringUtils::StringToInt(id_), "subTitleText", subTitleText));
435         }
436         parent->AppendChild(subTitleBox);
437     }
438 }
439 
BuildLogo(const RefPtr<ComponentGroup> & parent)440 void WatchTitleBarBuilder::BuildLogo(const RefPtr<ComponentGroup>& parent)
441 {
442     auto logoSize = theme_->GetLogoIconSize();
443     IconImage logoIconImage(logoSrc_, logoSize, logoSize);
444     parent->AppendChild(GenerateAccessibilityComposed(StringUtils::StringToInt(id_), "image", logoIconImage.image));
445 }
446 
Build()447 RefPtr<Component> WatchTitleBarBuilder::Build()
448 {
449     RefPtr<ColumnComponent> container =
450         AceType::MakeRefPtr<ColumnComponent>(FlexAlign::FLEX_START, FlexAlign::CENTER, std::list<RefPtr<Component>>());
451     container->SetMainAxisSize(MainAxisSize::MIN);
452     container->SetTextDirection(direction_);
453 
454     if (!title_.empty()) {
455         BuildTitle(container);
456     } else {
457         LOGW("navigation bar no title, will don't show");
458         return container;
459     }
460 
461     BuildSubTitle(container);
462     return container;
463 }
464 
Build(const WeakPtr<PipelineContext> & context)465 RefPtr<Component> NavigationBarComponent::Build(const WeakPtr<PipelineContext>& context)
466 {
467     auto deviceType = SystemProperties::GetDeviceType();
468     RefPtr<TitleBarBuilder> builder;
469     switch (deviceType) {
470 #ifndef WEARABLE_PRODUCT
471         case DeviceType::TV:
472             builder = AceType::MakeRefPtr<TVTitleBarBuilder>(data_);
473             break;
474         case DeviceType::PHONE:
475         case DeviceType::TABLET:
476             if (data_->type == NavigationBarType::EMPHASIZE) {
477                 builder = AceType::MakeRefPtr<EmphasizeTitleBarBuilder>(data_);
478             } else {
479                 auto normalBuilder = AceType::MakeRefPtr<NormalTitleBarBuilder>(data_);
480                 normalBuilder->BindDefaultBackEvent(context);
481                 builder = normalBuilder;
482             }
483             break;
484 #endif
485         case DeviceType::WATCH:
486             builder = AceType::MakeRefPtr<WatchTitleBarBuilder>(data_);
487             break;
488         default:
489             LOGW("build navigation bar failed, unknown device type");
490             return nullptr;
491     }
492 
493     builder->SetContext(context);
494     builder->SetId(GetId());
495     builder->SetTextDirection(direction_);
496     auto component = builder->Build();
497 #ifndef WEARABLE_PRODUCT
498     auto menuBuilder = AceType::DynamicCast<TitleBarMenuBuilder>(builder);
499     if (menuBuilder) {
500         moreButton_ = menuBuilder->GetMoreButton();
501         menuItemsInBar_ = menuBuilder->GetMenuItemsInBar();
502     }
503 #endif
504 
505     return component;
506 }
507 
508 } // namespace OHOS::Ace
509