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 | |
36 | struct _GtkBinLayout |
37 | { |
38 | GtkLayoutManager parent_instance; |
39 | }; |
40 | |
41 | G_DEFINE_TYPE (GtkBinLayout, gtk_bin_layout, GTK_TYPE_LAYOUT_MANAGER) |
42 | |
43 | static void |
44 | gtk_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 | |
81 | static void |
82 | gtk_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 | } |
98 | static void |
99 | gtk_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 | |
107 | static void |
108 | gtk_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 | */ |
119 | GtkLayoutManager * |
120 | gtk_bin_layout_new (void) |
121 | { |
122 | return g_object_new (GTK_TYPE_BIN_LAYOUT, NULL); |
123 | } |
124 | |