diff --git a/frameworks/base/geometry/ng/size_t.h b/frameworks/base/geometry/ng/size_t.h index 7966855bccb87e499bcc81c710c1db2b76b73635..bc1a665b51dd9c9a9d999f6b7b9380621657d9b7 100644 --- a/frameworks/base/geometry/ng/size_t.h +++ b/frameworks/base/geometry/ng/size_t.h @@ -455,6 +455,16 @@ public: axis == Axis::HORIZONTAL ? height_ = crossSize : width_ = crossSize; } + void SetMainSize(const std::optional& mainSize, Axis axis) + { + axis == Axis::HORIZONTAL ? width_ = mainSize : height_ = mainSize; + } + + void SetCrossSize(const std::optional& crossSize, Axis axis) + { + axis == Axis::HORIZONTAL ? height_ = crossSize : width_ = crossSize; + } + void SetWidth(const std::optional& width) { width_ = width; diff --git a/frameworks/bridge/declarative_frontend/jsview/js_grid.cpp b/frameworks/bridge/declarative_frontend/jsview/js_grid.cpp index 13d30dbc32611f735e4b21017e7ea18251351a8f..1423813e6a194476879ae48a94691ef4bc50ae5d 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_grid.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_grid.cpp @@ -387,6 +387,7 @@ void JSGrid::JSBind(BindingTarget globalObj) JSClass::StaticMethod("nestedScroll", &JSGrid::SetNestedScroll); JSClass::StaticMethod("enableScrollInteraction", &JSGrid::SetScrollEnabled); JSClass::StaticMethod("friction", &JSGrid::SetFriction); + JSClass::StaticMethod("alignItems", &JSGrid::SetAlignItems); JSClass::StaticMethod("onScroll", &JSGrid::JsOnScroll); JSClass::StaticMethod("onReachStart", &JSGrid::JsOnReachStart); @@ -659,6 +660,24 @@ void JSGrid::SetFriction(const JSCallbackInfo& info) GridModel::GetInstance()->SetFriction(friction); } +void JSGrid::SetAlignItems(const JSCallbackInfo& info) +{ + if (info.Length() > 0) { + GridModel::GetInstance()->SetAlignItems(GridItemAlignment::DEFAULT); + return; + } + + if (info[0]->IsNumber()) { + auto itemAlign = static_cast(info[0]->ToNumber()); + if (itemAlign < GridItemAlignment::DEFAULT || itemAlign > GridItemAlignment::STRETCH) { + itemAlign = GridItemAlignment::DEFAULT; + } + GridModel::GetInstance()->SetAlignItems(itemAlign); + } else { + GridModel::GetInstance()->SetAlignItems(GridItemAlignment::DEFAULT); + } +} + void JSGrid::JsOnScroll(const JSCallbackInfo& args) { if (args[0]->IsFunction()) { diff --git a/frameworks/bridge/declarative_frontend/jsview/js_grid.h b/frameworks/bridge/declarative_frontend/jsview/js_grid.h index 5835d3c2157daec04e73e35ef8c773865ba77bc5..0be071a727d36284dc8a27669c45fdc51e650348 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_grid.h +++ b/frameworks/bridge/declarative_frontend/jsview/js_grid.h @@ -57,6 +57,7 @@ public: static void SetNestedScroll(const JSCallbackInfo& args); static void SetScrollEnabled(const JSCallbackInfo& args); static void SetFriction(const JSCallbackInfo& info); + static void SetAlignItems(const JSCallbackInfo& info); static void JsOnScroll(const JSCallbackInfo& args); static void JsOnReachStart(const JSCallbackInfo& args); diff --git a/frameworks/bridge/declarative_frontend/jsview/models/grid_model_impl.h b/frameworks/bridge/declarative_frontend/jsview/models/grid_model_impl.h index d5ac270489780a1fbae5041c9a7c6b2ecd4cd0ed..dfb45e84c9defe77b0316ad174085fa8c6f705c5 100644 --- a/frameworks/bridge/declarative_frontend/jsview/models/grid_model_impl.h +++ b/frameworks/bridge/declarative_frontend/jsview/models/grid_model_impl.h @@ -49,6 +49,7 @@ public: void SetNestedScroll(const NestedScrollOptions& nestedOpt) override {}; void SetScrollEnabled(bool scrollEnabled) override {}; void SetFriction(double friction) override {}; + void SetAlignItems(GridItemAlignment itemAlign) override {}; void SetOnScrollToIndex(std::function&& value) override; void SetOnScrollBarUpdate( std::function, std::optional>(int32_t, Dimension)>&& value) override; diff --git a/frameworks/core/components_ng/pattern/BUILD.gn b/frameworks/core/components_ng/pattern/BUILD.gn index 9b937fa2f4952d0099baa86503a2f3e60dc1bfb6..c257977e6576fd17fa7e2021ea030ca7d480256c 100644 --- a/frameworks/core/components_ng/pattern/BUILD.gn +++ b/frameworks/core/components_ng/pattern/BUILD.gn @@ -133,10 +133,12 @@ build_component_ng("pattern_ng") { "grid/grid_adaptive/grid_adaptive_layout_algorithm.cpp", "grid/grid_event_hub.cpp", "grid/grid_item_accessibility_property.cpp", + "grid/grid_item_layout_algorithm.cpp", "grid/grid_item_layout_property.cpp", "grid/grid_item_model_ng.cpp", "grid/grid_item_pattern.cpp", "grid/grid_layout/grid_layout_algorithm.cpp", + "grid/grid_layout_base_algorithm.cpp", "grid/grid_layout_info.cpp", "grid/grid_layout_property.cpp", "grid/grid_model_ng.cpp", diff --git a/frameworks/core/components_ng/pattern/grid/grid_constants.h b/frameworks/core/components_ng/pattern/grid/grid_constants.h new file mode 100644 index 0000000000000000000000000000000000000000..c26849cbfeba84191f18ae4280a792cf262f403c --- /dev/null +++ b/frameworks/core/components_ng/pattern/grid/grid_constants.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_CONSTANTS_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_CONSTANTS_H + +namespace OHOS::Ace { + +enum class GridItemAlignment : uint32_t { + DEFAULT = 0, + STRETCH = 1 +}; +} // namespace OHOS::Ace::NG +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_CONSTANTS_H diff --git a/frameworks/core/components_ng/pattern/grid/grid_item_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/grid/grid_item_layout_algorithm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b845cd9b21c2538d2acc60ee950d8564edf4285c --- /dev/null +++ b/frameworks/core/components_ng/pattern/grid/grid_item_layout_algorithm.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "core/components_ng/pattern/grid/grid_item_layout_algorithm.h" + +#include "core/components_ng/base/frame_node.h" +#include "core/components_ng/pattern/grid/grid_item_layout_property.h" + +namespace OHOS::Ace::NG { +void GridItemLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) +{ + auto props = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); + CHECK_NULL_VOID(props); + auto layoutConstraint = CreateChildConstraint(layoutWrapper); + + for (auto&& child : layoutWrapper->GetAllChildrenWithBuild()) { + child->Measure(layoutConstraint); + } + BoxLayoutAlgorithm::PerformMeasureSelf(layoutWrapper); +} + +LayoutConstraintF GridItemLayoutAlgorithm::CreateChildConstraint(LayoutWrapper* layoutWrapper) +{ + auto props = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); + auto layoutConstraint = props->CreateChildConstraint(); + + if (!props->GetNeedStretch()) { + return layoutConstraint; + } + + auto child = layoutWrapper->GetOrCreateChildByIndex(0); + if (!child) { + return layoutConstraint; + } + + auto childLayoutProperty = child->GetLayoutProperty(); + if (!childLayoutProperty) { + layoutConstraint.selfIdealSize.SetHeight(layoutConstraint.parentIdealSize.Height()); + return layoutConstraint; + } + + auto childConstraint = childLayoutProperty->GetLayoutConstraint(); + if (!childConstraint->selfIdealSize.MainSize(props->GetAxis()).has_value() && + layoutConstraint.parentIdealSize.MainSize(props->GetAxis()).has_value()) { + layoutConstraint.selfIdealSize.SetMainSize( + layoutConstraint.parentIdealSize.MainSize(props->GetAxis()), props->GetAxis()); + child->GetHostNode()->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + } + return layoutConstraint; +} +} // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/grid/grid_item_layout_algorithm.h b/frameworks/core/components_ng/pattern/grid/grid_item_layout_algorithm.h new file mode 100644 index 0000000000000000000000000000000000000000..07253c1ad5b55689d26f89e52d4bad6416d3026b --- /dev/null +++ b/frameworks/core/components_ng/pattern/grid/grid_item_layout_algorithm.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_GRID_GRID_ITEM_LAYOUT_ALGORITHM_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_GRID_GRID_ITEM_LAYOUT_ALGORITHM_H + +#include "core/components_ng/layout/box_layout_algorithm.h" + +namespace OHOS::Ace::NG { +class ACE_FORCE_EXPORT GridItemLayoutAlgorithm : public BoxLayoutAlgorithm { + DECLARE_ACE_TYPE(GridItemLayoutAlgorithm, BoxLayoutAlgorithm) +public: + GridItemLayoutAlgorithm() = default; + ~GridItemLayoutAlgorithm() override = default; + + void Measure(LayoutWrapper* layoutWrapper) override; + + LayoutConstraintF CreateChildConstraint(LayoutWrapper* layoutWrapper); +}; +} // namespace OHOS::Ace::NG + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_GRID_GRID_ITEM_LAYOUT_ALGORITHM_H \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/grid/grid_item_layout_property.h b/frameworks/core/components_ng/pattern/grid/grid_item_layout_property.h index 713bc4b4aee94b0ab619c4e6ce6baf7d2455dc44..520179cb75eb99654f4eb49f76769f030a6a5cee 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_item_layout_property.h +++ b/frameworks/core/components_ng/pattern/grid/grid_item_layout_property.h @@ -90,11 +90,33 @@ public: bool CheckWhetherCurrentItemAtExpectedPosition(Axis axis) const; int32_t GetRealMainSpan(Axis axis) const; int32_t GetRealCrossSpan(Axis axis) const; + void SetNeedStretch(bool needStretch) + { + needStretch_ = needStretch; + } + + bool GetNeedStretch() const + { + return needStretch_; + } + + void SetAxis(Axis axis) + { + axis_ = axis; + } + + Axis GetAxis() const + { + return axis_; + } private: ACE_DISALLOW_COPY_AND_MOVE(GridItemLayoutProperty); void ResetGridLayoutInfoAndMeasure() const; + + bool needStretch_ = false; + Axis axis_ = Axis::NONE; }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/grid/grid_item_pattern.h b/frameworks/core/components_ng/pattern/grid/grid_item_pattern.h index dee8cef19c774c05ef42296a0d6fc7449f247c8b..5ca098d82144908e7dcdae859e086a18fbb32857 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_item_pattern.h +++ b/frameworks/core/components_ng/pattern/grid/grid_item_pattern.h @@ -19,6 +19,7 @@ #include "core/components_ng/base/inspector_filter.h" #include "core/components_ng/pattern/grid/grid_item_accessibility_property.h" #include "core/components_ng/pattern/grid/grid_item_event_hub.h" +#include "core/components_ng/pattern/grid/grid_item_layout_algorithm.h" #include "core/components_ng/pattern/grid/grid_item_layout_property.h" #include "core/components_ng/pattern/grid/grid_item_model.h" #include "core/components_ng/pattern/grid/grid_item_theme.h" @@ -37,6 +38,11 @@ public: {} ~GridItemPattern() override = default; + RefPtr CreateLayoutAlgorithm() override + { + return MakeRefPtr(); + } + bool IsAtomicNode() const override { return false; diff --git a/frameworks/core/components_ng/pattern/grid/grid_layout_base_algorithm.cpp b/frameworks/core/components_ng/pattern/grid/grid_layout_base_algorithm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f5cc84dc20fb2ee832495167f21d9358dee02031 --- /dev/null +++ b/frameworks/core/components_ng/pattern/grid/grid_layout_base_algorithm.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "core/components_ng/pattern/grid/grid_layout_base_algorithm.h" + +namespace OHOS::Ace::NG { + +void GridLayoutBaseAlgorithm::AdjustChildrenHeight(LayoutWrapper* layoutWrapper) +{ + clearStretch_ = false; + auto gridLayoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); + CHECK_NULL_VOID(gridLayoutProperty); + const int32_t cacheCount = gridLayoutProperty->GetCachedCountValue(1); + const int32_t startLine = std::max(gridLayoutInfo_.startMainLineIndex_ - cacheCount, 0); + const int32_t endLine = gridLayoutInfo_.endMainLineIndex_ + cacheCount; + for (int i = startLine; i <= endLine; i++) { + if (IsIrregularLine(i)) { + continue; + } + const auto& line = gridLayoutInfo_.gridMatrix_.find(i); + if (line == gridLayoutInfo_.gridMatrix_.end() || line->second.empty()) { + continue; + } + + auto lineHeightIter = gridLayoutInfo_.lineHeightMap_.find(i); + if (lineHeightIter == gridLayoutInfo_.lineHeightMap_.end()) { + continue; + } + const float lineHeight = lineHeightIter->second; + + for (auto iter = line->second.begin(); iter != line->second.end(); iter++) { + const int32_t itemIndex = iter->second; + auto child = layoutWrapper->GetChildByIndex(itemIndex); + if (!child) { + break; + } + auto childLayoutProperty = AceType::DynamicCast(child->GetLayoutProperty()); + if (!childLayoutProperty) { + break; + } + auto childConstraint = childLayoutProperty->GetLayoutConstraint(); + if (!childLayoutProperty->GetNeedStretch() && + childConstraint->selfIdealSize.MainSize(gridLayoutInfo_.axis_).has_value()) { + continue; + } + + auto childFrameSize = child->GetGeometryNode()->GetFrameSize(); + if (GreatOrEqual(childFrameSize.MainSize(gridLayoutInfo_.axis_), lineHeight)) { + continue; + } + childConstraint->selfIdealSize.SetMainSize(lineHeight, gridLayoutInfo_.axis_); + childLayoutProperty->SetNeedStretch(true); + childLayoutProperty->SetAxis(gridLayoutInfo_.axis_); + child->Measure(childConstraint); + } + } +} +} // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/grid/grid_layout_base_algorithm.h b/frameworks/core/components_ng/pattern/grid/grid_layout_base_algorithm.h index b9c61ce0b5251744d6e5c5bebdaac681adc7d95e..904b09a95d2a62301551cc853d04761272ebeb7e 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_layout_base_algorithm.h +++ b/frameworks/core/components_ng/pattern/grid/grid_layout_base_algorithm.h @@ -68,7 +68,16 @@ public: } protected: + void AdjustChildrenHeight(LayoutWrapper* layoutWrapper); + + // The default value is set to true to skip the second measure in other layout algorithms. + virtual bool IsIrregularLine(int32_t lineIndex) const + { + return true; + } + GridLayoutInfo gridLayoutInfo_; + bool clearStretch_ = false; ACE_DISALLOW_COPY_AND_MOVE(GridLayoutBaseAlgorithm); }; diff --git a/frameworks/core/components_ng/pattern/grid/grid_layout_info.h b/frameworks/core/components_ng/pattern/grid/grid_layout_info.h index 85293ab49459b340503ea0da72d44286099c6d92..20f1e28b676efa018e364c5870842a273a079fc2 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_layout_info.h +++ b/frameworks/core/components_ng/pattern/grid/grid_layout_info.h @@ -399,6 +399,8 @@ struct GridLayoutInfo { std::optional targetIndex_; + std::map irregularLines_; + private: float GetCurrentOffsetOfRegularGrid(float mainGap) const; float GetContentHeightOfRegularGrid(float mainGap) const; diff --git a/frameworks/core/components_ng/pattern/grid/grid_layout_property.h b/frameworks/core/components_ng/pattern/grid/grid_layout_property.h index bdb6ba0c6d938dbb062bda07a819a2fab73c6620..28118af93be19a2078fff85b0abf08ec68e8e13b 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_layout_property.h +++ b/frameworks/core/components_ng/pattern/grid/grid_layout_property.h @@ -17,6 +17,7 @@ #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_LAYOUT_PROPERTY_H #include "core/components_ng/layout/layout_property.h" +#include "core/components_ng/pattern/grid/grid_constants.h" #include "core/components_ng/pattern/grid/grid_layout_options.h" namespace OHOS::Ace::NG { @@ -141,6 +142,12 @@ public: ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Editable, bool, PROPERTY_UPDATE_LAYOUT); ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ScrollEnabled, bool, PROPERTY_UPDATE_MEASURE); + ACE_DEFINE_PROPERTY_ITEM_FUNC_WITHOUT_GROUP(AlignItems, GridItemAlignment); + void OnAlignItemsUpdate(GridItemAlignment /* alignItems */) const + { + ResetGridLayoutInfoAndMeasure(); + } + private: ACE_DISALLOW_COPY_AND_MOVE(GridLayoutProperty); diff --git a/frameworks/core/components_ng/pattern/grid/grid_model.h b/frameworks/core/components_ng/pattern/grid/grid_model.h index ad5f463fe94284665f93ae89c677bf401d41e20d..097cdcfce74145482bb4a9cf7efac7c567bd63fc 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_model.h +++ b/frameworks/core/components_ng/pattern/grid/grid_model.h @@ -25,6 +25,7 @@ #include "core/components/common/properties/color.h" #include "core/components/scroll_bar/scroll_bar_proxy.h" #include "core/components_ng/pattern/grid/grid_layout_options.h" +#include "core/components_ng/pattern/grid/grid_constants.h" #include "core/components_ng/pattern/scrollable/scrollable_properties.h" #include "core/components_v2/grid/grid_position_controller.h" #include "core/event/ace_events.h" @@ -62,6 +63,7 @@ public: virtual void SetNestedScroll(const NestedScrollOptions& nestedOpt) = 0; virtual void SetScrollEnabled(bool scrollEnabled) = 0; virtual void SetFriction(double friction) = 0; + virtual void SetAlignItems(GridItemAlignment itemAlign) = 0; virtual void SetOnScrollToIndex(std::function&& value) = 0; virtual void SetOnScrollBarUpdate( std::function, std::optional>(int32_t, Dimension)>&& value) = 0; diff --git a/frameworks/core/components_ng/pattern/grid/grid_model_ng.cpp b/frameworks/core/components_ng/pattern/grid/grid_model_ng.cpp index 758a101ab7d8e2024a3c6a592e35097fdb3056b1..53aa10e22d17c2208c7125edb3307e328a75fe74 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_model_ng.cpp +++ b/frameworks/core/components_ng/pattern/grid/grid_model_ng.cpp @@ -206,6 +206,11 @@ void GridModelNG::SetFriction(double friction) pattern->SetFriction(friction); } +void GridModelNG::SetAlignItems(GridItemAlignment itemAlign) +{ + ACE_UPDATE_LAYOUT_PROPERTY(GridLayoutProperty, AlignItems, itemAlign); +} + void GridModelNG::SetOnScrollToIndex(ScrollToIndexFunc&& value) { auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); @@ -501,6 +506,11 @@ void GridModelNG::SetFriction(FrameNode* frameNode, double friction) pattern->SetFriction(friction); } +void GridModelNG::SetAlignItems(FrameNode* frameNode, GridItemAlignment itemAlign) +{ + ACE_UPDATE_NODE_LAYOUT_PROPERTY(GridLayoutProperty, AlignItems, itemAlign, frameNode); +} + RefPtr GridModelNG::CreatePositionController() { return AceType::MakeRefPtr(); diff --git a/frameworks/core/components_ng/pattern/grid/grid_model_ng.h b/frameworks/core/components_ng/pattern/grid/grid_model_ng.h index 243f6cdc884cdc97c2cf97c7cc5b45779f6b289e..ad1801447481ff11af6aa5a74be65088bb06374d 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_model_ng.h +++ b/frameworks/core/components_ng/pattern/grid/grid_model_ng.h @@ -55,6 +55,7 @@ public: void SetNestedScroll(const NestedScrollOptions& nestedOpt) override; void SetScrollEnabled(bool scrollEnabled) override; void SetFriction(double friction) override; + void SetAlignItems(GridItemAlignment itemAlign) override; void SetOnScrollToIndex(ScrollToIndexFunc&& value) override; void SetOnScrollBarUpdate(ScrollBarUpdateFunc&& value) override; void SetOnItemDragStart(std::function&& value) override; @@ -97,6 +98,7 @@ public: static void SetNestedScroll(FrameNode* frameNode, const NestedScrollOptions& nestedOpt); static void SetScrollEnabled(FrameNode* frameNode, bool scrollEnabled); static void SetFriction(FrameNode* frameNode, double friction); + static void SetAlignItems(FrameNode* frameNode, GridItemAlignment itemAlign); static std::string GetColumnsTemplate(FrameNode* frameNode); static std::string GetRowsTemplate(FrameNode* frameNode); static float GetColumnsGap(FrameNode* frameNode); diff --git a/frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.cpp index 2475654959786cb18d133f8c281d51941d41c6ce..d7ff788eeb92f91baec444c0e712d739eaa45f83 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.cpp @@ -72,6 +72,10 @@ void GridScrollLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) } FillGridViewportAndMeasureChildren(mainSize, crossSize, layoutWrapper); + if (gridLayoutProperty->GetAlignItems().value_or(GridItemAlignment::DEFAULT) == GridItemAlignment::STRETCH) { + GridLayoutBaseAlgorithm::AdjustChildrenHeight(layoutWrapper); + } + // update cache info. layoutWrapper->SetCacheCount(static_cast(gridLayoutProperty->GetCachedCountValue(1) * crossCount_)); @@ -1710,6 +1714,11 @@ int32_t GridScrollLayoutAlgorithm::MeasureNewChild(const SizeF& frameSize, int32 MeasureChild(layoutWrapper, frameSize, childLayoutWrapper, crossIndex, crossSpan); itemsCrossPosition_.try_emplace(itemIndex, ComputeItemCrossPosition(layoutWrapper, crossIndex)); } + if (mainSpan > 1 || crossSpan > 1) { + for (int i = mainIndex; i < mainSpan; i++) { + gridLayoutInfo_.irregularLines_[i] = true; + } + } return crossSpan; } @@ -1723,6 +1732,12 @@ int32_t GridScrollLayoutAlgorithm::MeasureChildPlaced(const SizeF& frameSize, in crossStart, crossSpan); return 0; } + auto mainSpan = axis_ == Axis::HORIZONTAL ? currentItemColSpan_ : currentItemRowSpan_; + if (crossSpan > 1 || mainSpan > 1) { + for (int i = currentMainLineIndex_; i < mainSpan; i++) { + gridLayoutInfo_.irregularLines_[i] = true; + } + } MeasureChild(layoutWrapper, frameSize, childLayoutWrapper, crossStart, crossSpan); itemsCrossPosition_.try_emplace(itemIndex, ComputeItemCrossPosition(layoutWrapper, crossStart)); @@ -1742,6 +1757,30 @@ bool GridScrollLayoutAlgorithm::CheckNeedMeasure( return constraint.value() != layoutConstraint; } +bool GridScrollLayoutAlgorithm::CheckNeedMeasureWhenStretch( + const RefPtr& layoutWrapper, const LayoutConstraintF& layoutConstraint) const +{ + auto childLayoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); + if (!childLayoutProperty->GetNeedStretch()) { + return true; + } + if (clearStretch_) { + childLayoutProperty->SetNeedStretch(false); + if (axis_ == Axis::VERTICAL) { + childLayoutProperty->ClearUserDefinedIdealSize(false, true); + } else { + childLayoutProperty->ClearUserDefinedIdealSize(true, false); + } + return true; + } + auto geometryNode = layoutWrapper->GetGeometryNode(); + CHECK_NULL_RETURN(geometryNode, true); + auto constraint = geometryNode->GetParentLayoutConstraint(); + CHECK_NULL_RETURN(constraint, true); + return layoutConstraint.selfIdealSize.MainSize(axis_).has_value() || + layoutWrapper->CheckNeedForceMeasureAndLayout(); +} + void GridScrollLayoutAlgorithm::MeasureChild(LayoutWrapper* layoutWrapper, const SizeF& frameSize, const RefPtr& childLayoutWrapper, int32_t crossStart, int32_t crossSpan) { @@ -1752,11 +1791,16 @@ void GridScrollLayoutAlgorithm::MeasureChild(LayoutWrapper* layoutWrapper, const if (!CheckNeedMeasure(childLayoutWrapper, childConstraint)) { return; } - auto childLayoutProperty = childLayoutWrapper->GetLayoutProperty(); + auto childLayoutProperty = DynamicCast(childLayoutWrapper->GetLayoutProperty()); if (!childLayoutProperty) { childLayoutWrapper->Measure(childConstraint); return; } + if (childLayoutProperty->GetNeedStretch()) { + if (!CheckNeedMeasureWhenStretch(childLayoutWrapper, childConstraint)) { + return; + } + } auto oldConstraint = childLayoutProperty->GetLayoutConstraint(); if (oldConstraint.has_value() && !NearEqual(GetCrossAxisSize(oldConstraint.value().maxSize, axis_), GetCrossAxisSize(childConstraint.maxSize, axis_))) { @@ -2103,6 +2147,11 @@ int32_t GridScrollLayoutAlgorithm::MeasureCachedChild(const SizeF& frameSize, in itemsCrossPosition_.try_emplace(itemIndex, ComputeItemCrossPosition(layoutWrapper, crossIndex)); } + if (crossSpan > 1 || mainSpan > 1) { + for (int i = currentMainLineIndex_; i < mainSpan; i++) { + gridLayoutInfo_.irregularLines_[i] = true; + } + } return crossSpan; } @@ -2200,6 +2249,7 @@ void GridScrollLayoutAlgorithm::CheckReset(float mainSize, float crossSize, Layo gridLayoutInfo_.endMainLineIndex_ = 0; gridLayoutInfo_.prevOffset_ = gridLayoutInfo_.currentOffset_; gridLayoutInfo_.ResetPositionFlags(); + clearStretch_ = true; isChildrenUpdated_ = true; if (gridLayoutInfo_.childrenCount_ > 0) { ReloadToStartIndex(mainSize, crossSize, layoutWrapper); @@ -2213,6 +2263,7 @@ void GridScrollLayoutAlgorithm::CheckReset(float mainSize, float crossSize, Layo isChildrenUpdated_ = true; gridLayoutInfo_.irregularItemsPosition_.clear(); gridLayoutInfo_.ResetPositionFlags(); + clearStretch_ = true; gridLayoutInfo_.prevOffset_ = gridLayoutInfo_.currentOffset_; auto it = gridLayoutInfo_.FindInMatrix(updateIdx); it = gridLayoutInfo_.FindStartLineInMatrix(it, updateIdx); @@ -2254,4 +2305,13 @@ bool GridScrollLayoutAlgorithm::CheckLastLineItemFullyShowed(LayoutWrapper* layo } return true; } + +bool GridScrollLayoutAlgorithm::IsIrregularLine(int32_t lineIndex) const +{ + auto irregular = gridLayoutInfo_.irregularLines_.find(lineIndex); + if (irregular != gridLayoutInfo_.irregularLines_.end() && irregular->second) { + return true; + } + return false; +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.h b/frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.h index d5b42976042ffc8948e1919faa0082fc13791cbb..597ac7b065ba34d1bab1664d0c4ca442a1e54438 100644 --- a/frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/grid/grid_scroll/grid_scroll_layout_algorithm.h @@ -16,7 +16,6 @@ #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_SCROLL_GRID_SCROLL_LAYOUT_ALGORITHM_H #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_SCROLL_GRID_SCROLL_LAYOUT_ALGORITHM_H -#include "core/components_ng/layout/layout_wrapper.h" #include "core/components_ng/pattern/grid/grid_item_layout_property.h" #include "core/components_ng/pattern/grid/grid_layout_base_algorithm.h" #include "core/components_ng/pattern/grid/grid_layout_info.h" @@ -106,6 +105,8 @@ private: int32_t MeasureChildPlaced(const SizeF& frameSize, int32_t itemIndex, int32_t crossStart, LayoutWrapper* layoutWrapper, const RefPtr& childLayoutWrapper); bool CheckNeedMeasure(const RefPtr& layoutWrapper, const LayoutConstraintF& layoutConstraint) const; + bool CheckNeedMeasureWhenStretch( + const RefPtr& layoutWrapper, const LayoutConstraintF& layoutConstraint) const; void MeasureChild(LayoutWrapper* layoutWrapper, const SizeF& frameSize, const RefPtr& childLayoutWrapper, int32_t crossStart, int32_t crossSpan); @@ -178,6 +179,8 @@ private: bool CheckLastLineItemFullyShowed(LayoutWrapper* layoutWrapper); + bool IsIrregularLine(int32_t lineIndex) const override; + protected: uint32_t crossCount_ = 0; uint32_t mainCount_ = 0; @@ -204,6 +207,7 @@ private: bool expandSafeArea_ = false; bool canOverScroll_ = false; bool enableSkipping_ = true; // enables skipping lines on a large offset change. + bool clearStretch_ = false; GridLayoutInfo scrollGridLayoutInfo_; // Map structure: [index, crossPosition], store cross position of each item. diff --git a/frameworks/core/components_ng/pattern/grid/irregular/grid_irregular_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/grid/irregular/grid_irregular_layout_algorithm.cpp index 1333fa2a07bee58f813348cbe69ecf9ef1d0b02d..68ffaac2f9a07c2b94d53a564c949da64cf2ec1f 100644 --- a/frameworks/core/components_ng/pattern/grid/irregular/grid_irregular_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/grid/irregular/grid_irregular_layout_algorithm.cpp @@ -55,6 +55,10 @@ void GridIrregularLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) MeasureOnOffset(mainSize); } + if (props->GetAlignItems().value_or(GridItemAlignment::DEFAULT) == GridItemAlignment::STRETCH) { + GridLayoutBaseAlgorithm::AdjustChildrenHeight(layoutWrapper); + } + UpdateLayoutInfo(); wrapper_->SetCacheCount(static_cast(props->GetCachedCountValue(1) * gridLayoutInfo_.crossCount_)); } @@ -584,4 +588,20 @@ void GridIrregularLayoutAlgorithm::MeasureToTarget() filler.FillToTarget(param, *info.targetIndex_, info.startMainLineIndex_); } } + +bool GridIrregularLayoutAlgorithm::IsIrregularLine(int32_t lineIndex) const +{ + const auto& line = gridLayoutInfo_.gridMatrix_.find(lineIndex); + if (line == gridLayoutInfo_.gridMatrix_.end() || line->second.empty()) { + return true; + } + auto props = AceType::DynamicCast(wrapper_->GetLayoutProperty()); + auto opts = &props->GetLayoutOptions().value(); + for (const auto& item : line->second) { + if (!item.second || opts->irregularIndexes.find(std::abs(item.second)) != opts->irregularIndexes.end()) { + return true; + } + } + return false; +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/grid/irregular/grid_irregular_layout_algorithm.h b/frameworks/core/components_ng/pattern/grid/irregular/grid_irregular_layout_algorithm.h index 30ecaf3406c2159f6e7fc9601ccc85e135b18892..3d833dc15c6ae8e4700e99e9ead7b514a6960e0a 100644 --- a/frameworks/core/components_ng/pattern/grid/irregular/grid_irregular_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/grid/irregular/grid_irregular_layout_algorithm.h @@ -141,6 +141,8 @@ private: */ int32_t SkipLinesBackward() const; + bool IsIrregularLine(int32_t lineIndex) const override; + LayoutWrapper* wrapper_ = nullptr; std::vector crossLens_; /**< The column widths of the GridItems. */ diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 24be057290068b39d810a4aa36e71b3cc5545598..8e02c12daa2d71329adef2b7fd8a701f59f27de1 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -652,10 +652,12 @@ ohos_source_set("ace_components_pattern") { "$ace_root/frameworks/core/components_ng/pattern/grid/grid_adaptive/grid_adaptive_layout_algorithm.cpp", "$ace_root/frameworks/core/components_ng/pattern/grid/grid_event_hub.cpp", "$ace_root/frameworks/core/components_ng/pattern/grid/grid_item_accessibility_property.cpp", + "$ace_root/frameworks/core/components_ng/pattern/grid/grid_item_layout_algorithm.cpp", "$ace_root/frameworks/core/components_ng/pattern/grid/grid_item_layout_property.cpp", "$ace_root/frameworks/core/components_ng/pattern/grid/grid_item_model_ng.cpp", "$ace_root/frameworks/core/components_ng/pattern/grid/grid_item_pattern.cpp", "$ace_root/frameworks/core/components_ng/pattern/grid/grid_layout/grid_layout_algorithm.cpp", + "$ace_root/frameworks/core/components_ng/pattern/grid/grid_layout_base_algorithm.cpp", "$ace_root/frameworks/core/components_ng/pattern/grid/grid_layout_info.cpp", "$ace_root/frameworks/core/components_ng/pattern/grid/grid_layout_property.cpp", "$ace_root/frameworks/core/components_ng/pattern/grid/grid_model_ng.cpp", diff --git a/test/unittest/core/pattern/grid/grid_layout_test_ng.cpp b/test/unittest/core/pattern/grid/grid_layout_test_ng.cpp index 6a9a6f3ac4be4233f636773d613e8125f04fbe00..35df991dc0114232706d0aef399ab7af24be83d5 100644 --- a/test/unittest/core/pattern/grid/grid_layout_test_ng.cpp +++ b/test/unittest/core/pattern/grid/grid_layout_test_ng.cpp @@ -1751,4 +1751,243 @@ HWTEST_F(GridLayoutTestNg, Cache001, TestSize.Level1) // GridScroll algo currently not capable of preloading backward EXPECT_TRUE(pattern_->preloadItemList_.empty()); } + +/** + * @tc.name: Stretch001 + * @tc.desc: Test Grid AlignItems STRETCH + * @tc.type: FUNC + */ +HWTEST_F(GridLayoutTestNg, Stretch001, TestSize.Level1) +{ + /** + * 0: [0], [1] + * + * 1 will stretch + */ + GridModelNG model = CreateGrid(); + model.SetAlignItems(GridItemAlignment::STRETCH); + model.SetColumnsTemplate("1fr 1fr"); + + CreateFixedHeightItems(1, 150); + CreateAdaptChildSizeGridItems(1); + + CreateDone(frameNode_); + FlushLayoutTask(frameNode_); + + auto childRect0 = pattern_->GetItemRect(0); + auto childRect1 = pattern_->GetItemRect(1); + EXPECT_EQ(childRect0.Height(), childRect1.Height()); +} + +/** + * @tc.name: Stretch002 + * @tc.desc: Test Grid AlignItems STRETCH + * @tc.type: FUNC + */ +HWTEST_F(GridLayoutTestNg, Stretch002, TestSize.Level1) +{ + /** + * 0: [0], [1] + * 1: [0] + * + * 1 will not stretch + */ + GridModelNG model = CreateGrid(); + model.SetAlignItems(GridItemAlignment::STRETCH); + model.SetColumnsTemplate("1fr 1fr"); + + CreateBigItem(0, 1, 0, 0, ITEM_WIDTH, 200); + CreateAdaptChildSizeGridItems(1); + + CreateDone(frameNode_); + FlushLayoutTask(frameNode_); + + auto childRect1 = pattern_->GetItemRect(1); + EXPECT_EQ(childRect1.Height(), 0); +} + +/** + * @tc.name: Stretch003 + * @tc.desc: Test Grid AlignItems STRETCH + * @tc.type: FUNC + */ +HWTEST_F(GridLayoutTestNg, Stretch003, TestSize.Level1) +{ + /** + * 0: [0], [1] + * 1: [0], [2] + * 2: [3], [4] + * + * 1 and 2 will not stretch + * 3 will stretch + */ + GridModelNG model = CreateGrid(); + model.SetAlignItems(GridItemAlignment::STRETCH); + model.SetColumnsTemplate("1fr 1fr"); + + CreateBigItem(0, 1, 0, 0, ITEM_WIDTH, 200); + CreateAdaptChildSizeGridItems(3); + CreateFixedHeightItems(1, 150); + + CreateDone(frameNode_); + FlushLayoutTask(frameNode_); + + auto childRect1 = pattern_->GetItemRect(1); + EXPECT_EQ(childRect1.Height(), 0); + + auto childRect3 = pattern_->GetItemRect(3); + auto childRect4 = pattern_->GetItemRect(4); + EXPECT_EQ(childRect4.Height(), childRect3.Height()); +} + +/** + * @tc.name: Stretch004 + * @tc.desc: Test Grid AlignItems STRETCH + * @tc.type: FUNC + */ +HWTEST_F(GridLayoutTestNg, Stretch004, TestSize.Level1) +{ + /** + * 0: [0], [0], [1] + * + * 1 will not stretch + */ + GridModelNG model = CreateGrid(); + model.SetAlignItems(GridItemAlignment::STRETCH); + model.SetColumnsTemplate("1fr 1fr 1fr"); + + CreateBigItem(0, 1, 0, 1, ITEM_WIDTH, 200); + CreateAdaptChildSizeGridItems(1); + + CreateDone(frameNode_); + FlushLayoutTask(frameNode_); + + auto childRect1 = pattern_->GetItemRect(1); + EXPECT_EQ(childRect1.Height(), 0); + auto childRect2 = pattern_->GetItemRect(2); + EXPECT_EQ(childRect2.Height(), 0); +} + +/** + * @tc.name: Stretch005 + * @tc.desc: Test Grid AlignItems STRETCH + * @tc.type: FUNC + */ +HWTEST_F(GridLayoutTestNg, Stretch005, TestSize.Level1) +{ + /** + * 0 + * [0] + * [1] + * + * 1 will stretch + */ + GridModelNG model = CreateGrid(); + model.SetAlignItems(GridItemAlignment::STRETCH); + model.SetRowsTemplate("1fr 1fr"); + + CreateFixedHeightItems(1, 150); + CreateAdaptChildSizeGridItems(1); + + CreateDone(frameNode_); + FlushLayoutTask(frameNode_); + + auto childRect0 = pattern_->GetItemRect(0); + auto childRect1 = pattern_->GetItemRect(1); + EXPECT_EQ(childRect0.Width(), childRect1.Width()); +} + +/** + * @tc.name: Stretch006 + * @tc.desc: Test Grid AlignItems STRETCH + * @tc.type: FUNC + */ +HWTEST_F(GridLayoutTestNg, Stretch006, TestSize.Level1) +{ + /** + * 0 + * [0] + * [0] + * [1] + * + * 1 will not stretch + */ + GridModelNG model = CreateGrid(); + model.SetAlignItems(GridItemAlignment::STRETCH); + model.SetRowsTemplate("1fr 1fr 1fr"); + + CreateBigItem(0, 1, 0, 0, ITEM_WIDTH, ITEM_HEIGHT); + CreateAdaptChildSizeGridItems(1); + + CreateDone(frameNode_); + FlushLayoutTask(frameNode_); + + auto childRect1 = pattern_->GetItemRect(1); + EXPECT_EQ(childRect1.Width(), 0); +} + +/** + * @tc.name: Stretch007 + * @tc.desc: Test Grid AlignItems STRETCH + * @tc.type: FUNC + */ +HWTEST_F(GridLayoutTestNg, Stretch007, TestSize.Level1) +{ + /** + * 0 1 2 + * [0], [0], [3] + * [1], [2], [4] + * + * 1 and 2 will not stretch + * 3 will stretch + */ + GridModelNG model = CreateGrid(); + model.SetAlignItems(GridItemAlignment::STRETCH); + model.SetRowsTemplate("1fr 1fr"); + + CreateBigItem(0, 0, 0, 1, ITEM_WIDTH, ITEM_HEIGHT); + CreateAdaptChildSizeGridItems(3); + CreateFixedHeightItems(1, 150); + + CreateDone(frameNode_); + FlushLayoutTask(frameNode_); + + auto childRect1 = pattern_->GetItemRect(1); + EXPECT_EQ(childRect1.Width(), 0); + + auto childRect3 = pattern_->GetItemRect(3); + auto childRect4 = pattern_->GetItemRect(4); + EXPECT_EQ(childRect4.Width(), childRect3.Width()); +} + +/** + * @tc.name: Stretch008 + * @tc.desc: Test Grid AlignItems STRETCH + * @tc.type: FUNC + */ +HWTEST_F(GridLayoutTestNg, Stretch008, TestSize.Level1) +{ + /** + * 0 1 + * [0], [0] + * [0], [0] + * [1], [2] + * + * 1 and 2 will not stretch + */ + GridModelNG model = CreateGrid(); + model.SetAlignItems(GridItemAlignment::STRETCH); + model.SetRowsTemplate("1fr 1fr 1fr"); + + CreateBigItem(0, 1, 0, 1, ITEM_WIDTH, ITEM_HEIGHT); + CreateAdaptChildSizeGridItems(2); + + CreateDone(frameNode_); + FlushLayoutTask(frameNode_); + + auto childRect1 = pattern_->GetItemRect(1); + EXPECT_EQ(childRect1.Width(), 0); + auto childRect2 = pattern_->GetItemRect(2); + EXPECT_EQ(childRect2.Width(), 0); +} } // namespace OHOS::Ace::NG diff --git a/test/unittest/core/pattern/grid/grid_test_ng.cpp b/test/unittest/core/pattern/grid/grid_test_ng.cpp index 4480b9f708e5e15fc6c5bad31b2a76ec9edd31fa..fce891ee9a056bb54aeddf47ff61bc89f0e5593a 100644 --- a/test/unittest/core/pattern/grid/grid_test_ng.cpp +++ b/test/unittest/core/pattern/grid/grid_test_ng.cpp @@ -241,4 +241,21 @@ GridModelNG GridTestNg::CreateRepeatGrid(int32_t itemNumber, float itemHeight) repeatModel.Create(itemNumber, {}, createFunc, updateFunc, getKeys, getTypes); return model; } + +void GridTestNg::CreateAdaptChildSizeGridItems( + int32_t itemNumber, GridItemStyle gridItemStyle) +{ + for (int32_t i = 0; i < itemNumber; i++) { + ViewStackProcessor::GetInstance()->StartGetAccessRecordingFor(GetElmtId()); + GridItemModelNG itemModel; + itemModel.Create(gridItemStyle); + { + auto columnFrameNode = + FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, GetElmtId(), AceType::MakeRefPtr(true)); + ViewStackProcessor::GetInstance()->Pop(); + } + ViewStackProcessor::GetInstance()->Pop(); + ViewStackProcessor::GetInstance()->StopGetAccessRecording(); + } +} } // namespace OHOS::Ace::NG diff --git a/test/unittest/core/pattern/grid/grid_test_ng.h b/test/unittest/core/pattern/grid/grid_test_ng.h index 7fd4633986f07c97a9ad1ba0fd5c469adc1c9036..a0dbc3abda329fcd880debe7f74d9a454a36c2c8 100644 --- a/test/unittest/core/pattern/grid/grid_test_ng.h +++ b/test/unittest/core/pattern/grid/grid_test_ng.h @@ -23,6 +23,7 @@ #include "test/unittest/core/pattern/test_ng.h" #include "core/components_ng/pattern/button/button_model_ng.h" +#include "core/components_ng/pattern/linear_layout/column_model_ng.h" #include "core/components_ng/pattern/grid/grid_item_model_ng.h" #include "core/components_ng/pattern/grid/grid_item_theme.h" #include "core/components_ng/pattern/grid/grid_model_ng.h" @@ -77,6 +78,7 @@ public: void AddFixedHeightItems(int32_t cnt, float height); void ScrollTo(float position); void UpdateCurrentOffset(float offset, int32_t source = SCROLL_FROM_UPDATE); + void CreateAdaptChildSizeGridItems(int32_t itemNumber, GridItemStyle gridItemStyle = GridItemStyle::NONE); RefPtr frameNode_; RefPtr pattern_; diff --git a/test/unittest/core/pattern/grid/irregular/grid_irregular_layout_test.cpp b/test/unittest/core/pattern/grid/irregular/grid_irregular_layout_test.cpp index 57be4a3172c1cd1fca3fc7b2b503c2d86fa5f9ae..c1b0e5ac0d4ce9980bb4fe0bcbf7126f3849805d 100644 --- a/test/unittest/core/pattern/grid/irregular/grid_irregular_layout_test.cpp +++ b/test/unittest/core/pattern/grid/irregular/grid_irregular_layout_test.cpp @@ -1909,4 +1909,90 @@ HWTEST_F(GridIrregularLayoutTest, Add001, TestSize.Level1) EXPECT_EQ(info.startIndex_, 3); EXPECT_EQ(info.endIndex_, 21); } + +/** + * @tc.name: Stretch001 + * @tc.desc: Test Grid AlignItems STRETCH + * @tc.type: FUNC + */ +HWTEST_F(GridIrregularLayoutTest, Stretch001, TestSize.Level1) +{ + GridLayoutOptions option; + option.irregularIndexes = { + 1, // [1 x 2] + }; + auto onGetIrregularSizeByIndex = [](int32_t index) -> GridItemSize { + if (index == 1) { + return { .rows = 2, .columns = 1 }; + } + return { .rows = 1, .columns = 1 }; + }; + option.getSizeByIndex = std::move(onGetIrregularSizeByIndex); + + GridModelNG model = CreateGrid(); + model.SetAlignItems(GridItemAlignment::STRETCH); + model.SetColumnsTemplate("1fr 1fr"); + model.SetLayoutOptions(option); + + CreateAdaptChildSizeGridItems(1); + CreateFixedHeightItems(1, 150); + CreateAdaptChildSizeGridItems(2); + CreateFixedHeightItems(1, 150); + + CreateDone(frameNode_); + FlushLayoutTask(frameNode_); + + auto childRect0 = pattern_->GetItemRect(0); + EXPECT_EQ(childRect0.Height(), 0); + + auto childRect2 = pattern_->GetItemRect(2); + EXPECT_EQ(childRect2.Height(), 0); + + auto childRect3 = pattern_->GetItemRect(3); + auto childRect4 = pattern_->GetItemRect(4); + EXPECT_EQ(childRect3.Height(), childRect4.Height()); +} + +/** + * @tc.name: Stretch002 + * @tc.desc: Test Grid AlignItems STRETCH + * @tc.type: FUNC + */ +HWTEST_F(GridIrregularLayoutTest, Stretch002, TestSize.Level1) +{ + GridLayoutOptions option; + option.irregularIndexes = { + 0, // [2 x 2] + 3, // [2 x 1] + }; + auto onGetIrregularSizeByIndex = [](int32_t index) -> GridItemSize { + if (index == 0) { + return { .rows = 2, .columns = 2 }; + } + return { .rows = 1, .columns = 2 }; + }; + option.getSizeByIndex = std::move(onGetIrregularSizeByIndex); + + GridModelNG model = CreateGrid(); + model.SetAlignItems(GridItemAlignment::STRETCH); + model.SetColumnsTemplate("1fr 1fr 1fr"); + model.SetLayoutOptions(option); + + CreateFixedHeightItems(1, 150); + CreateAdaptChildSizeGridItems(2); + CreateFixedHeightItems(1, 150); + CreateAdaptChildSizeGridItems(1); + + CreateDone(frameNode_); + FlushLayoutTask(frameNode_); + + auto childRect1 = pattern_->GetItemRect(1); + EXPECT_EQ(childRect1.Height(), 0); + + auto childRect2 = pattern_->GetItemRect(2); + EXPECT_EQ(childRect2.Height(), 0); + + auto childRect4 = pattern_->GetItemRect(4); + EXPECT_EQ(childRect4.Height(), 0); +} } // namespace OHOS::Ace::NG