]> Pileus Git - ~andy/gtk/blob - gtk/gtkwidgetpath.c
s/child class/region/ everywhere.
[~andy/gtk] / gtk / gtkwidgetpath.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 2010 Carlos Garnacho <carlosg@gnome.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include "config.h"
21
22 #include <string.h>
23
24 #include "gtkwidget.h"
25 #include "gtkwidgetpath.h"
26
27 typedef struct GtkPathElement GtkPathElement;
28
29 struct GtkPathElement
30 {
31   GType type;
32   GQuark name;
33   GHashTable *regions;
34 };
35
36 struct GtkWidgetPath
37 {
38   GArray *elems; /* First element contains the described widget */
39 };
40
41 GtkWidgetPath *
42 gtk_widget_path_new (void)
43 {
44   GtkWidgetPath *path;
45
46   path = g_slice_new0 (GtkWidgetPath);
47   path->elems = g_array_new (FALSE, TRUE, sizeof (GtkPathElement));
48
49   return path;
50 }
51
52 GtkWidgetPath *
53 gtk_widget_path_copy (const GtkWidgetPath *path)
54 {
55   GtkWidgetPath *new_path;
56   guint i;
57
58   g_return_val_if_fail (path != NULL, NULL);
59
60   new_path = gtk_widget_path_new ();
61
62   for (i = 0; i < path->elems->len; i++)
63     {
64       GtkPathElement *elem, new = { 0 };
65
66       elem = &g_array_index (path->elems, GtkPathElement, i);
67
68       new.type = elem->type;
69       new.name = elem->name;
70
71       if (elem->regions)
72         {
73           GHashTableIter iter;
74           gpointer key, value;
75
76           g_hash_table_iter_init (&iter, elem->regions);
77           new.regions = g_hash_table_new (NULL, NULL);
78
79           while (g_hash_table_iter_next (&iter, &key, &value))
80             g_hash_table_insert (new.regions, key, value);
81         }
82
83       g_array_append_val (new_path->elems, new);
84     }
85
86   return new_path;
87 }
88
89 void
90 gtk_widget_path_free (GtkWidgetPath *path)
91 {
92   guint i;
93
94   g_return_if_fail (path != NULL);
95
96   for (i = 0; i < path->elems->len; i++)
97     {
98       GtkPathElement *elem;
99
100       elem = &g_array_index (path->elems, GtkPathElement, i);
101
102       if (elem->regions)
103         g_hash_table_destroy (elem->regions);
104     }
105
106   g_array_free (path->elems, TRUE);
107   g_slice_free (GtkWidgetPath, path);
108 }
109
110 guint
111 gtk_widget_path_length (const GtkWidgetPath *path)
112 {
113   g_return_val_if_fail (path != NULL, 0);
114
115   return path->elems->len;
116 }
117
118 guint
119 gtk_widget_path_prepend_type (GtkWidgetPath *path,
120                               GType          type)
121 {
122   GtkPathElement new = { 0 };
123
124   g_return_val_if_fail (path != NULL, 0);
125   g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), 0);
126
127   new.type = type;
128   g_array_append_val (path->elems, new);
129
130   return path->elems->len - 1;
131 }
132
133 GType
134 gtk_widget_path_iter_get_widget_type (const GtkWidgetPath *path,
135                                       guint                pos)
136 {
137   GtkPathElement *elem;
138
139   g_return_val_if_fail (path != NULL, G_TYPE_INVALID);
140   g_return_val_if_fail (pos < path->elems->len, G_TYPE_INVALID);
141
142   elem = &g_array_index (path->elems, GtkPathElement, pos);
143   return elem->type;
144 }
145
146 void
147 gtk_widget_path_iter_set_widget_type (GtkWidgetPath *path,
148                                       guint          pos,
149                                       GType          type)
150 {
151   GtkPathElement *elem;
152
153   g_return_if_fail (path != NULL);
154   g_return_if_fail (pos < path->elems->len);
155   g_return_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET));
156
157   elem = &g_array_index (path->elems, GtkPathElement, pos);
158   elem->type = type;
159 }
160
161 G_CONST_RETURN gchar *
162 gtk_widget_path_iter_get_name (const GtkWidgetPath *path,
163                                guint                pos)
164 {
165   GtkPathElement *elem;
166
167   g_return_val_if_fail (path != NULL, NULL);
168   g_return_val_if_fail (pos < path->elems->len, NULL);
169
170   elem = &g_array_index (path->elems, GtkPathElement, pos);
171   return g_quark_to_string (elem->name);
172 }
173
174 void
175 gtk_widget_path_iter_set_name (GtkWidgetPath *path,
176                                guint          pos,
177                                const gchar   *name)
178 {
179   GtkPathElement *elem;
180
181   g_return_if_fail (path != NULL);
182   g_return_if_fail (pos < path->elems->len);
183   g_return_if_fail (name != NULL);
184
185   elem = &g_array_index (path->elems, GtkPathElement, pos);
186
187   elem->name = g_quark_from_string (name);
188 }
189
190 gboolean
191 gtk_widget_path_iter_has_qname (const GtkWidgetPath *path,
192                                 guint                pos,
193                                 GQuark               qname)
194 {
195   GtkPathElement *elem;
196
197   g_return_val_if_fail (path != NULL, FALSE);
198   g_return_val_if_fail (qname != 0, FALSE);
199   g_return_val_if_fail (pos < path->elems->len, FALSE);
200
201   elem = &g_array_index (path->elems, GtkPathElement, pos);
202
203   return (elem->name == qname);
204 }
205
206 gboolean
207 gtk_widget_path_iter_has_name (const GtkWidgetPath *path,
208                                guint                pos,
209                                const gchar         *name)
210 {
211   GQuark qname;
212
213   g_return_val_if_fail (path != NULL, FALSE);
214   g_return_val_if_fail (name != NULL, FALSE);
215   g_return_val_if_fail (pos < path->elems->len, FALSE);
216
217   qname = g_quark_try_string (name);
218
219   if (qname == 0)
220     return FALSE;
221
222   return gtk_widget_path_iter_has_qname (path, pos, qname);
223 }
224
225 void
226 gtk_widget_path_iter_add_region (GtkWidgetPath  *path,
227                                  guint           pos,
228                                  const gchar    *name,
229                                  GtkRegionFlags  flags)
230 {
231   GtkPathElement *elem;
232   GQuark qname;
233
234   g_return_if_fail (path != NULL);
235   g_return_if_fail (pos < path->elems->len);
236   g_return_if_fail (name != NULL);
237
238   elem = &g_array_index (path->elems, GtkPathElement, pos);
239   qname = g_quark_from_string (name);
240
241   if (!elem->regions)
242     elem->regions = g_hash_table_new (NULL, NULL);
243
244   g_hash_table_insert (elem->regions,
245                        GUINT_TO_POINTER (qname),
246                        GUINT_TO_POINTER (flags));
247 }
248
249 void
250 gtk_widget_path_iter_remove_region (GtkWidgetPath *path,
251                                     guint          pos,
252                                     const gchar   *name)
253 {
254   GtkPathElement *elem;
255   GQuark qname;
256
257   g_return_if_fail (path != NULL);
258   g_return_if_fail (pos < path->elems->len);
259   g_return_if_fail (name != NULL);
260
261   qname = g_quark_try_string (name);
262
263   if (qname == 0)
264     return;
265
266   elem = &g_array_index (path->elems, GtkPathElement, pos);
267
268   if (elem->regions)
269     g_hash_table_remove (elem->regions, GUINT_TO_POINTER (qname));
270 }
271
272 void
273 gtk_widget_path_iter_clear_regions (GtkWidgetPath *path,
274                                     guint          pos)
275 {
276   GtkPathElement *elem;
277
278   g_return_if_fail (path != NULL);
279   g_return_if_fail (pos < path->elems->len);
280
281   elem = &g_array_index (path->elems, GtkPathElement, pos);
282
283   if (elem->regions)
284     g_hash_table_remove_all (elem->regions);
285 }
286
287 GSList *
288 gtk_widget_path_iter_list_regions (const GtkWidgetPath *path,
289                                    guint                pos)
290 {
291   GtkPathElement *elem;
292   GHashTableIter iter;
293   GSList *list = NULL;
294   gpointer key;
295
296   g_return_val_if_fail (path != NULL, NULL);
297   g_return_val_if_fail (pos < path->elems->len, NULL);
298
299   elem = &g_array_index (path->elems, GtkPathElement, pos);
300
301   if (!elem->regions)
302     return NULL;
303
304   g_hash_table_iter_init (&iter, elem->regions);
305
306   while (g_hash_table_iter_next (&iter, &key, NULL))
307     {
308       GQuark qname;
309
310       qname = GPOINTER_TO_UINT (key);
311       list = g_slist_prepend (list, (gchar *) g_quark_to_string (qname));
312     }
313
314   return list;
315 }
316
317 gboolean
318 gtk_widget_path_iter_has_qregion (const GtkWidgetPath *path,
319                                   guint                pos,
320                                   GQuark               qname,
321                                   GtkRegionFlags      *flags)
322 {
323   GtkPathElement *elem;
324   gpointer value;
325
326   g_return_val_if_fail (path != NULL, FALSE);
327   g_return_val_if_fail (pos < path->elems->len, FALSE);
328   g_return_val_if_fail (qname != 0, FALSE);
329
330   elem = &g_array_index (path->elems, GtkPathElement, pos);
331
332   if (!elem->regions)
333     return FALSE;
334
335   if (!g_hash_table_lookup_extended (elem->regions,
336                                      GUINT_TO_POINTER (qname),
337                                      NULL, &value))
338     return FALSE;
339
340   if (flags)
341     *flags = GPOINTER_TO_UINT (value);
342
343   return TRUE;
344 }
345
346 gboolean
347 gtk_widget_path_iter_has_region (const GtkWidgetPath *path,
348                                  guint                pos,
349                                  const gchar         *name,
350                                  GtkRegionFlags      *flags)
351 {
352   GQuark qname;
353
354   g_return_val_if_fail (path != NULL, FALSE);
355   g_return_val_if_fail (pos < path->elems->len, FALSE);
356   g_return_val_if_fail (name != NULL, FALSE);
357
358   qname = g_quark_try_string (name);
359
360   if (qname == 0)
361     return FALSE;
362
363   return gtk_widget_path_iter_has_qregion (path, pos, qname, flags);
364 }
365
366 GType
367 gtk_widget_path_get_widget_type (const GtkWidgetPath *path)
368 {
369   GtkPathElement *elem;
370
371   g_return_val_if_fail (path != NULL, G_TYPE_INVALID);
372
373   elem = &g_array_index (path->elems, GtkPathElement, 0);
374   return elem->type;
375 }
376
377 gboolean
378 gtk_widget_path_is_type (const GtkWidgetPath *path,
379                          GType                type)
380 {
381   GtkPathElement *elem;
382
383   g_return_val_if_fail (path != NULL, FALSE);
384   g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), FALSE);
385
386   elem = &g_array_index (path->elems, GtkPathElement, 0);
387
388   if (elem->type == type ||
389       g_type_is_a (elem->type, type))
390     return TRUE;
391
392   return FALSE;
393 }
394
395 gboolean
396 gtk_widget_path_has_parent (const GtkWidgetPath *path,
397                             GType                type)
398 {
399   guint i;
400
401   g_return_val_if_fail (path != NULL, FALSE);
402   g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), FALSE);
403
404   for (i = 1; i < path->elems->len; i++)
405     {
406       GtkPathElement *elem;
407
408       elem = &g_array_index (path->elems, GtkPathElement, i);
409
410       if (elem->type == type ||
411           g_type_is_a (elem->type, type))
412         return TRUE;
413     }
414
415   return FALSE;
416 }
417
418 #define __GTK_WIDGET_PATH_C__
419 #include "gtkaliasdef.c"