【Menu】修复横屏及非手机设备预览菜单布局异常

Signed-off-by: wangyihui <wangyihui16@huawei.com>
Change-Id: Ie87765fa710063d9a117a97c4d224c53ff12bd6a
This commit is contained in:
wangyihui 2024-07-18 13:17:53 +00:00
parent 593cfa28ce
commit f92d0e36be
4 changed files with 56 additions and 131 deletions

View File

@ -280,39 +280,6 @@ MenuLayoutAlgorithm::~MenuLayoutAlgorithm()
setVertical_.clear();
}
void MenuLayoutAlgorithm::ModifyNormalPreviewMenuPortraitPlacement(LayoutWrapper* layoutWrapper)
{
CHECK_NULL_VOID(layoutWrapper);
auto props = AceType::DynamicCast<MenuLayoutProperty>(layoutWrapper->GetLayoutProperty());
CHECK_NULL_VOID(props);
auto hasPlacement = props->GetMenuPlacement().has_value();
if (placement_ == Placement::TOP_LEFT || placement_ == Placement::TOP || placement_ == Placement::TOP_RIGHT) {
if (!hasPlacement) {
placement_ = Placement::TOP_LEFT;
props->UpdateMenuPlacement(placement_);
}
} else if (!hasPlacement) {
placement_ = Placement::BOTTOM_LEFT;
props->UpdateMenuPlacement(placement_);
}
}
void MenuLayoutAlgorithm::ModifyNormalPreviewMenuPlacement(LayoutWrapper* layoutWrapper)
{
CHECK_NULL_VOID(layoutWrapper);
auto props = AceType::DynamicCast<MenuLayoutProperty>(layoutWrapper->GetLayoutProperty());
CHECK_NULL_VOID(props);
auto hasPlacement = props->GetMenuPlacement().has_value();
if (SystemProperties::GetDeviceOrientation() == DeviceOrientation::PORTRAIT) {
ModifyNormalPreviewMenuPortraitPlacement(layoutWrapper);
} else if (!hasPlacement) {
placement_ = Placement::RIGHT_TOP;
props->UpdateMenuPlacement(placement_);
}
}
void MenuLayoutAlgorithm::ModifyPreviewMenuPlacement(LayoutWrapper* layoutWrapper)
{
CHECK_NULL_VOID(layoutWrapper);
@ -323,10 +290,13 @@ void MenuLayoutAlgorithm::ModifyPreviewMenuPlacement(LayoutWrapper* layoutWrappe
auto menuTheme = pipeline->GetTheme<NG::MenuTheme>();
CHECK_NULL_VOID(menuTheme);
auto hasPlacement = props->GetMenuPlacement().has_value();
if (menuTheme->GetNormalPlacement()) {
ModifyNormalPreviewMenuPlacement(layoutWrapper);
} else {
if (!hasPlacement) {
if (!hasPlacement) {
if (menuTheme->GetNormalPlacement() &&
SystemProperties::GetDeviceOrientation() == DeviceOrientation::PORTRAIT) {
// for Phone with PORTRAIT orientation, default placement is BOTTOM_LEFT
placement_ = Placement::BOTTOM_LEFT;
props->UpdateMenuPlacement(placement_);
} else {
placement_ = Placement::RIGHT_TOP;
props->UpdateMenuPlacement(placement_);
}
@ -647,7 +617,7 @@ void MenuLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper)
childConstraint.parentIdealSize.SetWidth(selectMenuWidth);
childConstraint.selfIdealSize.SetWidth(selectMenuWidth);
}
auto parentItem = menuPattern->GetParentMenuItem();
CalculateIdealSize(layoutWrapper, childConstraint, padding, idealSize, parentItem);
}
@ -812,10 +782,11 @@ void MenuLayoutAlgorithm::LayoutNormalTopPreviewBottomMenuLessThan(
CHECK_NULL_VOID(previewGeometryNode);
CHECK_NULL_VOID(menuGeometryNode);
OffsetF center(targetOffset_.GetX() + targetSize_.Width() / 2, targetOffset_.GetY() + targetSize_.Height() / 2);
OffsetF center(
targetOffset_.GetX() + targetSize_.Width() / HALF, targetOffset_.GetY() + targetSize_.Height() / HALF);
targetCenterOffset_ = center;
auto previewSize = previewGeometryNode->GetMarginFrameSize() * previewScale_;
OffsetF offset(center.GetX() - previewSize.Width() / 2,
OffsetF offset(center.GetX() - previewSize.Width() / HALF,
std::min<float>(center.GetY() - previewSize.Height() / HALF, param_.windowGlobalSizeF.Height() -
param_.bottomSecurity - param_.bottom -
totalSize.Height() - param_.previewMenuGap));
@ -823,8 +794,8 @@ void MenuLayoutAlgorithm::LayoutNormalTopPreviewBottomMenuLessThan(
static_cast<float>(wrapperRect_.Right()) - paddingEnd_ - previewSize.Width());
auto y = std::clamp(offset.GetY(), static_cast<float>(wrapperRect_.Top()) + param_.topSecurity,
static_cast<float>(wrapperRect_.Bottom()) - param_.bottomSecurity - previewSize.Height());
x = x + (previewSize.Width() - previewSize.Width() / previewScale_) / 2;
y = y + (previewSize.Height() - previewSize.Height() / previewScale_) / 2;
x = x + (previewSize.Width() - previewSize.Width() / previewScale_) / HALF;
y = y + (previewSize.Height() - previewSize.Height() / previewScale_) / HALF;
previewGeometryNode->SetMarginFrameOffset(OffsetF(x, y));
}
@ -1080,55 +1051,6 @@ float MenuLayoutAlgorithm::GetMenuItemTotalHeight(const RefPtr<LayoutWrapper>& m
return height;
}
void MenuLayoutAlgorithm::LayoutNormalPreviewMenu(LayoutWrapper* layoutWrapper)
{
CHECK_NULL_VOID(layoutWrapper);
auto menuNode = layoutWrapper->GetHostNode();
CHECK_NULL_VOID(menuNode);
auto parentNode = AceType::DynamicCast<FrameNode>(menuNode->GetParent());
CHECK_NULL_VOID(parentNode);
RefPtr<LayoutWrapper> menuLayoutWrapper;
RefPtr<LayoutWrapper> previewLayoutWrapper;
SizeF totalSize = GetPreviewNodeAndMenuNodeTotalSize(parentNode, previewLayoutWrapper, menuLayoutWrapper);
CHECK_NULL_VOID(menuLayoutWrapper);
CHECK_NULL_VOID(previewLayoutWrapper);
RefPtr<GeometryNode> menuGeometryNode = menuLayoutWrapper->GetGeometryNode();
RefPtr<GeometryNode> previewGeometryNode = previewLayoutWrapper->GetGeometryNode();
auto menuItemTotalHeight = GetMenuItemTotalHeight(menuLayoutWrapper);
if (SystemProperties::GetDeviceOrientation() == DeviceOrientation::PORTRAIT) {
if (placement_ == Placement::TOP_LEFT || placement_ == Placement::TOP || placement_ == Placement::TOP_RIGHT) {
LayoutNormalBottomPreviewTopMenu(previewGeometryNode, menuGeometryNode, totalSize, menuItemTotalHeight);
} else {
LayoutNormalTopPreviewBottomMenu(previewGeometryNode, menuGeometryNode, totalSize, menuItemTotalHeight);
}
} else {
LayoutOtherDeviceLeftPreviewRightMenu(previewGeometryNode, menuGeometryNode, totalSize, menuItemTotalHeight);
}
UpdateScrollAndColumnLayoutConstraint(previewLayoutWrapper, menuLayoutWrapper);
auto previewSize = previewGeometryNode->GetMarginFrameSize();
previewOffset_ = previewGeometryNode->GetFrameOffset();
auto previewOffsetX = previewOffset_.GetX();
auto previewOffsetY = previewOffset_.GetY();
targetSize_ = previewSize * previewScale_;
targetOffset_ = OffsetF(previewOffsetX + (previewSize.Width() - targetSize_.Width()) / 2,
previewOffsetY + (previewSize.Height() - targetSize_.Height()) / 2);
auto previewHostNode = previewLayoutWrapper->GetHostNode();
CHECK_NULL_VOID(previewHostNode);
auto renderContext = previewHostNode->GetRenderContext();
CHECK_NULL_VOID(renderContext);
renderContext->UpdatePosition(OffsetT<Dimension>(Dimension(previewOffsetX), Dimension(previewOffsetY)));
auto menuHostNode = menuLayoutWrapper->GetHostNode();
CHECK_NULL_VOID(menuHostNode);
previewOriginOffset_ = targetCenterOffset_ - OffsetF(previewSize.Width() / 2, previewSize.Height() / 2);
previewSize_ = previewSize;
auto menuPattern = menuHostNode->GetPattern<MenuPattern>();
CHECK_NULL_VOID(menuPattern);
menuPattern->SetPreviewOriginOffset(previewOriginOffset_);
}
void MenuLayoutAlgorithm::LayoutOtherDeviceLeftPreviewRightMenuLessThan(
const RefPtr<GeometryNode>& previewGeometryNode, const RefPtr<GeometryNode>& menuGeometryNode, SizeF& totalSize)
{
@ -1238,14 +1160,16 @@ void MenuLayoutAlgorithm::LayoutOtherDeviceLeftPreviewRightMenu(const RefPtr<Geo
}
}
void MenuLayoutAlgorithm::LayoutOtherDevicePreviewMenu(LayoutWrapper* layoutWrapper)
void MenuLayoutAlgorithm::LayoutPreviewMenu(LayoutWrapper* layoutWrapper)
{
CHECK_NULL_VOID(layoutWrapper);
auto paintProperty = GetPaintProperty(layoutWrapper);
CHECK_NULL_VOID(paintProperty);
paintProperty->UpdateEnableArrow(false);
auto menuNode = layoutWrapper->GetHostNode();
CHECK_NULL_VOID(menuNode);
auto parentNode = AceType::DynamicCast<FrameNode>(menuNode->GetParent());
CHECK_NULL_VOID(parentNode);
RefPtr<LayoutWrapper> menuLayoutWrapper;
RefPtr<LayoutWrapper> previewLayoutWrapper;
SizeF totalSize = GetPreviewNodeAndMenuNodeTotalSize(parentNode, previewLayoutWrapper, menuLayoutWrapper);
@ -1256,15 +1180,36 @@ void MenuLayoutAlgorithm::LayoutOtherDevicePreviewMenu(LayoutWrapper* layoutWrap
CHECK_NULL_VOID(menuGeometryNode);
CHECK_NULL_VOID(previewGeometryNode);
auto menuItemTotalHeight = GetMenuItemTotalHeight(menuLayoutWrapper);
LayoutOtherDeviceLeftPreviewRightMenu(previewGeometryNode, menuGeometryNode, totalSize, menuItemTotalHeight);
if (placement_ == Placement::BOTTOM_LEFT || placement_ == Placement::BOTTOM ||
placement_ == Placement::BOTTOM_RIGHT) {
LayoutNormalTopPreviewBottomMenu(previewGeometryNode, menuGeometryNode, totalSize, menuItemTotalHeight);
} else if (placement_ == Placement::TOP_LEFT || placement_ == Placement::TOP ||
placement_ == Placement::TOP_RIGHT) {
LayoutNormalBottomPreviewTopMenu(previewGeometryNode, menuGeometryNode, totalSize, menuItemTotalHeight);
} else {
LayoutOtherDeviceLeftPreviewRightMenu(previewGeometryNode, menuGeometryNode, totalSize, menuItemTotalHeight);
}
UpdateScrollAndColumnLayoutConstraint(previewLayoutWrapper, menuLayoutWrapper);
UpdatePreviewPositionAndOffset(previewLayoutWrapper, menuLayoutWrapper);
}
void MenuLayoutAlgorithm::UpdatePreviewPositionAndOffset(
RefPtr<LayoutWrapper>& previewLayoutWrapper, RefPtr<LayoutWrapper>& menuLayoutWrapper)
{
CHECK_NULL_VOID(previewLayoutWrapper);
CHECK_NULL_VOID(menuLayoutWrapper);
RefPtr<GeometryNode> previewGeometryNode = previewLayoutWrapper->GetGeometryNode();
RefPtr<GeometryNode> menuGeometryNode = menuLayoutWrapper->GetGeometryNode();
CHECK_NULL_VOID(previewGeometryNode);
CHECK_NULL_VOID(menuGeometryNode);
auto previewSize = previewGeometryNode->GetMarginFrameSize();
previewOffset_ = previewGeometryNode->GetFrameOffset();
auto previewOffsetX = previewGeometryNode->GetFrameOffset().GetX();
auto previewOffsetY = previewGeometryNode->GetFrameOffset().GetY();
auto previewOffsetX = previewOffset_.GetX();
auto previewOffsetY = previewOffset_.GetY();
targetSize_ = previewSize * previewScale_;
targetOffset_ = OffsetF(previewOffsetX + (previewSize.Width() - targetSize_.Width()) / 2,
previewOffsetY + (previewSize.Height() - targetSize_.Height()) / 2);
targetOffset_ = OffsetF(previewOffsetX + (previewSize.Width() - targetSize_.Width()) / HALF,
previewOffsetY + (previewSize.Height() - targetSize_.Height()) / HALF);
auto previewHostNode = previewLayoutWrapper->GetHostNode();
CHECK_NULL_VOID(previewHostNode);
auto renderContext = previewHostNode->GetRenderContext();
@ -1273,29 +1218,12 @@ void MenuLayoutAlgorithm::LayoutOtherDevicePreviewMenu(LayoutWrapper* layoutWrap
auto menuHostNode = menuLayoutWrapper->GetHostNode();
CHECK_NULL_VOID(menuHostNode);
previewOriginOffset_ = targetCenterOffset_ - OffsetF(previewSize.Width() / 2, previewSize.Height() / 2);
previewOriginOffset_ = targetCenterOffset_ - OffsetF(previewSize.Width() / HALF, previewSize.Height() / HALF);
previewSize_ = previewSize;
auto menuPattern = menuHostNode->GetPattern<MenuPattern>();
CHECK_NULL_VOID(menuPattern);
menuPattern->SetPreviewOriginOffset(previewOriginOffset_);
}
void MenuLayoutAlgorithm::LayoutPreviewMenu(LayoutWrapper* layoutWrapper)
{
auto paintProperty = GetPaintProperty(layoutWrapper);
CHECK_NULL_VOID(paintProperty);
paintProperty->UpdateEnableArrow(false);
auto pipeline = PipelineBase::GetCurrentContext();
CHECK_NULL_VOID(pipeline);
auto menuTheme = pipeline->GetTheme<NG::MenuTheme>();
CHECK_NULL_VOID(menuTheme);
if (menuTheme->GetNormalLayout()) {
LayoutNormalPreviewMenu(layoutWrapper);
} else {
LayoutOtherDevicePreviewMenu(layoutWrapper);
}
}
OffsetF MenuLayoutAlgorithm::FixMenuOriginOffset(float beforeAnimationScale, float afterAnimationScale)
{
auto beforeRate = (1.0f - beforeAnimationScale) / 2;

View File

@ -170,9 +170,9 @@ private:
RefPtr<PipelineContext> GetCurrentPipelineContext();
void LayoutPreviewMenu(LayoutWrapper* layoutWrapper);
void UpdatePreviewPositionAndOffset(
RefPtr<LayoutWrapper>& previewLayoutWrapper, RefPtr<LayoutWrapper>& menuLayoutWrapper);
void ModifyPreviewMenuPlacement(LayoutWrapper* layoutWrapper);
void ModifyNormalPreviewMenuPlacement(LayoutWrapper* layoutWrapper);
void ModifyNormalPreviewMenuPortraitPlacement(LayoutWrapper* layoutWrapper);
void GetPreviewNodeTotalSize(const RefPtr<LayoutWrapper>& child, const Rect& windowGlobalRect,
RefPtr<LayoutWrapper>& previewLayoutWrapper, SizeF& size, bool isShowHoverImage);
void GetPreviewNodeTargetHoverImageChild(const RefPtr<LayoutWrapper>& child,
@ -180,7 +180,6 @@ private:
SizeF GetPreviewNodeAndMenuNodeTotalSize(const RefPtr<FrameNode>& frameNode,
RefPtr<LayoutWrapper>& previewLayoutWrapper, RefPtr<LayoutWrapper>& menuLayoutWrapper);
void LayoutNormalPreviewMenu(LayoutWrapper* layoutWrapper);
void LayoutNormalTopPreviewBottomMenu(const RefPtr<GeometryNode>& previewGeometryNode,
const RefPtr<GeometryNode>& menuGeometryNode, SizeF& totalSize, float menuItemTotalHeight);
void LayoutNormalTopPreviewBottomMenuLessThan(const RefPtr<GeometryNode>& previewGeometryNode,
@ -194,7 +193,6 @@ private:
void LayoutNormalBottomPreviewTopMenuGreateThan(const RefPtr<GeometryNode>& previewGeometryNode,
const RefPtr<GeometryNode>& menuGeometryNode, SizeF& totalSize);
void LayoutOtherDevicePreviewMenu(LayoutWrapper* layoutWrapper);
void LayoutOtherDeviceLeftPreviewRightMenu(const RefPtr<GeometryNode>& previewGeometryNode,
const RefPtr<GeometryNode>& menuGeometryNode, SizeF& totalSize, float menuItemTotalHeight);
void LayoutOtherDeviceLeftPreviewRightMenuLessThan(const RefPtr<GeometryNode>& previewGeometryNode,

View File

@ -94,10 +94,8 @@ constexpr float OFFSET_FIRST = 20.0f;
constexpr float OFFSET_THIRD = 200.0f;
constexpr float OFFSET_FORTH = 300.0f;
constexpr float OFFSET_FIFTH = 50.0f;
constexpr int OFFSET_X_THIRD = 100;
constexpr int OFFSET_Y_THIRD = 20;
constexpr int TOP_LEFT_Y = 18;
constexpr int PLACEMENT_LEFT_BOTTOM_X = 99;
constexpr int PLACEMENT_RIGHT_Y = 29;
const SizeF FULL_SCREEN_SIZE(FULL_SCREEN_WIDTH, FULL_SCREEN_HEIGHT);
constexpr float PREVIEW_HEIGHT = 125.0f;
@ -570,10 +568,10 @@ HWTEST_F(MenuLayout2TestNg, MenuLayoutAlgorithmTestNg4600, TestSize.Level1)
menuAlgorithm->Layout(AceType::RawPtr(menuNode));
auto expectPreviewOffset = OffsetF(OFFSET_THIRD, OFFSET_THIRD + (TARGET_SIZE_HEIGHT - OFFSET_THIRD) / 2);
EXPECT_EQ(previewGeometryNode->GetFrameOffset(), OffsetF(0, 0));
EXPECT_EQ(previewGeometryNode->GetFrameSize(), SizeF(TARGET_SIZE_WIDTH, OFFSET_THIRD));
auto expectMenuOffset = OffsetF(-TARGET_SIZE_WIDTH, -TARGET_SIZE_WIDTH);
EXPECT_EQ(previewGeometryNode->GetFrameSize(), SizeF(0, 0));
auto expectMenuOffset = OffsetF(-TARGET_SIZE_WIDTH, -CONST_DOUBLE_ZREO);
EXPECT_EQ(menuGeometryNode->GetFrameOffset(), expectMenuOffset);
EXPECT_EQ(menuGeometryNode->GetFrameSize(), SizeF(TARGET_SIZE_WIDTH, TARGET_SIZE_WIDTH));
EXPECT_EQ(menuGeometryNode->GetFrameSize(), SizeF(TARGET_SIZE_WIDTH, CONST_DOUBLE_ZREO));
/**
* @tc.steps: step3. the window can accommodate preview, placement is LEFT_TOP, layout preview and menu
* @tc.expected: menu and preview left border distance TARGET_SECURITY, align the menu with the top border of the
@ -643,11 +641,11 @@ HWTEST_F(MenuLayout2TestNg, MenuLayoutAlgorithmTestNg4700, TestSize.Level1)
menuAlgorithm->Layout(AceType::RawPtr(menuNode));
auto expectPreviewOffset = OffsetF(CONST_DOUBLE_ZREO, CONST_DOUBLE_ZREO);
EXPECT_EQ(previewGeometryNode->GetFrameOffset(), expectPreviewOffset);
EXPECT_EQ(previewGeometryNode->GetFrameSize(), SizeF(POSITION_OFFSET, OFFSET_THIRD));
auto expectMenuOffset = OffsetF((OFFSET_X_THIRD - PLACEMENT_LEFT_BOTTOM_X) - OFFSET_THIRD, -POSITION_OFFSET);
EXPECT_EQ(previewGeometryNode->GetFrameSize(), SizeF(-MENU_SIZE_WIDTH_SECOND, -MENU_SIZE_WIDTH_SECOND * 2));
auto expectMenuOffset = OffsetF(-MENU_SIZE_WIDTH_SECOND, CONST_DOUBLE_ZREO);
EXPECT_EQ(menuGeometryNode->GetFrameOffset(), expectMenuOffset);
EXPECT_EQ(menuGeometryNode->GetFrameSize(),
SizeF(OFFSET_THIRD - (OFFSET_X_THIRD - PLACEMENT_LEFT_BOTTOM_X), POSITION_OFFSET));
SizeF(MENU_SIZE_WIDTH_SECOND, CONST_DOUBLE_ZREO));
/**
* @tc.steps: step3. the window can not accommodate preview, placement is RIGHT, layout preview and menu
* @tc.expected: menu and preview bottom right distance TARGET_SECURITY, align the menu with the preview in the
@ -1374,7 +1372,7 @@ HWTEST_F(MenuLayout2TestNg, MenuLayoutAlgorithmTestNg5910, TestSize.Level1)
ASSERT_NE(menuPattern, nullptr);
EXPECT_EQ(menuPattern->GetPreviewBeforeAnimationScale(), scaleOptions.scaleFrom);
EXPECT_EQ(menuPattern->GetPreviewAfterAnimationScale(), scaleOptions.scaleTo);
layoutAlgorithm->LayoutNormalPreviewMenu(&layoutWrapper);
layoutAlgorithm->LayoutPreviewMenu(&layoutWrapper);
EXPECT_EQ(layoutAlgorithm->previewScale_, scaleOptions.scaleTo - 1);
}
@ -1425,7 +1423,7 @@ HWTEST_F(MenuLayout2TestNg, MenuLayoutAlgorithmTestNg5920, TestSize.Level1)
ASSERT_NE(menuPattern, nullptr);
EXPECT_EQ(menuPattern->GetPreviewBeforeAnimationScale(), scaleOptions.scaleFrom);
EXPECT_EQ(menuPattern->GetPreviewAfterAnimationScale(), scaleOptions.scaleTo);
layoutAlgorithm->LayoutNormalPreviewMenu(&layoutWrapper);
layoutAlgorithm->LayoutPreviewMenu(&layoutWrapper);
EXPECT_EQ(layoutAlgorithm->previewScale_, scaleOptions.scaleTo - 1);
}

View File

@ -91,6 +91,7 @@ constexpr double MENU_OFFSET_Y = 10.0;
constexpr float MENU_ITEM_SIZE_WIDTH = 100.0f;
constexpr float MENU_ITEM_SIZE_HEIGHT = 50.0f;
constexpr float GREATER_WINDOW_MENU_HEIGHT = 1190.0f;
constexpr float CONST_FLOAT_ZREO = 0.0f;
constexpr float OFFSET_THIRD = 200.0f;
constexpr int NODEID = 1;
@ -2107,7 +2108,7 @@ HWTEST_F(MenuTestNg, MenuLayoutAlgorithmAvoidWithPreview, TestSize.Level1)
previewGeometryNode->SetFrameSize(SizeF(TARGET_SIZE_WIDTH, TARGET_SIZE_HEIGHT));
menuGeometryNode->SetFrameSize(SizeF(TARGET_SIZE_WIDTH, TARGET_SIZE_HEIGHT));
menuAlgorithm->Layout(AceType::RawPtr(menuNode));
EXPECT_EQ(menuGeometryNode->GetFrameOffset(), OffsetF(-TARGET_SIZE_WIDTH, -TARGET_SIZE_WIDTH));
EXPECT_EQ(menuGeometryNode->GetFrameOffset(), OffsetF(-TARGET_SIZE_WIDTH, CONST_FLOAT_ZREO));
}
/**
* @tc.name: MenuLayoutAlgorithmAdjustMenuTest