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