diff --git a/frameworks/core/components_ng/base/frame_node.cpp b/frameworks/core/components_ng/base/frame_node.cpp index 239a389a61015ec3bfd524edfcf7a5a7f17cf939..af5de1539315bbae9725df67dc63edeaf892ad2d 100644 --- a/frameworks/core/components_ng/base/frame_node.cpp +++ b/frameworks/core/components_ng/base/frame_node.cpp @@ -2201,6 +2201,39 @@ bool FrameNode::IsSecurityComponent() GetTag() == V2::SAVE_BUTTON_ETS_TAG; } +void FrameNode::GetPercentSensitive() +{ + auto res = layoutProperty_->GetPercentSensitive(); + if (res.first) { + if (layoutAlgorithm_) { + layoutAlgorithm_->SetPercentWidth(true); + } + } + if (res.second) { + if (layoutAlgorithm_) { + layoutAlgorithm_->SetPercentHeight(true); + } + } +} + +void FrameNode::UpdatePercentSensitive() +{ + auto res = layoutProperty_->UpdatePercentSensitive( + layoutAlgorithm_->GetPercentHeight(), layoutAlgorithm_->GetPercentWidth()); + if (res.first) { + auto parent = GetAncestorNodeOfFrame(); + if (parent && parent->layoutAlgorithm_) { + parent->layoutAlgorithm_->SetPercentWidth(true); + } + } + if (res.second) { + auto parent = GetAncestorNodeOfFrame(); + if (parent && parent->layoutAlgorithm_) { + parent->layoutAlgorithm_->SetPercentHeight(true); + } + } +} + // This will call child and self measure process. void FrameNode::Measure(const std::optional& parentConstraint) { @@ -2246,12 +2279,8 @@ void FrameNode::Measure(const std::optional& parentConstraint geometryNode_->UpdateMargin(layoutProperty_->CreateMargin()); geometryNode_->UpdatePaddingWithBorder(layoutProperty_->CreatePaddingAndBorder()); - isConstraintNotChanged_ = preConstraint ? preConstraint == layoutProperty_->GetLayoutConstraint() : false; + isConstraintNotChanged_ = layoutProperty_->ConstraintEqual(preConstraint, contentConstraint); - if (!isConstraintNotChanged_) { - isConstraintNotChanged_ = - contentConstraint ? contentConstraint == layoutProperty_->GetContentLayoutConstraint() : false; - } LOGD("Measure: %{public}s, depth: %{public}d, Constraint: %{public}s", GetTag().c_str(), GetDepth(), layoutProperty_->GetLayoutConstraint()->ToString().c_str()); @@ -2270,10 +2299,12 @@ void FrameNode::Measure(const std::optional& parentConstraint if (size.has_value()) { geometryNode_->SetContentSize(size.value()); } + GetPercentSensitive(); layoutAlgorithm_->Measure(this); if (overlayNode_) { overlayNode_->Measure(layoutProperty_->CreateChildConstraint()); } + UpdatePercentSensitive(); // check aspect radio. if (pattern_ && pattern_->IsNeedAdjustByAspectRatio()) { const auto& magicItemProperty = layoutProperty_->GetMagicItemProperty(); diff --git a/frameworks/core/components_ng/base/frame_node.h b/frameworks/core/components_ng/base/frame_node.h index 3b5e40606088abbc807e3e8740c57f01c772ff7a..4410e272a197783d38faed70da5cbd7e587d099d 100644 --- a/frameworks/core/components_ng/base/frame_node.h +++ b/frameworks/core/components_ng/base/frame_node.h @@ -600,6 +600,9 @@ private: // set costom background layoutConstraint void SetBackgroundLayoutConstraint(const RefPtr& customNode); + void GetPercentSensitive(); + void UpdatePercentSensitive(); + // sort in ZIndex. std::multiset, ZIndexComparator> frameChildren_; RefPtr geometryNode_ = MakeRefPtr(); diff --git a/frameworks/core/components_ng/layout/layout_algorithm.h b/frameworks/core/components_ng/layout/layout_algorithm.h index e12ec8d30a59a9b12d39991271b4b90fd455e2ec..1a99891575fa6301be36334702b2475f08a286b0 100644 --- a/frameworks/core/components_ng/layout/layout_algorithm.h +++ b/frameworks/core/components_ng/layout/layout_algorithm.h @@ -158,11 +158,33 @@ public: return frameId != UITaskScheduler::GetFrameId(); } + void SetPercentHeight(bool value) + { + percentHeight_ = value; + } + + void SetPercentWidth(bool value) + { + percentWidth_ = value; + } + + bool GetPercentHeight() const + { + return percentHeight_; + } + + bool GetPercentWidth() const + { + return percentHeight_; + } + private: RefPtr layoutAlgorithm_; bool skipMeasure_ = false; bool skipLayout_ = false; + bool percentHeight_ = false; + bool percentWidth_ = false; uint64_t frameId = UITaskScheduler::GetFrameId(); ACE_DISALLOW_COPY_AND_MOVE(LayoutAlgorithmWrapper); diff --git a/frameworks/core/components_ng/layout/layout_property.cpp b/frameworks/core/components_ng/layout/layout_property.cpp index 6893290ad3435ecc62b9993b8bf4a1f79e8ec697..191eece4138b2edd5d977dbcee544bea70b2f6f3 100644 --- a/frameworks/core/components_ng/layout/layout_property.cpp +++ b/frameworks/core/components_ng/layout/layout_property.cpp @@ -1002,4 +1002,61 @@ void LayoutProperty::UpdateAllGeometryTransition(const RefPtr& parent) } } } + +std::pair LayoutProperty::GetPercentSensitive() +{ + if (!contentConstraint_.has_value()) { + return { false, false }; + } + std::pair res = { false, false }; + const auto& constraint = contentConstraint_.value(); + if (GreaterOrEqualToInfinity(constraint.maxSize.Height())) { + if (calcLayoutConstraint_ && calcLayoutConstraint_->PercentHeight()) { + res.second = true; + } + } + if (GreaterOrEqualToInfinity(constraint.maxSize.Width())) { + if (calcLayoutConstraint_ && calcLayoutConstraint_->PercentWidth()) { + res.first = true; + } + } + return res; +} + +std::pair LayoutProperty::UpdatePercentSensitive(bool width, bool height) +{ + if (!contentConstraint_.has_value()) { + return { false, false }; + } + const auto& constraint = contentConstraint_.value(); + if (GreaterOrEqualToInfinity(constraint.maxSize.Height())) { + heightPercentSensitive_ = heightPercentSensitive_ || height; + } + if (GreaterOrEqualToInfinity(constraint.maxSize.Width())) { + widthPercentSensitive_ = heightPercentSensitive_ || width; + } + return { widthPercentSensitive_, heightPercentSensitive_ }; +} + +bool LayoutProperty::ConstraintEqual(const std::optional& preLayoutConstraint, + const std::optional& preContentConstraint) +{ + if (!preLayoutConstraint || !layoutConstraint_) { + return false; + } + if (!preContentConstraint || !contentConstraint_) { + return false; + } + const auto& layout = layoutConstraint_.value(); + const auto& content = contentConstraint_.value(); + if (GreaterOrEqualToInfinity(layout.maxSize.Width()) && !widthPercentSensitive_) { + return (layout.EqualWithoutPercentWidth(preLayoutConstraint.value()) && + content.EqualWithoutPercentWidth(preContentConstraint.value())); + } + if (GreaterOrEqualToInfinity(layout.maxSize.Height()) && !heightPercentSensitive_) { + return (layout.EqualWithoutPercentHeight(preLayoutConstraint.value()) && + content.EqualWithoutPercentHeight(preContentConstraint.value())); + } + return (preLayoutConstraint == layoutConstraint_ && preContentConstraint == contentConstraint_); +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/layout/layout_property.h b/frameworks/core/components_ng/layout/layout_property.h index e2fa4647286d5269b179d609e2717a89bc95e158..a528f85133b35f851175e291666125379a275f72 100644 --- a/frameworks/core/components_ng/layout/layout_property.h +++ b/frameworks/core/components_ng/layout/layout_property.h @@ -270,6 +270,11 @@ public: static void UpdateAllGeometryTransition(const RefPtr& parent); + std::pair GetPercentSensitive(); + std::pair UpdatePercentSensitive(bool width, bool height); + bool ConstraintEqual(const std::optional& preLayoutConstraint, + const std::optional& preContentConstraint); + protected: void UpdateLayoutProperty(const LayoutProperty* layoutProperty); @@ -312,6 +317,9 @@ private: Dimension overlayOffsetX_; Dimension overlayOffsetY_; + bool heightPercentSensitive_ = false; + bool widthPercentSensitive_ = false; + ACE_DISALLOW_COPY_AND_MOVE(LayoutProperty); }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/property/layout_constraint.h b/frameworks/core/components_ng/property/layout_constraint.h index 8e26ed4f41dbb75a41e99c2403bda43216e51c83..548f6f2dd857ea54fe5e73d96c85a5e9c3b8a661 100644 --- a/frameworks/core/components_ng/property/layout_constraint.h +++ b/frameworks/core/components_ng/property/layout_constraint.h @@ -62,6 +62,22 @@ struct LayoutConstraintT { return !(*this == layoutConstraint); } + bool EqualWithoutPercentWidth(const LayoutConstraintT& layoutConstraint) const + { + return (scaleProperty == layoutConstraint.scaleProperty) && (minSize == layoutConstraint.minSize) && + (maxSize == layoutConstraint.maxSize) && (parentIdealSize == layoutConstraint.parentIdealSize) && + (percentReference.Height() == layoutConstraint.percentReference.Height()) && + (selfIdealSize == layoutConstraint.selfIdealSize); + } + + bool EqualWithoutPercentHeight(const LayoutConstraintT& layoutConstraint) const + { + return (scaleProperty == layoutConstraint.scaleProperty) && (minSize == layoutConstraint.minSize) && + (maxSize == layoutConstraint.maxSize) && (parentIdealSize == layoutConstraint.parentIdealSize) && + (percentReference.Width() == layoutConstraint.percentReference.Width()) && + (selfIdealSize == layoutConstraint.selfIdealSize); + } + bool UpdateSelfMarginSizeWithCheck(const OptionalSize& size) { if (selfIdealSize == size) { diff --git a/frameworks/core/components_ng/property/measure_property.h b/frameworks/core/components_ng/property/measure_property.h index a6e1a29af8e97198fc0a4e6e687e77c69eb20e5c..f6fceaa6053b56a6077c70fe2da9a00752cf157e 100644 --- a/frameworks/core/components_ng/property/measure_property.h +++ b/frameworks/core/components_ng/property/measure_property.h @@ -132,6 +132,16 @@ public: return height_ && height_->GetDimension().Unit() != DimensionUnit::PERCENT; } + bool PercentWidth() const + { + return width_ && width_->GetDimension().Unit() == DimensionUnit::PERCENT; + } + + bool PercentHeight() const + { + return height_ && height_->GetDimension().Unit() == DimensionUnit::PERCENT; + } + std::string ToString() const { static const int32_t precision = 2; @@ -212,6 +222,34 @@ struct MeasureProperty { return true; } + bool PercentWidth() const + { + if (selfIdealSize.has_value()) { + return selfIdealSize->PercentWidth(); + } + if (maxSize.has_value()) { + return maxSize->PercentWidth(); + } + if (minSize.has_value()) { + return minSize->PercentWidth(); + } + return false; + } + + bool PercentHeight() const + { + if (selfIdealSize.has_value()) { + return selfIdealSize->PercentHeight(); + } + if (maxSize.has_value()) { + return maxSize->PercentHeight(); + } + if (minSize.has_value()) { + return minSize->PercentHeight(); + } + return false; + } + std::string ToString() const { std::string str; diff --git a/frameworks/core/components_ng/test/mock/layout/mock_layout_property.cpp b/frameworks/core/components_ng/test/mock/layout/mock_layout_property.cpp index 106e9908fa5ccc5429458c0ed1abbe6ff0e44cae..6aa223714b29d474f591f2cb21cb6402930b356a 100644 --- a/frameworks/core/components_ng/test/mock/layout/mock_layout_property.cpp +++ b/frameworks/core/components_ng/test/mock/layout/mock_layout_property.cpp @@ -181,4 +181,20 @@ PaddingPropertyF LayoutProperty::CreatePaddingAndBorder() { return PaddingPropertyF(); } + +std::pair LayoutProperty::GetPercentSensitive() +{ + return { false, false }; +} + +std::pair LayoutProperty::UpdatePercentSensitive(bool width, bool height) +{ + return { widthPercentSensitive_, heightPercentSensitive_ }; +} + +bool LayoutProperty::ConstraintEqual(const std::optional& preLayoutConstraint, + const std::optional& preContentConstraint) +{ + return false; +} } // namespace OHOS::Ace::NG