1/* gtkbinlayout.c: Layout manager for bin-like widgets
2 * Copyright 2019 GNOME Foundation
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/**
19 * GtkBinLayout:
20 *
21 * `GtkBinLayout` is a `GtkLayoutManager` subclass useful for create "bins" of
22 * widgets.
23 *
24 * `GtkBinLayout` will stack each child of a widget on top of each other,
25 * using the [property@Gtk.Widget:hexpand], [property@Gtk.Widget:vexpand],
26 * [property@Gtk.Widget:halign], and [property@Gtk.Widget:valign] properties
27 * of each child to determine where they should be positioned.
28 */
29
30#include "config.h"
31
32#include "gtkbinlayout.h"
33
34#include "gtkwidgetprivate.h"
35
36struct _GtkBinLayout
37{
38 GtkLayoutManager parent_instance;
39};
40
41G_DEFINE_TYPE (GtkBinLayout, gtk_bin_layout, GTK_TYPE_LAYOUT_MANAGER)
42
43static void
44gtk_bin_layout_measure (GtkLayoutManager *layout_manager,
45 GtkWidget *widget,
46 GtkOrientation orientation,
47 int for_size,
48 int *minimum,
49 int *natural,
50 int *minimum_baseline,
51 int *natural_baseline)
52{
53 GtkWidget *child;
54
55 for (child = _gtk_widget_get_first_child (widget);
56 child != NULL;
57 child = _gtk_widget_get_next_sibling (widget: child))
58 {
59 if (gtk_widget_should_layout (widget: child))
60 {
61 int child_min = 0;
62 int child_nat = 0;
63 int child_min_baseline = -1;
64 int child_nat_baseline = -1;
65
66 gtk_widget_measure (widget: child, orientation, for_size,
67 minimum: &child_min, natural: &child_nat,
68 minimum_baseline: &child_min_baseline, natural_baseline: &child_nat_baseline);
69
70 *minimum = MAX (*minimum, child_min);
71 *natural = MAX (*natural, child_nat);
72
73 if (child_min_baseline > -1)
74 *minimum_baseline = MAX (*minimum_baseline, child_min_baseline);
75 if (child_nat_baseline > -1)
76 *natural_baseline = MAX (*natural_baseline, child_nat_baseline);
77 }
78 }
79}
80
81static void
82gtk_bin_layout_allocate (GtkLayoutManager *layout_manager,
83 GtkWidget *widget,
84 int width,
85 int height,
86 int baseline)
87{
88 GtkWidget *child;
89
90 for (child = _gtk_widget_get_first_child (widget);
91 child != NULL;
92 child = _gtk_widget_get_next_sibling (widget: child))
93 {
94 if (child && gtk_widget_should_layout (widget: child))
95 gtk_widget_allocate (widget: child, width, height, baseline, NULL);
96 }
97}
98static void
99gtk_bin_layout_class_init (GtkBinLayoutClass *klass)
100{
101 GtkLayoutManagerClass *layout_manager_class = GTK_LAYOUT_MANAGER_CLASS (ptr: klass);
102
103 layout_manager_class->measure = gtk_bin_layout_measure;
104 layout_manager_class->allocate = gtk_bin_layout_allocate;
105}
106
107static void
108gtk_bin_layout_init (GtkBinLayout *self)
109{
110}
111
112/**
113 * gtk_bin_layout_new:
114 *
115 * Creates a new `GtkBinLayout` instance.
116 *
117 * Returns: the newly created `GtkBinLayout`
118 */
119GtkLayoutManager *
120gtk_bin_layout_new (void)
121{
122 return g_object_new (GTK_TYPE_BIN_LAYOUT, NULL);
123}
124

source code of gtk/gtk/gtkbinlayout.c