File: | ctk/ctkgrid.c |
Warning: | line 979, column 7 Access of 'struct _CtkGridLine' element in the memory returned by 'alloca' at index 1 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* CTK - The GIMP Toolkit | |||
2 | * Copyright (C) 2010 Red Hat, Inc. | |||
3 | * Author: Matthias Clasen | |||
4 | * | |||
5 | * This library is free software; you can redistribute it and/or | |||
6 | * modify it under the terms of the GNU Lesser General Public | |||
7 | * License as published by the Free Software Foundation; either | |||
8 | * version 2 of the License, or (at your option) any later version. | |||
9 | * | |||
10 | * This library is distributed in the hope that it will be useful, | |||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
13 | * Lesser General Public License for more details. | |||
14 | * | |||
15 | * You should have received a copy of the GNU Lesser General Public | |||
16 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | |||
17 | */ | |||
18 | ||||
19 | #include "config.h" | |||
20 | ||||
21 | #include <string.h> | |||
22 | ||||
23 | #include "ctkgrid.h" | |||
24 | ||||
25 | #include "ctkorientableprivate.h" | |||
26 | #include "ctkrender.h" | |||
27 | #include "ctksizerequest.h" | |||
28 | #include "ctkwidgetprivate.h" | |||
29 | #include "ctkcontainerprivate.h" | |||
30 | #include "ctkcsscustomgadgetprivate.h" | |||
31 | #include "ctkprivate.h" | |||
32 | #include "ctkintl.h" | |||
33 | ||||
34 | ||||
35 | /** | |||
36 | * SECTION:ctkgrid | |||
37 | * @Short_description: Pack widgets in rows and columns | |||
38 | * @Title: CtkGrid | |||
39 | * @See_also: #CtkBox | |||
40 | * | |||
41 | * CtkGrid is a container which arranges its child widgets in | |||
42 | * rows and columns, with arbitrary positions and horizontal/vertical spans. | |||
43 | * | |||
44 | * Children are added using ctk_grid_attach(). They can span multiple | |||
45 | * rows or columns. It is also possible to add a child next to an | |||
46 | * existing child, using ctk_grid_attach_next_to(). The behaviour of | |||
47 | * CtkGrid when several children occupy the same grid cell is undefined. | |||
48 | * | |||
49 | * CtkGrid can be used like a #CtkBox by just using ctk_container_add(), | |||
50 | * which will place children next to each other in the direction determined | |||
51 | * by the #CtkOrientable:orientation property. However, if all you want is a | |||
52 | * single row or column, then #CtkBox is the preferred widget. | |||
53 | * | |||
54 | * # CSS nodes | |||
55 | * | |||
56 | * CtkGrid uses a single CSS node with name grid. | |||
57 | */ | |||
58 | ||||
59 | typedef struct _CtkGridChild CtkGridChild; | |||
60 | typedef struct _CtkGridChildAttach CtkGridChildAttach; | |||
61 | typedef struct _CtkGridRowProperties CtkGridRowProperties; | |||
62 | typedef struct _CtkGridLine CtkGridLine; | |||
63 | typedef struct _CtkGridLines CtkGridLines; | |||
64 | typedef struct _CtkGridLineData CtkGridLineData; | |||
65 | typedef struct _CtkGridRequest CtkGridRequest; | |||
66 | ||||
67 | struct _CtkGridChildAttach | |||
68 | { | |||
69 | gint pos; | |||
70 | gint span; | |||
71 | }; | |||
72 | ||||
73 | struct _CtkGridRowProperties | |||
74 | { | |||
75 | gint row; | |||
76 | CtkBaselinePosition baseline_position; | |||
77 | }; | |||
78 | ||||
79 | static const CtkGridRowProperties ctk_grid_row_properties_default = { | |||
80 | 0, | |||
81 | CTK_BASELINE_POSITION_CENTER | |||
82 | }; | |||
83 | ||||
84 | struct _CtkGridChild | |||
85 | { | |||
86 | CtkWidget *widget; | |||
87 | CtkGridChildAttach attach[2]; | |||
88 | }; | |||
89 | ||||
90 | #define CHILD_LEFT(child)((child)->attach[CTK_ORIENTATION_HORIZONTAL].pos) ((child)->attach[CTK_ORIENTATION_HORIZONTAL].pos) | |||
91 | #define CHILD_WIDTH(child)((child)->attach[CTK_ORIENTATION_HORIZONTAL].span) ((child)->attach[CTK_ORIENTATION_HORIZONTAL].span) | |||
92 | #define CHILD_TOP(child)((child)->attach[CTK_ORIENTATION_VERTICAL].pos) ((child)->attach[CTK_ORIENTATION_VERTICAL].pos) | |||
93 | #define CHILD_HEIGHT(child)((child)->attach[CTK_ORIENTATION_VERTICAL].span) ((child)->attach[CTK_ORIENTATION_VERTICAL].span) | |||
94 | ||||
95 | /* A CtkGridLineData struct contains row/column specific parts | |||
96 | * of the grid. | |||
97 | */ | |||
98 | struct _CtkGridLineData | |||
99 | { | |||
100 | gint16 spacing; | |||
101 | guint homogeneous : 1; | |||
102 | }; | |||
103 | ||||
104 | struct _CtkGridPrivate | |||
105 | { | |||
106 | GList *children; | |||
107 | GList *row_properties; | |||
108 | ||||
109 | CtkCssGadget *gadget; | |||
110 | ||||
111 | CtkOrientation orientation; | |||
112 | gint baseline_row; | |||
113 | ||||
114 | CtkGridLineData linedata[2]; | |||
115 | }; | |||
116 | ||||
117 | #define ROWS(priv)(&(priv)->linedata[CTK_ORIENTATION_HORIZONTAL]) (&(priv)->linedata[CTK_ORIENTATION_HORIZONTAL]) | |||
118 | #define COLUMNS(priv)(&(priv)->linedata[CTK_ORIENTATION_VERTICAL]) (&(priv)->linedata[CTK_ORIENTATION_VERTICAL]) | |||
119 | ||||
120 | /* A CtkGridLine struct represents a single row or column | |||
121 | * during size requests | |||
122 | */ | |||
123 | struct _CtkGridLine | |||
124 | { | |||
125 | gint minimum; | |||
126 | gint natural; | |||
127 | gint minimum_above; | |||
128 | gint minimum_below; | |||
129 | gint natural_above; | |||
130 | gint natural_below; | |||
131 | ||||
132 | gint position; | |||
133 | gint allocation; | |||
134 | gint allocated_baseline; | |||
135 | ||||
136 | guint need_expand : 1; | |||
137 | guint expand : 1; | |||
138 | guint empty : 1; | |||
139 | }; | |||
140 | ||||
141 | struct _CtkGridLines | |||
142 | { | |||
143 | CtkGridLine *lines; | |||
144 | gint min, max; | |||
145 | }; | |||
146 | ||||
147 | struct _CtkGridRequest | |||
148 | { | |||
149 | CtkGrid *grid; | |||
150 | CtkGridLines lines[2]; | |||
151 | }; | |||
152 | ||||
153 | ||||
154 | enum | |||
155 | { | |||
156 | PROP_0, | |||
157 | PROP_ROW_SPACING, | |||
158 | PROP_COLUMN_SPACING, | |||
159 | PROP_ROW_HOMOGENEOUS, | |||
160 | PROP_COLUMN_HOMOGENEOUS, | |||
161 | PROP_BASELINE_ROW, | |||
162 | N_PROPERTIES, | |||
163 | PROP_ORIENTATION | |||
164 | }; | |||
165 | ||||
166 | static GParamSpec *obj_properties[N_PROPERTIES] = { NULL((void*)0), }; | |||
167 | ||||
168 | enum | |||
169 | { | |||
170 | CHILD_PROP_0, | |||
171 | CHILD_PROP_LEFT_ATTACH, | |||
172 | CHILD_PROP_TOP_ATTACH, | |||
173 | CHILD_PROP_WIDTH, | |||
174 | CHILD_PROP_HEIGHT, | |||
175 | N_CHILD_PROPERTIES | |||
176 | }; | |||
177 | ||||
178 | static GParamSpec *child_properties[N_CHILD_PROPERTIES] = { NULL((void*)0), }; | |||
179 | ||||
180 | G_DEFINE_TYPE_WITH_CODE (CtkGrid, ctk_grid, CTK_TYPE_CONTAINER,static void ctk_grid_init (CtkGrid *self); static void ctk_grid_class_init (CtkGridClass *klass); static GType ctk_grid_get_type_once ( void); static gpointer ctk_grid_parent_class = ((void*)0); static gint CtkGrid_private_offset; static void ctk_grid_class_intern_init (gpointer klass) { ctk_grid_parent_class = g_type_class_peek_parent (klass); if (CtkGrid_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkGrid_private_offset); ctk_grid_class_init (( CtkGridClass*) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_grid_get_instance_private (CtkGrid *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkGrid_private_offset )))); } GType ctk_grid_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); (void ) (0 ? (gpointer) * (&static_g_define_type_id) : ((void*) 0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_grid_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_grid_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple ((ctk_container_get_type ()), g_intern_static_string ("CtkGrid"), sizeof (CtkGridClass ), (GClassInitFunc)(void (*)(void)) ctk_grid_class_intern_init , sizeof (CtkGrid), (GInstanceInitFunc)(void (*)(void)) ctk_grid_init , (GTypeFlags) 0); { {{ CtkGrid_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkGridPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc)(void (*) (void)) ((void*)0), ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id, (ctk_orientable_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } | |||
181 | G_ADD_PRIVATE (CtkGrid)static void ctk_grid_init (CtkGrid *self); static void ctk_grid_class_init (CtkGridClass *klass); static GType ctk_grid_get_type_once ( void); static gpointer ctk_grid_parent_class = ((void*)0); static gint CtkGrid_private_offset; static void ctk_grid_class_intern_init (gpointer klass) { ctk_grid_parent_class = g_type_class_peek_parent (klass); if (CtkGrid_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkGrid_private_offset); ctk_grid_class_init (( CtkGridClass*) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_grid_get_instance_private (CtkGrid *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkGrid_private_offset )))); } GType ctk_grid_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); (void ) (0 ? (gpointer) * (&static_g_define_type_id) : ((void*) 0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_grid_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_grid_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple ((ctk_container_get_type ()), g_intern_static_string ("CtkGrid"), sizeof (CtkGridClass ), (GClassInitFunc)(void (*)(void)) ctk_grid_class_intern_init , sizeof (CtkGrid), (GInstanceInitFunc)(void (*)(void)) ctk_grid_init , (GTypeFlags) 0); { {{ CtkGrid_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkGridPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc)(void (*) (void)) ((void*)0), ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id, (ctk_orientable_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } | |||
182 | G_IMPLEMENT_INTERFACE (CTK_TYPE_ORIENTABLE, NULL))static void ctk_grid_init (CtkGrid *self); static void ctk_grid_class_init (CtkGridClass *klass); static GType ctk_grid_get_type_once ( void); static gpointer ctk_grid_parent_class = ((void*)0); static gint CtkGrid_private_offset; static void ctk_grid_class_intern_init (gpointer klass) { ctk_grid_parent_class = g_type_class_peek_parent (klass); if (CtkGrid_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkGrid_private_offset); ctk_grid_class_init (( CtkGridClass*) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_grid_get_instance_private (CtkGrid *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkGrid_private_offset )))); } GType ctk_grid_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); (void ) (0 ? (gpointer) * (&static_g_define_type_id) : ((void*) 0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_grid_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_grid_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple ((ctk_container_get_type ()), g_intern_static_string ("CtkGrid"), sizeof (CtkGridClass ), (GClassInitFunc)(void (*)(void)) ctk_grid_class_intern_init , sizeof (CtkGrid), (GInstanceInitFunc)(void (*)(void)) ctk_grid_init , (GTypeFlags) 0); { {{ CtkGrid_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkGridPrivate)); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc)(void (*) (void)) ((void*)0), ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id, (ctk_orientable_get_type ()), &g_implement_interface_info ); };} } return g_define_type_id; } | |||
183 | ||||
184 | ||||
185 | static void ctk_grid_row_properties_free (CtkGridRowProperties *props); | |||
186 | ||||
187 | static void | |||
188 | ctk_grid_get_property (GObject *object, | |||
189 | guint prop_id, | |||
190 | GValue *value, | |||
191 | GParamSpec *pspec) | |||
192 | { | |||
193 | CtkGrid *grid = CTK_GRID (object)((((CtkGrid*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ctk_grid_get_type ())))))); | |||
194 | CtkGridPrivate *priv = grid->priv; | |||
195 | ||||
196 | switch (prop_id) | |||
197 | { | |||
198 | case PROP_ORIENTATION: | |||
199 | g_value_set_enum (value, priv->orientation); | |||
200 | break; | |||
201 | ||||
202 | case PROP_ROW_SPACING: | |||
203 | g_value_set_int (value, COLUMNS (priv)(&(priv)->linedata[CTK_ORIENTATION_VERTICAL])->spacing); | |||
204 | break; | |||
205 | ||||
206 | case PROP_COLUMN_SPACING: | |||
207 | g_value_set_int (value, ROWS (priv)(&(priv)->linedata[CTK_ORIENTATION_HORIZONTAL])->spacing); | |||
208 | break; | |||
209 | ||||
210 | case PROP_ROW_HOMOGENEOUS: | |||
211 | g_value_set_boolean (value, COLUMNS (priv)(&(priv)->linedata[CTK_ORIENTATION_VERTICAL])->homogeneous); | |||
212 | break; | |||
213 | ||||
214 | case PROP_COLUMN_HOMOGENEOUS: | |||
215 | g_value_set_boolean (value, ROWS (priv)(&(priv)->linedata[CTK_ORIENTATION_HORIZONTAL])->homogeneous); | |||
216 | break; | |||
217 | ||||
218 | case PROP_BASELINE_ROW: | |||
219 | g_value_set_int (value, priv->baseline_row); | |||
220 | break; | |||
221 | ||||
222 | default: | |||
223 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkgrid.c", 223, ("property"), _glib__property_id, _glib__pspec ->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) ( _glib__pspec))->g_class))->g_type)))), (g_type_name ((( (((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); | |||
224 | break; | |||
225 | } | |||
226 | } | |||
227 | ||||
228 | static void | |||
229 | ctk_grid_set_orientation (CtkGrid *grid, | |||
230 | CtkOrientation orientation) | |||
231 | { | |||
232 | CtkGridPrivate *priv = grid->priv; | |||
233 | ||||
234 | if (priv->orientation != orientation) | |||
235 | { | |||
236 | priv->orientation = orientation; | |||
237 | _ctk_orientable_set_style_classes (CTK_ORIENTABLE (grid)((((CtkOrientable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_orientable_get_type ()))))))); | |||
238 | ||||
239 | g_object_notify (G_OBJECT (grid)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), (((GType) ((20) << (2)))))))), "orientation"); | |||
240 | } | |||
241 | } | |||
242 | ||||
243 | static void | |||
244 | ctk_grid_set_property (GObject *object, | |||
245 | guint prop_id, | |||
246 | const GValue *value, | |||
247 | GParamSpec *pspec) | |||
248 | { | |||
249 | CtkGrid *grid = CTK_GRID (object)((((CtkGrid*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ctk_grid_get_type ())))))); | |||
250 | ||||
251 | switch (prop_id) | |||
252 | { | |||
253 | case PROP_ORIENTATION: | |||
254 | ctk_grid_set_orientation (grid, g_value_get_enum (value)); | |||
255 | break; | |||
256 | ||||
257 | case PROP_ROW_SPACING: | |||
258 | ctk_grid_set_row_spacing (grid, g_value_get_int (value)); | |||
259 | break; | |||
260 | ||||
261 | case PROP_COLUMN_SPACING: | |||
262 | ctk_grid_set_column_spacing (grid, g_value_get_int (value)); | |||
263 | break; | |||
264 | ||||
265 | case PROP_ROW_HOMOGENEOUS: | |||
266 | ctk_grid_set_row_homogeneous (grid, g_value_get_boolean (value)); | |||
267 | break; | |||
268 | ||||
269 | case PROP_COLUMN_HOMOGENEOUS: | |||
270 | ctk_grid_set_column_homogeneous (grid, g_value_get_boolean (value)); | |||
271 | break; | |||
272 | ||||
273 | case PROP_BASELINE_ROW: | |||
274 | ctk_grid_set_baseline_row (grid, g_value_get_int (value)); | |||
275 | break; | |||
276 | ||||
277 | default: | |||
278 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkgrid.c", 278, ("property"), _glib__property_id, _glib__pspec ->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) ( _glib__pspec))->g_class))->g_type)))), (g_type_name ((( (((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); | |||
279 | break; | |||
280 | } | |||
281 | } | |||
282 | ||||
283 | static CtkGridChild * | |||
284 | find_grid_child (CtkGrid *grid, | |||
285 | CtkWidget *widget) | |||
286 | { | |||
287 | CtkGridPrivate *priv = grid->priv; | |||
288 | CtkGridChild *child; | |||
289 | GList *list; | |||
290 | ||||
291 | for (list = priv->children; list; list = list->next) | |||
292 | { | |||
293 | child = list->data; | |||
294 | ||||
295 | if (child->widget == widget) | |||
296 | return child; | |||
297 | } | |||
298 | ||||
299 | return NULL((void*)0); | |||
300 | } | |||
301 | ||||
302 | static void | |||
303 | ctk_grid_get_child_property (CtkContainer *container, | |||
304 | CtkWidget *child, | |||
305 | guint property_id, | |||
306 | GValue *value, | |||
307 | GParamSpec *pspec) | |||
308 | { | |||
309 | CtkGrid *grid = CTK_GRID (container)((((CtkGrid*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((container)), ((ctk_grid_get_type ())))))); | |||
310 | CtkGridChild *grid_child; | |||
311 | ||||
312 | grid_child = find_grid_child (grid, child); | |||
313 | ||||
314 | if (grid_child == NULL((void*)0)) | |||
315 | { | |||
316 | CTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec)do { GObject *_glib__object = (GObject*) ((container)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((property_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkgrid.c", 316, ("child property"), _glib__property_id, _glib__pspec ->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) ( _glib__pspec))->g_class))->g_type)))), (g_type_name ((( (((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); | |||
317 | return; | |||
318 | } | |||
319 | ||||
320 | switch (property_id) | |||
321 | { | |||
322 | case CHILD_PROP_LEFT_ATTACH: | |||
323 | g_value_set_int (value, CHILD_LEFT (grid_child)((grid_child)->attach[CTK_ORIENTATION_HORIZONTAL].pos)); | |||
324 | break; | |||
325 | ||||
326 | case CHILD_PROP_TOP_ATTACH: | |||
327 | g_value_set_int (value, CHILD_TOP (grid_child)((grid_child)->attach[CTK_ORIENTATION_VERTICAL].pos)); | |||
328 | break; | |||
329 | ||||
330 | case CHILD_PROP_WIDTH: | |||
331 | g_value_set_int (value, CHILD_WIDTH (grid_child)((grid_child)->attach[CTK_ORIENTATION_HORIZONTAL].span)); | |||
332 | break; | |||
333 | ||||
334 | case CHILD_PROP_HEIGHT: | |||
335 | g_value_set_int (value, CHILD_HEIGHT (grid_child)((grid_child)->attach[CTK_ORIENTATION_VERTICAL].span)); | |||
336 | break; | |||
337 | ||||
338 | default: | |||
339 | CTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec)do { GObject *_glib__object = (GObject*) ((container)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((property_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkgrid.c", 339, ("child property"), _glib__property_id, _glib__pspec ->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) ( _glib__pspec))->g_class))->g_type)))), (g_type_name ((( (((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); | |||
340 | break; | |||
341 | } | |||
342 | } | |||
343 | ||||
344 | static void | |||
345 | ctk_grid_set_child_property (CtkContainer *container, | |||
346 | CtkWidget *child, | |||
347 | guint property_id, | |||
348 | const GValue *value, | |||
349 | GParamSpec *pspec) | |||
350 | { | |||
351 | CtkGrid *grid = CTK_GRID (container)((((CtkGrid*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((container)), ((ctk_grid_get_type ())))))); | |||
352 | CtkGridChild *grid_child; | |||
353 | ||||
354 | grid_child = find_grid_child (grid, child); | |||
355 | ||||
356 | if (grid_child == NULL((void*)0)) | |||
357 | { | |||
358 | CTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec)do { GObject *_glib__object = (GObject*) ((container)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((property_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkgrid.c", 358, ("child property"), _glib__property_id, _glib__pspec ->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) ( _glib__pspec))->g_class))->g_type)))), (g_type_name ((( (((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); | |||
359 | return; | |||
360 | } | |||
361 | ||||
362 | switch (property_id) | |||
363 | { | |||
364 | case CHILD_PROP_LEFT_ATTACH: | |||
365 | CHILD_LEFT (grid_child)((grid_child)->attach[CTK_ORIENTATION_HORIZONTAL].pos) = g_value_get_int (value); | |||
366 | break; | |||
367 | ||||
368 | case CHILD_PROP_TOP_ATTACH: | |||
369 | CHILD_TOP (grid_child)((grid_child)->attach[CTK_ORIENTATION_VERTICAL].pos) = g_value_get_int (value); | |||
370 | break; | |||
371 | ||||
372 | case CHILD_PROP_WIDTH: | |||
373 | CHILD_WIDTH (grid_child)((grid_child)->attach[CTK_ORIENTATION_HORIZONTAL].span) = g_value_get_int (value); | |||
374 | break; | |||
375 | ||||
376 | case CHILD_PROP_HEIGHT: | |||
377 | CHILD_HEIGHT (grid_child)((grid_child)->attach[CTK_ORIENTATION_VERTICAL].span) = g_value_get_int (value); | |||
378 | break; | |||
379 | ||||
380 | default: | |||
381 | CTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec)do { GObject *_glib__object = (GObject*) ((container)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((property_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctkgrid.c", 381, ("child property"), _glib__property_id, _glib__pspec ->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) ( _glib__pspec))->g_class))->g_type)))), (g_type_name ((( (((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); | |||
382 | break; | |||
383 | } | |||
384 | ||||
385 | if (_ctk_widget_get_visible (child) && | |||
386 | _ctk_widget_get_visible (CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ())))))))) | |||
387 | ctk_widget_queue_resize (child); | |||
388 | } | |||
389 | ||||
390 | static void | |||
391 | ctk_grid_finalize (GObject *object) | |||
392 | { | |||
393 | CtkGrid *grid = CTK_GRID (object)((((CtkGrid*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ctk_grid_get_type ())))))); | |||
394 | CtkGridPrivate *priv = grid->priv; | |||
395 | ||||
396 | g_list_free_full (priv->row_properties, (GDestroyNotify)ctk_grid_row_properties_free); | |||
397 | ||||
398 | g_clear_object (&priv->gadget)do { _Static_assert (sizeof *((&priv->gadget)) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ ((( &priv->gadget))) _pp = ((&priv->gadget)); __typeof__ (*((&priv->gadget))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while (0); | |||
399 | ||||
400 | G_OBJECT_CLASS (ctk_grid_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_grid_parent_class)), (((GType) ((20) << (2)))) ))))->finalize (object); | |||
401 | } | |||
402 | ||||
403 | static void | |||
404 | grid_attach (CtkGrid *grid, | |||
405 | CtkWidget *widget, | |||
406 | gint left, | |||
407 | gint top, | |||
408 | gint width, | |||
409 | gint height) | |||
410 | { | |||
411 | CtkGridPrivate *priv = grid->priv; | |||
412 | CtkGridChild *child; | |||
413 | ||||
414 | child = g_slice_new (CtkGridChild)((CtkGridChild*) g_slice_alloc (sizeof (CtkGridChild))); | |||
415 | child->widget = widget; | |||
416 | CHILD_LEFT (child)((child)->attach[CTK_ORIENTATION_HORIZONTAL].pos) = left; | |||
417 | CHILD_TOP (child)((child)->attach[CTK_ORIENTATION_VERTICAL].pos) = top; | |||
418 | CHILD_WIDTH (child)((child)->attach[CTK_ORIENTATION_HORIZONTAL].span) = width; | |||
419 | CHILD_HEIGHT (child)((child)->attach[CTK_ORIENTATION_VERTICAL].span) = height; | |||
420 | ||||
421 | priv->children = g_list_prepend (priv->children, child); | |||
422 | ||||
423 | ctk_widget_set_parent (widget, CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ()))))))); | |||
424 | } | |||
425 | ||||
426 | /* Find the position 'touching' existing | |||
427 | * children. @orientation and @max determine | |||
428 | * from which direction to approach (horizontal | |||
429 | * + max = right, vertical + !max = top, etc). | |||
430 | * @op_pos, @op_span determine the rows/columns | |||
431 | * in which the touching has to happen. | |||
432 | */ | |||
433 | static gint | |||
434 | find_attach_position (CtkGrid *grid, | |||
435 | CtkOrientation orientation, | |||
436 | gint op_pos, | |||
437 | gint op_span, | |||
438 | gboolean max) | |||
439 | { | |||
440 | CtkGridPrivate *priv = grid->priv; | |||
441 | CtkGridChild *grid_child; | |||
442 | CtkGridChildAttach *attach; | |||
443 | CtkGridChildAttach *opposite; | |||
444 | GList *list; | |||
445 | gint pos; | |||
446 | gboolean hit; | |||
447 | ||||
448 | if (max) | |||
449 | pos = -G_MAXINT2147483647; | |||
450 | else | |||
451 | pos = G_MAXINT2147483647; | |||
452 | ||||
453 | hit = FALSE(0); | |||
454 | ||||
455 | for (list = priv->children; list; list = list->next) | |||
456 | { | |||
457 | grid_child = list->data; | |||
458 | ||||
459 | attach = &grid_child->attach[orientation]; | |||
460 | opposite = &grid_child->attach[1 - orientation]; | |||
461 | ||||
462 | /* check if the ranges overlap */ | |||
463 | if (opposite->pos <= op_pos + op_span && op_pos <= opposite->pos + opposite->span) | |||
464 | { | |||
465 | hit = TRUE(!(0)); | |||
466 | ||||
467 | if (max) | |||
468 | pos = MAX (pos, attach->pos + attach->span)(((pos) > (attach->pos + attach->span)) ? (pos) : (attach ->pos + attach->span)); | |||
469 | else | |||
470 | pos = MIN (pos, attach->pos)(((pos) < (attach->pos)) ? (pos) : (attach->pos)); | |||
471 | } | |||
472 | } | |||
473 | ||||
474 | if (!hit) | |||
475 | pos = 0; | |||
476 | ||||
477 | return pos; | |||
478 | } | |||
479 | ||||
480 | static void | |||
481 | ctk_grid_add (CtkContainer *container, | |||
482 | CtkWidget *child) | |||
483 | { | |||
484 | CtkGrid *grid = CTK_GRID (container)((((CtkGrid*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((container)), ((ctk_grid_get_type ())))))); | |||
485 | CtkGridPrivate *priv = grid->priv; | |||
486 | gint pos[2] = { 0, 0 }; | |||
487 | ||||
488 | pos[priv->orientation] = find_attach_position (grid, priv->orientation, 0, 1, TRUE(!(0))); | |||
489 | grid_attach (grid, child, pos[0], pos[1], 1, 1); | |||
490 | } | |||
491 | ||||
492 | static void | |||
493 | ctk_grid_remove (CtkContainer *container, | |||
494 | CtkWidget *child) | |||
495 | { | |||
496 | CtkGrid *grid = CTK_GRID (container)((((CtkGrid*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((container)), ((ctk_grid_get_type ())))))); | |||
497 | CtkGridPrivate *priv = grid->priv; | |||
498 | CtkGridChild *grid_child; | |||
499 | GList *list; | |||
500 | ||||
501 | for (list = priv->children; list; list = list->next) | |||
502 | { | |||
503 | grid_child = list->data; | |||
504 | ||||
505 | if (grid_child->widget == child) | |||
506 | { | |||
507 | gboolean was_visible = _ctk_widget_get_visible (child); | |||
508 | ||||
509 | ctk_widget_unparent (child); | |||
510 | ||||
511 | priv->children = g_list_remove (priv->children, grid_child); | |||
512 | ||||
513 | g_slice_free (CtkGridChild, grid_child)do { if (1) g_slice_free1 (sizeof (CtkGridChild), (grid_child )); else (void) ((CtkGridChild*) 0 == (grid_child)); } while ( 0); | |||
514 | ||||
515 | if (was_visible && _ctk_widget_get_visible (CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ())))))))) | |||
516 | ctk_widget_queue_resize (CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ()))))))); | |||
517 | ||||
518 | break; | |||
519 | } | |||
520 | } | |||
521 | } | |||
522 | ||||
523 | static void | |||
524 | ctk_grid_forall (CtkContainer *container, | |||
525 | gboolean include_internals G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
526 | CtkCallback callback, | |||
527 | gpointer callback_data) | |||
528 | { | |||
529 | CtkGrid *grid = CTK_GRID (container)((((CtkGrid*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((container)), ((ctk_grid_get_type ())))))); | |||
530 | CtkGridPrivate *priv = grid->priv; | |||
531 | CtkGridChild *child; | |||
532 | GList *list; | |||
533 | ||||
534 | list = priv->children; | |||
535 | while (list) | |||
536 | { | |||
537 | child = list->data; | |||
538 | list = list->next; | |||
539 | ||||
540 | (* callback) (child->widget, callback_data); | |||
541 | } | |||
542 | } | |||
543 | ||||
544 | static GType | |||
545 | ctk_grid_child_type (CtkContainer *container G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
546 | { | |||
547 | return CTK_TYPE_WIDGET(ctk_widget_get_type ()); | |||
548 | } | |||
549 | ||||
550 | /* Calculates the min and max numbers for both orientations. | |||
551 | */ | |||
552 | static void | |||
553 | ctk_grid_request_count_lines (CtkGridRequest *request) | |||
554 | { | |||
555 | CtkGridPrivate *priv = request->grid->priv; | |||
556 | CtkGridChild *child; | |||
557 | CtkGridChildAttach *attach; | |||
558 | GList *list; | |||
559 | gint min[2]; | |||
560 | gint max[2]; | |||
561 | ||||
562 | min[0] = min[1] = G_MAXINT2147483647; | |||
563 | max[0] = max[1] = G_MININT(-2147483647 -1); | |||
564 | ||||
565 | for (list = priv->children; list; list = list->next) | |||
566 | { | |||
567 | child = list->data; | |||
568 | attach = child->attach; | |||
569 | ||||
570 | min[0] = MIN (min[0], attach[0].pos)(((min[0]) < (attach[0].pos)) ? (min[0]) : (attach[0].pos) ); | |||
571 | max[0] = MAX (max[0], attach[0].pos + attach[0].span)(((max[0]) > (attach[0].pos + attach[0].span)) ? (max[0]) : (attach[0].pos + attach[0].span)); | |||
572 | min[1] = MIN (min[1], attach[1].pos)(((min[1]) < (attach[1].pos)) ? (min[1]) : (attach[1].pos) ); | |||
573 | max[1] = MAX (max[1], attach[1].pos + attach[1].span)(((max[1]) > (attach[1].pos + attach[1].span)) ? (max[1]) : (attach[1].pos + attach[1].span)); | |||
574 | } | |||
575 | ||||
576 | request->lines[0].min = min[0]; | |||
577 | request->lines[0].max = max[0]; | |||
578 | request->lines[1].min = min[1]; | |||
579 | request->lines[1].max = max[1]; | |||
580 | } | |||
581 | ||||
582 | /* Sets line sizes to 0 and marks lines as expand | |||
583 | * if they have a non-spanning expanding child. | |||
584 | */ | |||
585 | static void | |||
586 | ctk_grid_request_init (CtkGridRequest *request, | |||
587 | CtkOrientation orientation) | |||
588 | { | |||
589 | CtkGridPrivate *priv = request->grid->priv; | |||
590 | CtkGridChild *child; | |||
591 | CtkGridChildAttach *attach; | |||
592 | CtkGridLines *lines; | |||
593 | GList *list; | |||
594 | gint i; | |||
595 | ||||
596 | lines = &request->lines[orientation]; | |||
597 | ||||
598 | for (i = 0; i < lines->max - lines->min; i++) | |||
599 | { | |||
600 | lines->lines[i].minimum = 0; | |||
601 | lines->lines[i].natural = 0; | |||
602 | lines->lines[i].minimum_above = -1; | |||
603 | lines->lines[i].minimum_below = -1; | |||
604 | lines->lines[i].natural_above = -1; | |||
605 | lines->lines[i].natural_below = -1; | |||
606 | lines->lines[i].expand = FALSE(0); | |||
607 | lines->lines[i].empty = TRUE(!(0)); | |||
608 | } | |||
609 | ||||
610 | for (list = priv->children; list; list = list->next) | |||
611 | { | |||
612 | child = list->data; | |||
613 | ||||
614 | attach = &child->attach[orientation]; | |||
615 | if (attach->span == 1 && ctk_widget_compute_expand (child->widget, orientation)) | |||
616 | lines->lines[attach->pos - lines->min].expand = TRUE(!(0)); | |||
617 | } | |||
618 | } | |||
619 | ||||
620 | /* Sums allocations for lines spanned by child and their spacing. | |||
621 | */ | |||
622 | static gint | |||
623 | compute_allocation_for_child (CtkGridRequest *request, | |||
624 | CtkGridChild *child, | |||
625 | CtkOrientation orientation) | |||
626 | { | |||
627 | CtkGridPrivate *priv = request->grid->priv; | |||
628 | CtkGridLineData *linedata; | |||
629 | CtkGridLines *lines; | |||
630 | CtkGridLine *line; | |||
631 | CtkGridChildAttach *attach; | |||
632 | gint size; | |||
633 | gint i; | |||
634 | ||||
635 | linedata = &priv->linedata[orientation]; | |||
636 | lines = &request->lines[orientation]; | |||
637 | attach = &child->attach[orientation]; | |||
638 | ||||
639 | size = (attach->span - 1) * linedata->spacing; | |||
640 | for (i = 0; i < attach->span; i++) | |||
641 | { | |||
642 | line = &lines->lines[attach->pos - lines->min + i]; | |||
643 | size += line->allocation; | |||
644 | } | |||
645 | ||||
646 | return size; | |||
647 | } | |||
648 | ||||
649 | static void | |||
650 | compute_request_for_child (CtkGridRequest *request, | |||
651 | CtkGridChild *child, | |||
652 | CtkOrientation orientation, | |||
653 | gboolean contextual, | |||
654 | gint *minimum, | |||
655 | gint *natural, | |||
656 | gint *minimum_baseline, | |||
657 | gint *natural_baseline) | |||
658 | { | |||
659 | if (minimum_baseline) | |||
660 | *minimum_baseline = -1; | |||
661 | if (natural_baseline) | |||
662 | *natural_baseline = -1; | |||
663 | if (contextual) | |||
664 | { | |||
665 | gint size; | |||
666 | ||||
667 | size = compute_allocation_for_child (request, child, 1 - orientation); | |||
668 | if (orientation == CTK_ORIENTATION_HORIZONTAL) | |||
669 | ctk_widget_get_preferred_width_for_height (child->widget, | |||
670 | size, | |||
671 | minimum, natural); | |||
672 | else | |||
673 | ctk_widget_get_preferred_height_and_baseline_for_width (child->widget, | |||
674 | size, | |||
675 | minimum, natural, | |||
676 | minimum_baseline, natural_baseline); | |||
677 | } | |||
678 | else | |||
679 | { | |||
680 | if (orientation == CTK_ORIENTATION_HORIZONTAL) | |||
681 | ctk_widget_get_preferred_width (child->widget, minimum, natural); | |||
682 | else | |||
683 | ctk_widget_get_preferred_height_and_baseline_for_width (child->widget, | |||
684 | -1, | |||
685 | minimum, natural, | |||
686 | minimum_baseline, natural_baseline); | |||
687 | } | |||
688 | } | |||
689 | ||||
690 | /* Sets requisition to max. of non-spanning children. | |||
691 | * If contextual is TRUE, requires allocations of | |||
692 | * lines in the opposite orientation to be set. | |||
693 | */ | |||
694 | static void | |||
695 | ctk_grid_request_non_spanning (CtkGridRequest *request, | |||
696 | CtkOrientation orientation, | |||
697 | gboolean contextual) | |||
698 | { | |||
699 | CtkGridPrivate *priv = request->grid->priv; | |||
700 | CtkGridChild *child; | |||
701 | CtkGridChildAttach *attach; | |||
702 | CtkGridLines *lines; | |||
703 | CtkGridLine *line; | |||
704 | GList *list; | |||
705 | gint i; | |||
706 | CtkBaselinePosition baseline_pos; | |||
707 | gint minimum, minimum_baseline; | |||
708 | gint natural, natural_baseline; | |||
709 | ||||
710 | lines = &request->lines[orientation]; | |||
711 | ||||
712 | for (list = priv->children; list; list = list->next) | |||
713 | { | |||
714 | child = list->data; | |||
715 | ||||
716 | if (!_ctk_widget_get_visible (child->widget)) | |||
717 | continue; | |||
718 | ||||
719 | attach = &child->attach[orientation]; | |||
720 | if (attach->span != 1) | |||
721 | continue; | |||
722 | ||||
723 | compute_request_for_child (request, child, orientation, contextual, &minimum, &natural, &minimum_baseline, &natural_baseline); | |||
724 | ||||
725 | line = &lines->lines[attach->pos - lines->min]; | |||
726 | ||||
727 | if (minimum_baseline != -1) | |||
728 | { | |||
729 | line->minimum_above = MAX (line->minimum_above, minimum_baseline)(((line->minimum_above) > (minimum_baseline)) ? (line-> minimum_above) : (minimum_baseline)); | |||
730 | line->minimum_below = MAX (line->minimum_below, minimum - minimum_baseline)(((line->minimum_below) > (minimum - minimum_baseline)) ? (line->minimum_below) : (minimum - minimum_baseline)); | |||
731 | line->natural_above = MAX (line->natural_above, natural_baseline)(((line->natural_above) > (natural_baseline)) ? (line-> natural_above) : (natural_baseline)); | |||
732 | line->natural_below = MAX (line->natural_below, natural - natural_baseline)(((line->natural_below) > (natural - natural_baseline)) ? (line->natural_below) : (natural - natural_baseline)); | |||
733 | } | |||
734 | else | |||
735 | { | |||
736 | line->minimum = MAX (line->minimum, minimum)(((line->minimum) > (minimum)) ? (line->minimum) : ( minimum)); | |||
737 | line->natural = MAX (line->natural, natural)(((line->natural) > (natural)) ? (line->natural) : ( natural)); | |||
738 | } | |||
739 | } | |||
740 | ||||
741 | for (i = 0; i < lines->max - lines->min; i++) | |||
742 | { | |||
743 | line = &lines->lines[i]; | |||
744 | ||||
745 | if (line->minimum_above != -1) | |||
746 | { | |||
747 | line->minimum = MAX (line->minimum, line->minimum_above + line->minimum_below)(((line->minimum) > (line->minimum_above + line-> minimum_below)) ? (line->minimum) : (line->minimum_above + line->minimum_below)); | |||
748 | line->natural = MAX (line->natural, line->natural_above + line->natural_below)(((line->natural) > (line->natural_above + line-> natural_below)) ? (line->natural) : (line->natural_above + line->natural_below)); | |||
749 | ||||
750 | baseline_pos = ctk_grid_get_row_baseline_position (request->grid, i + lines->min); | |||
751 | ||||
752 | switch (baseline_pos) | |||
753 | { | |||
754 | case CTK_BASELINE_POSITION_TOP: | |||
755 | line->minimum_above += 0; | |||
756 | line->minimum_below += line->minimum - (line->minimum_above + line->minimum_below); | |||
757 | line->natural_above += 0; | |||
758 | line->natural_below += line->natural - (line->natural_above + line->natural_below); | |||
759 | break; | |||
760 | case CTK_BASELINE_POSITION_CENTER: | |||
761 | line->minimum_above += (line->minimum - (line->minimum_above + line->minimum_below))/2; | |||
762 | line->minimum_below += (line->minimum - (line->minimum_above + line->minimum_below))/2; | |||
763 | line->natural_above += (line->natural - (line->natural_above + line->natural_below))/2; | |||
764 | line->natural_below += (line->natural - (line->natural_above + line->natural_below))/2; | |||
765 | break; | |||
766 | case CTK_BASELINE_POSITION_BOTTOM: | |||
767 | line->minimum_above += line->minimum - (line->minimum_above + line->minimum_below); | |||
768 | line->minimum_below += 0; | |||
769 | line->natural_above += line->natural - (line->natural_above + line->natural_below); | |||
770 | line->natural_below += 0; | |||
771 | break; | |||
772 | } | |||
773 | } | |||
774 | } | |||
775 | } | |||
776 | ||||
777 | /* Enforce homogeneous sizes. | |||
778 | */ | |||
779 | static void | |||
780 | ctk_grid_request_homogeneous (CtkGridRequest *request, | |||
781 | CtkOrientation orientation) | |||
782 | { | |||
783 | CtkGridPrivate *priv = request->grid->priv; | |||
784 | CtkGridLineData *linedata; | |||
785 | CtkGridLines *lines; | |||
786 | gint minimum, natural; | |||
787 | gint i; | |||
788 | ||||
789 | linedata = &priv->linedata[orientation]; | |||
790 | lines = &request->lines[orientation]; | |||
791 | ||||
792 | if (!linedata->homogeneous) | |||
793 | return; | |||
794 | ||||
795 | minimum = 0; | |||
796 | natural = 0; | |||
797 | ||||
798 | for (i = 0; i < lines->max - lines->min; i++) | |||
799 | { | |||
800 | minimum = MAX (minimum, lines->lines[i].minimum)(((minimum) > (lines->lines[i].minimum)) ? (minimum) : ( lines->lines[i].minimum)); | |||
801 | natural = MAX (natural, lines->lines[i].natural)(((natural) > (lines->lines[i].natural)) ? (natural) : ( lines->lines[i].natural)); | |||
802 | } | |||
803 | ||||
804 | for (i = 0; i < lines->max - lines->min; i++) | |||
805 | { | |||
806 | lines->lines[i].minimum = minimum; | |||
807 | lines->lines[i].natural = natural; | |||
808 | /* TODO: Do we want to adjust the baseline here too? | |||
809 | * And if so, also in the homogenous resize. | |||
810 | */ | |||
811 | } | |||
812 | } | |||
813 | ||||
814 | /* Deals with spanning children. | |||
815 | * Requires expand fields of lines to be set for | |||
816 | * non-spanning children. | |||
817 | */ | |||
818 | static void | |||
819 | ctk_grid_request_spanning (CtkGridRequest *request, | |||
820 | CtkOrientation orientation, | |||
821 | gboolean contextual) | |||
822 | { | |||
823 | CtkGridPrivate *priv = request->grid->priv; | |||
824 | GList *list; | |||
825 | CtkGridChild *child; | |||
826 | CtkGridChildAttach *attach; | |||
827 | CtkGridLineData *linedata; | |||
828 | CtkGridLines *lines; | |||
829 | CtkGridLine *line; | |||
830 | gint minimum; | |||
831 | gint natural; | |||
832 | gint span_minimum; | |||
833 | gint span_natural; | |||
834 | gint span_expand; | |||
835 | gboolean force_expand; | |||
836 | gint extra; | |||
837 | gint expand; | |||
838 | gint line_extra; | |||
839 | gint i; | |||
840 | ||||
841 | linedata = &priv->linedata[orientation]; | |||
842 | lines = &request->lines[orientation]; | |||
843 | ||||
844 | for (list = priv->children; list; list = list->next) | |||
845 | { | |||
846 | child = list->data; | |||
847 | ||||
848 | if (!_ctk_widget_get_visible (child->widget)) | |||
849 | continue; | |||
850 | ||||
851 | attach = &child->attach[orientation]; | |||
852 | if (attach->span == 1) | |||
853 | continue; | |||
854 | ||||
855 | /* We ignore baselines for spanning children */ | |||
856 | compute_request_for_child (request, child, orientation, contextual, &minimum, &natural, NULL((void*)0), NULL((void*)0)); | |||
857 | ||||
858 | span_minimum = (attach->span - 1) * linedata->spacing; | |||
859 | span_natural = (attach->span - 1) * linedata->spacing; | |||
860 | span_expand = 0; | |||
861 | force_expand = FALSE(0); | |||
862 | for (i = 0; i < attach->span; i++) | |||
863 | { | |||
864 | line = &lines->lines[attach->pos - lines->min + i]; | |||
865 | span_minimum += line->minimum; | |||
866 | span_natural += line->natural; | |||
867 | if (line->expand) | |||
868 | span_expand += 1; | |||
869 | } | |||
870 | if (span_expand == 0) | |||
871 | { | |||
872 | span_expand = attach->span; | |||
873 | force_expand = TRUE(!(0)); | |||
874 | } | |||
875 | ||||
876 | /* If we need to request more space for this child to fill | |||
877 | * its requisition, then divide up the needed space amongst the | |||
878 | * lines it spans, favoring expandable lines if any. | |||
879 | * | |||
880 | * When doing homogeneous allocation though, try to keep the | |||
881 | * line allocations even, since we're going to force them to | |||
882 | * be the same anyway, and we don't want to introduce unnecessary | |||
883 | * extra space. | |||
884 | */ | |||
885 | if (span_minimum < minimum) | |||
886 | { | |||
887 | if (linedata->homogeneous) | |||
888 | { | |||
889 | gint total, m; | |||
890 | ||||
891 | total = minimum - (attach->span - 1) * linedata->spacing; | |||
892 | m = total / attach->span + (total % attach->span ? 1 : 0); | |||
893 | for (i = 0; i < attach->span; i++) | |||
894 | { | |||
895 | line = &lines->lines[attach->pos - lines->min + i]; | |||
896 | line->minimum = MAX(line->minimum, m)(((line->minimum) > (m)) ? (line->minimum) : (m)); | |||
897 | } | |||
898 | } | |||
899 | else | |||
900 | { | |||
901 | extra = minimum - span_minimum; | |||
902 | expand = span_expand; | |||
903 | for (i = 0; i < attach->span; i++) | |||
904 | { | |||
905 | line = &lines->lines[attach->pos - lines->min + i]; | |||
906 | if (force_expand || line->expand) | |||
907 | { | |||
908 | line_extra = extra / expand; | |||
909 | line->minimum += line_extra; | |||
910 | extra -= line_extra; | |||
911 | expand -= 1; | |||
912 | } | |||
913 | } | |||
914 | } | |||
915 | } | |||
916 | ||||
917 | if (span_natural < natural) | |||
918 | { | |||
919 | if (linedata->homogeneous) | |||
920 | { | |||
921 | gint total, n; | |||
922 | ||||
923 | total = natural - (attach->span - 1) * linedata->spacing; | |||
924 | n = total / attach->span + (total % attach->span ? 1 : 0); | |||
925 | for (i = 0; i < attach->span; i++) | |||
926 | { | |||
927 | line = &lines->lines[attach->pos - lines->min + i]; | |||
928 | line->natural = MAX(line->natural, n)(((line->natural) > (n)) ? (line->natural) : (n)); | |||
929 | } | |||
930 | } | |||
931 | else | |||
932 | { | |||
933 | extra = natural - span_natural; | |||
934 | expand = span_expand; | |||
935 | for (i = 0; i < attach->span; i++) | |||
936 | { | |||
937 | line = &lines->lines[attach->pos - lines->min + i]; | |||
938 | if (force_expand || line->expand) | |||
939 | { | |||
940 | line_extra = extra / expand; | |||
941 | line->natural += line_extra; | |||
942 | extra -= line_extra; | |||
943 | expand -= 1; | |||
944 | } | |||
945 | } | |||
946 | } | |||
947 | } | |||
948 | } | |||
949 | } | |||
950 | ||||
951 | /* Marks empty and expanding lines and counts them. | |||
952 | */ | |||
953 | static void | |||
954 | ctk_grid_request_compute_expand (CtkGridRequest *request, | |||
955 | CtkOrientation orientation, | |||
956 | gint min, | |||
957 | gint max, | |||
958 | gint *nonempty_lines, | |||
959 | gint *expand_lines) | |||
960 | { | |||
961 | CtkGridPrivate *priv = request->grid->priv; | |||
962 | CtkGridChild *child; | |||
963 | CtkGridChildAttach *attach; | |||
964 | GList *list; | |||
965 | gint i; | |||
966 | CtkGridLines *lines; | |||
967 | CtkGridLine *line; | |||
968 | gboolean has_expand; | |||
969 | gint expand; | |||
970 | gint empty; | |||
971 | ||||
972 | lines = &request->lines[orientation]; | |||
973 | ||||
974 | min = MAX (min, lines->min)(((min) > (lines->min)) ? (min) : (lines->min)); | |||
975 | max = MIN (max, lines->max)(((max) < (lines->max)) ? (max) : (lines->max)); | |||
976 | ||||
977 | for (i = min - lines->min; i < max - lines->min; i++) | |||
978 | { | |||
979 | lines->lines[i].need_expand = FALSE(0); | |||
| ||||
980 | lines->lines[i].expand = FALSE(0); | |||
981 | lines->lines[i].empty = TRUE(!(0)); | |||
982 | } | |||
983 | ||||
984 | for (list = priv->children; list; list = list->next) | |||
985 | { | |||
986 | child = list->data; | |||
987 | ||||
988 | if (!_ctk_widget_get_visible (child->widget)) | |||
989 | continue; | |||
990 | ||||
991 | attach = &child->attach[orientation]; | |||
992 | if (attach->span != 1) | |||
993 | continue; | |||
994 | ||||
995 | if (attach->pos >= max || attach->pos < min) | |||
996 | continue; | |||
997 | ||||
998 | line = &lines->lines[attach->pos - lines->min]; | |||
999 | line->empty = FALSE(0); | |||
1000 | if (ctk_widget_compute_expand (child->widget, orientation)) | |||
1001 | line->expand = TRUE(!(0)); | |||
1002 | } | |||
1003 | ||||
1004 | for (list = priv->children; list; list = list->next) | |||
1005 | { | |||
1006 | child = list->data; | |||
1007 | ||||
1008 | if (!_ctk_widget_get_visible (child->widget)) | |||
1009 | continue; | |||
1010 | ||||
1011 | attach = &child->attach[orientation]; | |||
1012 | if (attach->span == 1) | |||
1013 | continue; | |||
1014 | ||||
1015 | has_expand = FALSE(0); | |||
1016 | for (i = 0; i < attach->span; i++) | |||
1017 | { | |||
1018 | line = &lines->lines[attach->pos - lines->min + i]; | |||
1019 | ||||
1020 | if (line->expand) | |||
1021 | has_expand = TRUE(!(0)); | |||
1022 | ||||
1023 | if (attach->pos + i >= max || attach->pos + 1 < min) | |||
1024 | continue; | |||
1025 | ||||
1026 | line->empty = FALSE(0); | |||
1027 | } | |||
1028 | ||||
1029 | if (!has_expand && ctk_widget_compute_expand (child->widget, orientation)) | |||
1030 | { | |||
1031 | for (i = 0; i < attach->span; i++) | |||
1032 | { | |||
1033 | if (attach->pos + i >= max || attach->pos + 1 < min) | |||
1034 | continue; | |||
1035 | ||||
1036 | line = &lines->lines[attach->pos - lines->min + i]; | |||
1037 | line->need_expand = TRUE(!(0)); | |||
1038 | } | |||
1039 | } | |||
1040 | } | |||
1041 | ||||
1042 | empty = 0; | |||
1043 | expand = 0; | |||
1044 | for (i = min - lines->min; i < max - lines->min; i++) | |||
1045 | { | |||
1046 | line = &lines->lines[i]; | |||
1047 | ||||
1048 | if (line->need_expand) | |||
1049 | line->expand = TRUE(!(0)); | |||
1050 | ||||
1051 | if (line->empty) | |||
1052 | empty += 1; | |||
1053 | ||||
1054 | if (line->expand) | |||
1055 | expand += 1; | |||
1056 | } | |||
1057 | ||||
1058 | if (nonempty_lines) | |||
1059 | *nonempty_lines = max - min - empty; | |||
1060 | ||||
1061 | if (expand_lines) | |||
1062 | *expand_lines = expand; | |||
1063 | } | |||
1064 | ||||
1065 | /* Sums the minimum and natural fields of lines and their spacing. | |||
1066 | */ | |||
1067 | static void | |||
1068 | ctk_grid_request_sum (CtkGridRequest *request, | |||
1069 | CtkOrientation orientation, | |||
1070 | gint *minimum, | |||
1071 | gint *natural, | |||
1072 | gint *minimum_baseline, | |||
1073 | gint *natural_baseline) | |||
1074 | { | |||
1075 | CtkGridPrivate *priv = request->grid->priv; | |||
1076 | CtkGridLineData *linedata; | |||
1077 | CtkGridLines *lines; | |||
1078 | gint i; | |||
1079 | gint min, nat; | |||
1080 | gint nonempty; | |||
1081 | ||||
1082 | ctk_grid_request_compute_expand (request, orientation, G_MININT(-2147483647 -1), G_MAXINT2147483647, &nonempty, NULL((void*)0)); | |||
1083 | ||||
1084 | linedata = &priv->linedata[orientation]; | |||
1085 | lines = &request->lines[orientation]; | |||
1086 | ||||
1087 | min = 0; | |||
1088 | nat = 0; | |||
1089 | for (i = 0; i < lines->max - lines->min; i++) | |||
1090 | { | |||
1091 | if (orientation == CTK_ORIENTATION_VERTICAL && | |||
1092 | lines->min + i == priv->baseline_row && | |||
1093 | lines->lines[i].minimum_above != -1) | |||
1094 | { | |||
1095 | if (minimum_baseline) | |||
1096 | *minimum_baseline = min + lines->lines[i].minimum_above; | |||
1097 | if (natural_baseline) | |||
1098 | *natural_baseline = nat + lines->lines[i].natural_above; | |||
1099 | } | |||
1100 | ||||
1101 | min += lines->lines[i].minimum; | |||
1102 | nat += lines->lines[i].natural; | |||
1103 | ||||
1104 | if (!lines->lines[i].empty) | |||
1105 | { | |||
1106 | min += linedata->spacing; | |||
1107 | nat += linedata->spacing; | |||
1108 | } | |||
1109 | } | |||
1110 | ||||
1111 | /* Remove last spacing, if any was applied */ | |||
1112 | if (nonempty > 0) | |||
1113 | { | |||
1114 | min -= linedata->spacing; | |||
1115 | nat -= linedata->spacing; | |||
1116 | } | |||
1117 | ||||
1118 | *minimum = min; | |||
1119 | *natural = nat; | |||
1120 | } | |||
1121 | ||||
1122 | /* Computes minimum and natural fields of lines. | |||
1123 | * When contextual is TRUE, requires allocation of | |||
1124 | * lines in the opposite orientation to be set. | |||
1125 | */ | |||
1126 | static void | |||
1127 | ctk_grid_request_run (CtkGridRequest *request, | |||
1128 | CtkOrientation orientation, | |||
1129 | gboolean contextual) | |||
1130 | { | |||
1131 | ctk_grid_request_init (request, orientation); | |||
1132 | ctk_grid_request_non_spanning (request, orientation, contextual); | |||
1133 | ctk_grid_request_homogeneous (request, orientation); | |||
1134 | ctk_grid_request_spanning (request, orientation, contextual); | |||
1135 | ctk_grid_request_homogeneous (request, orientation); | |||
1136 | } | |||
1137 | ||||
1138 | static void | |||
1139 | ctk_grid_distribute_non_homogeneous (CtkGridLines *lines, | |||
1140 | gint nonempty, | |||
1141 | gint expand, | |||
1142 | gint size, | |||
1143 | gint min, | |||
1144 | gint max) | |||
1145 | { | |||
1146 | CtkRequestedSize *sizes; | |||
1147 | CtkGridLine *line; | |||
1148 | gint extra; | |||
1149 | gint rest; | |||
1150 | int i, j; | |||
1151 | ||||
1152 | if (nonempty == 0) | |||
1153 | return; | |||
1154 | ||||
1155 | sizes = g_newa (CtkRequestedSize, nonempty)((CtkRequestedSize*) __builtin_alloca (sizeof (CtkRequestedSize ) * (gsize) (nonempty))); | |||
1156 | ||||
1157 | j = 0; | |||
1158 | for (i = min - lines->min; i < max - lines->min; i++) | |||
1159 | { | |||
1160 | line = &lines->lines[i]; | |||
1161 | if (line->empty) | |||
1162 | continue; | |||
1163 | ||||
1164 | size -= line->minimum; | |||
1165 | ||||
1166 | sizes[j].minimum_size = line->minimum; | |||
1167 | sizes[j].natural_size = line->natural; | |||
1168 | sizes[j].data = line; | |||
1169 | j++; | |||
1170 | } | |||
1171 | ||||
1172 | size = ctk_distribute_natural_allocation (MAX (0, size)(((0) > (size)) ? (0) : (size)), nonempty, sizes); | |||
1173 | ||||
1174 | if (expand > 0) | |||
1175 | { | |||
1176 | extra = size / expand; | |||
1177 | rest = size % expand; | |||
1178 | } | |||
1179 | else | |||
1180 | { | |||
1181 | extra = 0; | |||
1182 | rest = 0; | |||
1183 | } | |||
1184 | ||||
1185 | j = 0; | |||
1186 | for (i = min - lines->min; i < max - lines->min; i++) | |||
1187 | { | |||
1188 | line = &lines->lines[i]; | |||
1189 | if (line->empty) | |||
1190 | continue; | |||
1191 | ||||
1192 | g_assert (line == sizes[j].data)do { if (line == sizes[j].data) ; else g_assertion_message_expr ("Ctk", "ctkgrid.c", 1192, ((const char*) (__func__)), "line == sizes[j].data" ); } while (0); | |||
1193 | ||||
1194 | line->allocation = sizes[j].minimum_size; | |||
1195 | if (line->expand) | |||
1196 | { | |||
1197 | line->allocation += extra; | |||
1198 | if (rest > 0) | |||
1199 | { | |||
1200 | line->allocation += 1; | |||
1201 | rest -= 1; | |||
1202 | } | |||
1203 | } | |||
1204 | ||||
1205 | j++; | |||
1206 | } | |||
1207 | } | |||
1208 | ||||
1209 | /* Requires that the minimum and natural fields of lines | |||
1210 | * have been set, computes the allocation field of lines | |||
1211 | * by distributing total_size among lines. | |||
1212 | */ | |||
1213 | static void | |||
1214 | ctk_grid_request_allocate (CtkGridRequest *request, | |||
1215 | CtkOrientation orientation, | |||
1216 | gint total_size) | |||
1217 | { | |||
1218 | CtkGridPrivate *priv = request->grid->priv; | |||
1219 | CtkGridLineData *linedata; | |||
1220 | CtkGridLines *lines; | |||
1221 | CtkGridLine *line; | |||
1222 | gint nonempty1, nonempty2; | |||
1223 | gint expand1, expand2; | |||
1224 | gint i; | |||
1225 | CtkBaselinePosition baseline_pos; | |||
1226 | gint baseline; | |||
1227 | gint extra, extra2; | |||
1228 | gint rest; | |||
1229 | gint size1, size2; | |||
1230 | gint split, split_pos; | |||
1231 | ||||
1232 | linedata = &priv->linedata[orientation]; | |||
1233 | lines = &request->lines[orientation]; | |||
1234 | ||||
1235 | baseline = ctk_widget_get_allocated_baseline (CTK_WIDGET (request->grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((request->grid)), ((ctk_widget_get_type ()))))))); | |||
1236 | ||||
1237 | if (orientation
| |||
1238 | priv->baseline_row >= lines->min && priv->baseline_row < lines->max && | |||
1239 | lines->lines[priv->baseline_row - lines->min].minimum_above != -1) | |||
1240 | { | |||
1241 | split = priv->baseline_row; | |||
1242 | split_pos = baseline - lines->lines[priv->baseline_row - lines->min].minimum_above; | |||
1243 | ctk_grid_request_compute_expand (request, orientation, lines->min, split, &nonempty1, &expand1); | |||
1244 | ctk_grid_request_compute_expand (request, orientation, split, lines->max, &nonempty2, &expand2); | |||
1245 | ||||
1246 | if (nonempty2 > 0) | |||
1247 | { | |||
1248 | size1 = split_pos - (nonempty1) * linedata->spacing; | |||
1249 | size2 = (total_size - split_pos) - (nonempty2 - 1) * linedata->spacing; | |||
1250 | } | |||
1251 | else | |||
1252 | { | |||
1253 | size1 = total_size - (nonempty1 - 1) * linedata->spacing; | |||
1254 | size2 = 0; | |||
1255 | } | |||
1256 | } | |||
1257 | else | |||
1258 | { | |||
1259 | ctk_grid_request_compute_expand (request, orientation, lines->min, lines->max, &nonempty1, &expand1); | |||
1260 | nonempty2 = expand2 = 0; | |||
1261 | split = lines->max; | |||
1262 | ||||
1263 | size1 = total_size - (nonempty1 - 1) * linedata->spacing; | |||
1264 | size2 = 0; | |||
1265 | } | |||
1266 | ||||
1267 | if (nonempty1 == 0 && nonempty2 == 0) | |||
1268 | return; | |||
1269 | ||||
1270 | if (linedata->homogeneous) | |||
1271 | { | |||
1272 | if (nonempty1 > 0) | |||
1273 | { | |||
1274 | extra = size1 / nonempty1; | |||
1275 | rest = size1 % nonempty1; | |||
1276 | } | |||
1277 | else | |||
1278 | { | |||
1279 | extra = 0; | |||
1280 | rest = 0; | |||
1281 | } | |||
1282 | if (nonempty2 > 0) | |||
1283 | { | |||
1284 | extra2 = size2 / nonempty2; | |||
1285 | if (extra2 < extra || nonempty1 == 0) | |||
1286 | { | |||
1287 | extra = extra2; | |||
1288 | rest = size2 % nonempty2; | |||
1289 | } | |||
1290 | } | |||
1291 | ||||
1292 | for (i = 0; i < lines->max - lines->min; i++) | |||
1293 | { | |||
1294 | line = &lines->lines[i]; | |||
1295 | if (line->empty) | |||
1296 | continue; | |||
1297 | ||||
1298 | line->allocation = extra; | |||
1299 | if (rest > 0) | |||
1300 | { | |||
1301 | line->allocation += 1; | |||
1302 | rest -= 1; | |||
1303 | } | |||
1304 | } | |||
1305 | } | |||
1306 | else | |||
1307 | { | |||
1308 | ctk_grid_distribute_non_homogeneous (lines, | |||
1309 | nonempty1, | |||
1310 | expand1, | |||
1311 | size1, | |||
1312 | lines->min, | |||
1313 | split); | |||
1314 | ctk_grid_distribute_non_homogeneous (lines, | |||
1315 | nonempty2, | |||
1316 | expand2, | |||
1317 | size2, | |||
1318 | split, | |||
1319 | lines->max); | |||
1320 | } | |||
1321 | ||||
1322 | for (i = 0; i < lines->max - lines->min; i++) | |||
1323 | { | |||
1324 | line = &lines->lines[i]; | |||
1325 | if (line->empty) | |||
1326 | continue; | |||
1327 | ||||
1328 | if (line->minimum_above != -1) | |||
1329 | { | |||
1330 | /* Note: This is overridden in ctk_grid_request_position for the allocated baseline */ | |||
1331 | baseline_pos = ctk_grid_get_row_baseline_position (request->grid, i + lines->min); | |||
1332 | ||||
1333 | switch (baseline_pos) | |||
1334 | { | |||
1335 | case CTK_BASELINE_POSITION_TOP: | |||
1336 | line->allocated_baseline = | |||
1337 | line->minimum_above; | |||
1338 | break; | |||
1339 | case CTK_BASELINE_POSITION_CENTER: | |||
1340 | line->allocated_baseline = | |||
1341 | line->minimum_above + | |||
1342 | (line->allocation - (line->minimum_above + line->minimum_below)) / 2; | |||
1343 | break; | |||
1344 | case CTK_BASELINE_POSITION_BOTTOM: | |||
1345 | line->allocated_baseline = | |||
1346 | line->allocation - line->minimum_below; | |||
1347 | break; | |||
1348 | } | |||
1349 | } | |||
1350 | else | |||
1351 | line->allocated_baseline = -1; | |||
1352 | } | |||
1353 | } | |||
1354 | ||||
1355 | /* Computes the position fields from allocation and spacing. | |||
1356 | */ | |||
1357 | static void | |||
1358 | ctk_grid_request_position (CtkGridRequest *request, | |||
1359 | CtkOrientation orientation) | |||
1360 | { | |||
1361 | CtkGridPrivate *priv = request->grid->priv; | |||
1362 | CtkGridLineData *linedata; | |||
1363 | CtkGridLines *lines; | |||
1364 | CtkGridLine *line; | |||
1365 | gint position, old_position; | |||
1366 | int allocated_baseline; | |||
1367 | gint i, j; | |||
1368 | ||||
1369 | linedata = &priv->linedata[orientation]; | |||
1370 | lines = &request->lines[orientation]; | |||
1371 | ||||
1372 | allocated_baseline = ctk_widget_get_allocated_baseline (CTK_WIDGET(request->grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((request->grid)), ((ctk_widget_get_type ()))))))); | |||
1373 | ||||
1374 | position = 0; | |||
1375 | for (i = 0; i < lines->max - lines->min; i++) | |||
1376 | { | |||
1377 | line = &lines->lines[i]; | |||
1378 | ||||
1379 | if (orientation == CTK_ORIENTATION_VERTICAL && | |||
1380 | i + lines->min == priv->baseline_row && | |||
1381 | allocated_baseline != -1 && | |||
1382 | lines->lines[i].minimum_above != -1) | |||
1383 | { | |||
1384 | old_position = position; | |||
1385 | position = allocated_baseline - line->minimum_above; | |||
1386 | ||||
1387 | /* Back-patch previous rows */ | |||
1388 | for (j = 0; j < i; j++) | |||
1389 | { | |||
1390 | if (!lines->lines[j].empty) | |||
1391 | lines->lines[j].position += position - old_position; | |||
1392 | } | |||
1393 | } | |||
1394 | ||||
1395 | if (!line->empty) | |||
1396 | { | |||
1397 | line->position = position; | |||
1398 | position += line->allocation + linedata->spacing; | |||
1399 | ||||
1400 | if (orientation == CTK_ORIENTATION_VERTICAL && | |||
1401 | i + lines->min == priv->baseline_row && | |||
1402 | allocated_baseline != -1 && | |||
1403 | lines->lines[i].minimum_above != -1) | |||
1404 | line->allocated_baseline = allocated_baseline - line->position; | |||
1405 | } | |||
1406 | } | |||
1407 | } | |||
1408 | ||||
1409 | static void | |||
1410 | ctk_grid_get_size (CtkGrid *grid, | |||
1411 | CtkOrientation orientation, | |||
1412 | gint *minimum, | |||
1413 | gint *natural, | |||
1414 | gint *minimum_baseline, | |||
1415 | gint *natural_baseline) | |||
1416 | { | |||
1417 | CtkGridRequest request; | |||
1418 | CtkGridLines *lines; | |||
1419 | ||||
1420 | *minimum = 0; | |||
1421 | *natural = 0; | |||
1422 | ||||
1423 | if (minimum_baseline) | |||
1424 | *minimum_baseline = -1; | |||
1425 | ||||
1426 | if (natural_baseline) | |||
1427 | *natural_baseline = -1; | |||
1428 | ||||
1429 | if (grid->priv->children == NULL((void*)0)) | |||
1430 | return; | |||
1431 | ||||
1432 | request.grid = grid; | |||
1433 | ctk_grid_request_count_lines (&request); | |||
1434 | lines = &request.lines[orientation]; | |||
1435 | lines->lines = g_newa (CtkGridLine, lines->max - lines->min)((CtkGridLine*) __builtin_alloca (sizeof (CtkGridLine) * (gsize ) (lines->max - lines->min))); | |||
1436 | memset (lines->lines, 0, (lines->max - lines->min) * sizeof (CtkGridLine)); | |||
1437 | ||||
1438 | ctk_grid_request_run (&request, orientation, FALSE(0)); | |||
1439 | ctk_grid_request_sum (&request, orientation, minimum, natural, | |||
1440 | minimum_baseline, natural_baseline); | |||
1441 | } | |||
1442 | ||||
1443 | static void | |||
1444 | ctk_grid_get_size_for_size (CtkGrid *grid, | |||
1445 | CtkOrientation orientation, | |||
1446 | gint size, | |||
1447 | gint *minimum, | |||
1448 | gint *natural, | |||
1449 | gint *minimum_baseline, | |||
1450 | gint *natural_baseline) | |||
1451 | { | |||
1452 | CtkGridRequest request; | |||
1453 | CtkGridLines *lines; | |||
1454 | gint min_size, nat_size; | |||
1455 | ||||
1456 | *minimum = 0; | |||
1457 | *natural = 0; | |||
1458 | ||||
1459 | if (minimum_baseline) | |||
1460 | *minimum_baseline = -1; | |||
1461 | ||||
1462 | if (natural_baseline) | |||
1463 | *natural_baseline = -1; | |||
1464 | ||||
1465 | if (grid->priv->children == NULL((void*)0)) | |||
1466 | return; | |||
1467 | ||||
1468 | request.grid = grid; | |||
1469 | ctk_grid_request_count_lines (&request); | |||
1470 | lines = &request.lines[0]; | |||
1471 | lines->lines = g_newa (CtkGridLine, lines->max - lines->min)((CtkGridLine*) __builtin_alloca (sizeof (CtkGridLine) * (gsize ) (lines->max - lines->min))); | |||
1472 | memset (lines->lines, 0, (lines->max - lines->min) * sizeof (CtkGridLine)); | |||
1473 | lines = &request.lines[1]; | |||
1474 | lines->lines = g_newa (CtkGridLine, lines->max - lines->min)((CtkGridLine*) __builtin_alloca (sizeof (CtkGridLine) * (gsize ) (lines->max - lines->min))); | |||
1475 | memset (lines->lines, 0, (lines->max - lines->min) * sizeof (CtkGridLine)); | |||
1476 | ||||
1477 | ctk_grid_request_run (&request, 1 - orientation, FALSE(0)); | |||
1478 | ctk_grid_request_sum (&request, 1 - orientation, &min_size, &nat_size, NULL((void*)0), NULL((void*)0)); | |||
1479 | ctk_grid_request_allocate (&request, 1 - orientation, MAX (size, min_size)(((size) > (min_size)) ? (size) : (min_size))); | |||
1480 | ||||
1481 | ctk_grid_request_run (&request, orientation, TRUE(!(0))); | |||
1482 | ctk_grid_request_sum (&request, orientation, minimum, natural, minimum_baseline, natural_baseline); | |||
1483 | } | |||
1484 | ||||
1485 | static void | |||
1486 | ctk_grid_get_preferred_width (CtkWidget *widget, | |||
1487 | gint *minimum, | |||
1488 | gint *natural) | |||
1489 | { | |||
1490 | ctk_css_gadget_get_preferred_size (CTK_GRID (widget)((((CtkGrid*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_grid_get_type ()))))))->priv->gadget, | |||
1491 | CTK_ORIENTATION_HORIZONTAL, | |||
1492 | -1, | |||
1493 | minimum, natural, | |||
1494 | NULL((void*)0), NULL((void*)0)); | |||
1495 | } | |||
1496 | ||||
1497 | static void | |||
1498 | ctk_grid_get_preferred_height (CtkWidget *widget, | |||
1499 | gint *minimum, | |||
1500 | gint *natural) | |||
1501 | { | |||
1502 | ctk_css_gadget_get_preferred_size (CTK_GRID (widget)((((CtkGrid*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_grid_get_type ()))))))->priv->gadget, | |||
1503 | CTK_ORIENTATION_VERTICAL, | |||
1504 | -1, | |||
1505 | minimum, natural, | |||
1506 | NULL((void*)0), NULL((void*)0)); | |||
1507 | } | |||
1508 | ||||
1509 | static void | |||
1510 | ctk_grid_get_preferred_width_for_height (CtkWidget *widget, | |||
1511 | gint height, | |||
1512 | gint *minimum, | |||
1513 | gint *natural) | |||
1514 | { | |||
1515 | ctk_css_gadget_get_preferred_size (CTK_GRID (widget)((((CtkGrid*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_grid_get_type ()))))))->priv->gadget, | |||
1516 | CTK_ORIENTATION_HORIZONTAL, | |||
1517 | height, | |||
1518 | minimum, natural, | |||
1519 | NULL((void*)0), NULL((void*)0)); | |||
1520 | } | |||
1521 | ||||
1522 | static void | |||
1523 | ctk_grid_get_preferred_height_for_width (CtkWidget *widget, | |||
1524 | gint width, | |||
1525 | gint *minimum, | |||
1526 | gint *natural) | |||
1527 | { | |||
1528 | ctk_css_gadget_get_preferred_size (CTK_GRID (widget)((((CtkGrid*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_grid_get_type ()))))))->priv->gadget, | |||
1529 | CTK_ORIENTATION_VERTICAL, | |||
1530 | width, | |||
1531 | minimum, natural, | |||
1532 | NULL((void*)0), NULL((void*)0)); | |||
1533 | } | |||
1534 | ||||
1535 | static void | |||
1536 | ctk_grid_get_preferred_height_and_baseline_for_width (CtkWidget *widget, | |||
1537 | gint width, | |||
1538 | gint *minimum, | |||
1539 | gint *natural, | |||
1540 | gint *minimum_baseline, | |||
1541 | gint *natural_baseline) | |||
1542 | { | |||
1543 | ctk_css_gadget_get_preferred_size (CTK_GRID (widget)((((CtkGrid*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_grid_get_type ()))))))->priv->gadget, | |||
1544 | CTK_ORIENTATION_VERTICAL, | |||
1545 | width, | |||
1546 | minimum, natural, | |||
1547 | minimum_baseline, natural_baseline); | |||
1548 | } | |||
1549 | ||||
1550 | static void | |||
1551 | ctk_grid_measure (CtkCssGadget *gadget, | |||
1552 | CtkOrientation orientation, | |||
1553 | int for_size, | |||
1554 | int *minimum, | |||
1555 | int *natural, | |||
1556 | int *minimum_baseline, | |||
1557 | int *natural_baseline, | |||
1558 | gpointer data G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
1559 | { | |||
1560 | CtkWidget *widget = ctk_css_gadget_get_owner (gadget); | |||
1561 | CtkGrid *grid = CTK_GRID (widget)((((CtkGrid*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_grid_get_type ())))))); | |||
1562 | ||||
1563 | if ((orientation == CTK_ORIENTATION_HORIZONTAL && | |||
1564 | ctk_widget_get_request_mode (widget) == CTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT) || | |||
1565 | (orientation == CTK_ORIENTATION_VERTICAL && | |||
1566 | ctk_widget_get_request_mode (widget) == CTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)) | |||
1567 | ctk_grid_get_size_for_size (grid, orientation, for_size, minimum, natural, minimum_baseline, natural_baseline); | |||
1568 | else | |||
1569 | ctk_grid_get_size (grid, orientation, minimum, natural, minimum_baseline, natural_baseline); | |||
1570 | } | |||
1571 | ||||
1572 | static void | |||
1573 | allocate_child (CtkGridRequest *request, | |||
1574 | CtkOrientation orientation, | |||
1575 | CtkGridChild *child, | |||
1576 | gint *position, | |||
1577 | gint *size, | |||
1578 | gint *baseline) | |||
1579 | { | |||
1580 | CtkGridPrivate *priv = request->grid->priv; | |||
1581 | CtkGridLineData *linedata; | |||
1582 | CtkGridLines *lines; | |||
1583 | CtkGridLine *line; | |||
1584 | CtkGridChildAttach *attach; | |||
1585 | gint i; | |||
1586 | ||||
1587 | linedata = &priv->linedata[orientation]; | |||
1588 | lines = &request->lines[orientation]; | |||
1589 | attach = &child->attach[orientation]; | |||
1590 | ||||
1591 | *position = lines->lines[attach->pos - lines->min].position; | |||
1592 | if (attach->span == 1) | |||
1593 | *baseline = lines->lines[attach->pos - lines->min].allocated_baseline; | |||
1594 | else | |||
1595 | *baseline = -1; | |||
1596 | ||||
1597 | *size = (attach->span - 1) * linedata->spacing; | |||
1598 | for (i = 0; i < attach->span; i++) | |||
1599 | { | |||
1600 | line = &lines->lines[attach->pos - lines->min + i]; | |||
1601 | *size += line->allocation; | |||
1602 | } | |||
1603 | } | |||
1604 | ||||
1605 | static void | |||
1606 | ctk_grid_request_allocate_children (CtkGridRequest *request, | |||
1607 | const CtkAllocation *allocation) | |||
1608 | { | |||
1609 | CtkGridPrivate *priv = request->grid->priv; | |||
1610 | GList *list; | |||
1611 | CtkGridChild *child; | |||
1612 | CtkAllocation child_allocation; | |||
1613 | gint x, y, width, height, baseline, ignore; | |||
1614 | ||||
1615 | for (list = priv->children; list; list = list->next) | |||
1616 | { | |||
1617 | child = list->data; | |||
1618 | ||||
1619 | if (!_ctk_widget_get_visible (child->widget)) | |||
1620 | continue; | |||
1621 | ||||
1622 | allocate_child (request, CTK_ORIENTATION_HORIZONTAL, child, &x, &width, &ignore); | |||
1623 | allocate_child (request, CTK_ORIENTATION_VERTICAL, child, &y, &height, &baseline); | |||
1624 | ||||
1625 | child_allocation.x = allocation->x + x; | |||
1626 | child_allocation.y = allocation->y + y; | |||
1627 | child_allocation.width = MAX (1, width)(((1) > (width)) ? (1) : (width)); | |||
1628 | child_allocation.height = MAX (1, height)(((1) > (height)) ? (1) : (height)); | |||
1629 | ||||
1630 | if (ctk_widget_get_direction (CTK_WIDGET (request->grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((request->grid)), ((ctk_widget_get_type ()))))))) == CTK_TEXT_DIR_RTL) | |||
1631 | child_allocation.x = allocation->x + allocation->width | |||
1632 | - (child_allocation.x - allocation->x) - child_allocation.width; | |||
1633 | ||||
1634 | ctk_widget_size_allocate_with_baseline (child->widget, &child_allocation, baseline); | |||
1635 | } | |||
1636 | } | |||
1637 | ||||
1638 | #define GET_SIZE(allocation, orientation)(orientation == CTK_ORIENTATION_HORIZONTAL ? allocation->width : allocation->height) (orientation == CTK_ORIENTATION_HORIZONTAL ? allocation->width : allocation->height) | |||
1639 | ||||
1640 | static void | |||
1641 | ctk_grid_size_allocate (CtkWidget *widget, | |||
1642 | CtkAllocation *allocation) | |||
1643 | { | |||
1644 | CtkAllocation clip; | |||
1645 | ||||
1646 | ctk_widget_set_allocation (widget, allocation); | |||
1647 | ||||
1648 | ctk_css_gadget_allocate (CTK_GRID (widget)((((CtkGrid*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_grid_get_type ()))))))->priv->gadget, | |||
1649 | allocation, | |||
1650 | ctk_widget_get_allocated_baseline (widget), | |||
1651 | &clip); | |||
1652 | ||||
1653 | ctk_widget_set_clip (widget, &clip); | |||
1654 | } | |||
1655 | ||||
1656 | static void | |||
1657 | ctk_grid_allocate (CtkCssGadget *gadget, | |||
1658 | const CtkAllocation *allocation, | |||
1659 | int baseline G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
1660 | CtkAllocation *out_clip, | |||
1661 | gpointer data G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
1662 | { | |||
1663 | CtkWidget *widget = ctk_css_gadget_get_owner (gadget); | |||
1664 | CtkGrid *grid = CTK_GRID (widget)((((CtkGrid*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_grid_get_type ())))))); | |||
1665 | CtkGridPrivate *priv = grid->priv; | |||
1666 | CtkGridRequest request; | |||
1667 | CtkGridLines *lines; | |||
1668 | CtkOrientation orientation; | |||
1669 | ||||
1670 | if (priv->children == NULL((void*)0)) | |||
| ||||
1671 | return; | |||
1672 | ||||
1673 | request.grid = grid; | |||
1674 | ||||
1675 | ctk_grid_request_count_lines (&request); | |||
1676 | lines = &request.lines[0]; | |||
1677 | lines->lines = g_newa (CtkGridLine, lines->max - lines->min)((CtkGridLine*) __builtin_alloca (sizeof (CtkGridLine) * (gsize ) (lines->max - lines->min))); | |||
1678 | memset (lines->lines, 0, (lines->max - lines->min) * sizeof (CtkGridLine)); | |||
1679 | lines = &request.lines[1]; | |||
1680 | lines->lines = g_newa (CtkGridLine, lines->max - lines->min)((CtkGridLine*) __builtin_alloca (sizeof (CtkGridLine) * (gsize ) (lines->max - lines->min))); | |||
1681 | memset (lines->lines, 0, (lines->max - lines->min) * sizeof (CtkGridLine)); | |||
1682 | ||||
1683 | if (ctk_widget_get_request_mode (widget) == CTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT) | |||
1684 | orientation = CTK_ORIENTATION_HORIZONTAL; | |||
1685 | else | |||
1686 | orientation = CTK_ORIENTATION_VERTICAL; | |||
1687 | ||||
1688 | ctk_grid_request_run (&request, 1 - orientation, FALSE(0)); | |||
1689 | ctk_grid_request_allocate (&request, 1 - orientation, GET_SIZE (allocation, 1 - orientation)(1 - orientation == CTK_ORIENTATION_HORIZONTAL ? allocation-> width : allocation->height)); | |||
1690 | ctk_grid_request_run (&request, orientation, TRUE(!(0))); | |||
1691 | ||||
1692 | ctk_grid_request_allocate (&request, orientation, GET_SIZE (allocation, orientation)(orientation == CTK_ORIENTATION_HORIZONTAL ? allocation->width : allocation->height)); | |||
1693 | ||||
1694 | ctk_grid_request_position (&request, 0); | |||
1695 | ctk_grid_request_position (&request, 1); | |||
1696 | ||||
1697 | ctk_grid_request_allocate_children (&request, allocation); | |||
1698 | ||||
1699 | ctk_container_get_children_clip (CTK_CONTAINER (grid)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_container_get_type ())))))), out_clip); | |||
1700 | } | |||
1701 | ||||
1702 | static gboolean | |||
1703 | ctk_grid_render (CtkCssGadget *gadget, | |||
1704 | cairo_t *cr, | |||
1705 | int x G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
1706 | int y G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
1707 | int width G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
1708 | int height G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
1709 | gpointer data G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
1710 | { | |||
1711 | CTK_WIDGET_CLASS (ctk_grid_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_grid_parent_class)), ((ctk_widget_get_type ()))))))->draw (ctk_css_gadget_get_owner (gadget), cr); | |||
1712 | ||||
1713 | return FALSE(0); | |||
1714 | } | |||
1715 | ||||
1716 | static gboolean | |||
1717 | ctk_grid_draw (CtkWidget *widget, | |||
1718 | cairo_t *cr) | |||
1719 | { | |||
1720 | ctk_css_gadget_draw (CTK_GRID (widget)((((CtkGrid*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_grid_get_type ()))))))->priv->gadget, cr); | |||
1721 | ||||
1722 | return FALSE(0); | |||
1723 | } | |||
1724 | ||||
1725 | static void | |||
1726 | ctk_grid_class_init (CtkGridClass *class) | |||
1727 | { | |||
1728 | GObjectClass *object_class = G_OBJECT_CLASS (class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((class)), (((GType) ((20) << (2)))))))); | |||
1729 | CtkWidgetClass *widget_class = CTK_WIDGET_CLASS (class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((class)), ((ctk_widget_get_type ())))))); | |||
1730 | CtkContainerClass *container_class = CTK_CONTAINER_CLASS (class)((((CtkContainerClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((class)), ((ctk_container_get_type ())))))); | |||
1731 | ||||
1732 | object_class->get_property = ctk_grid_get_property; | |||
1733 | object_class->set_property = ctk_grid_set_property; | |||
1734 | object_class->finalize = ctk_grid_finalize; | |||
1735 | ||||
1736 | widget_class->size_allocate = ctk_grid_size_allocate; | |||
1737 | widget_class->get_preferred_width = ctk_grid_get_preferred_width; | |||
1738 | widget_class->get_preferred_height = ctk_grid_get_preferred_height; | |||
1739 | widget_class->get_preferred_width_for_height = ctk_grid_get_preferred_width_for_height; | |||
1740 | widget_class->get_preferred_height_for_width = ctk_grid_get_preferred_height_for_width; | |||
1741 | widget_class->get_preferred_height_and_baseline_for_width = ctk_grid_get_preferred_height_and_baseline_for_width; | |||
1742 | widget_class->draw = ctk_grid_draw; | |||
1743 | ||||
1744 | container_class->add = ctk_grid_add; | |||
1745 | container_class->remove = ctk_grid_remove; | |||
1746 | container_class->forall = ctk_grid_forall; | |||
1747 | container_class->child_type = ctk_grid_child_type; | |||
1748 | container_class->set_child_property = ctk_grid_set_child_property; | |||
1749 | container_class->get_child_property = ctk_grid_get_child_property; | |||
1750 | ctk_container_class_handle_border_width (container_class); | |||
1751 | ||||
1752 | g_object_class_override_property (object_class, PROP_ORIENTATION, "orientation"); | |||
1753 | ||||
1754 | obj_properties[PROP_ROW_SPACING] = | |||
1755 | g_param_spec_int ("row-spacing", | |||
1756 | P_("Row spacing")g_dgettext("ctk30" "-properties","Row spacing"), | |||
1757 | P_("The amount of space between two consecutive rows")g_dgettext("ctk30" "-properties","The amount of space between two consecutive rows" ), | |||
1758 | 0, G_MAXINT16((gint16) 0x7fff), 0, | |||
1759 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); | |||
1760 | ||||
1761 | obj_properties[PROP_COLUMN_SPACING] = | |||
1762 | g_param_spec_int ("column-spacing", | |||
1763 | P_("Column spacing")g_dgettext("ctk30" "-properties","Column spacing"), | |||
1764 | P_("The amount of space between two consecutive columns")g_dgettext("ctk30" "-properties","The amount of space between two consecutive columns" ), | |||
1765 | 0, G_MAXINT16((gint16) 0x7fff), 0, | |||
1766 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); | |||
1767 | ||||
1768 | obj_properties[PROP_ROW_HOMOGENEOUS] = | |||
1769 | g_param_spec_boolean ("row-homogeneous", | |||
1770 | P_("Row Homogeneous")g_dgettext("ctk30" "-properties","Row Homogeneous"), | |||
1771 | P_("If TRUE, the rows are all the same height")g_dgettext("ctk30" "-properties","If TRUE, the rows are all the same height" ), | |||
1772 | FALSE(0), | |||
1773 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); | |||
1774 | ||||
1775 | obj_properties[PROP_COLUMN_HOMOGENEOUS] = | |||
1776 | g_param_spec_boolean ("column-homogeneous", | |||
1777 | P_("Column Homogeneous")g_dgettext("ctk30" "-properties","Column Homogeneous"), | |||
1778 | P_("If TRUE, the columns are all the same width")g_dgettext("ctk30" "-properties","If TRUE, the columns are all the same width" ), | |||
1779 | FALSE(0), | |||
1780 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); | |||
1781 | ||||
1782 | obj_properties[PROP_BASELINE_ROW] = | |||
1783 | g_param_spec_int ("baseline-row", | |||
1784 | P_("Baseline Row")g_dgettext("ctk30" "-properties","Baseline Row"), | |||
1785 | P_("The row to align the to the baseline when valign is CTK_ALIGN_BASELINE")g_dgettext("ctk30" "-properties","The row to align the to the baseline when valign is CTK_ALIGN_BASELINE" ), | |||
1786 | 0, G_MAXINT2147483647, 0, | |||
1787 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); | |||
1788 | ||||
1789 | g_object_class_install_properties (object_class, | |||
1790 | N_PROPERTIES, | |||
1791 | obj_properties); | |||
1792 | ||||
1793 | child_properties[CHILD_PROP_LEFT_ATTACH] = | |||
1794 | g_param_spec_int ("left-attach", | |||
1795 | P_("Left attachment")g_dgettext("ctk30" "-properties","Left attachment"), | |||
1796 | P_("The column number to attach the left side of the child to")g_dgettext("ctk30" "-properties","The column number to attach the left side of the child to" ), | |||
1797 | G_MININT(-2147483647 -1), G_MAXINT2147483647, 0, | |||
1798 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB); | |||
1799 | ||||
1800 | child_properties[CHILD_PROP_TOP_ATTACH] = | |||
1801 | g_param_spec_int ("top-attach", | |||
1802 | P_("Top attachment")g_dgettext("ctk30" "-properties","Top attachment"), | |||
1803 | P_("The row number to attach the top side of a child widget to")g_dgettext("ctk30" "-properties","The row number to attach the top side of a child widget to" ), | |||
1804 | G_MININT(-2147483647 -1), G_MAXINT2147483647, 0, | |||
1805 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB); | |||
1806 | ||||
1807 | child_properties[CHILD_PROP_WIDTH] = | |||
1808 | g_param_spec_int ("width", | |||
1809 | P_("Width")g_dgettext("ctk30" "-properties","Width"), | |||
1810 | P_("The number of columns that a child spans")g_dgettext("ctk30" "-properties","The number of columns that a child spans" ), | |||
1811 | 1, G_MAXINT2147483647, 1, | |||
1812 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB); | |||
1813 | ||||
1814 | child_properties[CHILD_PROP_HEIGHT] = | |||
1815 | g_param_spec_int ("height", | |||
1816 | P_("Height")g_dgettext("ctk30" "-properties","Height"), | |||
1817 | P_("The number of rows that a child spans")g_dgettext("ctk30" "-properties","The number of rows that a child spans" ), | |||
1818 | 1, G_MAXINT2147483647, 1, | |||
1819 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB); | |||
1820 | ||||
1821 | ctk_container_class_install_child_properties (container_class, N_CHILD_PROPERTIES, child_properties); | |||
1822 | ctk_widget_class_set_css_name (widget_class, "grid"); | |||
1823 | } | |||
1824 | ||||
1825 | static void | |||
1826 | ctk_grid_init (CtkGrid *grid) | |||
1827 | { | |||
1828 | CtkGridPrivate *priv; | |||
1829 | ||||
1830 | grid->priv = ctk_grid_get_instance_private (grid); | |||
1831 | priv = grid->priv; | |||
1832 | ||||
1833 | ctk_widget_set_has_window (CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ())))))), FALSE(0)); | |||
1834 | ||||
1835 | priv->children = NULL((void*)0); | |||
1836 | priv->orientation = CTK_ORIENTATION_HORIZONTAL; | |||
1837 | priv->baseline_row = 0; | |||
1838 | ||||
1839 | priv->linedata[0].spacing = 0; | |||
1840 | priv->linedata[1].spacing = 0; | |||
1841 | ||||
1842 | priv->linedata[0].homogeneous = FALSE(0); | |||
1843 | priv->linedata[1].homogeneous = FALSE(0); | |||
1844 | ||||
1845 | priv->gadget = ctk_css_custom_gadget_new_for_node (ctk_widget_get_css_node (CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ()))))))), | |||
1846 | CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ())))))), | |||
1847 | ctk_grid_measure, | |||
1848 | ctk_grid_allocate, | |||
1849 | ctk_grid_render, | |||
1850 | NULL((void*)0), | |||
1851 | NULL((void*)0)); | |||
1852 | ||||
1853 | ||||
1854 | _ctk_orientable_set_style_classes (CTK_ORIENTABLE (grid)((((CtkOrientable*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_orientable_get_type ()))))))); | |||
1855 | } | |||
1856 | ||||
1857 | /** | |||
1858 | * ctk_grid_new: | |||
1859 | * | |||
1860 | * Creates a new grid widget. | |||
1861 | * | |||
1862 | * Returns: the new #CtkGrid | |||
1863 | */ | |||
1864 | CtkWidget * | |||
1865 | ctk_grid_new (void) | |||
1866 | { | |||
1867 | return g_object_new (CTK_TYPE_GRID(ctk_grid_get_type ()), NULL((void*)0)); | |||
1868 | } | |||
1869 | ||||
1870 | /** | |||
1871 | * ctk_grid_attach: | |||
1872 | * @grid: a #CtkGrid | |||
1873 | * @child: the widget to add | |||
1874 | * @left: the column number to attach the left side of @child to | |||
1875 | * @top: the row number to attach the top side of @child to | |||
1876 | * @width: the number of columns that @child will span | |||
1877 | * @height: the number of rows that @child will span | |||
1878 | * | |||
1879 | * Adds a widget to the grid. | |||
1880 | * | |||
1881 | * The position of @child is determined by @left and @top. The | |||
1882 | * number of “cells” that @child will occupy is determined by | |||
1883 | * @width and @height. | |||
1884 | */ | |||
1885 | void | |||
1886 | ctk_grid_attach (CtkGrid *grid, | |||
1887 | CtkWidget *child, | |||
1888 | gint left, | |||
1889 | gint top, | |||
1890 | gint width, | |||
1891 | gint height) | |||
1892 | { | |||
1893 | g_return_if_fail (CTK_IS_GRID (grid))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return; } } while (0); | |||
1894 | g_return_if_fail (CTK_IS_WIDGET (child))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((child)); GType __t = ((ctk_widget_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_WIDGET (child)"); return; } } while (0); | |||
1895 | g_return_if_fail (_ctk_widget_get_parent (child) == NULL)do { if ((_ctk_widget_get_parent (child) == ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "_ctk_widget_get_parent (child) == NULL"); return; } } while (0); | |||
1896 | g_return_if_fail (width > 0)do { if ((width > 0)) { } else { g_return_if_fail_warning ( "Ctk", ((const char*) (__func__)), "width > 0"); return; } } while (0); | |||
1897 | g_return_if_fail (height > 0)do { if ((height > 0)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "height > 0"); return ; } } while (0); | |||
1898 | ||||
1899 | grid_attach (grid, child, left, top, width, height); | |||
1900 | } | |||
1901 | ||||
1902 | /** | |||
1903 | * ctk_grid_attach_next_to: | |||
1904 | * @grid: a #CtkGrid | |||
1905 | * @child: the widget to add | |||
1906 | * @sibling: (allow-none): the child of @grid that @child will be placed | |||
1907 | * next to, or %NULL to place @child at the beginning or end | |||
1908 | * @side: the side of @sibling that @child is positioned next to | |||
1909 | * @width: the number of columns that @child will span | |||
1910 | * @height: the number of rows that @child will span | |||
1911 | * | |||
1912 | * Adds a widget to the grid. | |||
1913 | * | |||
1914 | * The widget is placed next to @sibling, on the side determined by | |||
1915 | * @side. When @sibling is %NULL, the widget is placed in row (for | |||
1916 | * left or right placement) or column 0 (for top or bottom placement), | |||
1917 | * at the end indicated by @side. | |||
1918 | * | |||
1919 | * Attaching widgets labeled [1], [2], [3] with @sibling == %NULL and | |||
1920 | * @side == %CTK_POS_LEFT yields a layout of [3][2][1]. | |||
1921 | */ | |||
1922 | void | |||
1923 | ctk_grid_attach_next_to (CtkGrid *grid, | |||
1924 | CtkWidget *child, | |||
1925 | CtkWidget *sibling, | |||
1926 | CtkPositionType side, | |||
1927 | gint width, | |||
1928 | gint height) | |||
1929 | { | |||
1930 | CtkGridChild *grid_sibling; | |||
1931 | gint left, top; | |||
1932 | ||||
1933 | g_return_if_fail (CTK_IS_GRID (grid))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return; } } while (0); | |||
1934 | g_return_if_fail (CTK_IS_WIDGET (child))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((child)); GType __t = ((ctk_widget_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_WIDGET (child)"); return; } } while (0); | |||
1935 | g_return_if_fail (_ctk_widget_get_parent (child) == NULL)do { if ((_ctk_widget_get_parent (child) == ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "_ctk_widget_get_parent (child) == NULL"); return; } } while (0); | |||
1936 | g_return_if_fail (sibling == NULL || _ctk_widget_get_parent (sibling) == (CtkWidget*)grid)do { if ((sibling == ((void*)0) || _ctk_widget_get_parent (sibling ) == (CtkWidget*)grid)) { } else { g_return_if_fail_warning ( "Ctk", ((const char*) (__func__)), "sibling == NULL || _ctk_widget_get_parent (sibling) == (CtkWidget*)grid" ); return; } } while (0); | |||
1937 | g_return_if_fail (width > 0)do { if ((width > 0)) { } else { g_return_if_fail_warning ( "Ctk", ((const char*) (__func__)), "width > 0"); return; } } while (0); | |||
1938 | g_return_if_fail (height > 0)do { if ((height > 0)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "height > 0"); return ; } } while (0); | |||
1939 | ||||
1940 | if (sibling) | |||
1941 | { | |||
1942 | grid_sibling = find_grid_child (grid, sibling); | |||
1943 | ||||
1944 | switch (side) | |||
1945 | { | |||
1946 | case CTK_POS_LEFT: | |||
1947 | left = CHILD_LEFT (grid_sibling)((grid_sibling)->attach[CTK_ORIENTATION_HORIZONTAL].pos) - width; | |||
1948 | top = CHILD_TOP (grid_sibling)((grid_sibling)->attach[CTK_ORIENTATION_VERTICAL].pos); | |||
1949 | break; | |||
1950 | case CTK_POS_RIGHT: | |||
1951 | left = CHILD_LEFT (grid_sibling)((grid_sibling)->attach[CTK_ORIENTATION_HORIZONTAL].pos) + CHILD_WIDTH (grid_sibling)((grid_sibling)->attach[CTK_ORIENTATION_HORIZONTAL].span); | |||
1952 | top = CHILD_TOP (grid_sibling)((grid_sibling)->attach[CTK_ORIENTATION_VERTICAL].pos); | |||
1953 | break; | |||
1954 | case CTK_POS_TOP: | |||
1955 | left = CHILD_LEFT (grid_sibling)((grid_sibling)->attach[CTK_ORIENTATION_HORIZONTAL].pos); | |||
1956 | top = CHILD_TOP (grid_sibling)((grid_sibling)->attach[CTK_ORIENTATION_VERTICAL].pos) - height; | |||
1957 | break; | |||
1958 | case CTK_POS_BOTTOM: | |||
1959 | left = CHILD_LEFT (grid_sibling)((grid_sibling)->attach[CTK_ORIENTATION_HORIZONTAL].pos); | |||
1960 | top = CHILD_TOP (grid_sibling)((grid_sibling)->attach[CTK_ORIENTATION_VERTICAL].pos) + CHILD_HEIGHT (grid_sibling)((grid_sibling)->attach[CTK_ORIENTATION_VERTICAL].span); | |||
1961 | break; | |||
1962 | default: | |||
1963 | g_assert_not_reached ()do { g_assertion_message_expr ("Ctk", "ctkgrid.c", 1963, ((const char*) (__func__)), ((void*)0)); } while (0); | |||
1964 | } | |||
1965 | } | |||
1966 | else | |||
1967 | { | |||
1968 | switch (side) | |||
1969 | { | |||
1970 | case CTK_POS_LEFT: | |||
1971 | left = find_attach_position (grid, CTK_ORIENTATION_HORIZONTAL, 0, height, FALSE(0)); | |||
1972 | left -= width; | |||
1973 | top = 0; | |||
1974 | break; | |||
1975 | case CTK_POS_RIGHT: | |||
1976 | left = find_attach_position (grid, CTK_ORIENTATION_HORIZONTAL, 0, height, TRUE(!(0))); | |||
1977 | top = 0; | |||
1978 | break; | |||
1979 | case CTK_POS_TOP: | |||
1980 | left = 0; | |||
1981 | top = find_attach_position (grid, CTK_ORIENTATION_VERTICAL, 0, width, FALSE(0)); | |||
1982 | top -= height; | |||
1983 | break; | |||
1984 | case CTK_POS_BOTTOM: | |||
1985 | left = 0; | |||
1986 | top = find_attach_position (grid, CTK_ORIENTATION_VERTICAL, 0, width, TRUE(!(0))); | |||
1987 | break; | |||
1988 | default: | |||
1989 | g_assert_not_reached ()do { g_assertion_message_expr ("Ctk", "ctkgrid.c", 1989, ((const char*) (__func__)), ((void*)0)); } while (0); | |||
1990 | } | |||
1991 | } | |||
1992 | ||||
1993 | grid_attach (grid, child, left, top, width, height); | |||
1994 | } | |||
1995 | ||||
1996 | /** | |||
1997 | * ctk_grid_get_child_at: | |||
1998 | * @grid: a #CtkGrid | |||
1999 | * @left: the left edge of the cell | |||
2000 | * @top: the top edge of the cell | |||
2001 | * | |||
2002 | * Gets the child of @grid whose area covers the grid | |||
2003 | * cell whose upper left corner is at @left, @top. | |||
2004 | * | |||
2005 | * Returns: (transfer none) (nullable): the child at the given position, or %NULL | |||
2006 | * | |||
2007 | * Since: 3.2 | |||
2008 | */ | |||
2009 | CtkWidget * | |||
2010 | ctk_grid_get_child_at (CtkGrid *grid, | |||
2011 | gint left, | |||
2012 | gint top) | |||
2013 | { | |||
2014 | CtkGridPrivate *priv; | |||
2015 | CtkGridChild *child; | |||
2016 | GList *list; | |||
2017 | ||||
2018 | g_return_val_if_fail (CTK_IS_GRID (grid), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return (((void*)0)); } } while (0); | |||
2019 | ||||
2020 | priv = grid->priv; | |||
2021 | ||||
2022 | for (list = priv->children; list; list = list->next) | |||
2023 | { | |||
2024 | child = list->data; | |||
2025 | ||||
2026 | if (CHILD_LEFT (child)((child)->attach[CTK_ORIENTATION_HORIZONTAL].pos) <= left && | |||
2027 | CHILD_LEFT (child)((child)->attach[CTK_ORIENTATION_HORIZONTAL].pos) + CHILD_WIDTH (child)((child)->attach[CTK_ORIENTATION_HORIZONTAL].span) > left && | |||
2028 | CHILD_TOP (child)((child)->attach[CTK_ORIENTATION_VERTICAL].pos) <= top && | |||
2029 | CHILD_TOP (child)((child)->attach[CTK_ORIENTATION_VERTICAL].pos) + CHILD_HEIGHT (child)((child)->attach[CTK_ORIENTATION_VERTICAL].span) > top) | |||
2030 | return child->widget; | |||
2031 | } | |||
2032 | ||||
2033 | return NULL((void*)0); | |||
2034 | } | |||
2035 | ||||
2036 | /** | |||
2037 | * ctk_grid_insert_row: | |||
2038 | * @grid: a #CtkGrid | |||
2039 | * @position: the position to insert the row at | |||
2040 | * | |||
2041 | * Inserts a row at the specified position. | |||
2042 | * | |||
2043 | * Children which are attached at or below this position | |||
2044 | * are moved one row down. Children which span across this | |||
2045 | * position are grown to span the new row. | |||
2046 | * | |||
2047 | * Since: 3.2 | |||
2048 | */ | |||
2049 | void | |||
2050 | ctk_grid_insert_row (CtkGrid *grid, | |||
2051 | gint position) | |||
2052 | { | |||
2053 | CtkGridPrivate *priv; | |||
2054 | CtkGridChild *child; | |||
2055 | GList *list; | |||
2056 | gint top, height; | |||
2057 | ||||
2058 | g_return_if_fail (CTK_IS_GRID (grid))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return; } } while (0); | |||
2059 | ||||
2060 | priv = grid->priv; | |||
2061 | ||||
2062 | for (list = priv->children; list; list = list->next) | |||
2063 | { | |||
2064 | child = list->data; | |||
2065 | ||||
2066 | top = CHILD_TOP (child)((child)->attach[CTK_ORIENTATION_VERTICAL].pos); | |||
2067 | height = CHILD_HEIGHT (child)((child)->attach[CTK_ORIENTATION_VERTICAL].span); | |||
2068 | ||||
2069 | if (top >= position) | |||
2070 | { | |||
2071 | CHILD_TOP (child)((child)->attach[CTK_ORIENTATION_VERTICAL].pos) = top + 1; | |||
2072 | ctk_container_child_notify_by_pspec (CTK_CONTAINER (grid)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_container_get_type ())))))), | |||
2073 | child->widget, | |||
2074 | child_properties[CHILD_PROP_TOP_ATTACH]); | |||
2075 | } | |||
2076 | else if (top + height > position) | |||
2077 | { | |||
2078 | CHILD_HEIGHT (child)((child)->attach[CTK_ORIENTATION_VERTICAL].span) = height + 1; | |||
2079 | ctk_container_child_notify_by_pspec (CTK_CONTAINER (grid)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_container_get_type ())))))), | |||
2080 | child->widget, | |||
2081 | child_properties[CHILD_PROP_HEIGHT]); | |||
2082 | } | |||
2083 | } | |||
2084 | ||||
2085 | for (list = priv->row_properties; list != NULL((void*)0); list = list->next) | |||
2086 | { | |||
2087 | CtkGridRowProperties *prop = list->data; | |||
2088 | ||||
2089 | if (prop->row >= position) | |||
2090 | prop->row += 1; | |||
2091 | } | |||
2092 | } | |||
2093 | ||||
2094 | /** | |||
2095 | * ctk_grid_remove_row: | |||
2096 | * @grid: a #CtkGrid | |||
2097 | * @position: the position of the row to remove | |||
2098 | * | |||
2099 | * Removes a row from the grid. | |||
2100 | * | |||
2101 | * Children that are placed in this row are removed, | |||
2102 | * spanning children that overlap this row have their | |||
2103 | * height reduced by one, and children below the row | |||
2104 | * are moved up. | |||
2105 | * | |||
2106 | * Since: 3.10 | |||
2107 | */ | |||
2108 | void | |||
2109 | ctk_grid_remove_row (CtkGrid *grid, | |||
2110 | gint position) | |||
2111 | { | |||
2112 | CtkGridPrivate *priv; | |||
2113 | CtkGridChild *child; | |||
2114 | GList *list; | |||
2115 | gint top, height; | |||
2116 | ||||
2117 | g_return_if_fail (CTK_IS_GRID (grid))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return; } } while (0); | |||
2118 | ||||
2119 | priv = grid->priv; | |||
2120 | ||||
2121 | list = priv->children; | |||
2122 | while (list) | |||
2123 | { | |||
2124 | child = list->data; | |||
2125 | list = list->next; | |||
2126 | ||||
2127 | top = CHILD_TOP (child)((child)->attach[CTK_ORIENTATION_VERTICAL].pos); | |||
2128 | height = CHILD_HEIGHT (child)((child)->attach[CTK_ORIENTATION_VERTICAL].span); | |||
2129 | ||||
2130 | if (top <= position && top + height > position) | |||
2131 | height--; | |||
2132 | if (top > position) | |||
2133 | top--; | |||
2134 | ||||
2135 | if (height <= 0) | |||
2136 | ctk_container_remove (CTK_CONTAINER (grid)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_container_get_type ())))))), child->widget); | |||
2137 | else | |||
2138 | ctk_container_child_set (CTK_CONTAINER (grid)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_container_get_type ())))))), child->widget, | |||
2139 | "height", height, | |||
2140 | "top-attach", top, | |||
2141 | NULL((void*)0)); | |||
2142 | } | |||
2143 | } | |||
2144 | ||||
2145 | /** | |||
2146 | * ctk_grid_insert_column: | |||
2147 | * @grid: a #CtkGrid | |||
2148 | * @position: the position to insert the column at | |||
2149 | * | |||
2150 | * Inserts a column at the specified position. | |||
2151 | * | |||
2152 | * Children which are attached at or to the right of this position | |||
2153 | * are moved one column to the right. Children which span across this | |||
2154 | * position are grown to span the new column. | |||
2155 | * | |||
2156 | * Since: 3.2 | |||
2157 | */ | |||
2158 | void | |||
2159 | ctk_grid_insert_column (CtkGrid *grid, | |||
2160 | gint position) | |||
2161 | { | |||
2162 | CtkGridPrivate *priv; | |||
2163 | CtkGridChild *child; | |||
2164 | GList *list; | |||
2165 | gint left, width; | |||
2166 | ||||
2167 | g_return_if_fail (CTK_IS_GRID (grid))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return; } } while (0); | |||
2168 | ||||
2169 | priv = grid->priv; | |||
2170 | ||||
2171 | for (list = priv->children; list; list = list->next) | |||
2172 | { | |||
2173 | child = list->data; | |||
2174 | ||||
2175 | left = CHILD_LEFT (child)((child)->attach[CTK_ORIENTATION_HORIZONTAL].pos); | |||
2176 | width = CHILD_WIDTH (child)((child)->attach[CTK_ORIENTATION_HORIZONTAL].span); | |||
2177 | ||||
2178 | if (left >= position) | |||
2179 | { | |||
2180 | CHILD_LEFT (child)((child)->attach[CTK_ORIENTATION_HORIZONTAL].pos) = left + 1; | |||
2181 | ctk_container_child_notify_by_pspec (CTK_CONTAINER (grid)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_container_get_type ())))))), | |||
2182 | child->widget, | |||
2183 | child_properties[CHILD_PROP_LEFT_ATTACH]); | |||
2184 | } | |||
2185 | else if (left + width > position) | |||
2186 | { | |||
2187 | CHILD_WIDTH (child)((child)->attach[CTK_ORIENTATION_HORIZONTAL].span) = width + 1; | |||
2188 | ctk_container_child_notify_by_pspec (CTK_CONTAINER (grid)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_container_get_type ())))))), | |||
2189 | child->widget, | |||
2190 | child_properties[CHILD_PROP_WIDTH]); | |||
2191 | } | |||
2192 | } | |||
2193 | } | |||
2194 | ||||
2195 | /** | |||
2196 | * ctk_grid_remove_column: | |||
2197 | * @grid: a #CtkGrid | |||
2198 | * @position: the position of the column to remove | |||
2199 | * | |||
2200 | * Removes a column from the grid. | |||
2201 | * | |||
2202 | * Children that are placed in this column are removed, | |||
2203 | * spanning children that overlap this column have their | |||
2204 | * width reduced by one, and children after the column | |||
2205 | * are moved to the left. | |||
2206 | * | |||
2207 | * Since: 3.10 | |||
2208 | */ | |||
2209 | void | |||
2210 | ctk_grid_remove_column (CtkGrid *grid, | |||
2211 | gint position) | |||
2212 | { | |||
2213 | CtkGridPrivate *priv; | |||
2214 | CtkGridChild *child; | |||
2215 | GList *list; | |||
2216 | gint left, width; | |||
2217 | ||||
2218 | g_return_if_fail (CTK_IS_GRID (grid))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return; } } while (0); | |||
2219 | ||||
2220 | priv = grid->priv; | |||
2221 | ||||
2222 | list = priv->children; | |||
2223 | while (list) | |||
2224 | { | |||
2225 | child = list->data; | |||
2226 | list = list->next; | |||
2227 | ||||
2228 | left = CHILD_LEFT (child)((child)->attach[CTK_ORIENTATION_HORIZONTAL].pos); | |||
2229 | width = CHILD_WIDTH (child)((child)->attach[CTK_ORIENTATION_HORIZONTAL].span); | |||
2230 | ||||
2231 | if (left <= position && left + width > position) | |||
2232 | width--; | |||
2233 | if (left > position) | |||
2234 | left--; | |||
2235 | ||||
2236 | if (width <= 0) | |||
2237 | ctk_container_remove (CTK_CONTAINER (grid)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_container_get_type ())))))), child->widget); | |||
2238 | else | |||
2239 | ctk_container_child_set (CTK_CONTAINER (grid)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_container_get_type ())))))), child->widget, | |||
2240 | "width", width, | |||
2241 | "left-attach", left, | |||
2242 | NULL((void*)0)); | |||
2243 | } | |||
2244 | } | |||
2245 | ||||
2246 | /** | |||
2247 | * ctk_grid_insert_next_to: | |||
2248 | * @grid: a #CtkGrid | |||
2249 | * @sibling: the child of @grid that the new row or column will be | |||
2250 | * placed next to | |||
2251 | * @side: the side of @sibling that @child is positioned next to | |||
2252 | * | |||
2253 | * Inserts a row or column at the specified position. | |||
2254 | * | |||
2255 | * The new row or column is placed next to @sibling, on the side | |||
2256 | * determined by @side. If @side is %CTK_POS_TOP or %CTK_POS_BOTTOM, | |||
2257 | * a row is inserted. If @side is %CTK_POS_LEFT of %CTK_POS_RIGHT, | |||
2258 | * a column is inserted. | |||
2259 | * | |||
2260 | * Since: 3.2 | |||
2261 | */ | |||
2262 | void | |||
2263 | ctk_grid_insert_next_to (CtkGrid *grid, | |||
2264 | CtkWidget *sibling, | |||
2265 | CtkPositionType side) | |||
2266 | { | |||
2267 | CtkGridChild *child; | |||
2268 | ||||
2269 | g_return_if_fail (CTK_IS_GRID (grid))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return; } } while (0); | |||
2270 | g_return_if_fail (CTK_IS_WIDGET (sibling))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((sibling)); GType __t = ((ctk_widget_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_WIDGET (sibling)"); return; } } while (0); | |||
2271 | g_return_if_fail (_ctk_widget_get_parent (sibling) == (CtkWidget*)grid)do { if ((_ctk_widget_get_parent (sibling) == (CtkWidget*)grid )) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "_ctk_widget_get_parent (sibling) == (CtkWidget*)grid" ); return; } } while (0); | |||
2272 | ||||
2273 | child = find_grid_child (grid, sibling); | |||
2274 | ||||
2275 | switch (side) | |||
2276 | { | |||
2277 | case CTK_POS_LEFT: | |||
2278 | ctk_grid_insert_column (grid, CHILD_LEFT (child)((child)->attach[CTK_ORIENTATION_HORIZONTAL].pos)); | |||
2279 | break; | |||
2280 | case CTK_POS_RIGHT: | |||
2281 | ctk_grid_insert_column (grid, CHILD_LEFT (child)((child)->attach[CTK_ORIENTATION_HORIZONTAL].pos) + CHILD_WIDTH (child)((child)->attach[CTK_ORIENTATION_HORIZONTAL].span)); | |||
2282 | break; | |||
2283 | case CTK_POS_TOP: | |||
2284 | ctk_grid_insert_row (grid, CHILD_TOP (child)((child)->attach[CTK_ORIENTATION_VERTICAL].pos)); | |||
2285 | break; | |||
2286 | case CTK_POS_BOTTOM: | |||
2287 | ctk_grid_insert_row (grid, CHILD_TOP (child)((child)->attach[CTK_ORIENTATION_VERTICAL].pos) + CHILD_HEIGHT (child)((child)->attach[CTK_ORIENTATION_VERTICAL].span)); | |||
2288 | break; | |||
2289 | default: | |||
2290 | g_assert_not_reached ()do { g_assertion_message_expr ("Ctk", "ctkgrid.c", 2290, ((const char*) (__func__)), ((void*)0)); } while (0); | |||
2291 | } | |||
2292 | } | |||
2293 | ||||
2294 | /** | |||
2295 | * ctk_grid_set_row_homogeneous: | |||
2296 | * @grid: a #CtkGrid | |||
2297 | * @homogeneous: %TRUE to make rows homogeneous | |||
2298 | * | |||
2299 | * Sets whether all rows of @grid will have the same height. | |||
2300 | */ | |||
2301 | void | |||
2302 | ctk_grid_set_row_homogeneous (CtkGrid *grid, | |||
2303 | gboolean homogeneous) | |||
2304 | { | |||
2305 | CtkGridPrivate *priv; | |||
2306 | g_return_if_fail (CTK_IS_GRID (grid))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return; } } while (0); | |||
2307 | ||||
2308 | priv = grid->priv; | |||
2309 | ||||
2310 | /* Yes, homogeneous rows means all the columns have the same size */ | |||
2311 | if (COLUMNS (priv)(&(priv)->linedata[CTK_ORIENTATION_VERTICAL])->homogeneous != homogeneous) | |||
2312 | { | |||
2313 | COLUMNS (priv)(&(priv)->linedata[CTK_ORIENTATION_VERTICAL])->homogeneous = homogeneous; | |||
2314 | ||||
2315 | if (_ctk_widget_get_visible (CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ())))))))) | |||
2316 | ctk_widget_queue_resize (CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ()))))))); | |||
2317 | ||||
2318 | g_object_notify_by_pspec (G_OBJECT (grid)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), (((GType) ((20) << (2)))))))), obj_properties [PROP_ROW_HOMOGENEOUS]); | |||
2319 | } | |||
2320 | } | |||
2321 | ||||
2322 | /** | |||
2323 | * ctk_grid_get_row_homogeneous: | |||
2324 | * @grid: a #CtkGrid | |||
2325 | * | |||
2326 | * Returns whether all rows of @grid have the same height. | |||
2327 | * | |||
2328 | * Returns: whether all rows of @grid have the same height. | |||
2329 | */ | |||
2330 | gboolean | |||
2331 | ctk_grid_get_row_homogeneous (CtkGrid *grid) | |||
2332 | { | |||
2333 | CtkGridPrivate *priv; | |||
2334 | g_return_val_if_fail (CTK_IS_GRID (grid), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return ((0)); } } while (0); | |||
2335 | ||||
2336 | priv = grid->priv; | |||
2337 | ||||
2338 | return COLUMNS (priv)(&(priv)->linedata[CTK_ORIENTATION_VERTICAL])->homogeneous; | |||
2339 | } | |||
2340 | ||||
2341 | /** | |||
2342 | * ctk_grid_set_column_homogeneous: | |||
2343 | * @grid: a #CtkGrid | |||
2344 | * @homogeneous: %TRUE to make columns homogeneous | |||
2345 | * | |||
2346 | * Sets whether all columns of @grid will have the same width. | |||
2347 | */ | |||
2348 | void | |||
2349 | ctk_grid_set_column_homogeneous (CtkGrid *grid, | |||
2350 | gboolean homogeneous) | |||
2351 | { | |||
2352 | CtkGridPrivate *priv; | |||
2353 | g_return_if_fail (CTK_IS_GRID (grid))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return; } } while (0); | |||
2354 | ||||
2355 | priv = grid->priv; | |||
2356 | ||||
2357 | /* Yes, homogeneous columns means all the rows have the same size */ | |||
2358 | if (ROWS (priv)(&(priv)->linedata[CTK_ORIENTATION_HORIZONTAL])->homogeneous != homogeneous) | |||
2359 | { | |||
2360 | ROWS (priv)(&(priv)->linedata[CTK_ORIENTATION_HORIZONTAL])->homogeneous = homogeneous; | |||
2361 | ||||
2362 | if (_ctk_widget_get_visible (CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ())))))))) | |||
2363 | ctk_widget_queue_resize (CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ()))))))); | |||
2364 | ||||
2365 | g_object_notify_by_pspec (G_OBJECT (grid)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), (((GType) ((20) << (2)))))))), obj_properties [PROP_COLUMN_HOMOGENEOUS]); | |||
2366 | } | |||
2367 | } | |||
2368 | ||||
2369 | /** | |||
2370 | * ctk_grid_get_column_homogeneous: | |||
2371 | * @grid: a #CtkGrid | |||
2372 | * | |||
2373 | * Returns whether all columns of @grid have the same width. | |||
2374 | * | |||
2375 | * Returns: whether all columns of @grid have the same width. | |||
2376 | */ | |||
2377 | gboolean | |||
2378 | ctk_grid_get_column_homogeneous (CtkGrid *grid) | |||
2379 | { | |||
2380 | CtkGridPrivate *priv; | |||
2381 | g_return_val_if_fail (CTK_IS_GRID (grid), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return ((0)); } } while (0); | |||
2382 | ||||
2383 | priv = grid->priv; | |||
2384 | ||||
2385 | return ROWS (priv)(&(priv)->linedata[CTK_ORIENTATION_HORIZONTAL])->homogeneous; | |||
2386 | } | |||
2387 | ||||
2388 | /** | |||
2389 | * ctk_grid_set_row_spacing: | |||
2390 | * @grid: a #CtkGrid | |||
2391 | * @spacing: the amount of space to insert between rows | |||
2392 | * | |||
2393 | * Sets the amount of space between rows of @grid. | |||
2394 | */ | |||
2395 | void | |||
2396 | ctk_grid_set_row_spacing (CtkGrid *grid, | |||
2397 | guint spacing) | |||
2398 | { | |||
2399 | CtkGridPrivate *priv; | |||
2400 | g_return_if_fail (CTK_IS_GRID (grid))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return; } } while (0); | |||
2401 | g_return_if_fail (spacing <= G_MAXINT16)do { if ((spacing <= ((gint16) 0x7fff))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "spacing <= G_MAXINT16" ); return; } } while (0); | |||
2402 | ||||
2403 | priv = grid->priv; | |||
2404 | ||||
2405 | if (COLUMNS (priv)(&(priv)->linedata[CTK_ORIENTATION_VERTICAL])->spacing != spacing) | |||
2406 | { | |||
2407 | COLUMNS (priv)(&(priv)->linedata[CTK_ORIENTATION_VERTICAL])->spacing = spacing; | |||
2408 | ||||
2409 | if (_ctk_widget_get_visible (CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ())))))))) | |||
2410 | ctk_widget_queue_resize (CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ()))))))); | |||
2411 | ||||
2412 | g_object_notify_by_pspec (G_OBJECT (grid)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), (((GType) ((20) << (2)))))))), obj_properties [PROP_ROW_SPACING]); | |||
2413 | } | |||
2414 | } | |||
2415 | ||||
2416 | /** | |||
2417 | * ctk_grid_get_row_spacing: | |||
2418 | * @grid: a #CtkGrid | |||
2419 | * | |||
2420 | * Returns the amount of space between the rows of @grid. | |||
2421 | * | |||
2422 | * Returns: the row spacing of @grid | |||
2423 | */ | |||
2424 | guint | |||
2425 | ctk_grid_get_row_spacing (CtkGrid *grid) | |||
2426 | { | |||
2427 | CtkGridPrivate *priv; | |||
2428 | g_return_val_if_fail (CTK_IS_GRID (grid), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return (0); } } while (0); | |||
2429 | ||||
2430 | priv = grid->priv; | |||
2431 | ||||
2432 | return COLUMNS (priv)(&(priv)->linedata[CTK_ORIENTATION_VERTICAL])->spacing; | |||
2433 | } | |||
2434 | ||||
2435 | /** | |||
2436 | * ctk_grid_set_column_spacing: | |||
2437 | * @grid: a #CtkGrid | |||
2438 | * @spacing: the amount of space to insert between columns | |||
2439 | * | |||
2440 | * Sets the amount of space between columns of @grid. | |||
2441 | */ | |||
2442 | void | |||
2443 | ctk_grid_set_column_spacing (CtkGrid *grid, | |||
2444 | guint spacing) | |||
2445 | { | |||
2446 | CtkGridPrivate *priv; | |||
2447 | g_return_if_fail (CTK_IS_GRID (grid))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return; } } while (0); | |||
2448 | g_return_if_fail (spacing <= G_MAXINT16)do { if ((spacing <= ((gint16) 0x7fff))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "spacing <= G_MAXINT16" ); return; } } while (0); | |||
2449 | ||||
2450 | priv = grid->priv; | |||
2451 | ||||
2452 | if (ROWS (priv)(&(priv)->linedata[CTK_ORIENTATION_HORIZONTAL])->spacing != spacing) | |||
2453 | { | |||
2454 | ROWS (priv)(&(priv)->linedata[CTK_ORIENTATION_HORIZONTAL])->spacing = spacing; | |||
2455 | ||||
2456 | if (_ctk_widget_get_visible (CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ())))))))) | |||
2457 | ctk_widget_queue_resize (CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ()))))))); | |||
2458 | ||||
2459 | g_object_notify_by_pspec (G_OBJECT (grid)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), (((GType) ((20) << (2)))))))), obj_properties [PROP_COLUMN_SPACING]); | |||
2460 | } | |||
2461 | } | |||
2462 | ||||
2463 | /** | |||
2464 | * ctk_grid_get_column_spacing: | |||
2465 | * @grid: a #CtkGrid | |||
2466 | * | |||
2467 | * Returns the amount of space between the columns of @grid. | |||
2468 | * | |||
2469 | * Returns: the column spacing of @grid | |||
2470 | */ | |||
2471 | guint | |||
2472 | ctk_grid_get_column_spacing (CtkGrid *grid) | |||
2473 | { | |||
2474 | CtkGridPrivate *priv; | |||
2475 | ||||
2476 | g_return_val_if_fail (CTK_IS_GRID (grid), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return (0); } } while (0); | |||
2477 | ||||
2478 | priv = grid->priv; | |||
2479 | ||||
2480 | return ROWS (priv)(&(priv)->linedata[CTK_ORIENTATION_HORIZONTAL])->spacing; | |||
2481 | } | |||
2482 | ||||
2483 | static CtkGridRowProperties * | |||
2484 | find_row_properties (CtkGrid *grid, | |||
2485 | gint row) | |||
2486 | { | |||
2487 | GList *l; | |||
2488 | ||||
2489 | for (l = grid->priv->row_properties; l != NULL((void*)0); l = l->next) | |||
2490 | { | |||
2491 | CtkGridRowProperties *prop = l->data; | |||
2492 | if (prop->row == row) | |||
2493 | return prop; | |||
2494 | } | |||
2495 | ||||
2496 | return NULL((void*)0); | |||
2497 | } | |||
2498 | ||||
2499 | static void | |||
2500 | ctk_grid_row_properties_free (CtkGridRowProperties *props) | |||
2501 | { | |||
2502 | g_slice_free (CtkGridRowProperties, props)do { if (1) g_slice_free1 (sizeof (CtkGridRowProperties), (props )); else (void) ((CtkGridRowProperties*) 0 == (props)); } while (0); | |||
2503 | } | |||
2504 | ||||
2505 | static CtkGridRowProperties * | |||
2506 | get_row_properties_or_create (CtkGrid *grid, | |||
2507 | gint row) | |||
2508 | { | |||
2509 | CtkGridRowProperties *props; | |||
2510 | CtkGridPrivate *priv = grid->priv; | |||
2511 | ||||
2512 | props = find_row_properties (grid, row); | |||
2513 | if (props) | |||
2514 | return props; | |||
2515 | ||||
2516 | props = g_slice_new (CtkGridRowProperties)((CtkGridRowProperties*) g_slice_alloc (sizeof (CtkGridRowProperties ))); | |||
2517 | *props = ctk_grid_row_properties_default; | |||
2518 | props->row = row; | |||
2519 | ||||
2520 | priv->row_properties = | |||
2521 | g_list_prepend (priv->row_properties, props); | |||
2522 | ||||
2523 | return props; | |||
2524 | } | |||
2525 | ||||
2526 | static const CtkGridRowProperties * | |||
2527 | get_row_properties_or_default (CtkGrid *grid, | |||
2528 | gint row) | |||
2529 | { | |||
2530 | CtkGridRowProperties *props; | |||
2531 | ||||
2532 | props = find_row_properties (grid, row); | |||
2533 | if (props) | |||
2534 | return props; | |||
2535 | return &ctk_grid_row_properties_default; | |||
2536 | } | |||
2537 | ||||
2538 | /** | |||
2539 | * ctk_grid_set_row_baseline_position: | |||
2540 | * @grid: a #CtkGrid | |||
2541 | * @row: a row index | |||
2542 | * @pos: a #CtkBaselinePosition | |||
2543 | * | |||
2544 | * Sets how the baseline should be positioned on @row of the | |||
2545 | * grid, in case that row is assigned more space than is requested. | |||
2546 | * | |||
2547 | * Since: 3.10 | |||
2548 | */ | |||
2549 | void | |||
2550 | ctk_grid_set_row_baseline_position (CtkGrid *grid, | |||
2551 | gint row, | |||
2552 | CtkBaselinePosition pos) | |||
2553 | { | |||
2554 | CtkGridRowProperties *props; | |||
2555 | ||||
2556 | g_return_if_fail (CTK_IS_GRID (grid))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return; } } while (0); | |||
2557 | ||||
2558 | props = get_row_properties_or_create (grid, row); | |||
2559 | ||||
2560 | if (props->baseline_position != pos) | |||
2561 | { | |||
2562 | props->baseline_position = pos; | |||
2563 | ||||
2564 | if (_ctk_widget_get_visible (CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ())))))))) | |||
2565 | ctk_widget_queue_resize (CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ()))))))); | |||
2566 | } | |||
2567 | } | |||
2568 | ||||
2569 | /** | |||
2570 | * ctk_grid_get_row_baseline_position: | |||
2571 | * @grid: a #CtkGrid | |||
2572 | * @row: a row index | |||
2573 | * | |||
2574 | * Returns the baseline position of @row as set | |||
2575 | * by ctk_grid_set_row_baseline_position() or the default value | |||
2576 | * %CTK_BASELINE_POSITION_CENTER. | |||
2577 | * | |||
2578 | * Returns: the baseline position of @row | |||
2579 | * | |||
2580 | * Since: 3.10 | |||
2581 | */ | |||
2582 | CtkBaselinePosition | |||
2583 | ctk_grid_get_row_baseline_position (CtkGrid *grid, | |||
2584 | gint row) | |||
2585 | { | |||
2586 | const CtkGridRowProperties *props; | |||
2587 | ||||
2588 | g_return_val_if_fail (CTK_IS_GRID (grid), CTK_BASELINE_POSITION_CENTER)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return (CTK_BASELINE_POSITION_CENTER ); } } while (0); | |||
2589 | ||||
2590 | props = get_row_properties_or_default (grid, row); | |||
2591 | ||||
2592 | return props->baseline_position; | |||
2593 | } | |||
2594 | ||||
2595 | /** | |||
2596 | * ctk_grid_set_baseline_row: | |||
2597 | * @grid: a #CtkGrid | |||
2598 | * @row: the row index | |||
2599 | * | |||
2600 | * Sets which row defines the global baseline for the entire grid. | |||
2601 | * Each row in the grid can have its own local baseline, but only | |||
2602 | * one of those is global, meaning it will be the baseline in the | |||
2603 | * parent of the @grid. | |||
2604 | * | |||
2605 | * Since: 3.10 | |||
2606 | */ | |||
2607 | void | |||
2608 | ctk_grid_set_baseline_row (CtkGrid *grid, | |||
2609 | gint row) | |||
2610 | { | |||
2611 | CtkGridPrivate *priv; | |||
2612 | ||||
2613 | g_return_if_fail (CTK_IS_GRID (grid))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return; } } while (0); | |||
2614 | ||||
2615 | priv = grid->priv; | |||
2616 | ||||
2617 | if (priv->baseline_row != row) | |||
2618 | { | |||
2619 | priv->baseline_row = row; | |||
2620 | ||||
2621 | if (_ctk_widget_get_visible (CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ())))))))) | |||
2622 | ctk_widget_queue_resize (CTK_WIDGET (grid)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), ((ctk_widget_get_type ()))))))); | |||
2623 | g_object_notify (G_OBJECT (grid)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((grid)), (((GType) ((20) << (2)))))))), "baseline-row"); | |||
2624 | } | |||
2625 | } | |||
2626 | ||||
2627 | /** | |||
2628 | * ctk_grid_get_baseline_row: | |||
2629 | * @grid: a #CtkGrid | |||
2630 | * | |||
2631 | * Returns which row defines the global baseline of @grid. | |||
2632 | * | |||
2633 | * Returns: the row index defining the global baseline | |||
2634 | * | |||
2635 | * Since: 3.10 | |||
2636 | */ | |||
2637 | gint | |||
2638 | ctk_grid_get_baseline_row (CtkGrid *grid) | |||
2639 | { | |||
2640 | CtkGridPrivate *priv; | |||
2641 | ||||
2642 | g_return_val_if_fail (CTK_IS_GRID (grid), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((grid)); GType __t = ((ctk_grid_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_GRID (grid)"); return (0); } } while (0); | |||
2643 | ||||
2644 | priv = grid->priv; | |||
2645 | ||||
2646 | return priv->baseline_row; | |||
2647 | } |