Skip to content

Commit fccf7cc

Browse files
hartezrmarinho
andauthored
GridLayout with absolute and auto (#513)
* Grid stuff, in progress * Clean up after rebase; fix arrange call in layout manager * Adding some notes * Update ArrangeChildren method calls * Add missing TypeConverters * Update test values in light of new Arrange call * Formatting fix Co-authored-by: Rui Marinho <me@ruimarinho.net>
1 parent 05ba6f7 commit fccf7cc

24 files changed

+1461
-35
lines changed

src/Controls/samples/Controls.Sample/Pages/MainPage.cs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ void SetupMauiLayout()
3232
var verticalStack = new VerticalStackLayout() { Spacing = 5, BackgroundColor = Color.AntiqueWhite };
3333
var horizontalStack = new HorizontalStackLayout() { Spacing = 2, BackgroundColor = Color.CornflowerBlue };
3434

35+
36+
verticalStack.Add(CreateSampleGrid());
37+
3538
verticalStack.Add(new Label { Text = " ", Padding = new Thickness(10) });
3639
var label = new Label { Text = "End-aligned text", BackgroundColor = Color.Fuchsia, HorizontalTextAlignment = TextAlignment.End };
3740
label.Margin = new Thickness(15, 10, 20, 15);
@@ -47,7 +50,6 @@ void SetupMauiLayout()
4750
verticalStack.Add(new Label { Text = loremIpsum, MaxLines = 2, LineBreakMode = LineBreakMode.TailTruncation });
4851
verticalStack.Add(new Label { Text = "This should have five times the line height!", LineHeight = 5 });
4952

50-
5153
var paddingButton = new Button
5254
{
5355
Padding = new Thickness(40),
@@ -157,6 +159,7 @@ void SetupMauiLayout()
157159
Content = verticalStack
158160
};
159161
}
162+
160163

161164
void SetupCompatibilityLayout()
162165
{
@@ -202,5 +205,36 @@ void SetupCompatibilityLayout()
202205
}
203206

204207
public IView View { get => (IView)Content; set => Content = (View)value; }
208+
209+
IView CreateSampleGrid()
210+
{
211+
var layout = new Microsoft.Maui.Controls.Layout2.GridLayout() { ColumnSpacing = 5, RowSpacing = 8 };
212+
213+
layout.AddRowDefinition(new RowDefinition() { Height = new GridLength(40) });
214+
layout.AddRowDefinition(new RowDefinition() { Height = GridLength.Auto });
215+
216+
layout.AddColumnDefinition(new ColumnDefinition() { Width = new GridLength(100) });
217+
layout.AddColumnDefinition(new ColumnDefinition() { Width = new GridLength(100) });
218+
219+
var topLeft = new Label { Text = "Top Left", BackgroundColor = Color.LightBlue };
220+
layout.Add(topLeft);
221+
222+
var bottomLeft = new Label { Text = "Bottom Left", BackgroundColor = Color.Lavender };
223+
layout.Add(bottomLeft);
224+
layout.SetRow(bottomLeft, 1);
225+
226+
var topRight = new Label { Text = "Top Right", BackgroundColor = Color.Orange };
227+
layout.Add(topRight);
228+
layout.SetColumn(topRight, 1);
229+
230+
var bottomRight = new Label { Text = "Bottom Right", BackgroundColor = Color.MediumPurple };
231+
layout.Add(bottomRight);
232+
layout.SetRow(bottomRight, 1);
233+
layout.SetColumn(bottomRight, 1);
234+
235+
layout.BackgroundColor = Color.Chartreuse;
236+
237+
return layout;
238+
}
205239
}
206240
}

src/Controls/src/Core/ColumnDefinition.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Microsoft.Maui.Controls
44
{
5-
public sealed class ColumnDefinition : BindableObject, IDefinition
5+
public sealed class ColumnDefinition : BindableObject, IDefinition, IGridColumnDefinition
66
{
77
public static readonly BindableProperty WidthProperty = BindableProperty.Create("Width", typeof(GridLength), typeof(ColumnDefinition), new GridLength(1, GridUnitType.Star),
88
propertyChanged: (bindable, oldValue, newValue) => ((ColumnDefinition)bindable).OnSizeChanged());
@@ -12,6 +12,7 @@ public ColumnDefinition()
1212
MinimumWidth = -1;
1313
}
1414

15+
[TypeConverter(typeof(GridLengthTypeConverter))]
1516
public GridLength Width
1617
{
1718
get { return (GridLength)GetValue(WidthProperty); }

src/Controls/src/Core/Grid.cs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
using System.Linq;
66
using Microsoft.Maui.Controls.Internals;
77

8+
89
namespace Microsoft.Maui.Controls
910
{
10-
public partial class Grid : Layout<View>, IGridController, IElementConfiguration<Grid>
11+
public partial class Grid : Layout<View>, IGridController, IElementConfiguration<Grid>, IGridLayout
1112
{
1213
public static readonly BindableProperty RowProperty = BindableProperty.CreateAttached("Row", typeof(int), typeof(Grid), default(int), validateValue: (bindable, value) => (int)value >= 0);
1314

@@ -381,5 +382,48 @@ private int ColumnCount() => Math.Max(
381382
Parent.ColumnDefinitions.Count
382383
);
383384
}
385+
386+
int IGridLayout.GetRow(IView view)
387+
{
388+
if (view is BindableObject bo)
389+
{
390+
return GetRow(bo);
391+
}
392+
393+
throw new InvalidEnumArgumentException($"{nameof(view)} must be a BindableObject");
394+
}
395+
396+
int IGridLayout.GetColumn(IView view)
397+
{
398+
if (view is BindableObject bo)
399+
{
400+
return GetColumn(bo);
401+
}
402+
403+
throw new InvalidEnumArgumentException($"{nameof(view)} must be a BindableObject");
404+
}
405+
406+
int IGridLayout.GetRowSpan(IView view)
407+
{
408+
if (view is BindableObject bo)
409+
{
410+
return GetRowSpan(bo);
411+
}
412+
413+
throw new InvalidEnumArgumentException($"{nameof(view)} must be a BindableObject");
414+
}
415+
416+
int IGridLayout.GetColumnSpan(IView view)
417+
{
418+
if (view is BindableObject bo)
419+
{
420+
return GetColumnSpan(bo);
421+
}
422+
423+
throw new InvalidEnumArgumentException($"{nameof(view)} must be a BindableObject");
424+
}
425+
426+
IReadOnlyList<IGridRowDefinition> IGridLayout.RowDefinitions => RowDefinitions.ToList();
427+
IReadOnlyList<IGridColumnDefinition> IGridLayout.ColumnDefinitions => ColumnDefinitions.ToList();
384428
}
385429
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
using System.Collections.Generic;
2+
using Microsoft.Maui.Layouts;
3+
4+
// This is a temporary namespace until we rename everything and move the legacy layouts
5+
namespace Microsoft.Maui.Controls.Layout2
6+
{
7+
public class GridLayout : Layout, IGridLayout
8+
{
9+
List<IGridRowDefinition> _rowDefinitions = new List<IGridRowDefinition>();
10+
List<IGridColumnDefinition> _columnDefinitions = new List<IGridColumnDefinition>();
11+
12+
public IReadOnlyList<IGridRowDefinition> RowDefinitions => _rowDefinitions;
13+
public IReadOnlyList<IGridColumnDefinition> ColumnDefinitions => _columnDefinitions;
14+
15+
public double RowSpacing { get; set; }
16+
public double ColumnSpacing { get; set; }
17+
18+
Dictionary<IView, GridInfo> _viewInfo = new Dictionary<IView, GridInfo>();
19+
20+
// TODO ezhart This needs to override Remove and clean up any row/column/span info for the removed child
21+
22+
public int GetColumn(IView view)
23+
{
24+
if (_viewInfo.TryGetValue(view, out GridInfo gridInfo))
25+
{
26+
return gridInfo.Col;
27+
}
28+
29+
return 0;
30+
}
31+
32+
public int GetColumnSpan(IView view)
33+
{
34+
if (_viewInfo.TryGetValue(view, out GridInfo gridInfo))
35+
{
36+
return gridInfo.ColSpan;
37+
}
38+
39+
return 1;
40+
}
41+
42+
public int GetRow(IView view)
43+
{
44+
if (_viewInfo.TryGetValue(view, out GridInfo gridInfo))
45+
{
46+
return gridInfo.Row;
47+
}
48+
49+
return 0;
50+
}
51+
52+
public int GetRowSpan(IView view)
53+
{
54+
if (_viewInfo.TryGetValue(view, out GridInfo gridInfo))
55+
{
56+
return gridInfo.RowSpan;
57+
}
58+
59+
return 1;
60+
}
61+
62+
protected override ILayoutManager CreateLayoutManager() => new GridLayoutManager(this);
63+
64+
public void AddRowDefinition(IGridRowDefinition gridRowDefinition)
65+
{
66+
_rowDefinitions.Add(gridRowDefinition);
67+
}
68+
69+
public void AddColumnDefinition(IGridColumnDefinition gridColumnDefinition)
70+
{
71+
_columnDefinitions.Add(gridColumnDefinition);
72+
}
73+
74+
public void SetRow(IView view, int row)
75+
{
76+
if (_viewInfo.TryGetValue(view, out GridInfo gridInfo))
77+
{
78+
gridInfo.Row = row;
79+
}
80+
else
81+
{
82+
_viewInfo[view] = new GridInfo { Row = row };
83+
}
84+
}
85+
86+
public void SetRowSpan(IView view, int span)
87+
{
88+
if (_viewInfo.TryGetValue(view, out GridInfo gridInfo))
89+
{
90+
gridInfo.RowSpan = span;
91+
}
92+
else
93+
{
94+
_viewInfo[view] = new GridInfo { RowSpan = span };
95+
}
96+
}
97+
98+
public void SetColumn(IView view, int col)
99+
{
100+
if (_viewInfo.TryGetValue(view, out GridInfo gridInfo))
101+
{
102+
gridInfo.Col = col;
103+
}
104+
else
105+
{
106+
_viewInfo[view] = new GridInfo { Col = col };
107+
}
108+
}
109+
110+
public void SetColumnSpan(IView view, int span)
111+
{
112+
if (_viewInfo.TryGetValue(view, out GridInfo gridInfo))
113+
{
114+
gridInfo.ColSpan = span;
115+
}
116+
else
117+
{
118+
_viewInfo[view] = new GridInfo { ColSpan = span };
119+
}
120+
}
121+
122+
class GridInfo
123+
{
124+
public int Row { get; set; }
125+
public int Col { get; set; }
126+
public int RowSpan { get; set; } = 1;
127+
public int ColSpan { get; set; } = 1;
128+
}
129+
}
130+
}

src/Controls/src/Core/Layout/Layout.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
using System.Collections.Generic;
33
using Microsoft.Maui.Layouts;
44

5-
6-
75
// This is a temporary namespace until we rename everything and move the legacy layouts
86
namespace Microsoft.Maui.Controls.Layout2
97
{
@@ -61,7 +59,7 @@ protected override void ArrangeOverride(Rectangle bounds)
6159

6260
Arrange(bounds);
6361

64-
LayoutManager.Arrange(Frame);
62+
LayoutManager.ArrangeChildren(Frame);
6563
IsArrangeValid = true;
6664
Handler?.SetFrame(Frame);
6765
}

src/Controls/src/Core/Layout/StackLayout.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System.Linq;
2-
1+
using System.Linq;
32

43
// This is a temporary namespace until we rename everything and move the legacy layouts
54
namespace Microsoft.Maui.Controls.Layout2

src/Controls/src/Core/Layout/VerticalStackLayout.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using Microsoft.Maui.Handlers;
21
using Microsoft.Maui.Layouts;
32

43

src/Controls/src/Core/RowDefinition.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Microsoft.Maui.Controls
44
{
5-
public sealed class RowDefinition : BindableObject, IDefinition
5+
public sealed class RowDefinition : BindableObject, IDefinition, IGridRowDefinition
66
{
77
public static readonly BindableProperty HeightProperty = BindableProperty.Create("Height", typeof(GridLength), typeof(RowDefinition), new GridLength(1, GridUnitType.Star),
88
propertyChanged: (bindable, oldValue, newValue) => ((RowDefinition)bindable).OnSizeChanged());
@@ -12,6 +12,7 @@ public RowDefinition()
1212
MinimumHeight = -1;
1313
}
1414

15+
[TypeConverter(typeof(GridLengthTypeConverter))]
1516
public GridLength Height
1617
{
1718
get { return (GridLength)GetValue(HeightProperty); }
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace Microsoft.Maui
2+
{
3+
public interface IGridColumnDefinition
4+
{
5+
GridLength Width { get; }
6+
}
7+
}

src/Core/src/Core/IGridLayout.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System.Collections.Generic;
2+
3+
namespace Microsoft.Maui
4+
{
5+
public interface IGridLayout : ILayout
6+
{
7+
IReadOnlyList<IGridRowDefinition> RowDefinitions { get; }
8+
IReadOnlyList<IGridColumnDefinition> ColumnDefinitions { get; }
9+
10+
double RowSpacing { get; }
11+
double ColumnSpacing { get; }
12+
13+
int GetRow(IView view);
14+
int GetRowSpan(IView view);
15+
16+
int GetColumn(IView view);
17+
int GetColumnSpan(IView view);
18+
}
19+
}

0 commit comments

Comments
 (0)