diff --git a/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_pattern.h b/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_pattern.h index 225cdfccfbb702992d2bc0703c8c88f547041be2..571bf7510b4a5a5557aca7ef7b40300064047d7e 100644 --- a/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_pattern.h +++ b/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_pattern.h @@ -49,6 +49,11 @@ public: MenuItemPattern(bool isOptionPattern = false, int index = -1) : index_(index), isOptionPattern_(isOptionPattern) {} ~MenuItemPattern() override = default; + bool HasHideTask() + { + return hideTask_; + } + inline bool IsAtomicNode() const override { return false; 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 770a4a549640b8a76a6fc53e4afbaf3a4f5bbc87..99706a928ec64152f3bef46c91e03af987bc3128 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 @@ -296,6 +296,7 @@ void MenuWrapperPattern::HideSubMenuByDepth(const RefPtr& menuItem) CHECK_NULL_VOID(menuPattern); auto curDepth = menuPattern->GetSubMenuDepth(); auto children = host->GetChildren(); + bool clearShowedSubMenu = true; for (auto child = children.rbegin(); child != children.rend(); ++child) { auto childNode = DynamicCast(*child); CHECK_NULL_VOID(childNode); @@ -307,14 +308,26 @@ void MenuWrapperPattern::HideSubMenuByDepth(const RefPtr& menuItem) if (subMenuPattern->GetSubMenuDepth() <= curDepth) { break; } - if (subMenuPattern->GetSubMenuDepth() == (curDepth + 1)) { - subMenuPattern->RemoveParentHoverStyle(); + auto parentMenuItem = subMenuPattern->GetParentMenuItem(); + CHECK_NULL_VOID(parentMenuItem); + auto parentItemPattern = parentMenuItem->GetPattern(); + CHECK_NULL_VOID(parentItemPattern); + if (parentItemPattern->HasHideTask()) { + clearShowedSubMenu = false; + continue; + } + if (parentMenuItem->GetId() == menuItem->GetId()) { + clearShowedSubMenu = false; + break; } + subMenuPattern->RemoveParentHoverStyle(); UpdateMenuAnimation(host); SendToAccessibility(childNode, false); host->RemoveChild(childNode); } - menuPattern->SetShowedSubMenu(nullptr); + if (clearShowedSubMenu) { + menuPattern->SetShowedSubMenu(nullptr); + } host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD); } diff --git a/test/unittest/core/pattern/menu/menuitem_pattern_testone_ng.cpp b/test/unittest/core/pattern/menu/menuitem_pattern_testone_ng.cpp index 00003d5fffdc5d5f55845a74c62f05190bc5921d..3cdc5227f69a99187dd285696e0edea846fcd185 100644 --- a/test/unittest/core/pattern/menu/menuitem_pattern_testone_ng.cpp +++ b/test/unittest/core/pattern/menu/menuitem_pattern_testone_ng.cpp @@ -1929,11 +1929,80 @@ HWTEST_F(MenuItemPatternTestOneNg, OnHover002, TestSize.Level1) auto subMenuPattern = subMenu->GetPattern(); ASSERT_NE(subMenuPattern, nullptr); subMenuPattern->SetSubMenuDepth(1); + subMenuPattern->SetParentMenuItem(menuItemNode); auto menuItemPattern = menuItemNode->GetPattern(); ASSERT_NE(menuItemPattern, nullptr); menuItemPattern->OnHover(true); + auto menuWrapper = menuItemPattern->GetMenuWrapper(); + ASSERT_NE(menuWrapper, nullptr); + ASSERT_EQ(menuWrapper->GetChildren().size(), 3); +} + +/** + * @tc.name: OnHover003 + * @tc.desc: Verify OnHover. + * @tc.type: FUNC + */ +HWTEST_F(MenuItemPatternTestOneNg, OnHover003, TestSize.Level1) +{ + auto wrapperNode = + FrameNode::CreateFrameNode(V2::MENU_WRAPPER_ETS_TAG, 1, AceType::MakeRefPtr(1)); + auto mainMenu = + FrameNode::CreateFrameNode(V2::MENU_ETS_TAG, 2, AceType::MakeRefPtr(1, TEXT_TAG, MenuType::MENU)); + auto subMenu = FrameNode::CreateFrameNode( + V2::MENU_ETS_TAG, 3, AceType::MakeRefPtr(1, TEXT_TAG, MenuType::SUB_MENU)); + auto dummySubMenu = FrameNode::CreateFrameNode( + V2::TEXT_ETS_TAG, 3, AceType::MakeRefPtr()); + auto menuItemNode = FrameNode::CreateFrameNode(V2::MENU_ITEM_ETS_TAG, 4, AceType::MakeRefPtr()); + menuItemNode->MountToParent(mainMenu); + mainMenu->MountToParent(wrapperNode); + dummySubMenu->MountToParent(wrapperNode); + subMenu->MountToParent(wrapperNode); + auto subMenuPattern = subMenu->GetPattern(); + ASSERT_NE(subMenuPattern, nullptr); + subMenuPattern->SetSubMenuDepth(1); + auto tmpItemNode = FrameNode::CreateFrameNode(V2::MENU_ITEM_ETS_TAG, 5, AceType::MakeRefPtr()); + subMenuPattern->SetParentMenuItem(tmpItemNode); + + auto menuItemPattern = menuItemNode->GetPattern(); + ASSERT_NE(menuItemPattern, nullptr); + menuItemPattern->OnHover(true); + + auto menuWrapper = menuItemPattern->GetMenuWrapper(); + ASSERT_NE(menuWrapper, nullptr); + ASSERT_EQ(menuWrapper->GetChildren().size(), 2); +} + +/** + * @tc.name: OnHover004 + * @tc.desc: Verify OnHover. + * @tc.type: FUNC + */ +HWTEST_F(MenuItemPatternTestOneNg, OnHover004, TestSize.Level1) +{ + auto wrapperNode = + FrameNode::CreateFrameNode(V2::MENU_WRAPPER_ETS_TAG, 1, AceType::MakeRefPtr(1)); + auto mainMenu = + FrameNode::CreateFrameNode(V2::MENU_ETS_TAG, 2, AceType::MakeRefPtr(1, TEXT_TAG, MenuType::MENU)); + auto subMenu = FrameNode::CreateFrameNode( + V2::MENU_ETS_TAG, 3, AceType::MakeRefPtr(1, TEXT_TAG, MenuType::SUB_MENU)); + auto menuItemNode = FrameNode::CreateFrameNode(V2::MENU_ITEM_ETS_TAG, 4, AceType::MakeRefPtr()); + menuItemNode->MountToParent(mainMenu); + mainMenu->MountToParent(wrapperNode); + subMenu->MountToParent(wrapperNode); + auto subMenuPattern = subMenu->GetPattern(); + ASSERT_NE(subMenuPattern, nullptr); + subMenuPattern->SetSubMenuDepth(1); + subMenuPattern->SetParentMenuItem(menuItemNode); + + auto menuItemPattern = menuItemNode->GetPattern(); + ASSERT_NE(menuItemPattern, nullptr); + menuItemPattern->hideTask_.Reset([] { + }); + menuItemPattern->OnHover(true); + auto menuWrapper = menuItemPattern->GetMenuWrapper(); ASSERT_NE(menuWrapper, nullptr); ASSERT_EQ(menuWrapper->GetChildren().size(), 2);