diff --git a/frameworks/core/components_ng/pattern/relative_container/relative_container_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/relative_container/relative_container_layout_algorithm.cpp index 65e2e6363f30f9af2e6d3bc242fbf68950d0e568..3fcb95db79ecc9d504b0dc9c84f01f208aeda4c8 100644 --- a/frameworks/core/components_ng/pattern/relative_container/relative_container_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/relative_container/relative_container_layout_algorithm.cpp @@ -133,11 +133,11 @@ void RelativeContainerLayoutAlgorithm::UpdateSizeWhenChildrenEmpty(LayoutWrapper CHECK_NULL_VOID(calcLayoutConstraint); auto selfIdealSize = calcLayoutConstraint->selfIdealSize; padding_ = relativeContainerLayoutProperty->CreatePaddingAndBorder(); - if (selfIdealSize->Width()->GetDimension().Unit() == DimensionUnit::AUTO) { + if (selfIdealSize->IsWidthDimensionUnitAuto()) { layoutWrapper->GetGeometryNode()->SetFrameSize( SizeF(padding_.Width(), layoutWrapper->GetGeometryNode()->GetFrameSize().Height())); } - if (selfIdealSize->Height()->GetDimension().Unit() == DimensionUnit::AUTO) { + if (selfIdealSize->IsHeightDimensionUnitAuto()) { layoutWrapper->GetGeometryNode()->SetFrameSize( SizeF(layoutWrapper->GetGeometryNode()->GetFrameSize().Width(), padding_.Height())); } @@ -147,7 +147,7 @@ void RelativeContainerLayoutAlgorithm::CalcHorizontalGuideline( std::optional& selfIdealSize, float containerHeight, const GuidelineInfo& guidelineInfo) { ScaleProperty scaleProperty = ScaleProperty::CreateScaleProperty(); - bool heightAuto = (selfIdealSize->Height()->GetDimension().Unit() == DimensionUnit::AUTO); + bool heightAuto = selfIdealSize->IsHeightDimensionUnitAuto(); if (guidelineInfo.start.has_value()) { if ((guidelineInfo.start.value().Unit() == DimensionUnit::PERCENT) && heightAuto) { guidelines_[guidelineInfo.id] = std::make_pair(LineDirection::HORIZONTAL, 0.0f); @@ -170,7 +170,7 @@ void RelativeContainerLayoutAlgorithm::CalcVerticalGuideline( std::optional& selfIdealSize, float containerWidth, const GuidelineInfo& guidelineInfo) { ScaleProperty scaleProperty = ScaleProperty::CreateScaleProperty(); - bool widthAuto = (selfIdealSize->Width()->GetDimension().Unit() == DimensionUnit::AUTO); + bool widthAuto = selfIdealSize->IsWidthDimensionUnitAuto(); if (guidelineInfo.start.has_value()) { if ((guidelineInfo.start.value().Unit() == DimensionUnit::PERCENT) && widthAuto) { guidelines_[guidelineInfo.id] = std::make_pair(LineDirection::VERTICAL, 0.0f); @@ -586,7 +586,7 @@ bool RelativeContainerLayoutAlgorithm::IsNodeInVerticalChain(const std::string& float RelativeContainerLayoutAlgorithm::GetHorizontalAnchorValueByAlignRule(AlignRule& alignRule) { - if (IsGuideline(alignRule.anchor) || IsBarrier(alignRule.anchor)) { + if (IsGuidelineOrBarrier(alignRule.anchor)) { return recordOffsetMap_[alignRule.anchor].GetX(); } bool anchorIsContainer = IsAnchorContainer(alignRule.anchor); @@ -628,7 +628,7 @@ float RelativeContainerLayoutAlgorithm::GetHorizontalAnchorValueByAlignRule(Alig float RelativeContainerLayoutAlgorithm::GetVerticalAnchorValueByAlignRule(AlignRule& alignRule) { - if (IsGuideline(alignRule.anchor) || IsBarrier(alignRule.anchor)) { + if (IsGuidelineOrBarrier(alignRule.anchor)) { return recordOffsetMap_[alignRule.anchor].GetY(); } bool anchorIsContainer = IsAnchorContainer(alignRule.anchor); @@ -803,16 +803,7 @@ void RelativeContainerLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) } MeasureChild(layoutWrapper); - const auto& calcLayoutConstraint = relativeContainerLayoutProperty->GetCalcLayoutConstraint(); - CHECK_NULL_VOID(calcLayoutConstraint); - auto selfIdealSize = calcLayoutConstraint->selfIdealSize; - CHECK_NULL_VOID(selfIdealSize.has_value()); - if ((selfIdealSize.value().Width().has_value() && - selfIdealSize.value().Width().value().GetDimension().Unit() == DimensionUnit::AUTO) || - (selfIdealSize.value().Height().has_value() && - selfIdealSize.value().Height().value().GetDimension().Unit() == DimensionUnit::AUTO)) { - MeasureSelf(layoutWrapper); - } + MeasureSelf(layoutWrapper); AdjustOffsetRtl(layoutWrapper); } @@ -863,8 +854,12 @@ void RelativeContainerLayoutAlgorithm::MeasureSelf(LayoutWrapper* layoutWrapper) CHECK_NULL_VOID(layoutWrapper); auto relativeContainerLayoutProperty = layoutWrapper->GetLayoutProperty(); CHECK_NULL_VOID(relativeContainerLayoutProperty); + const auto& calcLayoutConstraint = relativeContainerLayoutProperty->GetCalcLayoutConstraint(); + CHECK_NULL_VOID(calcLayoutConstraint); + auto selfIdealSize = calcLayoutConstraint->selfIdealSize; + CHECK_NULL_VOID(selfIdealSize.has_value()); + CHECK_NULL_VOID(selfIdealSize->IsDimensionUnitAuto()); RectF relativeContainerRect(0, 0, 0, 0); - auto selfIdealSize = relativeContainerLayoutProperty->GetCalcLayoutConstraint()->selfIdealSize; for (const auto& nodeName : renderList_) { auto it = idNodeMap_.find(nodeName); if (it == idNodeMap_.end()) { @@ -882,11 +877,11 @@ void RelativeContainerLayoutAlgorithm::MeasureSelf(LayoutWrapper* layoutWrapper) relativeContainerRect = relativeContainerRect.IntersectRectT(RectF(0.0f, 0.0f, Infinity(), Infinity())); - if (selfIdealSize->Width()->GetDimension().Unit() == DimensionUnit::AUTO && !isHorizontalRelyOnContainer_) { + if (selfIdealSize->IsWidthDimensionUnitAuto() && !isHorizontalRelyOnContainer_) { layoutWrapper->GetGeometryNode()->SetFrameSize(SizeF(relativeContainerRect.Width() + padding_.Width(), layoutWrapper->GetGeometryNode()->GetFrameSize().Height())); } - if (selfIdealSize->Height()->GetDimension().Unit() == DimensionUnit::AUTO && !isVerticalRelyOnContainer_) { + if (selfIdealSize->IsHeightDimensionUnitAuto() && !isVerticalRelyOnContainer_) { layoutWrapper->GetGeometryNode()->SetFrameSize(SizeF(layoutWrapper->GetGeometryNode()->GetFrameSize().Width(), relativeContainerRect.Height() + padding_.Height())); } @@ -1601,6 +1596,18 @@ float RelativeContainerLayoutAlgorithm::CalcHorizontalOffsetAlignRight( return offsetX; } +bool RelativeContainerLayoutAlgorithm::IsGuidelineOrBarrier(const std::string& id) +{ + return IsGuideline(id) || IsBarrier(id); +} + +std::optional RelativeContainerLayoutAlgorithm::GetOriginMarginLeft( + TextDirection textDirection, const std::unique_ptr& marginProp) +{ + CHECK_NULL_RETURN(marginProp, 0); + return textDirection != TextDirection::RTL ? marginProp->left:marginProp->right; +} + float RelativeContainerLayoutAlgorithm::CalcHorizontalOffset( AlignDirection alignDirection, const AlignRule& alignRule, float containerWidth, const std::string& nodeName) { @@ -1609,26 +1616,12 @@ float RelativeContainerLayoutAlgorithm::CalcHorizontalOffset( auto childWrapper = idNodeMap_[nodeName].layoutWrapper; bool anchorIsContainer = IsAnchorContainer(alignRule.anchor); float flexItemWidth = childWrapper->GetGeometryNode()->GetMarginFrameSize().Width(); - float anchorWidth; - if (!versionGreatorOrEqualToEleven_) { - anchorWidth = anchorIsContainer - ? containerWidth - : idNodeMap_[alignRule.anchor].layoutWrapper->GetGeometryNode()->GetMarginFrameSize().Width(); - } else { - if (IsGuideline(alignRule.anchor) || IsBarrier(alignRule.anchor)) { - anchorWidth = 0; - } else if (anchorIsContainer) { - anchorWidth = containerWidth; - } else { - anchorWidth = idNodeMap_[alignRule.anchor].layoutWrapper->GetGeometryNode()->GetFrameSize().Width(); - } - } + float anchorWidth = CalcAnchorWidth(anchorIsContainer, containerWidth, alignRule.anchor); std::optional marginLeft; - if (!anchorIsContainer && !IsGuideline(alignRule.anchor) && !IsBarrier(alignRule.anchor)) { + if (!anchorIsContainer && !IsGuidelineOrBarrier(alignRule.anchor)) { auto anchorWrapper = idNodeMap_[alignRule.anchor].layoutWrapper; - if (anchorWrapper->GetGeometryNode()->GetMargin()) { - marginLeft = anchorWrapper->GetGeometryNode()->GetMargin()->left; - } + auto textDirection = anchorWrapper->GetLayoutProperty()->GetNonAutoLayoutDirection(); + marginLeft = GetOriginMarginLeft(textDirection, anchorWrapper->GetGeometryNode()->GetMargin()); } switch (alignDirection) { case AlignDirection::LEFT: @@ -1652,6 +1645,22 @@ float RelativeContainerLayoutAlgorithm::CalcHorizontalOffset( return offsetX; } +float RelativeContainerLayoutAlgorithm::CalcAnchorWidth( + bool anchorIsContainer, float& containerWidth, const std::string& anchor) +{ + if (!versionGreatorOrEqualToEleven_) { + return anchorIsContainer + ? containerWidth + : idNodeMap_[anchor].layoutWrapper->GetGeometryNode()->GetMarginFrameSize().Width(); + } + if (IsGuidelineOrBarrier(anchor)) { + return 0; + } else if (anchorIsContainer) { + return containerWidth; + } + return idNodeMap_[anchor].layoutWrapper->GetGeometryNode()->GetFrameSize().Width(); +} + float RelativeContainerLayoutAlgorithm::CalcVerticalOffsetAlignTop(const VerticalAlign& alignRule, float& anchorHeight) { float offsetY = 0.0f; @@ -1726,7 +1735,7 @@ float RelativeContainerLayoutAlgorithm::CalcVerticalOffset( ? containerHeight : idNodeMap_[alignRule.anchor].layoutWrapper->GetGeometryNode()->GetMarginFrameSize().Height(); } else { - if (IsGuideline(alignRule.anchor) || IsBarrier(alignRule.anchor)) { + if (IsGuidelineOrBarrier(alignRule.anchor)) { anchorHeight = 0; } else if (anchorIsContainer) { anchorHeight = containerHeight; @@ -1735,7 +1744,7 @@ float RelativeContainerLayoutAlgorithm::CalcVerticalOffset( } } std::optional marginTop; - if (!anchorIsContainer && !IsGuideline(alignRule.anchor) && !IsBarrier(alignRule.anchor)) { + if (!anchorIsContainer && !IsGuidelineOrBarrier(alignRule.anchor)) { auto anchorWrapper = idNodeMap_[alignRule.anchor].layoutWrapper; if (anchorWrapper->GetGeometryNode()->GetMargin()) { marginTop = anchorWrapper->GetGeometryNode()->GetMargin()->top; @@ -1764,7 +1773,7 @@ float RelativeContainerLayoutAlgorithm::CalcVerticalOffset( bool RelativeContainerLayoutAlgorithm::IsAnchorLegal(const std::string& anchorName) { - if (!IsAnchorContainer(anchorName) && !IsGuideline(anchorName) && !IsBarrier(anchorName) && + if (!IsAnchorContainer(anchorName) && !IsGuidelineOrBarrier(anchorName) && idNodeMap_.find(anchorName) == idNodeMap_.end()) { return false; } diff --git a/frameworks/core/components_ng/pattern/relative_container/relative_container_layout_algorithm.h b/frameworks/core/components_ng/pattern/relative_container/relative_container_layout_algorithm.h index fdc0ef681ae4b3d76c779e5670e721f66e41578d..af77f1e8f73431d8b3339d441eb4cad0d88e3640 100644 --- a/frameworks/core/components_ng/pattern/relative_container/relative_container_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/relative_container/relative_container_layout_algorithm.h @@ -85,6 +85,9 @@ private: void CalcBarrier(LayoutWrapper* layoutWrapper); bool IsGuideline(const std::string& id); bool IsBarrier(const std::string& id); + bool IsGuidelineOrBarrier(const std::string& id); + std::optional GetOriginMarginLeft( + TextDirection textDirection, const std::unique_ptr& marginProp); BarrierRect GetBarrierRectByReferencedIds(const std::vector& referencedIds); void MeasureBarrier(const std::string& barrierName); void CheckNodeInHorizontalChain(std::string& currentNode, std::string& nextNode, @@ -118,6 +121,7 @@ private: float CalcHorizontalOffsetAlignRight(const HorizontalAlign& alignRule, float& anchorWidth, float& flexItemWidth); float CalcHorizontalOffset( AlignDirection alignDirection, const AlignRule& alignRule, float containerWidth, const std::string& nodeName); + float CalcAnchorWidth(bool anchorIsContainer, float& containerWidth, const std::string& anchor); float CalcVerticalOffsetAlignTop(const VerticalAlign& alignRule, float& anchorHeight); float CalcVerticalOffsetAlignCenter(const VerticalAlign& alignRule, float& anchorHeight, float& flexItemHeight); float CalcVerticalOffsetAlignBottom(const VerticalAlign& alignRule, float& anchorHeight, float& flexItemHeight); diff --git a/frameworks/core/components_ng/property/measure_property.h b/frameworks/core/components_ng/property/measure_property.h index 94c2a476f78b197768318ad918b6ce88cc2833df..4a53e8041179ccef9804491357145010da038d0c 100644 --- a/frameworks/core/components_ng/property/measure_property.h +++ b/frameworks/core/components_ng/property/measure_property.h @@ -63,6 +63,21 @@ public: height_->GetDimension().Unit() != DimensionUnit::AUTO); } + bool IsDimensionUnitAuto() const + { + return IsWidthDimensionUnitAuto() || IsHeightDimensionUnitAuto(); + } + + bool IsWidthDimensionUnitAuto() const + { + return width_ && width_->GetDimension().Unit() == DimensionUnit::AUTO; + } + + bool IsHeightDimensionUnitAuto() const + { + return height_ && height_->GetDimension().Unit() == DimensionUnit::AUTO; + } + const std::optional& Width() const { return width_;