A game framework written with osu! in mind.
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2// See the LICENCE file in the repository root for full licence text.
3
4using System.Linq;
5using NUnit.Framework;
6using osu.Framework.Graphics;
7using osu.Framework.Graphics.Containers;
8using osu.Framework.Graphics.Shapes;
9using osu.Framework.Graphics.Sprites;
10using osu.Framework.Utils;
11using osuTK;
12using osuTK.Graphics;
13
14namespace osu.Framework.Tests.Visual.Layout
15{
16 public class TestSceneTableContainer : FrameworkTestScene
17 {
18 private TableContainer table;
19
20 [SetUp]
21 public void Setup() => Schedule(() =>
22 {
23 Child = new Container
24 {
25 Anchor = Anchor.Centre,
26 Origin = Anchor.Centre,
27 Size = new Vector2(300),
28 Children = new Drawable[]
29 {
30 new Container
31 {
32 RelativeSizeAxes = Axes.Both,
33 Masking = true,
34 BorderColour = Color4.White,
35 BorderThickness = 2,
36 Child = new Box
37 {
38 RelativeSizeAxes = Axes.Both,
39 Alpha = 0,
40 AlwaysPresent = true
41 }
42 },
43 table = new TableContainer { RelativeSizeAxes = Axes.Both }
44 }
45 };
46 });
47
48 [Test]
49 public void TestBlankTable()
50 {
51 }
52
53 [Test]
54 public void TestOnlyContent()
55 {
56 AddStep("set content", () => table.Content = createContent(2, 2));
57 AddAssert("headers not displayed", () => getGrid().Content.Count == 2);
58 }
59
60 [Test]
61 public void TestOnlyHeaders()
62 {
63 AddStep("set columns", () => table.Columns = new[]
64 {
65 new TableColumn("Col 1"),
66 new TableColumn("Col 2"),
67 });
68 }
69
70 [Test]
71 public void TestContentAndHeaders()
72 {
73 AddStep("set cells", () =>
74 {
75 table.Content = createContent(3, 3);
76 table.Columns = new[]
77 {
78 new TableColumn("Header 1"),
79 new TableColumn("Header 2"),
80 new TableColumn("Header 3"),
81 };
82 });
83
84 AddAssert("4 rows", () => getGrid().Content.Count == 4);
85 AddStep("disable headers", () => table.ShowHeaders = false);
86 AddAssert("3 rows", () => getGrid().Content.Count == 3);
87 }
88
89 [Test]
90 public void TestHeaderLongerThanContent()
91 {
92 AddStep("set cells", () =>
93 {
94 table.Content = createContent(2, 2);
95 table.Columns = new[]
96 {
97 new TableColumn("Header 1"),
98 new TableColumn("Header 2"),
99 new TableColumn("Header 3"),
100 };
101 });
102
103 AddAssert("3 columns", () => getGrid().Content.Max(r => r.Count) == 3);
104 AddStep("disable headers", () => table.ShowHeaders = false);
105 AddAssert("2 columns", () => getGrid().Content.Max(r => r.Count) == 2);
106 }
107
108 [Test]
109 public void TestContentLongerThanHeader()
110 {
111 AddStep("set cells", () =>
112 {
113 table.Content = createContent(3, 3);
114 table.Columns = new[]
115 {
116 new TableColumn("Header 1"),
117 new TableColumn("Header 2"),
118 };
119 });
120
121 AddAssert("3 columns", () => getGrid().Content.Max(r => r.Count) == 3);
122 AddStep("disable headers", () => table.ShowHeaders = false);
123 AddAssert("2 columns", () => getGrid().Content.Max(r => r.Count) == 3);
124 }
125
126 [Test]
127 public void TestColumnsWithAnchors()
128 {
129 AddStep("set content", () =>
130 {
131 table.Content = createContent(3, 3);
132 table.Columns = new[]
133 {
134 new TableColumn("Left", Anchor.CentreLeft),
135 new TableColumn("Centre", Anchor.Centre),
136 new TableColumn("Right", Anchor.CentreRight),
137 };
138 });
139
140 AddAssert("column 0 all left aligned", () => testColumn(0, Anchor.CentreLeft));
141 AddAssert("column 1 all centre aligned", () => testColumn(1, Anchor.Centre));
142 AddAssert("column 2 all right aligned", () => testColumn(2, Anchor.CentreRight));
143
144 AddStep("attempt to change anchor", () =>
145 {
146 var cell = table?.Content?[0, 0];
147 if (cell != null)
148 cell.Anchor = Anchor.Centre;
149 });
150
151 // This currently fails, but should probably pass, but is particularly hard to fix.
152 // It's open to interpretation for how this should work, though, so it's not critical...
153 // AddAssert("column 0 all left aligned", () => testColumn(0, Anchor.CentreLeft));
154
155 AddStep("change columns", () => table.Columns = new[]
156 {
157 new TableColumn("Left", Anchor.CentreRight),
158 new TableColumn("Centre", Anchor.Centre),
159 new TableColumn("Right", Anchor.CentreLeft),
160 });
161
162 AddAssert("column 0 all right aligned", () => testColumn(0, Anchor.CentreRight));
163 AddAssert("column 1 all centre aligned", () => testColumn(1, Anchor.Centre));
164 AddAssert("column 2 all left aligned", () => testColumn(2, Anchor.CentreLeft));
165
166 AddStep("change content", () => table.Content = createContent(4, 4));
167
168 AddAssert("column 0 all right aligned", () => testColumn(0, Anchor.CentreRight));
169 AddAssert("column 1 all centre aligned", () => testColumn(1, Anchor.Centre));
170 AddAssert("column 2 all left aligned", () => testColumn(2, Anchor.CentreLeft));
171 AddAssert("column 3 all top-left aligned", () => testColumn(3, Anchor.TopLeft));
172
173 bool testColumn(int index, Anchor anchor)
174 {
175 for (int r = 0; r < getGrid().Content.Count; r++)
176 {
177 if (getGrid().Content[r][index].Anchor != anchor)
178 return false;
179 }
180
181 return true;
182 }
183 }
184
185 [Test]
186 public void TestChangeColumns()
187 {
188 AddStep("set content", () =>
189 {
190 table.Content = createContent(2, 2);
191 table.Columns = new[]
192 {
193 new TableColumn("Header 1"),
194 new TableColumn("Header 2"),
195 };
196 });
197
198 AddStep("increase columns", () => table.Columns = new[]
199 {
200 new TableColumn("Header 1"),
201 new TableColumn("Header 2"),
202 new TableColumn("Header 3"),
203 });
204
205 AddAssert("3 columns", () => getGrid().Content.Max(r => r.Count) == 3);
206
207 AddStep("decrease columns", () => table.Columns = new[]
208 {
209 new TableColumn("Header 1"),
210 });
211
212 AddAssert("2 columns", () => getGrid().Content.Max(r => r.Count) == 2);
213 }
214
215 [Test]
216 public void TestRowSize()
217 {
218 AddStep("set content", () =>
219 {
220 table.Content = createContent(2, 2);
221 table.RowSize = new Dimension(GridSizeMode.Absolute, 30f);
222 });
223
224 AddAssert("all row size = 30", () => testRows(30));
225 AddStep("add headers", () => table.Columns = new[]
226 {
227 new TableColumn("Header 1"),
228 new TableColumn("Header 2"),
229 new TableColumn("Header 3"),
230 });
231
232 AddAssert("all row size = 30", () => testRows(30));
233 AddStep("change row size", () => table.RowSize = new Dimension(GridSizeMode.Absolute, 50));
234 AddAssert("all row size = 50", () => testRows(50));
235 AddStep("change content", () => table.Content = createContent(4, 4));
236 AddAssert("all row size = 50", () => testRows(50));
237 AddStep("remove custom row size", () => table.RowSize = null);
238 AddAssert("all row size = distributed", () => testRows(table.DrawHeight / 5f));
239
240 bool testRows(float expectedHeight)
241 {
242 for (int row = 0; row < getGrid().Content.Count; row++)
243 {
244 if (!Precision.AlmostEquals(expectedHeight, getGrid().Content[row][0].Parent.DrawHeight))
245 return false;
246 }
247
248 return true;
249 }
250 }
251
252 [Test]
253 public void TestClearGrid()
254 {
255 AddStep("set content", () =>
256 {
257 table.Content = createContent(3, 3);
258 table.Columns = new[]
259 {
260 new TableColumn("Header 1"),
261 new TableColumn("Header 2"),
262 new TableColumn("Header 3"),
263 };
264 });
265
266 AddStep("clear grid", () =>
267 {
268 table.Columns = null;
269 table.Content = null;
270 });
271 }
272
273 private Drawable[,] createContent(int rows, int columns)
274 {
275 var content = new Drawable[rows, columns];
276
277 int cellIndex = 0;
278
279 for (int r = 0; r < rows; r++)
280 {
281 for (int c = 0; c < columns; c++)
282 content[r, c] = new Cell(cellIndex++);
283 }
284
285 return content;
286 }
287
288 private GridContainer getGrid() => (GridContainer)table.InternalChild;
289
290 private class Cell : SpriteText
291 {
292 public Cell(int index)
293 {
294 Text = $"Cell {index}";
295 }
296 }
297 }
298}