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