From b880005f8af60ac6171ca967f0ea2db1a2e7f59a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E6=9C=A8=E5=AD=90?= <13940368937@163.com> Date: Wed, 12 Jun 2024 11:47:27 +0800 Subject: [PATCH] =?UTF-8?q?=E8=8F=9C=E5=8D=95=E9=80=80=E5=87=BA=E5=8A=A8?= =?UTF-8?q?=E6=95=88=E4=B8=8D=E4=B8=80=E8=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 李木子 <13940368937@163.com> --- .../menu/menu_item/menu_item_pattern.cpp | 18 +-- .../components_ng/pattern/menu/menu_pattern.h | 6 +- .../menu/wrapper/menu_wrapper_pattern.cpp | 103 ++++++++++++++++-- .../menu/wrapper/menu_wrapper_pattern.h | 17 ++- .../pattern/overlay/overlay_manager.cpp | 14 ++- .../pattern/overlay/overlay_manager.h | 2 +- 6 files changed, 132 insertions(+), 28 deletions(-) diff --git a/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_pattern.cpp b/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_pattern.cpp index b2acf424803..7faf869ea1e 100644 --- a/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_pattern.cpp +++ b/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_pattern.cpp @@ -592,6 +592,11 @@ void MenuItemPattern::ShowEmbeddedExpandMenu(const RefPtr& expandable CHECK_NULL_VOID(expandableNode); auto host = GetHost(); CHECK_NULL_VOID(host); + auto menuWrapper = GetMenuWrapper(); + CHECK_NULL_VOID(menuWrapper); + auto menuWrapperPattern = menuWrapper->GetPattern(); + CHECK_NULL_VOID(menuWrapperPattern); + menuWrapperPattern->IncreaseEmbeddedSubMenuCount(); auto rightRow = AceType::DynamicCast(host->GetChildAtIndex(1)); CHECK_NULL_VOID(rightRow); auto imageNode = AceType::DynamicCast(rightRow->GetChildren().back()); @@ -630,6 +635,11 @@ void MenuItemPattern::HideEmbeddedExpandMenu(const RefPtr& expandable CHECK_NULL_VOID(expandableNode); auto host = GetHost(); CHECK_NULL_VOID(host); + auto menuWrapper = GetMenuWrapper(); + CHECK_NULL_VOID(menuWrapper); + auto menuWrapperPattern = menuWrapper->GetPattern(); + CHECK_NULL_VOID(menuWrapperPattern); + menuWrapperPattern->DecreaseEmbeddedSubMenuCount(); auto expandableAreaContext = expandableNode->GetRenderContext(); CHECK_NULL_VOID(expandableAreaContext); @@ -664,15 +674,9 @@ void MenuItemPattern::CloseMenu() } auto menuWrapper = GetMenuWrapper(); CHECK_NULL_VOID(menuWrapper); - auto outterMenu = menuWrapper->GetFirstChild(); - CHECK_NULL_VOID(outterMenu); auto menuWrapperPattern = menuWrapper->GetPattern(); CHECK_NULL_VOID(menuWrapperPattern); - auto outterMenuPattern = AceType::DynamicCast( - AceType::DynamicCast(outterMenu)->GetPattern()); - CHECK_NULL_VOID(outterMenuPattern); - outterMenuPattern->SetHasDisappearAnimation(false); - + menuWrapperPattern->UpdateMenuAnimation(menuWrapper); menuWrapperPattern->HideMenu(); } diff --git a/frameworks/core/components_ng/pattern/menu/menu_pattern.h b/frameworks/core/components_ng/pattern/menu/menu_pattern.h index 22fc3da7727..53a09a2ca69 100644 --- a/frameworks/core/components_ng/pattern/menu/menu_pattern.h +++ b/frameworks/core/components_ng/pattern/menu/menu_pattern.h @@ -363,12 +363,14 @@ public: isExtensionMenuShow_ = true; } - void SetHasDisappearAnimation(bool hasAnimation) + void SetDisappearAnimation(bool hasAnimation) { + // false:exit from BOTTOM to TOP + // true:exit from LEFT_BOTTOM to RIGHT_TOP hasAnimation_ = hasAnimation; } - bool HasDisappearAnimation() const + bool GetDisappearAnimation() const { return hasAnimation_; } diff --git a/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.cpp b/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.cpp index 2225d4483b6..c4c127036b4 100644 --- a/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.cpp +++ b/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.cpp @@ -235,15 +235,25 @@ void MenuWrapperPattern::HideSubMenu() auto focusMenu = MenuFocusViewShow(); CHECK_NULL_VOID(focusMenu); auto innerMenu = GetMenuChild(focusMenu); + if (!innerMenu) { + UpdateMenuAnimation(host); + host->RemoveChild(subMenu); + host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD); + return; + } CHECK_NULL_VOID(innerMenu); auto innerMenuPattern = innerMenu->GetPattern(); CHECK_NULL_VOID(innerMenuPattern); auto layoutProps = innerMenuPattern->GetLayoutProperty(); CHECK_NULL_VOID(layoutProps); auto expandingMode = layoutProps->GetExpandingMode().value_or(SubMenuExpandingMode::SIDE); - if (expandingMode == SubMenuExpandingMode::STACK) { + auto outterMenuPattern = focusMenu->GetPattern(); + CHECK_NULL_VOID(outterMenuPattern); + bool hasAnimation = outterMenuPattern->GetDisappearAnimation(); + if (expandingMode == SubMenuExpandingMode::STACK && hasAnimation) { HideStackExpandMenu(subMenu); } else { + UpdateMenuAnimation(host); host->RemoveChild(subMenu); host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD); } @@ -251,11 +261,9 @@ void MenuWrapperPattern::HideSubMenu() bool MenuWrapperPattern::HasStackSubMenu() { - auto menu = GetMenu(); - CHECK_NULL_RETURN(menu, false); - auto scroll = menu->GetFirstChild(); - CHECK_NULL_RETURN(scroll, false); - auto innerMenu = AceType::DynamicCast(scroll->GetFirstChild()); + auto outterMenu = GetMenu(); + CHECK_NULL_RETURN(outterMenu, false); + auto innerMenu = GetMenuChild(outterMenu); CHECK_NULL_RETURN(innerMenu, false); auto innerMenuPattern = innerMenu->GetPattern(); CHECK_NULL_RETURN(innerMenuPattern, false); @@ -270,6 +278,20 @@ bool MenuWrapperPattern::HasStackSubMenu() return host->GetChildren().size() > 1; } +bool MenuWrapperPattern::HasEmbeddedSubMenu() +{ + auto outterMenu = GetMenu(); + CHECK_NULL_RETURN(outterMenu, false); + auto innerMenu = GetMenuChild(outterMenu); + CHECK_NULL_RETURN(innerMenu, false); + auto innerMenuPattern = innerMenu->GetPattern(); + CHECK_NULL_RETURN(innerMenuPattern, false); + auto layoutProps = innerMenuPattern->GetLayoutProperty(); + CHECK_NULL_RETURN(layoutProps, false); + auto expandingMode = layoutProps->GetExpandingMode().value_or(SubMenuExpandingMode::SIDE); + return expandingMode == SubMenuExpandingMode::EMBEDDED; +} + RefPtr MenuWrapperPattern::MenuFocusViewShow() { auto host = GetHost(); @@ -320,6 +342,7 @@ void MenuWrapperPattern::HideStackExpandMenu(const RefPtr& subMenu) CHECK_NULL_VOID(menuNodePattern); menuNodePattern->ShowStackExpandDisappearAnimation(DynamicCast(menuNode), DynamicCast(subMenu), option); + menuNodePattern->SetDisappearAnimation(true); } void MenuWrapperPattern::RegisterOnTouch() @@ -374,11 +397,7 @@ void MenuWrapperPattern::OnTouchEvent(const TouchEventInfo& info) if (!menuPattern) { continue; } - if (menuPattern->IsSubMenu() || menuPattern->IsSelectOverlaySubMenu()) { - HideSubMenu(); - } else { - HideMenu(menuWrapperChildNode); - } + HideMenu(menuPattern, menuWrapperChildNode, position); } } else if (touch.GetTouchType() == TouchType::MOVE) { auto menuNode = DynamicCast(host->GetChildAtIndex(0)); @@ -396,6 +415,68 @@ void MenuWrapperPattern::OnTouchEvent(const TouchEventInfo& info) } } +void MenuWrapperPattern::HideMenu(const RefPtr& menuPattern, const RefPtr& menu, + const OffsetF& position) +{ + auto host = GetHost(); + CHECK_NULL_VOID(host); + auto mainMenu = DynamicCast(host->GetFirstChild()); + CHECK_NULL_VOID(mainMenu); + auto mainMenuZone = mainMenu->GetGeometryNode()->GetFrameRect(); + bool isFindTargetId = false; + if (mainMenuZone.IsInRegion(PointF(position.GetX(), position.GetY()))) { + isFindTargetId = true; + } + if (menuPattern->IsSubMenu() || menuPattern->IsSelectOverlaySubMenu()) { + if (HasStackSubMenu() && !isFindTargetId) { + UpdateMenuAnimation(host); + } + HideSubMenu(); + } else { + if (HasEmbeddedSubMenu() && embeddedSubMenuCount_ > 0 && !isFindTargetId) { + UpdateMenuAnimation(host); + } + HideMenu(menu); + } +} + +void MenuWrapperPattern::UpdateMenuAnimation(const RefPtr& host) +{ + // update Menu disappear animation direction + // change to LEFT_BOTTOM -> RIGHT_TOP by calling SetExitAnimation + // or keep BOTTOM -> TOP by default + CHECK_NULL_VOID(host); + auto outterMenu = host->GetFirstChild(); + CHECK_NULL_VOID(outterMenu); + auto innerMenu = GetMenuChild(outterMenu); + if (!innerMenu && host->GetChildren().size() > 1) { + SetExitAnimation(host); + return; + } + CHECK_NULL_VOID(innerMenu); + auto innerMenuPattern = innerMenu->GetPattern(); + CHECK_NULL_VOID(innerMenuPattern); + auto layoutProps = innerMenuPattern->GetLayoutProperty(); + CHECK_NULL_VOID(layoutProps); + auto expandingMode = layoutProps->GetExpandingMode().value_or(SubMenuExpandingMode::SIDE); + if (host->GetChildren().size() > 1) { + SetExitAnimation(host); + } + if (expandingMode == SubMenuExpandingMode::EMBEDDED && embeddedSubMenuCount_ > 0) { + SetExitAnimation(host); + } +} + +void MenuWrapperPattern::SetExitAnimation(const RefPtr& host) +{ + CHECK_NULL_VOID(host); + auto outterMenu = AceType::DynamicCast(host->GetFirstChild()); + CHECK_NULL_VOID(outterMenu); + auto outterMenuPattern = outterMenu->GetPattern(); + CHECK_NULL_VOID(outterMenuPattern); + outterMenuPattern->SetDisappearAnimation(false); +} + void MenuWrapperPattern::CheckAndShowAnimation() { if (isFirstShow_) { diff --git a/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h b/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h index 8d022004b37..df72a27b3e3 100644 --- a/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h +++ b/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h @@ -357,11 +357,23 @@ public: lastTouchItem_ = lastTouchItem; } + int IncreaseEmbeddedSubMenuCount() + { + return ++embeddedSubMenuCount_; + } + + int DecreaseEmbeddedSubMenuCount() + { + return --embeddedSubMenuCount_; + } + RefPtr GetMenuChild(const RefPtr& node); RefPtr GetShowedSubMenu(); bool IsSelectOverlayCustomMenu(const RefPtr& menu) const; + bool HasEmbeddedSubMenu(); + void UpdateMenuAnimation(const RefPtr& host); bool HasStackSubMenu(); - + int embeddedSubMenuCount_ = 0; protected: void OnTouchEvent(const TouchEventInfo& info); void CheckAndShowAnimation(); @@ -387,7 +399,8 @@ private: RefPtr FindTouchedMenuItem(const RefPtr& menuNode, const OffsetF& position); void HideMenu(const RefPtr& menu); - + void HideMenu(const RefPtr& menuPattern, const RefPtr& menu, const OffsetF& position); + void SetExitAnimation(const RefPtr& host); std::function onAppearCallback_ = nullptr; std::function onDisappearCallback_ = nullptr; std::function aboutToAppearCallback_ = nullptr; diff --git a/frameworks/core/components_ng/pattern/overlay/overlay_manager.cpp b/frameworks/core/components_ng/pattern/overlay/overlay_manager.cpp index 64031121835..0b2c0413a59 100644 --- a/frameworks/core/components_ng/pattern/overlay/overlay_manager.cpp +++ b/frameworks/core/components_ng/pattern/overlay/overlay_manager.cpp @@ -1003,22 +1003,22 @@ void OverlayManager::ClearMenuAnimation(const RefPtr& menu, bool show ShowMenuClearAnimation(menu, option, showPreviewAnimation, startDrag); } -void OverlayManager::ShowMenuClearAnimation(const RefPtr& menu, AnimationOption& option, +void OverlayManager::ShowMenuClearAnimation(const RefPtr& menuWrapper, AnimationOption& option, bool showPreviewAnimation, bool startDrag) { - TAG_LOGD(AceLogTag::ACE_OVERLAY, "show menu clear animation enter"); - auto context = menu->GetRenderContext(); + TAG_LOGD(AceLogTag::ACE_OVERLAY, "show menuWrapper clear animation enter"); + auto context = menuWrapper->GetRenderContext(); CHECK_NULL_VOID(context); auto pipeline = PipelineBase::GetCurrentContext(); CHECK_NULL_VOID(pipeline); - auto menuWrapperPattern = menu->GetPattern(); + auto menuWrapperPattern = menuWrapper->GetPattern(); CHECK_NULL_VOID(menuWrapperPattern); auto menuAnimationOffset = menuWrapperPattern->GetAnimationOffset(); auto outterMenu = menuWrapperPattern->GetMenu(); CHECK_NULL_VOID(outterMenu); auto outterMenuPattern = outterMenu->GetPattern(); CHECK_NULL_VOID(outterMenuPattern); - bool isShow = outterMenuPattern->HasDisappearAnimation(); + bool isShow = outterMenuPattern->GetDisappearAnimation(); if (menuWrapperPattern->GetPreviewMode() != MenuPreviewMode::NONE) { if (!showPreviewAnimation) { CleanPreviewInSubWindow(); @@ -1809,6 +1809,9 @@ void OverlayManager::HideAllMenus() for (const auto& child : rootNode->GetChildren()) { auto node = DynamicCast(child); if (node && node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) { + auto wrapperPattern = node->GetPattern(); + CHECK_NULL_VOID(wrapperPattern); + wrapperPattern->UpdateMenuAnimation(node); PopMenuAnimation(node); } } @@ -2580,6 +2583,7 @@ bool OverlayManager::RemoveMenu(const RefPtr& overlay) TAG_LOGD(AceLogTag::ACE_OVERLAY, "remove menu enter"); auto menuWrapperPattern = overlay->GetPattern(); CHECK_NULL_RETURN(menuWrapperPattern, false); + menuWrapperPattern->UpdateMenuAnimation(overlay); menuWrapperPattern->HideMenu(); return true; } diff --git a/frameworks/core/components_ng/pattern/overlay/overlay_manager.h b/frameworks/core/components_ng/pattern/overlay/overlay_manager.h index a4c45dc9c7e..d722a13ae09 100644 --- a/frameworks/core/components_ng/pattern/overlay/overlay_manager.h +++ b/frameworks/core/components_ng/pattern/overlay/overlay_manager.h @@ -573,7 +573,7 @@ private: void SetPatternFirstShow(const RefPtr& menu); void PopMenuAnimation(const RefPtr& menu, bool showPreviewAnimation = true, bool startDrag = false); void ClearMenuAnimation(const RefPtr& menu, bool showPreviewAnimation = true, bool startDrag = false); - void ShowMenuClearAnimation(const RefPtr& menu, AnimationOption& option, + void ShowMenuClearAnimation(const RefPtr& menuWrapper, AnimationOption& option, bool showPreviewAnimation, bool startDrag); void OpenDialogAnimation(const RefPtr& node); -- Gitee