Skip to content

Commit

Permalink
Handle visibility and zero size properly
Browse files Browse the repository at this point in the history
  • Loading branch information
kmcginnes committed Jun 17, 2016
1 parent ee27f74 commit ab76e26
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 18 deletions.
37 changes: 23 additions & 14 deletions src/AutoGrid/StackPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ protected override Size MeasureOverride(Size constraint)
double parentHeight = 0; // Our current required height due to children thus far.
double accumulatedWidth = 0; // Total width consumed by children.
double accumulatedHeight = 0; // Total height consumed by children.


var isHorizontal = Orientation == Orientation.Horizontal;
foreach (var child in children.OfType<UIElement>().Where(x => GetFill(x) == StackPanelFill.Auto))
{
Size childConstraint; // Contains the suggested input constraint for this child.
Size childDesiredSize; // Contains the return size from child measure.

// Child constraint is the remaining size; this is total size minus size consumed by previous children.
childConstraint = Orientation == Orientation.Horizontal
childConstraint = isHorizontal
? new Size(Math.Max(0.0, constraint.Width - accumulatedWidth),
Math.Max(accumulatedHeight, constraint.Height))
: new Size(Math.Max(accumulatedWidth, constraint.Width),
Expand All @@ -32,7 +33,7 @@ protected override Size MeasureOverride(Size constraint)
child.Measure(childConstraint);
childDesiredSize = child.DesiredSize;

if (Orientation == Orientation.Horizontal)
if (isHorizontal)
{
accumulatedWidth += childDesiredSize.Width;
accumulatedHeight = Math.Max(accumulatedHeight, childDesiredSize.Height);
Expand All @@ -44,10 +45,13 @@ protected override Size MeasureOverride(Size constraint)
}
}

var marginMultiplier = Math.Max(children.Count - 1, 0);
var visibleChildrenCount = children
.OfType<UIElement>()
.Count(x => isHorizontal ? x.DesiredSize.Width != 0 : x.DesiredSize.Height != 0);
var marginMultiplier = Math.Max(visibleChildrenCount - 1, 0);
var marginToAdd = MarginBetweenChildren*marginMultiplier;

if (Orientation == Orientation.Horizontal)
if (isHorizontal)
{
accumulatedWidth += marginToAdd;
}
Expand All @@ -62,7 +66,7 @@ protected override Size MeasureOverride(Size constraint)
Size childDesiredSize; // Contains the return size from child measure.

// Child constraint is the remaining size; this is total size minus size consumed by previous children.
childConstraint = Orientation == Orientation.Horizontal
childConstraint = isHorizontal
? new Size(Math.Max(0.0, constraint.Width - accumulatedWidth),
Math.Max(accumulatedHeight, constraint.Height))
: new Size(Math.Max(accumulatedWidth, constraint.Width),
Expand All @@ -72,7 +76,7 @@ protected override Size MeasureOverride(Size constraint)
child.Measure(childConstraint);
childDesiredSize = child.DesiredSize;

if (Orientation == Orientation.Horizontal)
if (isHorizontal)
{
accumulatedWidth += childDesiredSize.Width;
accumulatedHeight = Math.Max(accumulatedHeight, childDesiredSize.Height);
Expand All @@ -99,9 +103,12 @@ protected override Size ArrangeOverride(Size arrangeSize)
double accumulatedLeft = 0;
double accumulatedTop = 0;

var marginMultiplier = Math.Max(totalChildrenCount - 1, 0);
var totalMarginToAdd = MarginBetweenChildren * marginMultiplier;
var isHorizontal = Orientation == Orientation.Horizontal;
var visibleChildrenCount = children
.OfType<UIElement>()
.Count(x => isHorizontal ? x.DesiredSize.Width != 0 : x.DesiredSize.Height != 0);
var marginMultiplier = Math.Max(visibleChildrenCount - 1, 0);
var totalMarginToAdd = MarginBetweenChildren * marginMultiplier;

double allAutoSizedSum = 0.0;
int countOfFillTypes = 0;
Expand All @@ -110,7 +117,8 @@ protected override Size ArrangeOverride(Size arrangeSize)
var fillType = GetFill(child);
if (fillType == StackPanelFill.Fill)
{
countOfFillTypes += 1;
if (isHorizontal ? child.DesiredSize.Width != 0 : child.DesiredSize.Height != 0)
countOfFillTypes += 1;
}
else
{
Expand All @@ -128,11 +136,12 @@ protected override Size ArrangeOverride(Size arrangeSize)
{
UIElement child = children[i];
if (child == null) { continue; }
Size childDesiredSize = child.DesiredSize;
var isCollapsed = isHorizontal ? childDesiredSize.Width == 0 : childDesiredSize.Height == 0;
var isLastChild = i == totalChildrenCount - 1;
var marginToAdd = isLastChild ? 0 : MarginBetweenChildren;
var marginToAdd = isLastChild || isCollapsed ? 0 : MarginBetweenChildren;
var fillType = GetFill(child);

Size childDesiredSize = child.DesiredSize;
Rect rcChild = new Rect(
accumulatedLeft,
accumulatedTop,
Expand All @@ -141,14 +150,14 @@ protected override Size ArrangeOverride(Size arrangeSize)

if (isHorizontal)
{
rcChild.Width = fillType == StackPanelFill.Auto ? childDesiredSize.Width : fillTypeSize;
rcChild.Width = fillType == StackPanelFill.Auto || isCollapsed ? childDesiredSize.Width : fillTypeSize;
rcChild.Height = arrangeSize.Height;
accumulatedLeft += rcChild.Width + marginToAdd;
}
else
{
rcChild.Width = arrangeSize.Width;
rcChild.Height = fillType == StackPanelFill.Auto ? childDesiredSize.Height : fillTypeSize;
rcChild.Height = fillType == StackPanelFill.Auto || isCollapsed ? childDesiredSize.Height : fillTypeSize;
accumulatedTop += rcChild.Height + marginToAdd;
}

Expand Down
11 changes: 7 additions & 4 deletions src/AutoGridSample/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,18 @@
<TextBox/>
</st:AutoGrid>
<st:StackPanel st:StackPanel.Fill="Fill" MarginBetweenChildren="10">
<TextBlock TextWrapping="Wrap" Text="Lebowski ipsum you think veer kidding und making mit de funny stuff? Dolor sit amet, consectetur. Are they gonna hurt us, Walter? Adipiscing elit praesent ac magna justo pellentesque ac. I mean his wife goes out and owes money and they pee on my rug. Lectus quis elit blandit fringilla a ut turpis praesent felis ligula, malesuada suscipit malesuada. And so, Theodore Donald Karabotsos, in accordance with what we think your dying wishes might well have been, we commit your mortal remains to the bosom of the Pacific Ocean, which you loved so well. Non, ultrices non urna sed orci ipsum, placerat id condimentum rutrum, rhoncus ac lorem."/>
<TextBlock TextWrapping="Wrap" Visibility="Visible" Text="Lebowski ipsum you think veer kidding und making mit de funny stuff? Dolor sit amet, consectetur. Are they gonna hurt us, Walter? Adipiscing elit praesent ac magna justo pellentesque ac. I mean his wife goes out and owes money and they pee on my rug. Lectus quis elit blandit fringilla a ut turpis praesent felis ligula, malesuada suscipit malesuada. And so, Theodore Donald Karabotsos, in accordance with what we think your dying wishes might well have been, we commit your mortal remains to the bosom of the Pacific Ocean, which you loved so well. Non, ultrices non urna sed orci ipsum, placerat id condimentum rutrum, rhoncus ac lorem."/>
<TextBlock Text="Some" HorizontalAlignment="Center"/>
<TextBlock Text="More" HorizontalAlignment="Center"/>
<TextBlock Text="More" Visibility="Collapsed" HorizontalAlignment="Center"/>
<TextBlock Text="Text" HorizontalAlignment="Center"/>
</st:StackPanel>
<st:StackPanel Orientation="Horizontal" MarginBetweenChildren="10" Margin="10">
<Button Content="Info" HorizontalAlignment="Left" st:StackPanel.Fill="Fill"/>
<st:StackPanel Orientation="Horizontal" MarginBetweenChildren="20" Margin="10">
<Button Content="Info" />
<Button Content="Info" Visibility="Visible" st:StackPanel.Fill="Fill" />
<Button Content="Cancel"/>
<Button Content="Save" Visibility="Collapsed"/>
<Button Content="Save"/>
<Button Content="Save" st:StackPanel.Fill="Fill"/>
</st:StackPanel>
</st:StackPanel>
</Window>

0 comments on commit ab76e26

Please sign in to comment.