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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NAVIGATION_BAR_NAVIGATION_BAR_COMPONENT_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NAVIGATION_BAR_NAVIGATION_BAR_COMPONENT_H 18 19 #include <cstdint> 20 #include "core/components/button/button_component.h" 21 #include "core/components/flex/flex_component.h" 22 #include "core/components/navigation_bar/navigation_bar_component_base.h" 23 #include "core/components/navigation_bar/navigation_bar_theme.h" 24 #include "core/components/text/text_component.h" 25 #ifndef WEARABLE_PRODUCT 26 #include "core/components/menu/menu_component.h" 27 #include "core/components/navigation_bar/render_collapsing_navigation_bar.h" 28 #include "core/components/select/select_component.h" 29 #include "core/components/tab_bar/tab_bar_component.h" 30 #endif 31 32 namespace OHOS::Ace { 33 namespace { 34 constexpr int32_t DEFAULT_HEIGHT_DIMENSION = 112; // default height in vp 35 } // namespace 36 37 using NavigationBarShowFunc = std::function<void()>; 38 using NavigationBarHideFunc = std::function<void()>; 39 40 class NavigationBarController : public virtual AceType { 41 DECLARE_ACE_TYPE(NavigationBarController, AceType); 42 43 public: Show()44 void Show() const 45 { 46 if (showFunc_) { 47 showFunc_(); 48 } 49 } 50 Hide()51 void Hide() const 52 { 53 if (hideFunc_) { 54 hideFunc_(); 55 } 56 } 57 SetFunction(const NavigationBarShowFunc & showFunc,const NavigationBarHideFunc & hideFunc)58 void SetFunction(const NavigationBarShowFunc& showFunc, const NavigationBarHideFunc& hideFunc) 59 { 60 showFunc_ = showFunc; 61 hideFunc_ = hideFunc; 62 } 63 64 private: 65 NavigationBarShowFunc showFunc_; 66 NavigationBarHideFunc hideFunc_; 67 }; 68 69 enum class NavigationBarType { 70 NORMAL = 0, 71 EMPHASIZE, 72 }; 73 74 class TitleBarBuilder; 75 76 struct NavigationBarData : public virtual AceType { 77 DECLARE_ACE_TYPE(NavigationBarData, AceType); 78 79 public: 80 NavigationBarData() = default; 81 ~NavigationBarData() = default; 82 83 std::string header; 84 std::string title; 85 std::string subTitle; 86 bool backEnabled = false; 87 EventMarker backClickMarker; 88 std::string logo; 89 std::string startIcon; 90 EventMarker startClickMarker; 91 std::string endIcon; 92 EventMarker endClickMarker; 93 Color titleColor; 94 Color subTitleColor; 95 std::optional<Color> imageFill; 96 NavigationBarType type = NavigationBarType::NORMAL; 97 98 #ifndef WEARABLE_PRODUCT 99 RefPtr<TabBarComponent> tabBar; 100 RefPtr<SelectComponent> selectPopup; 101 RefPtr<MenuComponent> menu; 102 std::list<RefPtr<OptionComponent>> allMenuItems; 103 #endif 104 105 RefPtr<NavigationBarController> controller; 106 RefPtr<NavigationBarTheme> theme; 107 }; 108 109 class NavigationBarComponent : public ComposedComponent { 110 DECLARE_ACE_TYPE(NavigationBarComponent, ComposedComponent); 111 112 public: 113 struct MenuItemInBar { 114 std::string value; 115 EventMarker clickEvent; 116 RefPtr<ButtonComponent> button; 117 }; 118 119 NavigationBarComponent(const ComposeId& id, const std::string& name); 120 ~NavigationBarComponent() override = default; 121 122 void InitStyle(const RefPtr<NavigationBarTheme>& theme); 123 RefPtr<Element> CreateElement() override; 124 RefPtr<Component> Build(const WeakPtr<PipelineContext>& context); 125 126 #ifndef WEARABLE_PRODUCT GetMenu()127 RefPtr<MenuComponent> GetMenu() const 128 { 129 return data_->menu; 130 } 131 GetMenuItemsInBar()132 const std::map<std::string, NavigationBarComponent::MenuItemInBar>& GetMenuItemsInBar() const 133 { 134 return menuItemsInBar_; 135 } 136 GetMoreButton()137 const RefPtr<ButtonComponent>& GetMoreButton() const 138 { 139 return moreButton_; 140 } 141 #endif GetData()142 const RefPtr<NavigationBarData>& GetData() const 143 { 144 return data_; 145 } 146 147 private: 148 WeakPtr<PipelineContext> context_; 149 RefPtr<NavigationBarData> data_; 150 #ifndef WEARABLE_PRODUCT 151 std::map<std::string, NavigationBarComponent::MenuItemInBar> menuItemsInBar_; 152 RefPtr<ButtonComponent> moreButton_; 153 #endif 154 }; 155 156 class CommonBuilder : public NavigationBarComponentBase { 157 public: 158 CommonBuilder() = delete; 159 virtual ~CommonBuilder() = default; CommonBuilder(const RefPtr<NavigationBarTheme> & theme)160 explicit CommonBuilder(const RefPtr<NavigationBarTheme>& theme) 161 : theme_(theme), menuZoneSize_(theme_->GetMenuZoneSize()), menuIconSize_(theme_->GetMenuIconSize()) 162 {} SetContext(const WeakPtr<PipelineContext> & context)163 void SetContext(const WeakPtr<PipelineContext>& context) 164 { 165 context_ = context; 166 } SetId(const ComposeId & id)167 void SetId(const ComposeId& id) 168 { 169 id_ = id; 170 } SetTextDirection(const TextDirection & direction)171 void SetTextDirection(const TextDirection& direction) 172 { 173 direction_ = direction; 174 } 175 176 protected: 177 RefPtr<NavigationBarTheme> theme_; 178 ComposeId id_; 179 Dimension menuZoneSize_; 180 Dimension menuIconSize_; 181 TextDirection direction_ = TextDirection::LTR; 182 }; 183 184 class TitleBarBuilder : public virtual AceType, public virtual CommonBuilder { 185 DECLARE_ACE_TYPE(TitleBarBuilder, AceType); 186 187 public: TitleBarBuilder(const RefPtr<NavigationBarData> & data)188 explicit TitleBarBuilder(const RefPtr<NavigationBarData>& data) 189 : CommonBuilder(data->theme), height_(data->theme->GetHeight()), title_(data->title), 190 titleColor_(data->titleColor), subTitle_(data->subTitle), subTitleColor_(data->subTitleColor), 191 subTitleFontSize_(data->theme->GetSubTitleFontSize()) 192 {} 193 virtual ~TitleBarBuilder() = default; 194 virtual RefPtr<Component> Build() = 0; 195 196 protected: 197 #ifndef WEARABLE_PRODUCT BuildContainer(const RefPtr<Component> & child)198 RefPtr<BoxComponent> BuildContainer(const RefPtr<Component>& child) 199 { 200 auto boxContainer = AceType::MakeRefPtr<BoxComponent>(); 201 boxContainer->SetHeight(height_.Value(), height_.Unit()); 202 boxContainer->SetChild(child); 203 boxContainer->SetPadding(padding_); 204 return boxContainer; 205 } 206 #endif 207 208 Edge padding_; 209 Dimension height_; 210 211 std::string title_; 212 Color titleColor_; 213 Dimension titleFontSize_; 214 215 std::string subTitle_; 216 Color subTitleColor_; 217 Dimension subTitleFontSize_; 218 }; 219 220 class WatchTitleBarBuilder : public TitleBarBuilder { 221 DECLARE_ACE_TYPE(WatchTitleBarBuilder, TitleBarBuilder); 222 223 public: WatchTitleBarBuilder(const RefPtr<NavigationBarData> & data)224 explicit WatchTitleBarBuilder(const RefPtr<NavigationBarData>& data) 225 : CommonBuilder(data->theme), TitleBarBuilder(data), logoSrc_(data->logo) 226 {} 227 ~WatchTitleBarBuilder() = default; 228 RefPtr<Component> Build() override; 229 230 private: 231 void BuildTitle(const RefPtr<ComponentGroup>& parent); 232 void BuildSubTitle(const RefPtr<ComponentGroup>& parent); 233 void BuildLogo(const RefPtr<ComponentGroup>& parent); 234 235 std::string logoSrc_; 236 }; 237 238 #ifndef WEARABLE_PRODUCT 239 class TabBarBuilder : public virtual CommonBuilder { 240 public: TabBarBuilder(const RefPtr<NavigationBarData> & data)241 explicit TabBarBuilder(const RefPtr<NavigationBarData>& data) : CommonBuilder(data->theme), tabBar_(data->tabBar) {} 242 ~TabBarBuilder() = default; 243 244 void BuildTabBar(const RefPtr<ComponentGroup>& parent); 245 246 protected: 247 RefPtr<TabBarComponent> tabBar_; 248 }; 249 250 class TitleBarMenuBuilder : public virtual AceType, public virtual CommonBuilder { 251 DECLARE_ACE_TYPE(TitleBarMenuBuilder, AceType); 252 253 public: TitleBarMenuBuilder(const RefPtr<NavigationBarData> & data)254 explicit TitleBarMenuBuilder(const RefPtr<NavigationBarData>& data) 255 : CommonBuilder(data->theme), menu_(data->menu), imageFill_(data->imageFill), 256 allMenuItems_(data->allMenuItems) {} 257 ~TitleBarMenuBuilder() = default; 258 GetMenuItemsInBar()259 const std::map<std::string, NavigationBarComponent::MenuItemInBar>& GetMenuItemsInBar() const 260 { 261 return menuItemsInBar_; 262 } GetMoreButton()263 const RefPtr<ButtonComponent>& GetMoreButton() const 264 { 265 return moreButton_; 266 } GetMenu()267 const RefPtr<MenuComponent>& GetMenu() const 268 { 269 return menu_; 270 } 271 272 protected: 273 bool AddMenu(const RefPtr<ComponentGroup>& container, bool canCollapse = true); 274 275 RefPtr<MenuComponent> menu_; 276 std::optional<Color> imageFill_; 277 278 private: 279 void MoveMenuItemsToBar(const RefPtr<ComponentGroup>& container); 280 void AddCollapseMenu(const RefPtr<ComponentGroup>& container); 281 282 std::map<std::string, NavigationBarComponent::MenuItemInBar> menuItemsInBar_; 283 std::list<RefPtr<OptionComponent>> allMenuItems_; 284 RefPtr<ButtonComponent> moreButton_; 285 }; 286 287 class TVTitleBarBuilder : public TitleBarBuilder, public TitleBarMenuBuilder { 288 DECLARE_ACE_TYPE(TVTitleBarBuilder, TitleBarBuilder, TitleBarMenuBuilder); 289 290 public: TVTitleBarBuilder(const RefPtr<NavigationBarData> & data)291 explicit TVTitleBarBuilder(const RefPtr<NavigationBarData>& data) 292 : CommonBuilder(data->theme), TitleBarBuilder(data), TitleBarMenuBuilder(data) 293 {} 294 ~TVTitleBarBuilder() = default; 295 296 RefPtr<Component> Build() override; 297 298 private: 299 void BuildTitle(const RefPtr<ComponentGroup>& parent); 300 void BuildSubTitle(const RefPtr<ComponentGroup>& parent, const RefPtr<ComponentGroup>& leftContainer); 301 }; 302 303 class PhoneTitleBarBuilder : public TitleBarBuilder, public TitleBarMenuBuilder, public TabBarBuilder { 304 DECLARE_ACE_TYPE(PhoneTitleBarBuilder, TitleBarBuilder, TitleBarMenuBuilder); 305 306 public: PhoneTitleBarBuilder(const RefPtr<NavigationBarData> & data)307 explicit PhoneTitleBarBuilder(const RefPtr<NavigationBarData>& data) 308 : CommonBuilder(data->theme), TitleBarBuilder(data), TitleBarMenuBuilder(data), TabBarBuilder(data), 309 selectPopup_(data->selectPopup) 310 { 311 titleFontSize_ = data->theme->GetTitleFontSize(); 312 } 313 ~PhoneTitleBarBuilder() = default; 314 315 RefPtr<Component> Build() override = 0; GetTitleComposed()316 const RefPtr<ComposedComponent>& GetTitleComposed() const 317 { 318 return titleComposed_; 319 } GetSubtitleComposed()320 const RefPtr<ComposedComponent>& GetSubtitleComposed() const 321 { 322 return subTitleComposed_; 323 } 324 325 protected: 326 RefPtr<Component> BuildTitle(double padding = 0.0); 327 void BuildSelectPopup(const RefPtr<ComponentGroup>& parent); 328 void BuildTitleZone(const RefPtr<ComponentGroup>& parent, double padding = 0.0); 329 330 RefPtr<SelectComponent> selectPopup_; 331 std::string header_; 332 RefPtr<ComposedComponent> titleComposed_; 333 RefPtr<ComposedComponent> subTitleComposed_; 334 }; 335 336 class EmphasizeTitleBarBuilder : public PhoneTitleBarBuilder { 337 DECLARE_ACE_TYPE(EmphasizeTitleBarBuilder, PhoneTitleBarBuilder); 338 339 public: EmphasizeTitleBarBuilder(const RefPtr<NavigationBarData> & data)340 explicit EmphasizeTitleBarBuilder(const RefPtr<NavigationBarData>& data) 341 : CommonBuilder(data->theme), PhoneTitleBarBuilder(data) 342 { 343 height_ = Dimension(DEFAULT_HEIGHT_DIMENSION, DimensionUnit::VP); 344 padding_.SetLeft(theme_->GetMaxPaddingStart()); 345 padding_.SetRight(theme_->GetDefaultPaddingEnd()); 346 titleFontSize_ = theme_->GetTitleFontSizeBig(); 347 header_ = data->header; 348 } 349 ~EmphasizeTitleBarBuilder() = default; 350 351 RefPtr<Component> Build() override; 352 }; 353 354 class NormalTitleBarBuilder : public PhoneTitleBarBuilder { 355 DECLARE_ACE_TYPE(NormalTitleBarBuilder, PhoneTitleBarBuilder); 356 357 public: NormalTitleBarBuilder(const RefPtr<NavigationBarData> & data)358 explicit NormalTitleBarBuilder(const RefPtr<NavigationBarData>& data) 359 : CommonBuilder(data->theme), PhoneTitleBarBuilder(data), backEnabled_(data->backEnabled), 360 backClickMarker_(data->backClickMarker), logoSrc_(data->logo), startIconSrc_(data->startIcon), 361 startClickMarker_(data->startClickMarker), endIconSrc_(data->endIcon), endClickMarker_(data->endClickMarker), 362 imageFill_(data->imageFill) 363 {} 364 ~NormalTitleBarBuilder() = default; 365 366 RefPtr<Component> Build() override; 367 void BindDefaultBackEvent(const WeakPtr<PipelineContext>& context); 368 369 private: 370 void BuildStartZone(const RefPtr<RowComponent>& parent); 371 void BuildLogo(const RefPtr<RowComponent>& parent); 372 void BuildEndZone(const RefPtr<RowComponent>& parent); 373 374 bool backEnabled_ = false; 375 EventMarker backClickMarker_; 376 std::string logoSrc_; 377 std::string startIconSrc_; 378 EventMarker startClickMarker_; 379 std::string endIconSrc_; 380 EventMarker endClickMarker_; 381 std::optional<Color> imageFill_; 382 }; 383 384 class CollapsingNavigationBarComponent : public ComponentGroup { 385 DECLARE_ACE_TYPE(CollapsingNavigationBarComponent, ComponentGroup); 386 387 public: 388 CollapsingNavigationBarComponent() = default; CollapsingNavigationBarComponent(const RefPtr<ComposedComponent> & title,const RefPtr<ComposedComponent> & subTitle,const EventMarker & changeEvent)389 CollapsingNavigationBarComponent(const RefPtr<ComposedComponent>& title, const RefPtr<ComposedComponent>& subTitle, 390 const EventMarker& changeEvent) 391 : titleComposed_(title), subTitleComposed_(subTitle), titleModeChangedEvent_(changeEvent) 392 {} CollapsingNavigationBarComponent(const RefPtr<EmphasizeTitleBarBuilder> & builder)393 explicit CollapsingNavigationBarComponent(const RefPtr<EmphasizeTitleBarBuilder>& builder) 394 { 395 titleComposed_ = builder->GetTitleComposed(); 396 subTitleComposed_ = builder->GetSubtitleComposed(); 397 } 398 ~CollapsingNavigationBarComponent() override = default; CreateElement()399 RefPtr<Element> CreateElement() override 400 { 401 return AceType::MakeRefPtr<ComponentGroupElement>(); 402 } 403 CreateRenderNode()404 RefPtr<RenderNode> CreateRenderNode() override 405 { 406 return AceType::MakeRefPtr<RenderCollapsingNavigationBar>(); 407 } GetTitleComposed()408 const RefPtr<ComposedComponent>& GetTitleComposed() const 409 { 410 return titleComposed_; 411 } GetSubtitleComposed()412 const RefPtr<ComposedComponent>& GetSubtitleComposed() const 413 { 414 return subTitleComposed_; 415 } GetMinHeight()416 const Dimension& GetMinHeight() const 417 { 418 return minHeight_; 419 } SetMinHeight(const Dimension & minHeight)420 void SetMinHeight(const Dimension& minHeight) 421 { 422 minHeight_ = minHeight; 423 } GetTitleModeChangedEvent()424 const EventMarker& GetTitleModeChangedEvent() const 425 { 426 return titleModeChangedEvent_; 427 } 428 429 private: 430 RefPtr<TextComponent> titleComponent_; 431 RefPtr<ComposedComponent> titleComposed_; 432 RefPtr<ComposedComponent> subTitleComposed_; 433 Dimension minHeight_; 434 EventMarker titleModeChangedEvent_; 435 }; 436 437 #endif 438 439 } // namespace OHOS::Ace 440 441 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NAVIGATION_BAR_NAVIGATION_BAR_COMPONENT_H 442