]> Pileus Git - ~andy/gtk/blob - gtk/gtkcssenumvalue.c
cssvalue: Add animation enum properties
[~andy/gtk] / gtk / gtkcssenumvalue.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 2011 Red Hat, Inc.
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, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include "config.h"
19
20 #include "gtkcssenumvalueprivate.h"
21
22 #include "gtkstylepropertyprivate.h"
23
24 /* repeated API */
25
26 struct _GtkCssValue {
27   GTK_CSS_VALUE_BASE
28   int value;
29   const char *name;
30 };
31
32 static void
33 gtk_css_value_enum_free (GtkCssValue *value)
34 {
35   g_slice_free (GtkCssValue, value);
36 }
37
38 static GtkCssValue *
39 gtk_css_value_enum_compute (GtkCssValue        *value,
40                             guint               property_id,
41                             GtkStyleContext    *context,
42                             GtkCssDependencies *dependencies)
43 {
44   return _gtk_css_value_ref (value);
45 }
46
47 static gboolean
48 gtk_css_value_enum_equal (const GtkCssValue *enum1,
49                           const GtkCssValue *enum2)
50 {
51   return enum1 == enum2;
52 }
53
54 static GtkCssValue *
55 gtk_css_value_enum_transition (GtkCssValue *start,
56                                GtkCssValue *end,
57                                guint        property_id,
58                                double       progress)
59 {
60   return NULL;
61 }
62
63 static void
64 gtk_css_value_enum_print (const GtkCssValue *value,
65                           GString           *string)
66 {
67   g_string_append (string, value->name);
68 }
69
70 /* GtkBorderStyle */
71
72 static const GtkCssValueClass GTK_CSS_VALUE_BORDER_STYLE = {
73   gtk_css_value_enum_free,
74   gtk_css_value_enum_compute,
75   gtk_css_value_enum_equal,
76   gtk_css_value_enum_transition,
77   gtk_css_value_enum_print
78 };
79
80 static GtkCssValue border_style_values[] = {
81   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_NONE, "none" },
82   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_SOLID, "solid" },
83   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_INSET, "inset" },
84   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_OUTSET, "outset" },
85   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_HIDDEN, "hidden" },
86   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_DOTTED, "dotted" },
87   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_DASHED, "dashed" },
88   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_DOUBLE, "double" },
89   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_GROOVE, "groove" },
90   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_RIDGE, "ridge" }
91 };
92
93 GtkCssValue *
94 _gtk_css_border_style_value_new (GtkBorderStyle border_style)
95 {
96   g_return_val_if_fail (border_style < G_N_ELEMENTS (border_style_values), NULL);
97
98   return _gtk_css_value_ref (&border_style_values[border_style]);
99 }
100
101 GtkCssValue *
102 _gtk_css_border_style_value_try_parse (GtkCssParser *parser)
103 {
104   guint i;
105
106   g_return_val_if_fail (parser != NULL, NULL);
107
108   for (i = 0; i < G_N_ELEMENTS (border_style_values); i++)
109     {
110       if (_gtk_css_parser_try (parser, border_style_values[i].name, TRUE))
111         return _gtk_css_value_ref (&border_style_values[i]);
112     }
113
114   return NULL;
115 }
116
117 GtkBorderStyle
118 _gtk_css_border_style_value_get (const GtkCssValue *value)
119 {
120   g_return_val_if_fail (value->class == &GTK_CSS_VALUE_BORDER_STYLE, GTK_BORDER_STYLE_NONE);
121
122   return value->value;
123 }
124
125 /* PangoStyle */
126
127 static const GtkCssValueClass GTK_CSS_VALUE_FONT_STYLE = {
128   gtk_css_value_enum_free,
129   gtk_css_value_enum_compute,
130   gtk_css_value_enum_equal,
131   gtk_css_value_enum_transition,
132   gtk_css_value_enum_print
133 };
134
135 static GtkCssValue font_style_values[] = {
136   { &GTK_CSS_VALUE_FONT_STYLE, 1, PANGO_STYLE_NORMAL, "normal" },
137   { &GTK_CSS_VALUE_FONT_STYLE, 1, PANGO_STYLE_OBLIQUE, "oblique" },
138   { &GTK_CSS_VALUE_FONT_STYLE, 1, PANGO_STYLE_ITALIC, "italic" }
139 };
140
141 GtkCssValue *
142 _gtk_css_font_style_value_new (PangoStyle font_style)
143 {
144   g_return_val_if_fail (font_style < G_N_ELEMENTS (font_style_values), NULL);
145
146   return _gtk_css_value_ref (&font_style_values[font_style]);
147 }
148
149 GtkCssValue *
150 _gtk_css_font_style_value_try_parse (GtkCssParser *parser)
151 {
152   guint i;
153
154   g_return_val_if_fail (parser != NULL, NULL);
155
156   for (i = 0; i < G_N_ELEMENTS (font_style_values); i++)
157     {
158       if (_gtk_css_parser_try (parser, font_style_values[i].name, TRUE))
159         return _gtk_css_value_ref (&font_style_values[i]);
160     }
161
162   return NULL;
163 }
164
165 PangoStyle
166 _gtk_css_font_style_value_get (const GtkCssValue *value)
167 {
168   g_return_val_if_fail (value->class == &GTK_CSS_VALUE_FONT_STYLE, PANGO_STYLE_NORMAL);
169
170   return value->value;
171 }
172
173 /* PangoVariant */
174
175 static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT = {
176   gtk_css_value_enum_free,
177   gtk_css_value_enum_compute,
178   gtk_css_value_enum_equal,
179   gtk_css_value_enum_transition,
180   gtk_css_value_enum_print
181 };
182
183 static GtkCssValue font_variant_values[] = {
184   { &GTK_CSS_VALUE_FONT_VARIANT, 1, PANGO_VARIANT_NORMAL, "normal" },
185   { &GTK_CSS_VALUE_FONT_VARIANT, 1, PANGO_VARIANT_SMALL_CAPS, "small-caps" }
186 };
187
188 GtkCssValue *
189 _gtk_css_font_variant_value_new (PangoVariant font_variant)
190 {
191   g_return_val_if_fail (font_variant < G_N_ELEMENTS (font_variant_values), NULL);
192
193   return _gtk_css_value_ref (&font_variant_values[font_variant]);
194 }
195
196 GtkCssValue *
197 _gtk_css_font_variant_value_try_parse (GtkCssParser *parser)
198 {
199   guint i;
200
201   g_return_val_if_fail (parser != NULL, NULL);
202
203   for (i = 0; i < G_N_ELEMENTS (font_variant_values); i++)
204     {
205       if (_gtk_css_parser_try (parser, font_variant_values[i].name, TRUE))
206         return _gtk_css_value_ref (&font_variant_values[i]);
207     }
208
209   return NULL;
210 }
211
212 PangoVariant
213 _gtk_css_font_variant_value_get (const GtkCssValue *value)
214 {
215   g_return_val_if_fail (value->class == &GTK_CSS_VALUE_FONT_VARIANT, PANGO_VARIANT_NORMAL);
216
217   return value->value;
218 }
219
220 /* PangoWeight */
221
222 static const GtkCssValueClass GTK_CSS_VALUE_FONT_WEIGHT = {
223   gtk_css_value_enum_free,
224   gtk_css_value_enum_compute,
225   gtk_css_value_enum_equal,
226   gtk_css_value_enum_transition,
227   gtk_css_value_enum_print
228 };
229
230 static GtkCssValue font_weight_values[] = {
231   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_THIN, "100" },
232   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_ULTRALIGHT, "200" },
233   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_LIGHT, "300" },
234   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_NORMAL, "normal" },
235   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_MEDIUM, "500" },
236   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_SEMIBOLD, "600" },
237   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_BOLD, "bold" },
238   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_ULTRABOLD, "800" },
239   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_HEAVY, "900" }
240 };
241
242 GtkCssValue *
243 _gtk_css_font_weight_value_new (PangoWeight font_weight)
244 {
245   guint i;
246   gint w;
247
248   w = ((font_weight + 50) / 100) * 100;
249
250   for (i = 0; i < G_N_ELEMENTS (font_weight_values); i++)
251     {
252       if (font_weight_values[i].value == w)
253         return _gtk_css_value_ref (&font_weight_values[i]);
254     }
255
256   g_return_val_if_reached (NULL);
257 }
258
259 GtkCssValue *
260 _gtk_css_font_weight_value_try_parse (GtkCssParser *parser)
261 {
262   guint i;
263
264   g_return_val_if_fail (parser != NULL, NULL);
265
266   for (i = 0; i < G_N_ELEMENTS (font_weight_values); i++)
267     {
268       if (_gtk_css_parser_try (parser, font_weight_values[i].name, TRUE))
269         return _gtk_css_value_ref (&font_weight_values[i]);
270     }
271   /* special cases go here */
272   if (_gtk_css_parser_try (parser, "400", TRUE))
273     return _gtk_css_value_ref (&font_weight_values[3]);
274   if (_gtk_css_parser_try (parser, "700", TRUE))
275     return _gtk_css_value_ref (&font_weight_values[6]);
276
277   return NULL;
278 }
279
280 PangoWeight
281 _gtk_css_font_weight_value_get (const GtkCssValue *value)
282 {
283   g_return_val_if_fail (value->class == &GTK_CSS_VALUE_FONT_WEIGHT, PANGO_WEIGHT_NORMAL);
284
285   return value->value;
286 }
287
288 /* GtkCssArea */
289
290 static const GtkCssValueClass GTK_CSS_VALUE_AREA = {
291   gtk_css_value_enum_free,
292   gtk_css_value_enum_compute,
293   gtk_css_value_enum_equal,
294   gtk_css_value_enum_transition,
295   gtk_css_value_enum_print
296 };
297
298 static GtkCssValue area_values[] = {
299   { &GTK_CSS_VALUE_AREA, 1, GTK_CSS_AREA_BORDER_BOX, "border-box" },
300   { &GTK_CSS_VALUE_AREA, 1, GTK_CSS_AREA_PADDING_BOX, "padding-box" },
301   { &GTK_CSS_VALUE_AREA, 1, GTK_CSS_AREA_CONTENT_BOX, "content-box" }
302 };
303
304 GtkCssValue *
305 _gtk_css_area_value_new (GtkCssArea area)
306 {
307   guint i;
308
309   for (i = 0; i < G_N_ELEMENTS (area_values); i++)
310     {
311       if (area_values[i].value == area)
312         return _gtk_css_value_ref (&area_values[i]);
313     }
314
315   g_return_val_if_reached (NULL);
316 }
317
318 GtkCssValue *
319 _gtk_css_area_value_try_parse (GtkCssParser *parser)
320 {
321   guint i;
322
323   g_return_val_if_fail (parser != NULL, NULL);
324
325   for (i = 0; i < G_N_ELEMENTS (area_values); i++)
326     {
327       if (_gtk_css_parser_try (parser, area_values[i].name, TRUE))
328         return _gtk_css_value_ref (&area_values[i]);
329     }
330
331   return NULL;
332 }
333
334 GtkCssArea
335 _gtk_css_area_value_get (const GtkCssValue *value)
336 {
337   g_return_val_if_fail (value->class == &GTK_CSS_VALUE_AREA, GTK_CSS_AREA_BORDER_BOX);
338
339   return value->value;
340 }
341
342 /* GtkCssDirection */
343
344 static const GtkCssValueClass GTK_CSS_VALUE_DIRECTION = {
345   gtk_css_value_enum_free,
346   gtk_css_value_enum_compute,
347   gtk_css_value_enum_equal,
348   gtk_css_value_enum_transition,
349   gtk_css_value_enum_print
350 };
351
352 static GtkCssValue direction_values[] = {
353   { &GTK_CSS_VALUE_DIRECTION, 1, GTK_CSS_DIRECTION_NORMAL, "normal" },
354   { &GTK_CSS_VALUE_DIRECTION, 1, GTK_CSS_DIRECTION_REVERSE, "reverse" },
355   { &GTK_CSS_VALUE_DIRECTION, 1, GTK_CSS_DIRECTION_ALTERNATE, "alternate" },
356   { &GTK_CSS_VALUE_DIRECTION, 1, GTK_CSS_DIRECTION_ALTERNATE_REVERSE, "alternate-reverse" }
357 };
358
359 GtkCssValue *
360 _gtk_css_direction_value_new (GtkCssDirection direction)
361 {
362   guint i;
363
364   for (i = 0; i < G_N_ELEMENTS (direction_values); i++)
365     {
366       if (direction_values[i].value == direction)
367         return _gtk_css_value_ref (&direction_values[i]);
368     }
369
370   g_return_val_if_reached (NULL);
371 }
372
373 GtkCssValue *
374 _gtk_css_direction_value_try_parse (GtkCssParser *parser)
375 {
376   guint i;
377
378   g_return_val_if_fail (parser != NULL, NULL);
379
380   for (i = 0; i < G_N_ELEMENTS (direction_values); i++)
381     {
382       if (_gtk_css_parser_try (parser, direction_values[i].name, TRUE))
383         return _gtk_css_value_ref (&direction_values[i]);
384     }
385
386   return NULL;
387 }
388
389 GtkCssDirection
390 _gtk_css_direction_value_get (const GtkCssValue *value)
391 {
392   g_return_val_if_fail (value->class == &GTK_CSS_VALUE_DIRECTION, GTK_CSS_DIRECTION_NORMAL);
393
394   return value->value;
395 }
396
397 /* GtkCssPlayState */
398
399 static const GtkCssValueClass GTK_CSS_VALUE_PLAY_STATE = {
400   gtk_css_value_enum_free,
401   gtk_css_value_enum_compute,
402   gtk_css_value_enum_equal,
403   gtk_css_value_enum_transition,
404   gtk_css_value_enum_print
405 };
406
407 static GtkCssValue play_state_values[] = {
408   { &GTK_CSS_VALUE_PLAY_STATE, 1, GTK_CSS_PLAY_STATE_RUNNING, "running" },
409   { &GTK_CSS_VALUE_PLAY_STATE, 1, GTK_CSS_PLAY_STATE_PAUSED, "paused" }
410 };
411
412 GtkCssValue *
413 _gtk_css_play_state_value_new (GtkCssPlayState play_state)
414 {
415   guint i;
416
417   for (i = 0; i < G_N_ELEMENTS (play_state_values); i++)
418     {
419       if (play_state_values[i].value == play_state)
420         return _gtk_css_value_ref (&play_state_values[i]);
421     }
422
423   g_return_val_if_reached (NULL);
424 }
425
426 GtkCssValue *
427 _gtk_css_play_state_value_try_parse (GtkCssParser *parser)
428 {
429   guint i;
430
431   g_return_val_if_fail (parser != NULL, NULL);
432
433   for (i = 0; i < G_N_ELEMENTS (play_state_values); i++)
434     {
435       if (_gtk_css_parser_try (parser, play_state_values[i].name, TRUE))
436         return _gtk_css_value_ref (&play_state_values[i]);
437     }
438
439   return NULL;
440 }
441
442 GtkCssPlayState
443 _gtk_css_play_state_value_get (const GtkCssValue *value)
444 {
445   g_return_val_if_fail (value->class == &GTK_CSS_VALUE_PLAY_STATE, GTK_CSS_PLAY_STATE_RUNNING);
446
447   return value->value;
448 }
449
450 /* GtkCssFillMode */
451
452 static const GtkCssValueClass GTK_CSS_VALUE_FILL_MODE = {
453   gtk_css_value_enum_free,
454   gtk_css_value_enum_compute,
455   gtk_css_value_enum_equal,
456   gtk_css_value_enum_transition,
457   gtk_css_value_enum_print
458 };
459
460 static GtkCssValue fill_mode_values[] = {
461   { &GTK_CSS_VALUE_FILL_MODE, 1, GTK_CSS_FILL_NONE, "none" },
462   { &GTK_CSS_VALUE_FILL_MODE, 1, GTK_CSS_FILL_FORWARDS, "forwards" },
463   { &GTK_CSS_VALUE_FILL_MODE, 1, GTK_CSS_FILL_BACKWARDS, "backwards" },
464   { &GTK_CSS_VALUE_FILL_MODE, 1, GTK_CSS_FILL_BOTH, "both" }
465 };
466
467 GtkCssValue *
468 _gtk_css_fill_mode_value_new (GtkCssFillMode fill_mode)
469 {
470   guint i;
471
472   for (i = 0; i < G_N_ELEMENTS (fill_mode_values); i++)
473     {
474       if (fill_mode_values[i].value == fill_mode)
475         return _gtk_css_value_ref (&fill_mode_values[i]);
476     }
477
478   g_return_val_if_reached (NULL);
479 }
480
481 GtkCssValue *
482 _gtk_css_fill_mode_value_try_parse (GtkCssParser *parser)
483 {
484   guint i;
485
486   g_return_val_if_fail (parser != NULL, NULL);
487
488   for (i = 0; i < G_N_ELEMENTS (fill_mode_values); i++)
489     {
490       if (_gtk_css_parser_try (parser, fill_mode_values[i].name, TRUE))
491         return _gtk_css_value_ref (&fill_mode_values[i]);
492     }
493
494   return NULL;
495 }
496
497 GtkCssFillMode
498 _gtk_css_fill_mode_value_get (const GtkCssValue *value)
499 {
500   g_return_val_if_fail (value->class == &GTK_CSS_VALUE_FILL_MODE, GTK_CSS_FILL_NONE);
501
502   return value->value;
503 }
504