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