From ff848574702d72faa85c07ee7edf3028606b125d Mon Sep 17 00:00:00 2001 From: Jaehyun Cho Date: Wed, 18 Aug 2021 21:54:00 +0900 Subject: [PATCH] [NUI] Fix to measure GridLayout's children sizes correctly Previously, if child's measured size is 0, then GridLayout does not update the child's measured size when the child's size is set by using GridLayout APIs. e.g. SetHorizontalStretch(child, GridLayout.StretchFlags.ExpandAndFill); Moreover, if child has its own size and ExpandAndFill is set, then child's size is set to be its own size (its measured size) plus its expanded size. e.g. parent size is 100. child1's measured size is 50 and ExpandAndFill. child2's measured size is 0 and ExpandAndFill. Then, child1's size is 50 + 25 = 75 and child2's size is 25. To resolve the above, GridLayout updates child's measured size in OnLayout() and child's size is set to be the bigger one between its measured size and its expanded size. --- .../src/internal/Layouting/GridLocations.cs | 17 ++++++-- src/Tizen.NUI/src/public/Layouting/GridLayout.cs | 49 +++++++++++++++++++++- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/src/Tizen.NUI/src/internal/Layouting/GridLocations.cs b/src/Tizen.NUI/src/internal/Layouting/GridLocations.cs index d3f9d6c..66fac24 100755 --- a/src/Tizen.NUI/src/internal/Layouting/GridLocations.cs +++ b/src/Tizen.NUI/src/internal/Layouting/GridLocations.cs @@ -293,9 +293,20 @@ namespace Tizen.NUI for (int i = 0; i < edgeList.Length; i++) { - float newLocation = locations[edgeList[i].Start] + edgeList[i].Edge + edgeList[i].ExpandedSize; - if (edgeList[i].Edge + edgeList[i].ExpandedSize > 0) - newLocation += space; + float newLocation = locations[edgeList[i].Start]; + // view's size is set to be the bigger one between its measured size and its expanded size. + if (edgeList[i].Edge > edgeList[i].ExpandedSize) + { + newLocation += edgeList[i].Edge; + if (edgeList[i].Edge > 0) + newLocation += space; + } + else + { + newLocation += edgeList[i].ExpandedSize; + if (edgeList[i].ExpandedSize > 0) + newLocation += space; + } if (locations[edgeList[i].End] < newLocation) { diff --git a/src/Tizen.NUI/src/public/Layouting/GridLayout.cs b/src/Tizen.NUI/src/public/Layouting/GridLayout.cs index 03f8e33..fb11baf 100755 --- a/src/Tizen.NUI/src/public/Layouting/GridLayout.cs +++ b/src/Tizen.NUI/src/public/Layouting/GridLayout.cs @@ -415,19 +415,64 @@ namespace Tizen.NUI float t = vLocations[row] + Padding.Top + view.Margin.Top; float width = hLocations[columnEnd] - hLocations[column] - ColumnSpacing - view.Margin.Start - view.Margin.End; float height = vLocations[rowEnd] - vLocations[row] - RowSpacing - view.Margin.Top - view.Margin.Bottom; + bool needMeasuredWidth = false; + bool needMeasuredHeight = false; - if (!child.Column.Stretch.HasFlag(StretchFlags.Fill)) + if (child.Column.Stretch.HasFlag(StretchFlags.Fill)) + { + needMeasuredWidth = true; + } + else { l += (width - child.LayoutItem.MeasuredWidth.Size.AsDecimal()) * halign.ToFloat(); width = child.LayoutItem.MeasuredWidth.Size.AsDecimal(); } - if (!child.Row.Stretch.HasFlag(StretchFlags.Fill)) + if (child.Row.Stretch.HasFlag(StretchFlags.Fill)) + { + needMeasuredHeight = true; + } + else { t += (height - child.LayoutItem.MeasuredHeight.Size.AsDecimal()) * valign.ToFloat(); height = child.LayoutItem.MeasuredHeight.Size.AsDecimal(); } + if (needMeasuredWidth || needMeasuredHeight) + { + // To calculate the grand children's Measure() with the mode type Exactly, + // children's Measure() is called with MatchParent if the children have WrapContent. + // + // i.e. + // If children have Wrapcontent and the grand children have MatchParent, + // then grand children's MeasuredWidth/Height do not fill the children + // because the grand children's Measure() is called with the mode type AtMost. + int widthSpecification = child.LayoutItem.Owner.WidthSpecification; + int heightSpecification = child.LayoutItem.Owner.HeightSpecification; + + if (needMeasuredWidth) + { + child.LayoutItem.Owner.WidthSpecification = LayoutParamPolicies.MatchParent; + } + if (needMeasuredHeight) + { + child.LayoutItem.Owner.HeightSpecification = LayoutParamPolicies.MatchParent; + } + + MeasureSpecification widthSpec = new MeasureSpecification(new LayoutLength(width), MeasureSpecification.ModeType.Exactly); + MeasureSpecification heightSpec = new MeasureSpecification(new LayoutLength(height), MeasureSpecification.ModeType.Exactly); + MeasureChild(child.LayoutItem, widthSpec, heightSpec); + + if (needMeasuredWidth) + { + child.LayoutItem.Owner.WidthSpecification = widthSpecification; + } + if (needMeasuredHeight) + { + child.LayoutItem.Owner.HeightSpecification = heightSpecification; + } + } + child.LayoutItem.Layout(new LayoutLength(l), new LayoutLength(t), new LayoutLength(l + width), new LayoutLength(t + height)); } } -- 2.7.4