1 /* Copyright (C) 2019 Red Hat, Inc.
2  *
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 2 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
15  */
16 #include <gtk/gtk.h>
17 
18 #define GTK_TYPE_GIZMO                 (gtk_gizmo_get_type ())
19 #define GTK_GIZMO(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_GIZMO, GtkGizmo))
20 #define GTK_GIZMO_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_GIZMO, GtkGizmoClass))
21 #define GTK_IS_GIZMO(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_GIZMO))
22 #define GTK_IS_GIZMO_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_GIZMO))
23 #define GTK_GIZMO_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_GIZMO, GtkGizmoClass))
24 
25 typedef struct _GtkGizmo GtkGizmo;
26 
27 struct _GtkGizmo {
28   GtkWidget parent;
29 
30   const char *name;
31   int min_width;
32   int min_height;
33   int nat_width;
34   int nat_height;
35   int width;
36   int height;
37 };
38 
39 typedef GtkWidgetClass GtkGizmoClass;
40 
41 G_DEFINE_TYPE (GtkGizmo, gtk_gizmo, GTK_TYPE_WIDGET);
42 
43 static void
gtk_gizmo_measure(GtkWidget * widget,GtkOrientation orientation,int for_size,int * minimum,int * natural,int * minimum_baseline,int * natural_baseline)44 gtk_gizmo_measure (GtkWidget      *widget,
45                    GtkOrientation  orientation,
46                    int             for_size,
47                    int            *minimum,
48                    int            *natural,
49                    int            *minimum_baseline,
50                    int            *natural_baseline)
51 {
52   GtkGizmo *self = GTK_GIZMO (widget);
53 
54   if (orientation == GTK_ORIENTATION_HORIZONTAL)
55     {
56       *minimum = self->min_width;
57       *natural = self->nat_width;
58     }
59   else
60     {
61       *minimum = self->min_height;
62       *natural = self->nat_height;
63     }
64 }
65 
66 static void
gtk_gizmo_size_allocate(GtkWidget * widget,int width,int height,int baseline)67 gtk_gizmo_size_allocate (GtkWidget *widget,
68                          int        width,
69                          int        height,
70                          int        baseline)
71 {
72   GtkGizmo *self = GTK_GIZMO (widget);
73 
74   self->width = width;
75   self->height = height;
76 }
77 
78 static void
gtk_gizmo_class_init(GtkGizmoClass * klass)79 gtk_gizmo_class_init (GtkGizmoClass *klass)
80 {
81   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
82 
83   widget_class->measure = gtk_gizmo_measure;
84   widget_class->size_allocate = gtk_gizmo_size_allocate;
85 }
86 
87 static void
gtk_gizmo_init(GtkGizmo * self)88 gtk_gizmo_init (GtkGizmo *self)
89 {
90 }
91 
92 /* Create a grid with three children in row
93  *
94  * +--------+--------+--------+
95  * | child1 | child2 | child3 |
96  * +--------+--------+--------+
97  *
98  * Verify that
99  * - the layout has the expected min and nat sizes
100  * - the children get their nat width when the layout does
101  * - they all get the same height
102  */
103 static void
test_simple_row(void)104 test_simple_row (void)
105 {
106   GtkWidget *window;
107   GtkWidget *parent;
108   GtkLayoutManager *layout;
109   GtkGizmo *child1;
110   GtkGizmo *child2;
111   GtkGizmo *child3;
112   GtkLayoutChild *lc;
113   int minimum, natural;
114 
115   window = gtk_window_new ();
116   parent = g_object_new (GTK_TYPE_GIZMO, NULL);
117   gtk_window_set_child (GTK_WINDOW (window), parent);
118 
119   layout = gtk_grid_layout_new ();
120   gtk_widget_set_layout_manager (parent, layout);
121 
122   child1 = g_object_new (GTK_TYPE_GIZMO, NULL);
123   child2 = g_object_new (GTK_TYPE_GIZMO, NULL);
124   child3 = g_object_new (GTK_TYPE_GIZMO, NULL);
125 
126   child1->name = "child1";
127   child1->min_width = 10;
128   child1->min_height = 10;
129   child1->nat_width = 20;
130   child1->nat_height = 20;
131   child2->name = "child2";
132   child2->min_width = 20;
133   child2->min_height = 20;
134   child2->nat_width = 30;
135   child2->nat_height = 30;
136   child3->name = "child3";
137   child3->min_width = 30;
138   child3->min_height = 30;
139   child3->nat_width = 40;
140   child3->nat_height = 40;
141 
142   gtk_widget_set_parent (GTK_WIDGET (child1), parent);
143   gtk_widget_set_parent (GTK_WIDGET (child2), parent);
144   gtk_widget_set_parent (GTK_WIDGET (child3), parent);
145 
146   lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child1));
147   gtk_grid_layout_child_set_column (GTK_GRID_LAYOUT_CHILD (lc), 0);
148   lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child2));
149   gtk_grid_layout_child_set_column (GTK_GRID_LAYOUT_CHILD (lc), 1);
150   lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child3));
151   gtk_grid_layout_child_set_column (GTK_GRID_LAYOUT_CHILD (lc), 2);
152 
153   gtk_layout_manager_measure (layout,
154                               parent,
155                               GTK_ORIENTATION_HORIZONTAL,
156                               -1,
157                               &minimum,
158                               &natural,
159                               NULL,
160                               NULL);
161 
162   g_assert_cmpint (minimum, ==, 10 + 20 + 30);
163   g_assert_cmpint (natural, ==, 20 + 30 + 40);
164 
165   gtk_layout_manager_measure (layout,
166                               parent,
167                               GTK_ORIENTATION_VERTICAL,
168                               -1,
169                               &minimum,
170                               &natural,
171                               NULL,
172                               NULL);
173 
174   g_assert_cmpint (minimum, ==, 30);
175   g_assert_cmpint (natural, ==, 40);
176 
177   gtk_layout_manager_allocate (layout, parent, 90, 40, 0);
178 
179   g_assert_cmpint (child1->width, ==, 20);
180   g_assert_cmpint (child2->width, ==, 30);
181   g_assert_cmpint (child3->width, ==, 40);
182 
183   g_assert_cmpint (child1->height, ==, 40);
184   g_assert_cmpint (child2->height, ==, 40);
185   g_assert_cmpint (child3->height, ==, 40);
186 
187   gtk_widget_unparent (GTK_WIDGET (child1));
188   gtk_widget_unparent (GTK_WIDGET (child2));
189   gtk_widget_unparent (GTK_WIDGET (child3));
190 
191   gtk_window_destroy (GTK_WINDOW (window));
192 }
193 
194 /* same as the previous test, with a column
195  */
196 static void
test_simple_column(void)197 test_simple_column (void)
198 {
199   GtkWidget *window;
200   GtkWidget *parent;
201   GtkLayoutManager *layout;
202   GtkGizmo *child1;
203   GtkGizmo *child2;
204   GtkGizmo *child3;
205   GtkLayoutChild *lc;
206   int minimum, natural;
207 
208   window = gtk_window_new ();
209   parent = g_object_new (GTK_TYPE_GIZMO, NULL);
210   gtk_window_set_child (GTK_WINDOW (window), parent);
211 
212   layout = gtk_grid_layout_new ();
213   gtk_widget_set_layout_manager (parent, layout);
214 
215   child1 = g_object_new (GTK_TYPE_GIZMO, NULL);
216   child2 = g_object_new (GTK_TYPE_GIZMO, NULL);
217   child3 = g_object_new (GTK_TYPE_GIZMO, NULL);
218 
219   child1->name = "child1";
220   child1->min_width = 10;
221   child1->min_height = 10;
222   child1->nat_width = 20;
223   child1->nat_height = 20;
224   child2->name = "child2";
225   child2->min_width = 20;
226   child2->min_height = 20;
227   child2->nat_width = 30;
228   child2->nat_height = 30;
229   child3->name = "child3";
230   child3->min_width = 30;
231   child3->min_height = 30;
232   child3->nat_width = 40;
233   child3->nat_height = 40;
234 
235   gtk_widget_set_parent (GTK_WIDGET (child1), parent);
236   gtk_widget_set_parent (GTK_WIDGET (child2), parent);
237   gtk_widget_set_parent (GTK_WIDGET (child3), parent);
238 
239   lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child1));
240   gtk_grid_layout_child_set_row (GTK_GRID_LAYOUT_CHILD (lc), 0);
241   lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child2));
242   gtk_grid_layout_child_set_row (GTK_GRID_LAYOUT_CHILD (lc), 1);
243   lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child3));
244   gtk_grid_layout_child_set_row (GTK_GRID_LAYOUT_CHILD (lc), 2);
245 
246   gtk_layout_manager_measure (layout,
247                               parent,
248                               GTK_ORIENTATION_HORIZONTAL,
249                               -1,
250                               &minimum,
251                               &natural,
252                               NULL,
253                               NULL);
254 
255   g_assert_cmpint (minimum, ==, 30);
256   g_assert_cmpint (natural, ==, 40);
257 
258   gtk_layout_manager_measure (layout,
259                               parent,
260                               GTK_ORIENTATION_VERTICAL,
261                               -1,
262                               &minimum,
263                               &natural,
264                               NULL,
265                               NULL);
266 
267   g_assert_cmpint (minimum, ==, 10 + 20 + 30);
268   g_assert_cmpint (natural, ==, 20 + 30 + 40);
269 
270   gtk_layout_manager_allocate (layout, parent, 40, 90, 0);
271 
272   g_assert_cmpint (child1->width, ==, 40);
273   g_assert_cmpint (child2->width, ==, 40);
274   g_assert_cmpint (child3->width, ==, 40);
275 
276   g_assert_cmpint (child1->height, ==, 20);
277   g_assert_cmpint (child2->height, ==, 30);
278   g_assert_cmpint (child3->height, ==, 40);
279 
280   gtk_widget_unparent (GTK_WIDGET (child1));
281   gtk_widget_unparent (GTK_WIDGET (child2));
282   gtk_widget_unparent (GTK_WIDGET (child3));
283 
284   gtk_window_destroy (GTK_WINDOW (window));
285 }
286 
287 /* Create a grid with spanning children
288  *
289  * +--------+-----------------+
290  * | child1 |      child2     |
291  * +--------+--------+--------+
292  * |      child3     | child4 |
293  * +-----------------+--------+
294  *
295  * Verify that
296  * - the layout has the expected min and nat sizes
297  * - the children get their nat width when the layout does
298  */
299 static void
test_spans(void)300 test_spans (void)
301 {
302   GtkWidget *window;
303   GtkWidget *parent;
304   GtkLayoutManager *layout;
305   GtkGizmo *child1;
306   GtkGizmo *child2;
307   GtkGizmo *child3;
308   GtkGizmo *child4;
309   GtkLayoutChild *lc;
310   int minimum, natural;
311 
312   window = gtk_window_new ();
313   parent = g_object_new (GTK_TYPE_GIZMO, NULL);
314   gtk_window_set_child (GTK_WINDOW (window), parent);
315 
316   layout = gtk_grid_layout_new ();
317   gtk_widget_set_layout_manager (parent, layout);
318 
319   child1 = g_object_new (GTK_TYPE_GIZMO, NULL);
320   child2 = g_object_new (GTK_TYPE_GIZMO, NULL);
321   child3 = g_object_new (GTK_TYPE_GIZMO, NULL);
322   child4 = g_object_new (GTK_TYPE_GIZMO, NULL);
323 
324   child1->name = "child1";
325   child1->min_width = 10;
326   child1->min_height = 10;
327   child1->nat_width = 20;
328   child1->nat_height = 20;
329   child2->name = "child2";
330   child2->min_width = 20;
331   child2->min_height = 20;
332   child2->nat_width = 30;
333   child2->nat_height = 30;
334   child3->name = "child3";
335   child3->min_width = 30;
336   child3->min_height = 30;
337   child3->nat_width = 40;
338   child3->nat_height = 40;
339   child4->name = "child4";
340   child4->min_width = 30;
341   child4->min_height = 30;
342   child4->nat_width = 40;
343   child4->nat_height = 40;
344 
345   gtk_widget_set_parent (GTK_WIDGET (child1), parent);
346   gtk_widget_set_parent (GTK_WIDGET (child2), parent);
347   gtk_widget_set_parent (GTK_WIDGET (child3), parent);
348   gtk_widget_set_parent (GTK_WIDGET (child4), parent);
349 
350   lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child1));
351   gtk_grid_layout_child_set_row (GTK_GRID_LAYOUT_CHILD (lc), 0);
352   gtk_grid_layout_child_set_column (GTK_GRID_LAYOUT_CHILD (lc), 0);
353 
354   lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child2));
355   gtk_grid_layout_child_set_row (GTK_GRID_LAYOUT_CHILD (lc), 0);
356   gtk_grid_layout_child_set_column (GTK_GRID_LAYOUT_CHILD (lc), 1);
357   gtk_grid_layout_child_set_column_span (GTK_GRID_LAYOUT_CHILD (lc), 2);
358 
359   lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child3));
360   gtk_grid_layout_child_set_row (GTK_GRID_LAYOUT_CHILD (lc), 1);
361   gtk_grid_layout_child_set_column (GTK_GRID_LAYOUT_CHILD (lc), 0);
362   gtk_grid_layout_child_set_column_span (GTK_GRID_LAYOUT_CHILD (lc), 2);
363 
364   lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child4));
365   gtk_grid_layout_child_set_row (GTK_GRID_LAYOUT_CHILD (lc), 1);
366   gtk_grid_layout_child_set_column (GTK_GRID_LAYOUT_CHILD (lc), 2);
367 
368   gtk_layout_manager_measure (layout,
369                               parent,
370                               GTK_ORIENTATION_HORIZONTAL,
371                               -1,
372                               &minimum,
373                               &natural,
374                               NULL,
375                               NULL);
376 
377   g_assert_cmpint (minimum, ==, 60);
378   g_assert_cmpint (natural, ==, 80);
379 
380   gtk_layout_manager_measure (layout,
381                               parent,
382                               GTK_ORIENTATION_VERTICAL,
383                               -1,
384                               &minimum,
385                               &natural,
386                               NULL,
387                               NULL);
388 
389   g_assert_cmpint (minimum, ==, 50);
390   g_assert_cmpint (natural, ==, 70);
391 
392   gtk_layout_manager_allocate (layout, parent, 80, 70, 0);
393 
394   g_assert_cmpint (child1->width, ==, 30);
395   g_assert_cmpint (child2->width, ==, 50);
396   g_assert_cmpint (child3->width, ==, 40);
397   g_assert_cmpint (child4->width, ==, 40);
398 
399   g_assert_cmpint (child1->height, ==, 30);
400   g_assert_cmpint (child2->height, ==, 30);
401   g_assert_cmpint (child3->height, ==, 40);
402   g_assert_cmpint (child4->height, ==, 40);
403 
404   gtk_widget_unparent (GTK_WIDGET (child1));
405   gtk_widget_unparent (GTK_WIDGET (child2));
406   gtk_widget_unparent (GTK_WIDGET (child3));
407   gtk_widget_unparent (GTK_WIDGET (child4));
408 
409   gtk_window_destroy (GTK_WINDOW (window));
410 }
411 
412 /* Create a 2x2 homogeneous grid and verify
413  * all children get the same size.
414  */
415 static void
test_homogeneous(void)416 test_homogeneous (void)
417 {
418   GtkWidget *window;
419   GtkWidget *parent;
420   GtkLayoutManager *layout;
421   GtkGizmo *child1;
422   GtkGizmo *child2;
423   GtkGizmo *child3;
424   GtkGizmo *child4;
425   GtkLayoutChild *lc;
426   int minimum, natural;
427 
428   window = gtk_window_new ();
429   parent = g_object_new (GTK_TYPE_GIZMO, NULL);
430   gtk_window_set_child (GTK_WINDOW (window), parent);
431 
432   layout = gtk_grid_layout_new ();
433   gtk_grid_layout_set_row_homogeneous (GTK_GRID_LAYOUT (layout), TRUE);
434   gtk_grid_layout_set_column_homogeneous (GTK_GRID_LAYOUT (layout), TRUE);
435   gtk_widget_set_layout_manager (parent, layout);
436 
437   child1 = g_object_new (GTK_TYPE_GIZMO, NULL);
438   child2 = g_object_new (GTK_TYPE_GIZMO, NULL);
439   child3 = g_object_new (GTK_TYPE_GIZMO, NULL);
440   child4 = g_object_new (GTK_TYPE_GIZMO, NULL);
441 
442   child1->name = "child1";
443   child1->min_width = 10;
444   child1->min_height = 10;
445   child1->nat_width = 20;
446   child1->nat_height = 20;
447   child2->name = "child2";
448   child2->min_width = 20;
449   child2->min_height = 20;
450   child2->nat_width = 30;
451   child2->nat_height = 30;
452   child3->name = "child3";
453   child3->min_width = 30;
454   child3->min_height = 30;
455   child3->nat_width = 40;
456   child3->nat_height = 40;
457   child4->name = "child4";
458   child4->min_width = 30;
459   child4->min_height = 30;
460   child4->nat_width = 40;
461   child4->nat_height = 40;
462 
463   gtk_widget_set_parent (GTK_WIDGET (child1), parent);
464   gtk_widget_set_parent (GTK_WIDGET (child2), parent);
465   gtk_widget_set_parent (GTK_WIDGET (child3), parent);
466   gtk_widget_set_parent (GTK_WIDGET (child4), parent);
467 
468   lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child1));
469   gtk_grid_layout_child_set_row (GTK_GRID_LAYOUT_CHILD (lc), 0);
470   gtk_grid_layout_child_set_column (GTK_GRID_LAYOUT_CHILD (lc), 0);
471 
472   lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child2));
473   gtk_grid_layout_child_set_row (GTK_GRID_LAYOUT_CHILD (lc), 0);
474   gtk_grid_layout_child_set_column (GTK_GRID_LAYOUT_CHILD (lc), 1);
475 
476   lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child3));
477   gtk_grid_layout_child_set_row (GTK_GRID_LAYOUT_CHILD (lc), 1);
478   gtk_grid_layout_child_set_column (GTK_GRID_LAYOUT_CHILD (lc), 0);
479 
480   lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child4));
481   gtk_grid_layout_child_set_row (GTK_GRID_LAYOUT_CHILD (lc), 1);
482   gtk_grid_layout_child_set_column (GTK_GRID_LAYOUT_CHILD (lc), 1);
483 
484   gtk_layout_manager_measure (layout,
485                               parent,
486                               GTK_ORIENTATION_HORIZONTAL,
487                               -1,
488                               &minimum,
489                               &natural,
490                               NULL,
491                               NULL);
492 
493   g_assert_cmpint (minimum, ==, 60);
494   g_assert_cmpint (natural, ==, 80);
495 
496   gtk_layout_manager_measure (layout,
497                               parent,
498                               GTK_ORIENTATION_VERTICAL,
499                               -1,
500                               &minimum,
501                               &natural,
502                               NULL,
503                               NULL);
504 
505   g_assert_cmpint (minimum, ==, 60);
506   g_assert_cmpint (natural, ==, 80);
507 
508   gtk_layout_manager_allocate (layout, parent, 80, 80, 0);
509 
510   g_assert_cmpint (child1->width, ==, 40);
511   g_assert_cmpint (child2->width, ==, 40);
512   g_assert_cmpint (child3->width, ==, 40);
513   g_assert_cmpint (child4->width, ==, 40);
514 
515   g_assert_cmpint (child1->height, ==, 40);
516   g_assert_cmpint (child2->height, ==, 40);
517   g_assert_cmpint (child3->height, ==, 40);
518   g_assert_cmpint (child4->height, ==, 40);
519 
520   gtk_widget_unparent (GTK_WIDGET (child1));
521   gtk_widget_unparent (GTK_WIDGET (child2));
522   gtk_widget_unparent (GTK_WIDGET (child3));
523   gtk_widget_unparent (GTK_WIDGET (child4));
524 
525   gtk_window_destroy (GTK_WINDOW (window));
526 }
527 
528 /* Create a layout with three children
529  *
530  * +--------+--------+
531  * | child1 | child2 |
532  * +--------+--------+
533  * |      child3     |
534  * +-----------------+
535  *
536  * This is a layout that we also reproduce with
537  * constraints, for comparison. Among the constraints:
538  * - child1.width == child2.width
539  * - child1.height == child2.height == child3.height
540  */
541 static void
test_simple_layout(void)542 test_simple_layout (void)
543 {
544   GtkWidget *window;
545   GtkWidget *parent;
546   GtkLayoutManager *layout;
547   GtkLayoutChild *lc;
548   GtkGizmo *child1;
549   GtkGizmo *child2;
550   GtkGizmo *child3;
551   int minimum, natural;
552 
553   window = gtk_window_new ();
554   parent = g_object_new (GTK_TYPE_GIZMO, NULL);
555   gtk_window_set_child (GTK_WINDOW (window), parent);
556 
557   layout = gtk_grid_layout_new ();
558   gtk_grid_layout_set_row_homogeneous (GTK_GRID_LAYOUT (layout), TRUE);
559   gtk_grid_layout_set_column_homogeneous (GTK_GRID_LAYOUT (layout), TRUE);
560   gtk_widget_set_layout_manager (parent, layout);
561 
562   child1 = g_object_new (GTK_TYPE_GIZMO, NULL);
563   child2 = g_object_new (GTK_TYPE_GIZMO, NULL);
564   child3 = g_object_new (GTK_TYPE_GIZMO, NULL);
565 
566   child1->name = "child1";
567   child1->min_width = 10;
568   child1->min_height = 10;
569   child1->nat_width = 50;
570   child1->nat_height = 50;
571   child2->name = "child2";
572   child2->min_width = 20;
573   child2->min_height = 20;
574   child2->nat_width = 50;
575   child2->nat_height = 50;
576   child3->name = "child3";
577   child3->min_width = 50;
578   child3->min_height = 10;
579   child3->nat_width = 50;
580   child3->nat_height = 50;
581 
582   gtk_widget_set_parent (GTK_WIDGET (child1), parent);
583   gtk_widget_set_parent (GTK_WIDGET (child2), parent);
584   gtk_widget_set_parent (GTK_WIDGET (child3), parent);
585 
586   lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child1));
587   gtk_grid_layout_child_set_row (GTK_GRID_LAYOUT_CHILD (lc), 0);
588   gtk_grid_layout_child_set_column (GTK_GRID_LAYOUT_CHILD (lc), 0);
589 
590   lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child2));
591   gtk_grid_layout_child_set_row (GTK_GRID_LAYOUT_CHILD (lc), 0);
592   gtk_grid_layout_child_set_column (GTK_GRID_LAYOUT_CHILD (lc), 1);
593 
594   lc = gtk_layout_manager_get_layout_child (layout, GTK_WIDGET (child3));
595   gtk_grid_layout_child_set_row (GTK_GRID_LAYOUT_CHILD (lc), 1);
596   gtk_grid_layout_child_set_column (GTK_GRID_LAYOUT_CHILD (lc), 0);
597   gtk_grid_layout_child_set_column_span (GTK_GRID_LAYOUT_CHILD (lc), 2);
598 
599   gtk_layout_manager_measure (layout,
600                               parent,
601                               GTK_ORIENTATION_HORIZONTAL,
602                               -1,
603                               &minimum,
604                               &natural,
605                               NULL,
606                               NULL);
607 
608   g_assert_cmpint (minimum, ==, 50);
609   g_assert_cmpint (natural, ==, 100);
610 
611   gtk_layout_manager_measure (layout,
612                               parent,
613                               GTK_ORIENTATION_VERTICAL,
614                               -1,
615                               &minimum,
616                               &natural,
617                               NULL,
618                               NULL);
619 
620   g_assert_cmpint (minimum, ==, 40);
621   g_assert_cmpint (natural, ==, 100);
622 
623   gtk_layout_manager_allocate (layout, parent, 100, 100, 0);
624 
625   g_assert_cmpint (child1->width, ==, 50);
626   g_assert_cmpint (child2->width, ==, 50);
627   g_assert_cmpint (child3->width, ==, 100);
628 
629   g_assert_cmpint (child1->height, ==, 50);
630   g_assert_cmpint (child2->height, ==, 50);
631   g_assert_cmpint (child3->height, ==, 50);
632 
633   gtk_widget_unparent (GTK_WIDGET (child1));
634   gtk_widget_unparent (GTK_WIDGET (child2));
635   gtk_widget_unparent (GTK_WIDGET (child3));
636 
637   gtk_window_destroy (GTK_WINDOW (window));
638 }
639 
640 int
main(int argc,char * argv[])641 main (int   argc,
642       char *argv[])
643 {
644   gtk_test_init (&argc, &argv);
645 
646   g_test_add_func ("/grid-layout/row", test_simple_row);
647   g_test_add_func ("/grid-layout/column", test_simple_column);
648   g_test_add_func ("/grid-layout/span", test_spans);
649   g_test_add_func ("/grid-layout/homogeneous", test_homogeneous);
650   g_test_add_func ("/grid-layout/simple", test_simple_layout);
651 
652   return g_test_run();
653 }
654