]> Pileus Git - ~andy/gtk/blob - gtk/gtkcssenumvalue.c
css: Pass property_id to compute function
[~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 {
43   return _gtk_css_value_ref (value);
44 }
45
46 static gboolean
47 gtk_css_value_enum_equal (const GtkCssValue *enum1,
48                           const GtkCssValue *enum2)
49 {
50   return enum1 == enum2;
51 }
52
53 static GtkCssValue *
54 gtk_css_value_enum_transition (GtkCssValue *start,
55                                GtkCssValue *end,
56                                double       progress)
57 {
58   return NULL;
59 }
60
61 static void
62 gtk_css_value_enum_print (const GtkCssValue *value,
63                           GString           *string)
64 {
65   g_string_append (string, value->name);
66 }
67
68 /* GtkBorderStyle */
69
70 static const GtkCssValueClass GTK_CSS_VALUE_BORDER_STYLE = {
71   gtk_css_value_enum_free,
72   gtk_css_value_enum_compute,
73   gtk_css_value_enum_equal,
74   gtk_css_value_enum_transition,
75   gtk_css_value_enum_print
76 };
77
78 static GtkCssValue border_style_values[] = {
79   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_NONE, "none" },
80   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_SOLID, "solid" },
81   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_INSET, "inset" },
82   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_OUTSET, "outset" },
83   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_HIDDEN, "hidden" },
84   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_DOTTED, "dotted" },
85   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_DASHED, "dashed" },
86   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_DOUBLE, "double" },
87   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_GROOVE, "groove" },
88   { &GTK_CSS_VALUE_BORDER_STYLE, 1, GTK_BORDER_STYLE_RIDGE, "ridge" }
89 };
90
91 GtkCssValue *
92 _gtk_css_border_style_value_new (GtkBorderStyle border_style)
93 {
94   g_return_val_if_fail (border_style < G_N_ELEMENTS (border_style_values), NULL);
95
96   return _gtk_css_value_ref (&border_style_values[border_style]);
97 }
98
99 GtkCssValue *
100 _gtk_css_border_style_value_try_parse (GtkCssParser *parser)
101 {
102   guint i;
103
104   g_return_val_if_fail (parser != NULL, NULL);
105
106   for (i = 0; i < G_N_ELEMENTS (border_style_values); i++)
107     {
108       if (_gtk_css_parser_try (parser, border_style_values[i].name, TRUE))
109         return _gtk_css_value_ref (&border_style_values[i]);
110     }
111
112   return NULL;
113 }
114
115 GtkBorderStyle
116 _gtk_css_border_style_value_get (const GtkCssValue *value)
117 {
118   g_return_val_if_fail (value->class == &GTK_CSS_VALUE_BORDER_STYLE, GTK_BORDER_STYLE_NONE);
119
120   return value->value;
121 }
122
123 /* PangoStyle */
124
125 static const GtkCssValueClass GTK_CSS_VALUE_FONT_STYLE = {
126   gtk_css_value_enum_free,
127   gtk_css_value_enum_compute,
128   gtk_css_value_enum_equal,
129   gtk_css_value_enum_transition,
130   gtk_css_value_enum_print
131 };
132
133 static GtkCssValue font_style_values[] = {
134   { &GTK_CSS_VALUE_FONT_STYLE, 1, PANGO_STYLE_NORMAL, "normal" },
135   { &GTK_CSS_VALUE_FONT_STYLE, 1, PANGO_STYLE_OBLIQUE, "oblique" },
136   { &GTK_CSS_VALUE_FONT_STYLE, 1, PANGO_STYLE_ITALIC, "italic" }
137 };
138
139 GtkCssValue *
140 _gtk_css_font_style_value_new (PangoStyle font_style)
141 {
142   g_return_val_if_fail (font_style < G_N_ELEMENTS (font_style_values), NULL);
143
144   return _gtk_css_value_ref (&font_style_values[font_style]);
145 }
146
147 GtkCssValue *
148 _gtk_css_font_style_value_try_parse (GtkCssParser *parser)
149 {
150   guint i;
151
152   g_return_val_if_fail (parser != NULL, NULL);
153
154   for (i = 0; i < G_N_ELEMENTS (font_style_values); i++)
155     {
156       if (_gtk_css_parser_try (parser, font_style_values[i].name, TRUE))
157         return _gtk_css_value_ref (&font_style_values[i]);
158     }
159
160   return NULL;
161 }
162
163 PangoStyle
164 _gtk_css_font_style_value_get (const GtkCssValue *value)
165 {
166   g_return_val_if_fail (value->class == &GTK_CSS_VALUE_FONT_STYLE, PANGO_STYLE_NORMAL);
167
168   return value->value;
169 }
170
171 /* PangoVariant */
172
173 static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT = {
174   gtk_css_value_enum_free,
175   gtk_css_value_enum_compute,
176   gtk_css_value_enum_equal,
177   gtk_css_value_enum_transition,
178   gtk_css_value_enum_print
179 };
180
181 static GtkCssValue font_variant_values[] = {
182   { &GTK_CSS_VALUE_FONT_VARIANT, 1, PANGO_VARIANT_NORMAL, "normal" },
183   { &GTK_CSS_VALUE_FONT_VARIANT, 1, PANGO_VARIANT_SMALL_CAPS, "small-caps" }
184 };
185
186 GtkCssValue *
187 _gtk_css_font_variant_value_new (PangoVariant font_variant)
188 {
189   g_return_val_if_fail (font_variant < G_N_ELEMENTS (font_variant_values), NULL);
190
191   return _gtk_css_value_ref (&font_variant_values[font_variant]);
192 }
193
194 GtkCssValue *
195 _gtk_css_font_variant_value_try_parse (GtkCssParser *parser)
196 {
197   guint i;
198
199   g_return_val_if_fail (parser != NULL, NULL);
200
201   for (i = 0; i < G_N_ELEMENTS (font_variant_values); i++)
202     {
203       if (_gtk_css_parser_try (parser, font_variant_values[i].name, TRUE))
204         return _gtk_css_value_ref (&font_variant_values[i]);
205     }
206
207   return NULL;
208 }
209
210 PangoVariant
211 _gtk_css_font_variant_value_get (const GtkCssValue *value)
212 {
213   g_return_val_if_fail (value->class == &GTK_CSS_VALUE_FONT_VARIANT, PANGO_VARIANT_NORMAL);
214
215   return value->value;
216 }
217
218 /* PangoWeight */
219
220 static const GtkCssValueClass GTK_CSS_VALUE_FONT_WEIGHT = {
221   gtk_css_value_enum_free,
222   gtk_css_value_enum_compute,
223   gtk_css_value_enum_equal,
224   gtk_css_value_enum_transition,
225   gtk_css_value_enum_print
226 };
227
228 static GtkCssValue font_weight_values[] = {
229   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_THIN, "100" },
230   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_ULTRALIGHT, "200" },
231   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_LIGHT, "300" },
232   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_NORMAL, "normal" },
233   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_MEDIUM, "500" },
234   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_SEMIBOLD, "600" },
235   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_BOLD, "bold" },
236   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_ULTRABOLD, "800" },
237   { &GTK_CSS_VALUE_FONT_WEIGHT, 1, PANGO_WEIGHT_HEAVY, "900" }
238 };
239
240 GtkCssValue *
241 _gtk_css_font_weight_value_new (PangoWeight font_weight)
242 {
243   guint i;
244   gint w;
245
246   w = ((font_weight + 50) / 100) * 100;
247
248   for (i = 0; i < G_N_ELEMENTS (font_weight_values); i++)
249     {
250       if (font_weight_values[i].value == w)
251         return _gtk_css_value_ref (&font_weight_values[i]);
252     }
253
254   g_return_val_if_reached (NULL);
255 }
256
257 GtkCssValue *
258 _gtk_css_font_weight_value_try_parse (GtkCssParser *parser)
259 {
260   guint i;
261
262   g_return_val_if_fail (parser != NULL, NULL);
263
264   for (i = 0; i < G_N_ELEMENTS (font_weight_values); i++)
265     {
266       if (_gtk_css_parser_try (parser, font_weight_values[i].name, TRUE))
267         return _gtk_css_value_ref (&font_weight_values[i]);
268     }
269   /* special cases go here */
270   if (_gtk_css_parser_try (parser, "400", TRUE))
271     return _gtk_css_value_ref (&font_weight_values[3]);
272   if (_gtk_css_parser_try (parser, "700", TRUE))
273     return _gtk_css_value_ref (&font_weight_values[6]);
274
275   return NULL;
276 }
277
278 PangoWeight
279 _gtk_css_font_weight_value_get (const GtkCssValue *value)
280 {
281   g_return_val_if_fail (value->class == &GTK_CSS_VALUE_FONT_WEIGHT, PANGO_WEIGHT_NORMAL);
282
283   return value->value;
284 }
285
286 /* GtkCssArea */
287
288 static const GtkCssValueClass GTK_CSS_VALUE_AREA = {
289   gtk_css_value_enum_free,
290   gtk_css_value_enum_compute,
291   gtk_css_value_enum_equal,
292   gtk_css_value_enum_transition,
293   gtk_css_value_enum_print
294 };
295
296 static GtkCssValue area_values[] = {
297   { &GTK_CSS_VALUE_AREA, 1, GTK_CSS_AREA_BORDER_BOX, "border-box" },
298   { &GTK_CSS_VALUE_AREA, 1, GTK_CSS_AREA_PADDING_BOX, "padding-box" },
299   { &GTK_CSS_VALUE_AREA, 1, GTK_CSS_AREA_CONTENT_BOX, "content-box" }
300 };
301
302 GtkCssValue *
303 _gtk_css_area_value_new (GtkCssArea area)
304 {
305   guint i;
306
307   for (i = 0; i < G_N_ELEMENTS (area_values); i++)
308     {
309       if (area_values[i].value == area)
310         return _gtk_css_value_ref (&area_values[i]);
311     }
312
313   g_return_val_if_reached (NULL);
314 }
315
316 GtkCssValue *
317 _gtk_css_area_value_try_parse (GtkCssParser *parser)
318 {
319   guint i;
320
321   g_return_val_if_fail (parser != NULL, NULL);
322
323   for (i = 0; i < G_N_ELEMENTS (area_values); i++)
324     {
325       if (_gtk_css_parser_try (parser, area_values[i].name, TRUE))
326         return _gtk_css_value_ref (&area_values[i]);
327     }
328
329   return NULL;
330 }
331
332 GtkCssArea
333 _gtk_css_area_value_get (const GtkCssValue *value)
334 {
335   g_return_val_if_fail (value->class == &GTK_CSS_VALUE_AREA, GTK_CSS_AREA_BORDER_BOX);
336
337   return value->value;
338 }
339