]> Pileus Git - ~andy/gtk/blob - gtk/tests/stylecontext.c
Some more documentation fixes
[~andy/gtk] / gtk / tests / stylecontext.c
1 #include <gtk/gtk.h>
2
3 static void
4 test_parse_selectors (void)
5 {
6   GtkCssProvider *provider;
7   GError *error;
8   gboolean res;
9   gint i;
10   const gchar *valid[] = {
11     "* {}",
12     "E {}",
13     "E F {}",
14     "E > F {}",
15     "E#id {}",
16     "#id {}",
17     "tab:first-child {}",
18     "tab:last-child {}",
19     "tab:nth-child(first) {}",
20     "tab:nth-child(last) {}",
21     "tab:nth-child(even) {}",
22     "tab:nth-child(odd) {}",
23     "tab:sorted {}",
24     ".some-class {}",
25     ".some-class.another-class {}",
26     ".some-class .another-class {}",
27     "E * {}",
28     "E .class {}",
29     "E > .foo {}",
30     "E > #id {}",
31     "E:active {}",
32     "E:prelight {}",
33     "E:hover {}",
34     "E:selected {}",
35     "E:insensitive {}",
36     "E:inconsistent {}",
37     "E:focused {}",
38     "E:active:prelight {}",
39     "* > .notebook tab:first-child .label:focused {}",
40     "E, F {}",
41     "E, F /* comment here */ {}",
42     "E,/* comment here */ F {}",
43     "E1.e1_2 #T3_4 {}",
44     "E:first-child {}",
45     "E:last-child {}",
46     "E:nth-child(first) {}",
47     "E:nth-child(last) {}",
48     "E:nth-child(even) {}",
49     "E:nth-child(odd) {}",
50     "E:sorted {}",
51     "E:focused tab {}",
52      NULL
53   };
54
55   error = NULL;
56   for (i = 0; valid[i]; i++)
57     {
58       provider = gtk_css_provider_new ();
59       res = gtk_css_provider_load_from_data (provider, valid[i], -1, &error);
60       if (error)
61         g_print ("parsing '%s': got unexpected error: %s\n", valid[i], error->message);
62       g_assert_no_error (error);
63       g_assert (res);
64
65       g_object_unref (provider);
66    }
67 }
68
69 static void
70 test_path (void)
71 {
72   GtkWidgetPath *path;
73   GtkWidgetPath *path2;
74   gint pos;
75   GtkRegionFlags flags;
76
77   path = gtk_widget_path_new ();
78   g_assert_cmpint (gtk_widget_path_length (path), ==, 0);
79
80   pos = gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
81   g_assert_cmpint (pos, ==, 0);
82   g_assert_cmpint (gtk_widget_path_length (path), ==, 1);
83   g_assert (gtk_widget_path_iter_get_object_type (path, 0) == GTK_TYPE_WINDOW);
84   g_assert (gtk_widget_path_is_type (path, GTK_TYPE_WIDGET));
85   g_assert (gtk_widget_path_iter_get_name (path, 0) == NULL);
86
87   pos = gtk_widget_path_append_type (path, GTK_TYPE_WIDGET);
88   g_assert_cmpint (pos, ==, 1);
89   g_assert_cmpint (gtk_widget_path_length (path), ==, 2);
90   gtk_widget_path_iter_set_object_type (path, pos, GTK_TYPE_BUTTON);
91   g_assert (gtk_widget_path_is_type (path, GTK_TYPE_BUTTON));
92   g_assert (gtk_widget_path_has_parent (path, GTK_TYPE_WIDGET));
93   g_assert (gtk_widget_path_has_parent (path, GTK_TYPE_WINDOW));
94   g_assert (!gtk_widget_path_has_parent (path, GTK_TYPE_DIALOG));
95   g_assert (gtk_widget_path_iter_get_name (path, 1) == NULL);
96
97   gtk_widget_path_iter_set_name (path, 1, "name");
98   g_assert (gtk_widget_path_iter_has_name (path, 1, "name"));
99
100   gtk_widget_path_iter_add_class (path, 1, "class1");
101   gtk_widget_path_iter_add_class (path, 1, "class2");
102   g_assert (gtk_widget_path_iter_has_class (path, 1, "class1"));
103   g_assert (gtk_widget_path_iter_has_class (path, 1, "class2"));
104   g_assert (!gtk_widget_path_iter_has_class (path, 1, "class3"));
105
106   path2 = gtk_widget_path_copy (path);
107   g_assert (gtk_widget_path_iter_has_class (path2, 1, "class1"));
108   g_assert (gtk_widget_path_iter_has_class (path2, 1, "class2"));
109   g_assert (!gtk_widget_path_iter_has_class (path2, 1, "class3"));
110   gtk_widget_path_free (path2);
111
112   gtk_widget_path_iter_remove_class (path, 1, "class2");
113   g_assert (gtk_widget_path_iter_has_class (path, 1, "class1"));
114   g_assert (!gtk_widget_path_iter_has_class (path, 1, "class2"));
115   gtk_widget_path_iter_clear_classes (path, 1);
116   g_assert (!gtk_widget_path_iter_has_class (path, 1, "class1"));
117
118   gtk_widget_path_iter_add_region (path, 1, "tab", 0);
119   gtk_widget_path_iter_add_region (path, 1, "title", GTK_REGION_EVEN | GTK_REGION_FIRST);
120
121   g_assert (gtk_widget_path_iter_has_region (path, 1, "tab", &flags) &&
122             flags == 0);
123   g_assert (gtk_widget_path_iter_has_region (path, 1, "title", &flags) &&
124             flags == (GTK_REGION_EVEN | GTK_REGION_FIRST));
125   g_assert (!gtk_widget_path_iter_has_region (path, 1, "extension", NULL));
126
127   path2 = gtk_widget_path_copy (path);
128   g_assert (gtk_widget_path_iter_has_region (path2, 1, "tab", &flags) &&
129             flags == 0);
130   g_assert (gtk_widget_path_iter_has_region (path2, 1, "title", &flags) &&
131             flags == (GTK_REGION_EVEN | GTK_REGION_FIRST));
132   g_assert (!gtk_widget_path_iter_has_region (path2, 1, "extension", NULL));
133   gtk_widget_path_free (path2);
134
135   gtk_widget_path_free (path);
136 }
137
138 static void
139 test_match (void)
140 {
141   GtkStyleContext *context;
142   GtkWidgetPath *path;
143   GtkCssProvider *provider;
144   GError *error;
145   const gchar *data;
146   GdkRGBA color;
147   GdkRGBA expected;
148
149   error = NULL;
150   provider = gtk_css_provider_new ();
151
152   gdk_rgba_parse (&expected, "#fff");
153
154   context = gtk_style_context_new ();
155
156   path = gtk_widget_path_new ();
157   gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
158   gtk_widget_path_append_type (path, GTK_TYPE_BOX);
159   gtk_widget_path_append_type (path, GTK_TYPE_BUTTON);
160   gtk_widget_path_iter_set_name (path, 0, "mywindow");
161   gtk_widget_path_iter_add_class (path, 2, "button");
162   gtk_style_context_set_path (context, path);
163   gtk_widget_path_free (path);
164
165   gtk_style_context_add_provider (context,
166                                   GTK_STYLE_PROVIDER (provider),
167                                   GTK_STYLE_PROVIDER_PRIORITY_USER);
168
169   data = "* { color: #fff }";
170   gtk_css_provider_load_from_data (provider, data, -1, &error);
171   g_assert_no_error (error);
172   gtk_style_context_invalidate (context);
173   gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
174   g_assert (gdk_rgba_equal (&color, &expected));
175
176   data = "* { color: #f00 }\n"
177          "GtkButton { color: #fff }";
178   gtk_css_provider_load_from_data (provider, data, -1, &error);
179   g_assert_no_error (error);
180   gtk_style_context_invalidate (context);
181   gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
182   g_assert (gdk_rgba_equal (&color, &expected));
183
184   data = "* { color: #f00 }\n"
185          "GtkButton { color: #fff }\n"
186          "GtkWindow > GtkButton { color: #000 }";
187   gtk_css_provider_load_from_data (provider, data, -1, &error);
188   g_assert_no_error (error);
189   gtk_style_context_invalidate (context);
190   gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
191   g_assert (gdk_rgba_equal (&color, &expected));
192
193   data = "* { color: #f00 }\n"
194          ".button { color: #fff }";
195   gtk_css_provider_load_from_data (provider, data, -1, &error);
196   g_assert_no_error (error);
197   gtk_style_context_invalidate (context);
198   gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
199   g_assert (gdk_rgba_equal (&color, &expected));
200
201   data = "* { color: #f00 }\n"
202          "GtkButton { color: #000 }\n"
203          ".button { color: #fff }";
204   gtk_css_provider_load_from_data (provider, data, -1, &error);
205   g_assert_no_error (error);
206   gtk_style_context_invalidate (context);
207   gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
208   g_assert (gdk_rgba_equal (&color, &expected));
209
210   data = "* { color: #f00 }\n"
211          "GtkButton { color: #000 }\n"
212          "GtkWindow GtkButton { color: #fff }";
213   gtk_css_provider_load_from_data (provider, data, -1, &error);
214   g_assert_no_error (error);
215   gtk_style_context_invalidate (context);
216   gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
217   g_assert (gdk_rgba_equal (&color, &expected));
218
219   data = "* { color: #f00 }\n"
220          ".button { color: #000 }\n"
221          "GtkWindow .button { color: #fff }";
222   gtk_css_provider_load_from_data (provider, data, -1, &error);
223   g_assert_no_error (error);
224   gtk_style_context_invalidate (context);
225   gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
226   g_assert (gdk_rgba_equal (&color, &expected));
227
228   data = "* { color: #f00 }\n"
229          "* .button { color: #000 }\n"
230          "#mywindow .button { color: #fff }";
231   gtk_css_provider_load_from_data (provider, data, -1, &error);
232   g_assert_no_error (error);
233   gtk_style_context_invalidate (context);
234   gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
235   g_assert (gdk_rgba_equal (&color, &expected));
236
237   data = "* { color: #f00 }\n"
238          "GtkWindow .button { color: #000 }\n"
239          "GtkWindow#mywindow .button { color: #fff }";
240   gtk_css_provider_load_from_data (provider, data, -1, &error);
241   g_assert_no_error (error);
242   gtk_style_context_invalidate (context);
243   gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
244   g_assert (gdk_rgba_equal (&color, &expected));
245
246   data = "* { color: #f00 }\n"
247          "GtkWindow .button { color: #000 }\n"
248          "GObject .button { color: #fff }";
249   gtk_css_provider_load_from_data (provider, data, -1, &error);
250   g_assert_no_error (error);
251   gtk_style_context_invalidate (context);
252   gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
253   g_assert (gdk_rgba_equal (&color, &expected));
254
255   g_object_unref (provider);
256   g_object_unref (context);
257 }
258
259 static void
260 test_style_property (void)
261 {
262   GtkStyleContext *context;
263   GtkWidgetPath *path;
264   GtkCssProvider *provider;
265   GError *error;
266   const gchar *data;
267   gint x;
268   GdkRGBA color;
269   GdkRGBA expected;
270
271   error = NULL;
272   provider = gtk_css_provider_new ();
273
274   context = gtk_style_context_new ();
275
276   path = gtk_widget_path_new ();
277   gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
278   gtk_widget_path_append_type (path, GTK_TYPE_BOX);
279   gtk_widget_path_append_type (path, GTK_TYPE_BUTTON);
280   gtk_style_context_set_path (context, path);
281   gtk_widget_path_free (path);
282   gtk_style_context_set_state (context, GTK_STATE_FLAG_PRELIGHT);
283
284   /* Since we set the prelight state on the context, we expect
285    * only the third selector to match, even though the second one
286    * has higher specificity, and the fourth one comes later.
287    *
288    * In particular, we want to verify that widget style properties and
289    * CSS properties follow the same matching rules, ie we expect
290    * color to be #003 and child-displacement-x to be 3.
291    */
292   data = "GtkButton:insensitive { color: #001; -GtkButton-child-displacement-x: 1 }\n"
293          "GtkBox GtkButton:selected { color: #002; -GtkButton-child-displacement-x: 2 }\n"
294          "GtkButton:prelight { color: #003; -GtkButton-child-displacement-x: 3 }\n"
295          "GtkButton:focused { color: #004; -GtkButton-child-displacement-x: 4 }\n";
296   gtk_css_provider_load_from_data (provider, data, -1, &error);
297   g_assert_no_error (error);
298   gtk_style_context_add_provider (context,
299                                   GTK_STYLE_PROVIDER (provider),
300                                   GTK_STYLE_PROVIDER_PRIORITY_USER);
301
302   gtk_style_context_invalidate (context);
303
304   gtk_style_context_get_color (context, GTK_STATE_FLAG_PRELIGHT, &color);
305   gdk_rgba_parse (&expected, "#003");
306   g_assert (gdk_rgba_equal (&color, &expected));
307
308   gtk_style_context_get_style (context, "child-displacement-x", &x, NULL);
309
310   g_assert_cmpint (x, ==, 3);
311
312   g_object_unref (provider);
313   g_object_unref (context);
314 }
315
316 static void
317 test_basic_properties (void)
318 {
319   GtkStyleContext *context;
320   GtkWidgetPath *path;
321   GdkRGBA *color;
322   GdkRGBA *bg_color;
323   PangoFontDescription *font;
324
325   context = gtk_style_context_new ();
326   path = gtk_widget_path_new ();
327   gtk_style_context_set_path (context, path);
328   gtk_widget_path_free (path);
329
330   gtk_style_context_get (context, 0,
331                          "color", &color,
332                          "background-color", &bg_color,
333                          "font", &font,
334                          NULL);
335   g_assert (color != NULL);
336   g_assert (bg_color != NULL);
337   g_assert (font != NULL);
338
339   gdk_rgba_free (color);
340   gdk_rgba_free (bg_color);
341   pango_font_description_free (font);
342
343   g_object_unref (context);
344 }
345
346 int
347 main (int argc, char *argv[])
348 {
349   gtk_init (NULL, NULL);
350   g_test_init (&argc, &argv, NULL);
351
352   g_test_add_func ("/style/parse/selectors", test_parse_selectors);
353   g_test_add_func ("/style/path", test_path);
354   g_test_add_func ("/style/match", test_match);
355   g_test_add_func ("/style/style-property", test_style_property);
356   g_test_add_func ("/style/basic", test_basic_properties);
357
358   return g_test_run ();
359 }