1 /* 2 * Copyright (c) 2022-2023 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_NG_PATTERNS_MENU_MENU_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_MENU_MENU_PATTERN_H 18 19 #include <optional> 20 #include <vector> 21 22 #include "base/geometry/dimension.h" 23 #include "base/geometry/ng/size_t.h" 24 #include "base/memory/referenced.h" 25 #include "base/utils/utils.h" 26 #include "core/components_ng/base/symbol_modifier.h" 27 #include "core/components_ng/pattern/menu/menu_accessibility_property.h" 28 #include "core/components_ng/pattern/menu/menu_layout_algorithm.h" 29 #include "core/components_ng/pattern/menu/menu_layout_property.h" 30 #include "core/components_ng/pattern/menu/menu_paint_method.h" 31 #include "core/components_ng/pattern/menu/menu_paint_property.h" 32 #include "core/components_ng/pattern/menu/menu_theme.h" 33 #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_paint_method.h" 34 #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_paint_property.h" 35 #include "core/components_ng/pattern/pattern.h" 36 #include "core/components_ng/pattern/select/select_model.h" 37 #include "core/components_ng/property/border_property.h" 38 #include "core/components_ng/property/menu_property.h" 39 #include "core/components_v2/inspector/inspector_constants.h" 40 41 constexpr int32_t DEFAULT_CLICK_DISTANCE = 15; 42 constexpr uint32_t MAX_SEARCH_DEPTH = 5; 43 constexpr double MENU_ANIMATION_MAX_SCALE = 1.0f; 44 constexpr double MENU_ANIMATION_MIN_OPACITY = 0.0f; 45 constexpr double MENU_ANIMATION_MAX_OPACITY = 1.0f; 46 namespace OHOS::Ace::NG { 47 48 struct SelectProperties { 49 std::string value; 50 std::string icon; 51 RefPtr<SymbolModifier> symbolModifier; 52 int index; 53 bool selected = false; 54 bool selectEnable = true; 55 }; 56 57 struct MenuItemInfo { 58 OffsetF originOffset = OffsetF(); 59 OffsetF endOffset = OffsetF(); 60 bool isFindTargetId = false; 61 }; 62 63 struct PreviewMenuAnimationInfo { 64 BorderRadiusProperty borderRadius = BorderRadiusProperty(Dimension(-1.0f)); 65 66 // for hoverScale animation 67 float clipRate = -1.0f; 68 }; 69 70 class MenuPattern : public Pattern, public FocusView { 71 DECLARE_ACE_TYPE(MenuPattern, Pattern, FocusView); 72 73 public: MenuPattern(int32_t targetId,std::string tag,MenuType type)74 MenuPattern(int32_t targetId, std::string tag, MenuType type) 75 : targetId_(targetId), targetTag_(std::move(tag)), type_(type) 76 {} 77 ~MenuPattern() override = default; 78 IsAtomicNode()79 bool IsAtomicNode() const override 80 { 81 return false; 82 } 83 GetFocusPattern()84 FocusPattern GetFocusPattern() const override 85 { 86 return { FocusType::SCOPE, true }; 87 } 88 GetRouteOfFirstScope()89 std::list<int32_t> GetRouteOfFirstScope() override 90 { 91 return { 0, 0 }; 92 } 93 IsEnableMatchParent()94 bool IsEnableMatchParent() override 95 { 96 return IsMultiMenu(); 97 } 98 IsEnableChildrenMatchParent()99 bool IsEnableChildrenMatchParent() override 100 { 101 return IsMultiMenu(); 102 } 103 IsEnableFix()104 bool IsEnableFix() override 105 { 106 return IsMultiMenu(); 107 } 108 ChildPreMeasureHelperEnabled()109 bool ChildPreMeasureHelperEnabled() override 110 { 111 return true; 112 } 113 PostponedTaskForIgnoreEnabled()114 bool PostponedTaskForIgnoreEnabled() override 115 { 116 return true; 117 } 118 IsEnabledContentForFixIdeal()119 bool IsEnabledContentForFixIdeal() 120 { 121 return IsMultiMenu(); 122 } 123 IsFocusViewLegal()124 bool IsFocusViewLegal() override 125 { 126 return type_ == MenuType::MENU || type_ == MenuType::CONTEXT_MENU || type_ == MenuType::SUB_MENU; 127 } 128 CreateLayoutProperty()129 RefPtr<LayoutProperty> CreateLayoutProperty() override 130 { 131 return MakeRefPtr<MenuLayoutProperty>(); 132 } 133 CreateAccessibilityProperty()134 RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override 135 { 136 return MakeRefPtr<MenuAccessibilityProperty>(); 137 } 138 139 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override; 140 CreatePaintProperty()141 RefPtr<PaintProperty> CreatePaintProperty() override 142 { 143 return MakeRefPtr<MenuPaintProperty>(); 144 } 145 CreateNodePaintMethod()146 RefPtr<NodePaintMethod> CreateNodePaintMethod() override 147 { 148 return AceType::MakeRefPtr<MenuPaintMethod>(); 149 } 150 GetMenuType()151 MenuType GetMenuType() const 152 { 153 return type_; 154 } 155 IsContextMenu()156 bool IsContextMenu() const 157 { 158 return type_ == MenuType::CONTEXT_MENU; 159 } 160 SetPreviewMode(MenuPreviewMode mode)161 void SetPreviewMode(MenuPreviewMode mode) 162 { 163 previewMode_ = mode; 164 } 165 GetPreviewMode()166 MenuPreviewMode GetPreviewMode() const 167 { 168 return previewMode_; 169 } 170 SetPreviewBeforeAnimationScale(float scaleBeforeAnimation)171 void SetPreviewBeforeAnimationScale(float scaleBeforeAnimation) 172 { 173 previewAnimationOptions_.scaleFrom = scaleBeforeAnimation; 174 } 175 GetPreviewBeforeAnimationScale()176 float GetPreviewBeforeAnimationScale() const 177 { 178 return previewAnimationOptions_.scaleFrom; 179 } 180 SetPreviewAfterAnimationScale(float scaleAfterAnimation)181 void SetPreviewAfterAnimationScale(float scaleAfterAnimation) 182 { 183 previewAnimationOptions_.scaleTo = scaleAfterAnimation; 184 } 185 GetPreviewAfterAnimationScale()186 float GetPreviewAfterAnimationScale() const 187 { 188 return previewAnimationOptions_.scaleTo; 189 } 190 SetIsShowHoverImage(bool isShow)191 void SetIsShowHoverImage(bool isShow) 192 { 193 isShowHoverImage_ = isShow; 194 } 195 GetIsShowHoverImage()196 bool GetIsShowHoverImage() const 197 { 198 return isShowHoverImage_; 199 } 200 IsNavigationMenu()201 bool IsNavigationMenu() const 202 { 203 return type_ == MenuType::NAVIGATION_MENU; 204 } 205 IsMultiMenu()206 bool IsMultiMenu() const 207 { 208 return type_ == MenuType::MULTI_MENU; 209 } 210 IsDesktopMenu()211 bool IsDesktopMenu() const 212 { 213 return type_ == MenuType::DESKTOP_MENU; 214 } 215 IsMenu()216 bool IsMenu() const 217 { 218 return type_ == MenuType::MENU; 219 } 220 IsSubMenu()221 bool IsSubMenu() const 222 { 223 return type_ == MenuType::SUB_MENU; 224 } 225 IsSelectOverlayExtensionMenu()226 bool IsSelectOverlayExtensionMenu() const 227 { 228 return type_ == MenuType::SELECT_OVERLAY_EXTENSION_MENU; 229 } 230 IsSelectOverlayCustomMenu()231 bool IsSelectOverlayCustomMenu() const 232 { 233 return type_ == MenuType::SELECT_OVERLAY_CUSTOM_MENU; 234 } 235 IsSelectOverlaySubMenu()236 bool IsSelectOverlaySubMenu() const 237 { 238 return type_ == MenuType::SELECT_OVERLAY_SUB_MENU; 239 } 240 IsSelectOverlayRightClickMenu()241 bool IsSelectOverlayRightClickMenu() const 242 { 243 return type_ == MenuType::SELECT_OVERLAY_RIGHT_CLICK_MENU; 244 } 245 SetParentMenuItem(const RefPtr<FrameNode> & parentMenuItem)246 void SetParentMenuItem(const RefPtr<FrameNode>& parentMenuItem) 247 { 248 parentMenuItem_ = parentMenuItem; 249 } 250 GetParentMenuItem()251 RefPtr<FrameNode> GetParentMenuItem() 252 { 253 return parentMenuItem_; 254 } 255 GetTargetId()256 int32_t GetTargetId() const 257 { 258 return targetId_; 259 } 260 GetTargetTag()261 const std::string& GetTargetTag() const 262 { 263 return targetTag_; 264 } 265 SetIsSelectMenu(bool isSelectMenu)266 void SetIsSelectMenu(bool isSelectMenu) 267 { 268 isSelectMenu_ = isSelectMenu; 269 } IsSelectMenu()270 bool IsSelectMenu() const 271 { 272 return isSelectMenu_; 273 } 274 SetHasOptionWidth(bool hasOptionWidth)275 void SetHasOptionWidth(bool hasOptionWidth) 276 { 277 hasOptionWidth_ = hasOptionWidth; 278 } 279 GetHasOptionWidth()280 bool GetHasOptionWidth() 281 { 282 return hasOptionWidth_; 283 } 284 AddOptionNode(const RefPtr<FrameNode> & option)285 void AddOptionNode(const RefPtr<FrameNode>& option) 286 { 287 CHECK_NULL_VOID(option); 288 options_.emplace_back(option); 289 } 290 GetBuilderId()291 int32_t GetBuilderId() 292 { 293 auto node = builderNode_.Upgrade(); 294 CHECK_NULL_RETURN(node, -1); 295 return node->GetId(); 296 } 297 PopOptionNode()298 void PopOptionNode() 299 { 300 if (options_.empty()) { 301 LOGW("options is empty."); 302 return; 303 } 304 options_.pop_back(); 305 } 306 GetOptions()307 const std::vector<RefPtr<FrameNode>>& GetOptions() const 308 { 309 return options_; 310 } 311 GetEmbeddedMenuItems()312 std::vector<RefPtr<FrameNode>>& GetEmbeddedMenuItems() 313 { 314 return embeddedMenuItems_; 315 } 316 AddEmbeddedMenuItem(const RefPtr<FrameNode> & menuItem)317 void AddEmbeddedMenuItem(const RefPtr<FrameNode>& menuItem) 318 { 319 embeddedMenuItems_.emplace_back(menuItem); 320 } 321 RemoveEmbeddedMenuItem(const RefPtr<FrameNode> & menuItem)322 void RemoveEmbeddedMenuItem(const RefPtr<FrameNode>& menuItem) 323 { 324 auto iter = std::find(embeddedMenuItems_.begin(), embeddedMenuItems_.end(), menuItem); 325 if (iter != embeddedMenuItems_.end()) { 326 embeddedMenuItems_.erase(iter); 327 } 328 } 329 330 void RemoveParentHoverStyle(); 331 332 void UpdateSelectParam(const std::vector<SelectParam>& params); 333 SetNeedHideAfterTouch(bool needHideAfterTouch)334 void SetNeedHideAfterTouch(bool needHideAfterTouch) 335 { 336 needHideAfterTouch_ = needHideAfterTouch; 337 } 338 HideMenu(const HideMenuType & reason)339 void HideMenu(const HideMenuType& reason) 340 { 341 HideMenu(false, OffsetF(), reason); 342 } 343 344 void HideMenu(bool isMenuOnTouch = false, OffsetF position = OffsetF(), 345 const HideMenuType& reason = HideMenuType::NORMAL) const; 346 347 bool HideStackExpandMenu(const OffsetF& position) const; 348 349 void HideStackMenu() const; 350 351 void MountOption(const RefPtr<FrameNode>& option); 352 353 void RemoveOption(); 354 RefPtr<FrameNode> DuplicateMenuNode(const RefPtr<FrameNode>& menuNode, const MenuParam& menuParam); 355 356 RefPtr<FrameNode> GetMenuColumn() const; 357 SetShowedSubMenu(const RefPtr<FrameNode> & subMenu)358 void SetShowedSubMenu(const RefPtr<FrameNode>& subMenu) 359 { 360 showedSubMenu_ = subMenu; 361 } GetShowedSubMenu()362 const RefPtr<FrameNode>& GetShowedSubMenu() const 363 { 364 return showedSubMenu_; 365 } 366 SetIsWidthModifiedBySelect(bool isModified)367 void SetIsWidthModifiedBySelect(bool isModified) 368 { 369 isWidthModifiedBySelect_ = isModified; 370 } 371 IsWidthModifiedBySelect()372 bool IsWidthModifiedBySelect() const 373 { 374 return isWidthModifiedBySelect_; 375 } 376 377 float GetSelectMenuWidth(); 378 void HideSubMenu(); 379 void OnModifyDone() override; 380 381 // acquire first menu node in wrapper node by submenu node 382 RefPtr<MenuPattern> GetMainMenuPattern() const; 383 uint32_t GetInnerMenuCount() const; 384 void OnColorConfigurationUpdate() override; 385 386 RefPtr<FrameNode> GetMenuWrapper() const; 387 RefPtr<FrameNode> GetFirstInnerMenu() const; 388 void DumpInfo() override; 389 void DumpInfo(std::unique_ptr<JsonValue>& json) override; DumpSimplifyInfo(std::shared_ptr<JsonValue> & json)390 void DumpSimplifyInfo(std::shared_ptr<JsonValue>& json) override {} SetFirstShow()391 void SetFirstShow() 392 { 393 isFirstShow_ = true; 394 } 395 GetIsFirstShow()396 bool GetIsFirstShow() const 397 { 398 return isFirstShow_; 399 } 400 SetOriginOffset(const OffsetF & offset)401 void SetOriginOffset(const OffsetF& offset) 402 { 403 originOffset_ = offset; 404 } 405 SetEndOffset(const OffsetF & offset)406 void SetEndOffset(const OffsetF& offset) 407 { 408 endOffset_ = offset; 409 } 410 GetEndOffset()411 OffsetF GetEndOffset() const 412 { 413 return endOffset_; 414 } 415 SetSelectOverlayExtensionMenuShow()416 void SetSelectOverlayExtensionMenuShow() 417 { 418 isExtensionMenuShow_ = true; 419 } 420 SetDisappearAnimation(bool hasAnimation)421 void SetDisappearAnimation(bool hasAnimation) 422 { 423 // false:exit from BOTTOM to TOP 424 // true:exit from LEFT_BOTTOM to RIGHT_TOP 425 hasAnimation_ = hasAnimation; 426 } 427 GetDisappearAnimation()428 bool GetDisappearAnimation() const 429 { 430 return hasAnimation_; 431 } 432 SetSubMenuShow(bool subMenuShowed)433 void SetSubMenuShow(bool subMenuShowed) 434 { 435 isSubMenuShow_ = subMenuShowed; 436 } 437 SetMenuShow()438 void SetMenuShow() 439 { 440 isMenuShow_ = true; 441 } 442 SetPreviewOriginOffset(const OffsetF & offset)443 void SetPreviewOriginOffset(const OffsetF& offset) 444 { 445 previewOriginOffset_ = offset; 446 } 447 GetPreviewOriginOffset()448 OffsetF GetPreviewOriginOffset() const 449 { 450 return previewOriginOffset_; 451 } 452 SetPreviewRect(RectF rect)453 void SetPreviewRect(RectF rect) 454 { 455 previewRect_ = rect; 456 } 457 GetPreviewRect()458 RectF GetPreviewRect() const 459 { 460 return previewRect_; 461 } 462 SetPreviewIdealSize(SizeF size)463 void SetPreviewIdealSize(SizeF size) 464 { 465 previewIdealSize_ = size; 466 } 467 GetPreviewIdealSize()468 SizeF GetPreviewIdealSize() const 469 { 470 return previewIdealSize_; 471 } 472 SetHasLaid(bool hasLaid)473 void SetHasLaid(bool hasLaid) 474 { 475 hasLaid_ = hasLaid; 476 } 477 HasLaid()478 bool HasLaid() const 479 { 480 return hasLaid_; 481 } 482 SetTargetSize(const SizeF & size)483 void SetTargetSize(const SizeF& size) 484 { 485 targetSize_ = size; 486 } 487 GetTargetSize()488 SizeF GetTargetSize() const 489 { 490 return targetSize_; 491 } 492 SetTargetOffset(const OffsetF & offset)493 void SetTargetOffset(const OffsetF& offset) 494 { 495 targetOffset_ = offset; 496 } 497 GetTargetOffset()498 OffsetF GetTargetOffset() const 499 { 500 return targetOffset_; 501 } 502 SetIsHeightModifiedBySelect(bool isModified)503 void SetIsHeightModifiedBySelect(bool isModified) 504 { 505 isHeightModifiedBySelect_ = isModified; 506 } 507 IsHeightModifiedBySelect()508 bool IsHeightModifiedBySelect() const 509 { 510 return isHeightModifiedBySelect_; 511 } 512 GetMenuExpandDisplay()513 bool GetMenuExpandDisplay() const 514 { 515 return expandDisplay_; 516 } 517 518 void ShowMenuDisappearAnimation(); 519 void ShowStackMenuDisappearAnimation(const RefPtr<FrameNode>& menuNode, 520 const RefPtr<FrameNode>& subMenuNode, AnimationOption& option) const; 521 SetBuilderFunc(SelectMakeCallback && makeFunc)522 void SetBuilderFunc(SelectMakeCallback&& makeFunc) 523 { 524 makeFunc_ = std::move(makeFunc); 525 } 526 ResetBuilderFunc()527 void ResetBuilderFunc() 528 { 529 makeFunc_ = std::nullopt; 530 } 531 532 void UpdateSelectIndex(int32_t index); 533 SetSelectProperties(const std::vector<SelectParam> & params)534 void SetSelectProperties(const std::vector<SelectParam>& params) 535 { 536 auto list = selectProperties_; 537 selectParams_ = params; 538 selectProperties_.clear(); 539 for (size_t i = 0; i < params.size(); i++) { 540 SelectProperties selectProperty; 541 selectProperty.value = params[i].text; 542 selectProperty.icon = params[i].icon; 543 selectProperty.symbolModifier = params[i].symbolModifier; 544 selectProperty.index = static_cast<int>(i); 545 if (i < list.size()) { 546 selectProperty.selected = list[i].selected; 547 selectProperty.selectEnable = list[i].selectEnable; 548 } 549 selectProperties_.push_back(selectProperty); 550 } 551 } 552 GetMenuDefaultShadowStyle()553 ShadowStyle GetMenuDefaultShadowStyle() 554 { 555 auto shadowStyle = ShadowStyle::OuterDefaultMD; 556 557 auto host = GetHost(); 558 CHECK_NULL_RETURN(host, shadowStyle); 559 auto pipeline = host->GetContextRefPtr(); 560 CHECK_NULL_RETURN(pipeline, shadowStyle); 561 auto menuTheme = pipeline->GetTheme<MenuTheme>(); 562 CHECK_NULL_RETURN(menuTheme, shadowStyle); 563 shadowStyle = menuTheme->GetMenuShadowStyle(); 564 return shadowStyle; 565 } 566 567 bool GetShadowFromTheme(ShadowStyle shadowStyle, Shadow& shadow); 568 UseContentModifier()569 bool UseContentModifier() 570 { 571 return builderNode_.Upgrade() != nullptr; 572 } 573 574 void FireBuilder(); 575 576 BorderRadiusProperty CalcIdealBorderRadius(const BorderRadiusProperty& borderRadius, const SizeF& menuSize); 577 578 void OnItemPressed(const RefPtr<UINode>& parent, int32_t index, bool press, bool hover = false); 579 GetLastSelectedItem()580 RefPtr<FrameNode> GetLastSelectedItem() 581 { 582 return lastSelectedItem_; 583 } 584 SetLastSelectedItem(const RefPtr<FrameNode> & lastSelectedItem)585 void SetLastSelectedItem(const RefPtr<FrameNode>& lastSelectedItem) 586 { 587 lastSelectedItem_ = lastSelectedItem; 588 } UpdateLastPosition(std::optional<OffsetF> lastPosition)589 void UpdateLastPosition(std::optional<OffsetF> lastPosition) 590 { 591 lastPosition_ = lastPosition; 592 } 593 UpdateLastPlacement(std::optional<Placement> lastPlacement)594 void UpdateLastPlacement(std::optional<Placement> lastPlacement) 595 { 596 lastPlacement_ = lastPlacement; 597 } 598 GetLastPlacement()599 std::optional<Placement> GetLastPlacement() 600 { 601 return lastPlacement_; 602 } 603 SetIsEmbedded()604 void SetIsEmbedded() 605 { 606 isEmbedded_ = true; 607 } IsEmbedded()608 bool IsEmbedded() 609 { 610 return isEmbedded_; 611 } SetIsStackSubmenu()612 void SetIsStackSubmenu() 613 { 614 isStackSubmenu_ = true; 615 } IsStackSubmenu()616 bool IsStackSubmenu() 617 { 618 return isStackSubmenu_; 619 } SetMenuWindowRect(const Rect & menuWindowRect)620 void SetMenuWindowRect(const Rect& menuWindowRect) 621 { 622 menuWindowRect_ = menuWindowRect; 623 } GetMenuWindowRect()624 Rect GetMenuWindowRect() const 625 { 626 return menuWindowRect_; 627 } 628 SetMenuLayoutParam(const PreviewMenuParam & layoutParam)629 void SetMenuLayoutParam(const PreviewMenuParam& layoutParam) 630 { 631 layoutParam_ = layoutParam; 632 } 633 GetMenuLayoutParam()634 PreviewMenuParam GetMenuLayoutParam() const 635 { 636 return layoutParam_; 637 } 638 GetPreviewMenuDisappearPosition()639 OffsetF GetPreviewMenuDisappearPosition() 640 { 641 return disappearOffset_; 642 } 643 644 void UpdateMenuPathParams(std::optional<MenuPathParams> pathParams); 645 GetMenuPathParams()646 std::optional<MenuPathParams> GetMenuPathParams() 647 { 648 return pathParams_; 649 } 650 SetCustomNode(WeakPtr<UINode> customNode)651 void SetCustomNode(WeakPtr<UINode> customNode) 652 { 653 customNode_ = customNode; 654 } 655 GetCustomNode()656 RefPtr<UINode> GetCustomNode() const 657 { 658 return customNode_.Upgrade(); 659 } 660 661 void UpdateSelectOptionTextByIndex(int32_t index, const std::string& text); 662 void UpdateSelectOptionIconByIndex(int32_t index, const std::string& icon); 663 664 void InitPreviewMenuAnimationInfo(const RefPtr<MenuTheme>& menuTheme); 665 666 float GetSelectMenuWidthFromTheme() const; 667 668 bool IsSelectOverlayDefaultModeRightClickMenu(); 669 void RemoveLastNodeDivider(const RefPtr<UINode>& lastNode); 670 void UpdateMenuItemDivider(); 671 void UpdateDividerProperty(const RefPtr<FrameNode>& dividerNode, const std::optional<V2::ItemDivider>& divider); 672 RefPtr<FrameNode> GetFirstMenuItem(); 673 RefPtr<FrameNode> GetLastMenuItem(); 674 std::pair<float, float> GetPreviewPositionY(); 675 GetTranslateYForStack()676 float GetTranslateYForStack() 677 { 678 return translateYForStack_; 679 } 680 SetTranslateYForStack(float tmp)681 void SetTranslateYForStack(float tmp) 682 { 683 translateYForStack_ = tmp; 684 } 685 GetOriginMenuYForStack()686 float GetOriginMenuYForStack() 687 { 688 return originMenuYForStack_; 689 } 690 SetOriginMenuYForStack(float tmp)691 void SetOriginMenuYForStack(float tmp) 692 { 693 originMenuYForStack_ = tmp; 694 } 695 GetOriginPreviewYForStack()696 float GetOriginPreviewYForStack() 697 { 698 return originPreviewYForStack_; 699 } 700 SetOriginPreviewYForStack(float tmp)701 void SetOriginPreviewYForStack(float tmp) 702 { 703 originPreviewYForStack_ = tmp; 704 } 705 706 void SetDisableMenuBgColorByUser(bool isSetByUser = false) 707 { 708 isDisableMenuBgColorByUser_ = isSetByUser; 709 } 710 SetSubMenuDepth(int32_t depth)711 void SetSubMenuDepth(int32_t depth) 712 { 713 subMenuDepth_ = depth; 714 } 715 GetSubMenuDepth()716 int32_t GetSubMenuDepth() const 717 { 718 return subMenuDepth_; 719 } 720 721 protected: 722 void UpdateMenuItemChildren(const RefPtr<UINode>& host, RefPtr<UINode>& previousNode); 723 void SetMenuAttribute(RefPtr<FrameNode>& host); 724 void SetAccessibilityAction(); SetType(MenuType value)725 void SetType(MenuType value) 726 { 727 type_ = value; 728 } ResetNeedDivider()729 void ResetNeedDivider() 730 { 731 isNeedDivider_ = false; 732 } 733 virtual void InitTheme(const RefPtr<FrameNode>& host); 734 virtual void UpdateBorderRadius(const RefPtr<FrameNode>& menuNode, const BorderRadiusProperty& borderRadius); 735 736 private: 737 void UpdateMenuDividerWithMode(const RefPtr<UINode>& previousNode, const RefPtr<UINode>& currentNode, 738 const RefPtr<MenuLayoutProperty>& property, int32_t& index); 739 void AddGroupHeaderDivider(RefPtr<UINode>& previousNode, const RefPtr<UINode>& currentNode, 740 const RefPtr<MenuLayoutProperty>& property, int32_t& index); 741 void AddGroupFooterDivider(RefPtr<UINode>& previousNode, const RefPtr<UINode>& currentNode, 742 const RefPtr<MenuLayoutProperty>& property, int32_t& index); 743 void OnAttachToFrameNode() override; 744 int32_t RegisterHalfFoldHover(const RefPtr<FrameNode>& menuNode); 745 void OnDetachFromFrameNode(FrameNode* frameNode) override; 746 void OnDetachFromMainTree() override; 747 748 void RegisterOnTouch(); 749 void OnTouchEvent(const TouchEventInfo& info); 750 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 751 752 // If CustomBuilder is declared with <Menu> and <MenuItem>, 753 // reset outer menu container and only apply theme on the inner <Menu> node. 754 void ResetTheme(const RefPtr<FrameNode>& host, bool resetForDesktopMenu); 755 void ResetScrollTheme(const RefPtr<FrameNode>& host); 756 void ResetThemeByInnerMenuCount(); 757 void CopyMenuAttr(const RefPtr<FrameNode>& menuNode) const; 758 759 void RegisterOnKeyEvent(const RefPtr<FocusHub>& focusHub); 760 bool OnKeyEvent(const KeyEvent& event); 761 762 void DisableTabInMenu(); 763 764 Offset GetTransformCenter() const; 765 OffsetF GetPreviewMenuAnimationOffset(const OffsetF& previewCenter, const SizeF& previewSize, float scale) const; 766 void ShowPreviewMenuAnimation(); 767 void ShowPreviewPositionAnimation(AnimationOption& option, int32_t delay); 768 void ShowPreviewMenuScaleAnimation(const RefPtr<MenuTheme>& menuTheme, AnimationOption& option, int32_t delay); 769 void ShowMenuAppearAnimation(); 770 void ShowStackMenuAppearAnimation(); 771 std::pair<OffsetF, OffsetF> GetMenuOffset(const RefPtr<FrameNode>& mainMenu, 772 const RefPtr<FrameNode>& subMenu, bool isNeedRestoreNodeId = false) const; 773 MenuItemInfo GetInnerMenuOffset(const RefPtr<UINode>& child, const RefPtr<FrameNode>& subMenu, 774 bool isNeedRestoreNodeId) const; 775 MenuItemInfo GetMenuItemInfo(const RefPtr<UINode>& child, const RefPtr<FrameNode>& subMenu, 776 bool isNeedRestoreNodeId) const; 777 std::vector<RefPtr<RenderContext>> GetOtherMenuItemContext(const RefPtr<FrameNode>& subMenuNode) const; 778 void ShowArrowRotateAnimation() const; 779 void ShowArrowReverseRotateAnimation() const; 780 RefPtr<FrameNode> GetArrowNode(const RefPtr<FrameNode>& host) const; // arrowNode in subMenu 781 782 void InitPanEvent(const RefPtr<GestureEventHub>& gestureHub); 783 void HandleDragEnd(float offsetX, float offsetY, float velocity); 784 void HandleScrollDragEnd(float offsetX, float offsetY, float velocity); 785 RefPtr<UINode> GetSyntaxNode(const RefPtr<UINode>& parent); 786 RefPtr<UINode> GetForEachMenuItem(const RefPtr<UINode>& parent, bool next); 787 RefPtr<UINode> GetOutsideForEachMenuItem(const RefPtr<UINode>& forEachNode, bool next); 788 RefPtr<UINode> GetIfElseMenuItem(const RefPtr<UINode>& parent, bool next); 789 void HandleNextPressed(const RefPtr<UINode>& parent, int32_t index, bool press, bool hover); 790 void HandlePrevPressed(const RefPtr<UINode>& parent, int32_t index, bool press); 791 void SetMenuBackGroundStyle(const RefPtr<FrameNode>& menuNode, const MenuParam& menuParam); 792 void UpdateMenuBorderAndBackgroundBlur(); 793 794 RefPtr<FrameNode> BuildContentModifierNode(int index); 795 bool IsMenuScrollable() const; 796 void UpdateClipPath(const RefPtr<LayoutWrapper>& dirty); 797 RefPtr<FrameNode> GetTitleContentNode(const RefPtr<FrameNode>& subMenuNode) const; 798 void ShowStackSubMenuAnimation(const RefPtr<FrameNode>& mainMenu, const RefPtr<FrameNode>& subMenuNode); 799 void ShowStackMainMenuAnimation(const RefPtr<FrameNode>& mainMenu, const RefPtr<FrameNode>& subMenuNode, 800 const RefPtr<FrameNode>& menuWrapper); 801 void ShowStackMainMenuOpacityAnimation(const RefPtr<FrameNode>& mainMenu); 802 void ShowStackSubMenuDisappearAnimation(const RefPtr<FrameNode>& menuNode, 803 const RefPtr<FrameNode>& subMenuNode) const; 804 void ShowStackMainMenuDisappearOpacityAnimation(const RefPtr<FrameNode>& menuNode, 805 AnimationOption& option) const; 806 void ShowStackMainMenuDisappearAnimation(const RefPtr<FrameNode>& menuNode, 807 const RefPtr<FrameNode>& subMenuNode, AnimationOption& option) const; 808 809 RefPtr<ClickEvent> onClick_; 810 RefPtr<TouchEventImpl> onTouch_; 811 std::optional<Offset> lastTouchOffset_; 812 const int32_t targetId_ = -1; 813 const std::string targetTag_; 814 MenuType type_ = MenuType::MENU; 815 std::vector<SelectProperties> selectProperties_; 816 std::vector<SelectParam> selectParams_; 817 std::optional<SelectMakeCallback> makeFunc_; 818 819 RefPtr<FrameNode> parentMenuItem_; 820 RefPtr<FrameNode> showedSubMenu_; 821 std::vector<RefPtr<FrameNode>> options_; 822 std::optional<int32_t> foldStatusChangedCallbackId_; 823 std::optional<int32_t> halfFoldHoverCallbackId_; 824 825 bool isSelectMenu_ = false; 826 MenuPreviewMode previewMode_ = MenuPreviewMode::NONE; 827 MenuPreviewAnimationOptions previewAnimationOptions_; 828 bool isShowHoverImage_ = false; 829 bool isFirstShow_ = false; 830 bool isExtensionMenuShow_ = false; 831 bool isSubMenuShow_ = false; 832 bool isMenuShow_ = false; 833 bool hasAnimation_ = true; 834 bool needHideAfterTouch_ = true; 835 836 std::optional<OffsetF> lastPosition_; 837 std::optional<Placement> lastPlacement_; 838 OffsetF originOffset_; 839 OffsetF endOffset_; 840 OffsetF disappearOffset_; 841 OffsetF previewOriginOffset_; 842 RectF previewRect_; 843 SizeF previewIdealSize_; 844 OffsetF statusOriginOffset_; 845 846 WeakPtr<FrameNode> builderNode_; 847 bool isWidthModifiedBySelect_ = false; 848 bool isHeightModifiedBySelect_ = false; 849 bool hasLaid_ = false; 850 bool hasOptionWidth_ = false; 851 OffsetF targetOffset_; 852 SizeF targetSize_; 853 bool expandDisplay_ = false; 854 RefPtr<FrameNode> lastSelectedItem_ = nullptr; 855 bool isEmbedded_ = false; 856 std::vector<RefPtr<FrameNode>> embeddedMenuItems_; 857 bool isStackSubmenu_ = false; 858 bool isNeedDivider_ = false; 859 Rect menuWindowRect_; 860 PreviewMenuParam layoutParam_; 861 WeakPtr<UINode> customNode_ = nullptr; 862 std::optional<MenuPathParams> pathParams_ = std::nullopt; 863 float translateYForStack_ = 0.0f; 864 float originMenuYForStack_ = 0.0f; 865 float originPreviewYForStack_ = 0.0f; 866 bool isDisableMenuBgColorByUser_ = false; 867 868 // only used for Side sub menu 869 int32_t subMenuDepth_ = 0; 870 871 ACE_DISALLOW_COPY_AND_MOVE(MenuPattern); 872 }; 873 874 // pattern of inner menu, corersponds to <Menu> tag in the frontend 875 class InnerMenuPattern : public MenuPattern { 876 DECLARE_ACE_TYPE(InnerMenuPattern, MenuPattern); 877 878 public: InnerMenuPattern(int32_t targetId,std::string tag,MenuType type)879 InnerMenuPattern(int32_t targetId, std::string tag, MenuType type) : MenuPattern(targetId, std::move(tag), type) {} 880 ~InnerMenuPattern() override = default; 881 void OnModifyDone() override; 882 void BeforeCreateLayoutWrapper() override; 883 bool isHalfFoldStatus_ = false; 884 885 void RecordItemsAndGroups(); 886 GetItemsAndGroups()887 const std::list<WeakPtr<UINode>>& GetItemsAndGroups() const 888 { 889 return itemsAndGroups_; 890 } 891 892 private: 893 void InitTheme(const RefPtr<FrameNode>& host) override; 894 void UpdateBorderRadius(const RefPtr<FrameNode>& menuNode, const BorderRadiusProperty& borderRadius) override; 895 uint32_t FindSiblingMenuCount(); 896 void ApplyDesktopMenuTheme(); 897 void ApplyMultiMenuTheme(); 898 899 void InitDefaultBorder(const RefPtr<FrameNode>& host); 900 901 // Record menu's items and groups at first level, 902 // use for group header and footer padding 903 std::list<WeakPtr<UINode>> itemsAndGroups_; 904 905 ACE_DISALLOW_COPY_AND_MOVE(InnerMenuPattern); 906 }; 907 } // namespace OHOS::Ace::NG 908 909 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_MENU_MENU_PATTERN_H 910