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