diff --git a/frameworks/core/components_ng/pattern/data_panel/data_panel_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/data_panel/data_panel_layout_algorithm.cpp index 4f5f80f2e05e986678cf7f52b84c93a0e8b736ac..b5ca328cd6a402f29529191bb617195cbb8a7925 100644 --- a/frameworks/core/components_ng/pattern/data_panel/data_panel_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/data_panel/data_panel_layout_algorithm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -26,22 +26,54 @@ void DataPanelLayoutAlgorithm::OnReset() {} std::optional DataPanelLayoutAlgorithm::MeasureContent( const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper) { + LOGD("Layout constraint is %{public}s", contentConstraint.ToString().c_str()); + + // 1.If user set the width and height, use the selfIdealSize. if (contentConstraint.selfIdealSize.IsValid()) { return contentConstraint.selfIdealSize.ConvertToSizeT(); } + + auto width = contentConstraint.percentReference.Width(); + auto height = contentConstraint.percentReference.Height(); + bool infWidth = GreaterOrEqualToInfinity(width); + bool infHeight = GreaterOrEqualToInfinity(height); + + // 2.If user set width only, use selfWidth and height of maxSize. + // If the height is infinite, set the min of selfWidth and infinite. if (contentConstraint.selfIdealSize.Width().has_value() && NonNegative(contentConstraint.selfIdealSize.Width().value())) { - auto width = contentConstraint.selfIdealSize.Width().value(); - auto height = contentConstraint.maxSize.Height(); - return SizeF(width, height); + auto selfWidth = contentConstraint.selfIdealSize.Width().value(); + if (infHeight) { + height = std::min(selfWidth, height); + } + return SizeF(selfWidth, height); } + + // 3.If user set height only, use selfHeight and width of maxSize. + // If the width is infinite, set the min of selfHeight and infinite. if (contentConstraint.selfIdealSize.Height().has_value() && NonNegative(contentConstraint.selfIdealSize.Height().value())) { - auto width = contentConstraint.maxSize.Width(); - auto height = contentConstraint.selfIdealSize.Height().value(); - return SizeF(width, height); + auto selfHeight = contentConstraint.selfIdealSize.Height().value(); + if (infWidth) { + width = std::min(width, selfHeight); + } + return SizeF(width, selfHeight); } - return contentConstraint.maxSize; + + // 4.If width and height are both infinite, use the root size as constraint. + if (infWidth && infHeight) { + auto minSize = std::min(PipelineContext::GetCurrentRootWidth(), PipelineContext::GetCurrentRootHeight()); + return SizeF(minSize, minSize); + } + + // 5.If the width or height is infinite, use the min of them as the constraint. + if (infWidth || infHeight) { + auto minSize = std::min(width, height); + return SizeF(minSize, minSize); + } + + // 6.Otherwise use the maxSize + return contentConstraint.percentReference; } } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/test/pattern/data_panel/data_panel_test_ng.cpp b/frameworks/core/components_ng/test/pattern/data_panel/data_panel_test_ng.cpp index 535c5024c54c8f61e033e4b804126f1d9223928f..823e5a950fb8e4c5c0a61b5d565748c0b3adda9c 100644 --- a/frameworks/core/components_ng/test/pattern/data_panel/data_panel_test_ng.cpp +++ b/frameworks/core/components_ng/test/pattern/data_panel/data_panel_test_ng.cpp @@ -44,6 +44,11 @@ constexpr Dimension HEIGHT = 50.0_vp; constexpr float MAX_WIDTH = 400.0f; constexpr float MAX_HEIGHT = 400.0f; const SizeF MAX_SIZE(MAX_WIDTH, MAX_HEIGHT); +constexpr float MAX_PERCENT_WIDTH = 200.0f; +constexpr float MAX_PERCENT_HEIGHT = 200.0f; +const SizeF MAX_PERCENT_SIZE(MAX_PERCENT_WIDTH, MAX_PERCENT_HEIGHT); +constexpr float MAX_INFINITE = 1000000.0f; +const SizeF MAX_INFINITE_SIZE(MAX_INFINITE, MAX_INFINITE); constexpr float NEGATIVE_NUMBER = -100; constexpr bool SKIP_MEASURE = true; constexpr bool NO_SKIP_MEASURE = false; @@ -66,6 +71,8 @@ constexpr float SPACEWIDTH = 5.0f; constexpr bool USE_EFFECT = false; constexpr bool USE_ANIMATOR = false; constexpr float PERCENT = 1.0f; +constexpr float ROOT_WIDTH = 1000.0f; +constexpr float ROOT_HEIGHT = 1000.0f; } // namespace class DataPanelTestNg : public testing::Test { @@ -224,6 +231,7 @@ HWTEST_F(DataPanelTestNg, DataPanelMeasureTest003, TestSize.Level1) */ LayoutConstraintF layoutConstraint; layoutConstraint.maxSize = MAX_SIZE; + layoutConstraint.percentReference = MAX_SIZE; auto dataPanelDefaultSize = dataPanelLayoutAlgorithm->MeasureContent(layoutConstraint, &layoutWrapper).value(); EXPECT_EQ(dataPanelDefaultSize, MAX_SIZE); @@ -233,18 +241,21 @@ HWTEST_F(DataPanelTestNg, DataPanelMeasureTest003, TestSize.Level1) */ LayoutConstraintF layoutConstraintVaildSize; layoutConstraintVaildSize.maxSize = MAX_SIZE; + layoutConstraint.percentReference = MAX_SIZE; layoutConstraintVaildSize.selfIdealSize.SetSize(SizeF(WIDTH.ConvertToPx(), HEIGHT.ConvertToPx())); auto dataPanelSize = dataPanelLayoutAlgorithm->MeasureContent(layoutConstraintVaildSize, &layoutWrapper).value(); EXPECT_EQ(dataPanelSize, SizeF(WIDTH.ConvertToPx(), HEIGHT.ConvertToPx())); LayoutConstraintF layoutConstraintHeight; layoutConstraintHeight.maxSize = MAX_SIZE; + layoutConstraintHeight.percentReference = MAX_SIZE; layoutConstraintHeight.selfIdealSize.SetHeight(HEIGHT.ConvertToPx()); dataPanelSize = dataPanelLayoutAlgorithm->MeasureContent(layoutConstraintHeight, &layoutWrapper).value(); EXPECT_EQ(dataPanelSize, SizeF(MAX_WIDTH, HEIGHT.ConvertToPx())); LayoutConstraintF layoutConstraintWidth; layoutConstraintWidth.maxSize = MAX_SIZE; + layoutConstraintWidth.percentReference = MAX_SIZE; layoutConstraintWidth.selfIdealSize.SetWidth(WIDTH.ConvertToPx()); dataPanelSize = dataPanelLayoutAlgorithm->MeasureContent(layoutConstraintWidth, &layoutWrapper).value(); EXPECT_EQ(dataPanelSize, SizeF(WIDTH.ConvertToPx(), MAX_HEIGHT)); @@ -254,7 +265,7 @@ HWTEST_F(DataPanelTestNg, DataPanelMeasureTest003, TestSize.Level1) * DataPanel({ { values: this.values, max: 100, type: DataPanelType.Line }}).height(-100) */ LayoutConstraintF layoutConstraintHeightUnvalid; - layoutConstraintHeightUnvalid.maxSize = MAX_SIZE; + layoutConstraintHeightUnvalid.percentReference = MAX_SIZE; layoutConstraintHeightUnvalid.selfIdealSize.SetHeight(NEGATIVE_NUMBER); dataPanelSize = dataPanelLayoutAlgorithm->MeasureContent(layoutConstraintHeightUnvalid, &layoutWrapper).value(); EXPECT_EQ(dataPanelSize, SizeF(MAX_WIDTH, MAX_HEIGHT)); @@ -264,12 +275,108 @@ HWTEST_F(DataPanelTestNg, DataPanelMeasureTest003, TestSize.Level1) * DataPanel({ { values: this.values, max: 100, type: DataPanelType.Line }}).width(-100) */ LayoutConstraintF layoutConstraintWidthUnvalid; - layoutConstraintWidthUnvalid.maxSize = MAX_SIZE; + layoutConstraintWidthUnvalid.percentReference = MAX_SIZE; layoutConstraintWidthUnvalid.selfIdealSize.SetWidth(NEGATIVE_NUMBER); dataPanelSize = dataPanelLayoutAlgorithm->MeasureContent(layoutConstraintHeightUnvalid, &layoutWrapper).value(); EXPECT_EQ(dataPanelSize, SizeF(MAX_WIDTH, MAX_HEIGHT)); } +/** + * @tc.name: DataPanelMeasureTest004 + * @tc.desc: Test DataPanel Measure by percentReference instead of maxSize. + * @tc.type: FUNC + */ +HWTEST_F(DataPanelTestNg, DataPanelMeasureTest004, TestSize.Level1) +{ + /** + * @tc.steps: step1. create datapanel and get framenode. + */ + DataPanelModelNG dataPanel; + dataPanel.Create(VALUES, MAX, TYPE_CYCLE); + dataPanel.SetEffect(!CLOSE_EFFECT); + auto frameNode = AceType::DynamicCast(ViewStackProcessor::GetInstance()->Finish()); + EXPECT_NE(frameNode, nullptr); + + /** + * @tc.steps: step2. Create LayoutWrapper and set dataPanelLayoutAlgorithm. + */ + RefPtr geometryNode = AceType::MakeRefPtr(); + EXPECT_NE(geometryNode, nullptr); + LayoutWrapper layoutWrapper = LayoutWrapper(frameNode, geometryNode, frameNode->GetLayoutProperty()); + auto dataPanelPattern = frameNode->GetPattern(); + EXPECT_NE(dataPanelPattern, nullptr); + auto dataPanelLayoutAlgorithm = dataPanelPattern->CreateLayoutAlgorithm(); + EXPECT_NE(dataPanelLayoutAlgorithm, nullptr); + dataPanelLayoutAlgorithm->Reset(); + layoutWrapper.SetLayoutAlgorithm(AceType::MakeRefPtr(dataPanelLayoutAlgorithm)); + + /** + * @tc.steps: step3. compare dataPanelSize with expected value. + * @tc.expected: step3. dataPanelSize is the same with expected value. + */ + /** + * corresponding ets code: + * DataPanel({ { values: this.values, max: 100, type: DataPanelType.Line }}) + */ + LayoutConstraintF layoutConstraint; + layoutConstraint.maxSize = MAX_SIZE; + layoutConstraint.percentReference = MAX_PERCENT_SIZE; + auto dataPanelDefaultSize = dataPanelLayoutAlgorithm->MeasureContent(layoutConstraint, &layoutWrapper).value(); + EXPECT_EQ(dataPanelDefaultSize, MAX_PERCENT_SIZE); + + /** + * corresponding ets code: + * DataPanel({ { values: this.values, max: 100, type: DataPanelType.Line }}).width(50).height(50) + */ + LayoutConstraintF layoutConstraintVaildSize; + layoutConstraintVaildSize.maxSize = MAX_SIZE; + layoutConstraint.percentReference = MAX_PERCENT_SIZE; + layoutConstraintVaildSize.selfIdealSize.SetSize(SizeF(WIDTH.ConvertToPx(), HEIGHT.ConvertToPx())); + auto dataPanelSize = dataPanelLayoutAlgorithm->MeasureContent(layoutConstraintVaildSize, &layoutWrapper).value(); + EXPECT_EQ(dataPanelSize, SizeF(WIDTH.ConvertToPx(), HEIGHT.ConvertToPx())); + + /** + * @tc.steps: step4. compare dataPanelSize with expected value. + * @tc.expected: step4. dataPanelSize is the same with expected value. + */ + LayoutConstraintF layoutConstraintHeight; + layoutConstraintHeight.maxSize = MAX_SIZE; + layoutConstraintHeight.percentReference = MAX_PERCENT_SIZE; + layoutConstraintHeight.selfIdealSize.SetHeight(HEIGHT.ConvertToPx()); + dataPanelSize = dataPanelLayoutAlgorithm->MeasureContent(layoutConstraintHeight, &layoutWrapper).value(); + EXPECT_EQ(dataPanelSize, SizeF(MAX_PERCENT_WIDTH, HEIGHT.ConvertToPx())); + + /** + * @tc.steps: step5. compare dataPanelSize with expected value. + * @tc.expected: step5. dataPanelSize is the same with expected value. + */ + LayoutConstraintF layoutConstraintWidth; + layoutConstraintWidth.maxSize = MAX_SIZE; + layoutConstraintWidth.percentReference = MAX_PERCENT_SIZE; + layoutConstraintWidth.selfIdealSize.SetWidth(WIDTH.ConvertToPx()); + dataPanelSize = dataPanelLayoutAlgorithm->MeasureContent(layoutConstraintWidth, &layoutWrapper).value(); + EXPECT_EQ(dataPanelSize, SizeF(WIDTH.ConvertToPx(), MAX_PERCENT_HEIGHT)); + + /** + * @tc.steps: step6. compare dataPanelSize with expected value by infinite. + * @tc.expected: step6. dataPanelSize is the same with expected value as root width and height. + */ + MockPipelineBase::GetCurrent()->SetRootSize(ROOT_WIDTH, ROOT_HEIGHT); + LayoutConstraintF layoutConstraintInfinite; + layoutConstraintInfinite.percentReference = MAX_INFINITE_SIZE; + dataPanelSize = dataPanelLayoutAlgorithm->MeasureContent(layoutConstraintInfinite, &layoutWrapper).value(); + EXPECT_EQ(dataPanelSize, SizeF(ROOT_WIDTH, ROOT_HEIGHT)); + + /** + * @tc.steps: step7. compare dataPanelSize with expected value by infinite width. + * @tc.expected: step7. dataPanelSize is the same with expected value as min width and height. + */ + LayoutConstraintF layoutConstraintWidthInfinite; + layoutConstraintWidthInfinite.percentReference = SizeF(MAX_INFINITE, MAX_HEIGHT); + dataPanelSize = dataPanelLayoutAlgorithm->MeasureContent(layoutConstraintWidthInfinite, &layoutWrapper).value(); + EXPECT_EQ(dataPanelSize, SizeF(MAX_HEIGHT, MAX_HEIGHT)); +} + /** * @tc.name: DataPanelPatternTest004 * @tc.desc: Test DataPanel isAtomicNode @@ -390,6 +497,7 @@ HWTEST_F(DataPanelTestNg, DataPanelPatternTest007, TestSize.Level1) */ LayoutConstraintF layoutConstraint; layoutConstraint.maxSize = MAX_SIZE; + layoutConstraint.percentReference = MAX_SIZE; auto dataPanelDefaultSize = dataPanelLayoutAlgorithm->MeasureContent(layoutConstraint, &layoutWrapper).value(); EXPECT_EQ(dataPanelDefaultSize, MAX_SIZE); }