diff --git a/frameworks/core/components_ng/pattern/calendar_picker/calendar_picker_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/calendar_picker/calendar_picker_layout_algorithm.cpp index d6de4c4c7e504a8e4b1d4a2e77e94b3e93a4a6be..b0011b3bd40058b603b3ed1f9b22cca2833e883c 100644 --- a/frameworks/core/components_ng/pattern/calendar_picker/calendar_picker_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/calendar_picker/calendar_picker_layout_algorithm.cpp @@ -19,6 +19,87 @@ namespace OHOS::Ace::NG { namespace { constexpr int32_t CHILDREN_SIZE = 5; + +bool IsMatchParent(const RefPtr& layoutProperty, const bool isWidth) +{ + CHECK_NULL_RETURN(layoutProperty, false); + auto layoutPolicyProperty = layoutProperty->GetLayoutPolicyProperty(); + CHECK_NULL_RETURN(layoutPolicyProperty.has_value(), false); + LayoutCalPolicy layoutPolicy = isWidth ? + layoutPolicyProperty.value().widthLayoutPolicy_.value_or(LayoutCalPolicy::NO_MATCH) : + layoutPolicyProperty.value().heightLayoutPolicy_.value_or(LayoutCalPolicy::NO_MATCH); + return layoutPolicy == LayoutCalPolicy::MATCH_PARENT; +} + +void CalculateTotalSize(const RefPtr& theme, const RefPtr& contentWrapper, + const RefPtr& layoutProperty, SizeF& totalSize) +{ + CHECK_NULL_VOID(theme); + CHECK_NULL_VOID(contentWrapper); + CHECK_NULL_VOID(layoutProperty); + auto contentLayoutProperty = contentWrapper->GetLayoutProperty(); + CHECK_NULL_VOID(contentLayoutProperty); + + float totalWidth = 0.0f; + float totalHeight = 0.0f; + for (int32_t i = 0; i < CHILDREN_SIZE; i++) { + auto textWrapper = contentWrapper->GetOrCreateChildByIndex(i); + CHECK_NULL_VOID(textWrapper); + contentLayoutProperty->UpdateContentConstraint(); + textWrapper->Measure(std::nullopt); + auto textGeometryNode = textWrapper->GetGeometryNode(); + CHECK_NULL_VOID(textGeometryNode); + totalWidth += textGeometryNode->GetFrameSize().Width(); + totalHeight = std::max(totalHeight, textGeometryNode->GetFrameSize().Height()); + } + + if (contentLayoutProperty->GetPaddingProperty() != nullptr) { + auto defaultTopMargin = theme->GetEntryDateTopBottomMargin(); + auto defaultLeftMargin = theme->GetEntryDateLeftRightMargin(); + PaddingProperty currentPadding = *(contentLayoutProperty->GetPaddingProperty()); + totalWidth += currentPadding.left.value_or(CalcLength(defaultLeftMargin)).GetDimension().ConvertToPx(); + totalWidth += currentPadding.right.value_or(CalcLength(defaultLeftMargin)).GetDimension().ConvertToPx(); + totalHeight += currentPadding.top.value_or(CalcLength(defaultTopMargin)).GetDimension().ConvertToPx(); + totalHeight += currentPadding.bottom.value_or(CalcLength(defaultTopMargin)).GetDimension().ConvertToPx(); + } + + BorderWidthProperty currentBorderWidth; + if (layoutProperty->GetBorderWidthProperty() != nullptr) { + currentBorderWidth = *(layoutProperty->GetBorderWidthProperty()); + } else { + currentBorderWidth.SetBorderWidth(theme->GetEntryBorderWidth()); + } + totalWidth = totalWidth + currentBorderWidth.leftDimen.value_or(theme->GetEntryBorderWidth()).ConvertToPx() + + currentBorderWidth.rightDimen.value_or(theme->GetEntryBorderWidth()).ConvertToPx(); + totalHeight = totalHeight + currentBorderWidth.topDimen.value_or(theme->GetEntryBorderWidth()).ConvertToPx() + + currentBorderWidth.bottomDimen.value_or(theme->GetEntryBorderWidth()).ConvertToPx(); + + totalWidth += theme->GetEntryButtonWidth().ConvertToPx(); + totalSize = SizeF(totalWidth, totalHeight); +} + +void CalculateContentSize(const RefPtr& theme, + const RefPtr& layoutProperty, const SizeF& totalSize, SizeF& contentMeasure) +{ + CHECK_NULL_VOID(theme); + CHECK_NULL_VOID(layoutProperty); + + BorderWidthProperty currentBorderWidth; + if (layoutProperty->GetBorderWidthProperty() != nullptr) { + currentBorderWidth = *(layoutProperty->GetBorderWidthProperty()); + } else { + currentBorderWidth.SetBorderWidth(theme->GetEntryBorderWidth()); + } + auto contentWidth = totalSize.Width() - theme->GetEntryButtonWidth().ConvertToPx() - + currentBorderWidth.leftDimen.value_or(theme->GetEntryBorderWidth()).ConvertToPx() - + currentBorderWidth.rightDimen.value_or(theme->GetEntryBorderWidth()).ConvertToPx(); + auto contentHeight = totalSize.Height() - + currentBorderWidth.topDimen.value_or(theme->GetEntryBorderWidth()).ConvertToPx() - + currentBorderWidth.bottomDimen.value_or(theme->GetEntryBorderWidth()).ConvertToPx(); + + contentMeasure = SizeF(contentWidth, contentHeight); +} + } // namespace void CalendarPickerLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) { @@ -43,33 +124,13 @@ void CalendarPickerLayoutAlgorithm::CalendarPickerContentMeasure(LayoutWrapper* RefPtr theme = pipelineContext->GetTheme(); CHECK_NULL_VOID(theme); - auto defaultTopMargin = theme->GetEntryDateTopBottomMargin(); - auto defaultLeftMargin = theme->GetEntryDateLeftRightMargin(); - PaddingProperty currentPadding; - if (contentLayoutProperty->GetPaddingProperty() != nullptr) { - currentPadding = *(contentLayoutProperty->GetPaddingProperty()); - } - auto layoutConstraint = layoutWrapper->GetLayoutProperty()->CreateChildConstraint(); for (const auto& child : layoutWrapper->GetAllChildrenWithBuild()) { child->Measure(layoutConstraint); } - float totalWidth = 0.0f; - float height = 0.0f; - for (int32_t i = 0; i < CHILDREN_SIZE; i++) { - auto textWrapper = contentWrapper->GetOrCreateChildByIndex(i); - CHECK_NULL_VOID(textWrapper); - contentLayoutProperty->UpdateContentConstraint(); - textWrapper->Measure(std::nullopt); - auto textGeometryNode = textWrapper->GetGeometryNode(); - CHECK_NULL_VOID(textGeometryNode); - totalWidth += textGeometryNode->GetFrameSize().Width(); - height = std::max(height, textGeometryNode->GetFrameSize().Height()); - } - totalWidth += currentPadding.left.value_or(CalcLength(defaultLeftMargin)).GetDimension().ConvertToPx(); - totalWidth += currentPadding.right.value_or(CalcLength(defaultLeftMargin)).GetDimension().ConvertToPx(); - height += currentPadding.top.value_or(CalcLength(defaultTopMargin)).GetDimension().ConvertToPx(); - height += currentPadding.bottom.value_or(CalcLength(defaultTopMargin)).GetDimension().ConvertToPx(); + + SizeF totalSize = SizeF(0.0f, 0.0f); + CalculateTotalSize(theme, contentWrapper, layoutProperty, totalSize); auto linearLayoutProperty = AceType::DynamicCast(contentLayoutProperty); CHECK_NULL_VOID(linearLayoutProperty); @@ -77,50 +138,34 @@ void CalendarPickerLayoutAlgorithm::CalendarPickerContentMeasure(LayoutWrapper* SizeF policySize = {constraint->selfIdealSize.Width().value_or(0), constraint->selfIdealSize.Height().value_or(0)}; UpdateFrameSizeWithLayoutPolicy(layoutWrapper, policySize); - if (LessNotEqual(totalWidth, policySize.Width() - theme->GetEntryButtonWidth().ConvertToPx())) { - totalWidth = policySize.Width() - theme->GetEntryButtonWidth().ConvertToPx(); + if (LessNotEqual(totalSize.Width(), policySize.Width()) || IsMatchParent(layoutProperty, true)) { + totalSize.SetWidth(policySize.Width()); linearLayoutProperty->UpdateMainAxisAlign(FlexAlign::CENTER); } else { linearLayoutProperty->UpdateMainAxisAlign(FlexAlign::FLEX_START); } - height = std::max(height, policySize.Height()); - contentMeasure_ = SizeF(totalWidth, height); + if (LessNotEqual(totalSize.Height(), policySize.Height()) || IsMatchParent(layoutProperty, false)) { + totalSize.SetHeight(policySize.Height()); + } + + CalculateContentSize(theme, layoutProperty, totalSize, contentMeasure_); contentGeometryNode->SetFrameSize(contentMeasure_); + + auto geometryNode = layoutWrapper->GetGeometryNode(); + CHECK_NULL_VOID(geometryNode); + geometryNode->SetFrameSize(SizeF(totalSize.Width(), totalSize.Height())); } void CalendarPickerLayoutAlgorithm::SelfMeasure(LayoutWrapper* layoutWrapper) { auto layoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); CHECK_NULL_VOID(layoutProperty); - auto geometryNode = layoutWrapper->GetGeometryNode(); - CHECK_NULL_VOID(geometryNode); auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck(); CHECK_NULL_VOID(pipelineContext); RefPtr theme = pipelineContext->GetTheme(); CHECK_NULL_VOID(theme); - BorderWidthProperty currentBorderWidth; - if (layoutProperty->GetBorderWidthProperty() != nullptr) { - currentBorderWidth = *(layoutProperty->GetBorderWidthProperty()); - } else { - currentBorderWidth.SetBorderWidth(theme->GetEntryBorderWidth()); - } - - auto width = contentMeasure_.Width() + theme->GetEntryButtonWidth().ConvertToPx(); - width += currentBorderWidth.topDimen.value_or(theme->GetEntryBorderWidth()).ConvertToPx(); - width += currentBorderWidth.bottomDimen.value_or(theme->GetEntryBorderWidth()).ConvertToPx(); - auto height = contentMeasure_.Height(); - - if (layoutProperty->HasAspectRatio() && layoutProperty->GetAspectRatio() != 0) { - height = width / layoutProperty->GetAspectRatio(); - } else { - height += currentBorderWidth.leftDimen.value_or(theme->GetEntryBorderWidth()).ConvertToPx(); - height += currentBorderWidth.rightDimen.value_or(theme->GetEntryBorderWidth()).ConvertToPx(); - } - SizeF idealSize(width, height); - geometryNode->SetFrameSize(idealSize); - auto flexWrapper = layoutWrapper->GetOrCreateChildByIndex(1); CHECK_NULL_VOID(flexWrapper); auto flexLayoutProperty = AceType::DynamicCast(flexWrapper->GetLayoutProperty()); @@ -128,13 +173,12 @@ void CalendarPickerLayoutAlgorithm::SelfMeasure(LayoutWrapper* layoutWrapper) auto flexGeometryNode = flexWrapper->GetGeometryNode(); CHECK_NULL_VOID(flexGeometryNode); - auto flexHeight = height - currentBorderWidth.leftDimen.value_or(theme->GetEntryBorderWidth()).ConvertToPx(); - flexHeight -= currentBorderWidth.rightDimen.value_or(theme->GetEntryBorderWidth()).ConvertToPx(); - CalcSize flexCalcSize((CalcLength(theme->GetEntryButtonWidth().ConvertToPx())), CalcLength(flexHeight)); - flexLayoutProperty->UpdateUserDefinedIdealSize(flexCalcSize); + auto flexHeight = contentMeasure_.Height(); + auto flexWidth = theme->GetEntryButtonWidth().ConvertToPx(); + flexLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(flexWidth), CalcLength(flexHeight))); auto flexLayoutConstraint = layoutProperty->CreateChildConstraint(); flexWrapper->Measure(flexLayoutConstraint); - flexMeasure_ = SizeF(theme->GetEntryButtonWidth().ConvertToPx(), flexHeight); + flexMeasure_ = SizeF(flexWidth, flexHeight); flexGeometryNode->SetFrameSize(flexMeasure_); for (int32_t i = 0; i < flexWrapper->GetTotalChildCount(); i++) { @@ -142,7 +186,7 @@ void CalendarPickerLayoutAlgorithm::SelfMeasure(LayoutWrapper* layoutWrapper) CHECK_NULL_VOID(child); auto childGeometryNode = child->GetGeometryNode(); CHECK_NULL_VOID(childGeometryNode); - SizeF childMeasure = SizeF(theme->GetEntryButtonWidth().ConvertToPx(), flexHeight / 2); + SizeF childMeasure = SizeF(flexWidth, flexHeight / 2); childGeometryNode->SetFrameSize(childMeasure); } } diff --git a/test/unittest/core/pattern/calendar_picker/calendar_picker_layout_algorithm_test.cpp b/test/unittest/core/pattern/calendar_picker/calendar_picker_layout_algorithm_test.cpp index 328db1d7211dd2d454141a5b5ebebf0ff5ac9d76..9d40abc472775fc62e767626d4619da174d1d59b 100644 --- a/test/unittest/core/pattern/calendar_picker/calendar_picker_layout_algorithm_test.cpp +++ b/test/unittest/core/pattern/calendar_picker/calendar_picker_layout_algorithm_test.cpp @@ -43,6 +43,7 @@ namespace { const SizeF CONTAINER_SIZE(720.0f, 1136.f); const SizeF PARENT_IDEAL_SIZE(720.0f, 1136.f); const SizeF SELF_IDEAL_SIZE(600.0f, 1000.f); +const Dimension ENTRY_BUTTON_WIDTH = Dimension(100.0, DimensionUnit::PX); } // namespace class CalendarPickerLayoutAlgorithmTest : public testing::Test { @@ -625,4 +626,42 @@ HWTEST_F(CalendarPickerLayoutAlgorithmTest, CalendarPickerContentMeasure002, Tes EXPECT_EQ(geometryFrameSize, PARENT_IDEAL_SIZE); } +/** + * @tc.name: SelfMeasure001 + * @tc.desc: Test SelfMeasure Function. + * @tc.type: FUNC + */ +HWTEST_F(CalendarPickerLayoutAlgorithmTest, SelfMeasure001, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create CalendarPicker. + */ + CreateCalendarPicker(); + ASSERT_NE(frameNode_, nullptr); + + /** + * @tc.steps: step2. Get CalendarPicker layout algorithm. + */ + GetCalendarPickerLayoutAlgorithm(); + ASSERT_NE(calendarPickerLayoutAlgorithm_, nullptr); + + /** + * @tc.steps: step3. Set entryButtonWidth_ and contentMeasure_. + */ + auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck(); + CHECK_NULL_VOID(pipelineContext); + RefPtr theme = pipelineContext->GetTheme(); + CHECK_NULL_VOID(theme); + + theme->entryButtonWidth_ = ENTRY_BUTTON_WIDTH; + calendarPickerLayoutAlgorithm_->contentMeasure_ = CONTAINER_SIZE; + + /** + * @tc.steps: step4. Call SelfMeasure function. + */ + calendarPickerLayoutAlgorithm_->SelfMeasure(AceType::RawPtr(layoutWrapper_)); + EXPECT_EQ(calendarPickerLayoutAlgorithm_->flexMeasure_.Width(), ENTRY_BUTTON_WIDTH.Value()); + EXPECT_EQ(calendarPickerLayoutAlgorithm_->flexMeasure_.Height(), CONTAINER_SIZE.Height()); +} + } // namespace OHOS::Ace::NG