]> Pileus Git - ~andy/gtk/blob - gtk/gtkcssrepeatvalue.c
Updated Arabic translation
[~andy/gtk] / gtk / gtkcssrepeatvalue.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 "gtkcssrepeatvalueprivate.h"
21
22 #include "gtkcssnumbervalueprivate.h"
23
24 struct _GtkCssValue {
25   GTK_CSS_VALUE_BASE
26   GtkCssRepeatStyle x;
27   GtkCssRepeatStyle y;
28 };
29
30 static void
31 gtk_css_value_repeat_free (GtkCssValue *value)
32 {
33   g_slice_free (GtkCssValue, value);
34 }
35
36 static gboolean
37 gtk_css_value_repeat_equal (const GtkCssValue *repeat1,
38                             const GtkCssValue *repeat2)
39 {
40   return repeat1->x == repeat2->x
41       && repeat1->y == repeat2->y;
42 }
43
44 static GtkCssValue *
45 gtk_css_value_repeat_transition (GtkCssValue *start,
46                                  GtkCssValue *end,
47                                  double       progress)
48 {
49   return NULL;
50 }
51
52 static void
53 gtk_css_value_background_repeat_print (const GtkCssValue *repeat,
54                                        GString           *string)
55 {
56   static const char *names[] = {
57     "no-repeat",
58     "repeat",
59     "round",
60     "space"
61   };
62
63   if (repeat->x == repeat->y)
64     {
65       g_string_append (string, names[repeat->x]);
66     }
67   else if (repeat->x == GTK_CSS_REPEAT_STYLE_REPEAT &&
68            repeat->y == GTK_CSS_REPEAT_STYLE_NO_REPEAT)
69     {
70       g_string_append (string, "repeat-x");
71     }
72   else if (repeat->x == GTK_CSS_REPEAT_STYLE_NO_REPEAT &&
73            repeat->y == GTK_CSS_REPEAT_STYLE_REPEAT)
74     {
75       g_string_append (string, "repeat-y");
76     }
77   else
78     {
79       g_string_append (string, names[repeat->x]);
80       g_string_append_c (string, ' ');
81       g_string_append (string, names[repeat->y]);
82     }
83 }
84
85 static void
86 gtk_css_value_border_repeat_print (const GtkCssValue *repeat,
87                                    GString           *string)
88 {
89   static const char *names[] = {
90     "stretch",
91     "repeat",
92     "round",
93     "space"
94   };
95
96   g_string_append (string, names[repeat->x]);
97   if (repeat->x != repeat->y)
98     {
99       g_string_append_c (string, ' ');
100       g_string_append (string, names[repeat->y]);
101     }
102 }
103
104 static const GtkCssValueClass GTK_CSS_VALUE_BACKGROUND_REPEAT = {
105   gtk_css_value_repeat_free,
106   gtk_css_value_repeat_equal,
107   gtk_css_value_repeat_transition,
108   gtk_css_value_background_repeat_print
109 };
110
111 static const GtkCssValueClass GTK_CSS_VALUE_BORDER_REPEAT = {
112   gtk_css_value_repeat_free,
113   gtk_css_value_repeat_equal,
114   gtk_css_value_repeat_transition,
115   gtk_css_value_border_repeat_print
116 };
117 /* BACKGROUND REPEAT */
118
119 static struct {
120   const char *name;
121   GtkCssValue values[4];
122 } background_repeat_values[4] = {
123   { "no-repeat",
124   { { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_NO_REPEAT, GTK_CSS_REPEAT_STYLE_NO_REPEAT },
125     { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_NO_REPEAT, GTK_CSS_REPEAT_STYLE_REPEAT    },
126     { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_NO_REPEAT, GTK_CSS_REPEAT_STYLE_ROUND     },
127     { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_NO_REPEAT, GTK_CSS_REPEAT_STYLE_SPACE     }
128   } },
129   { "repeat",
130   { { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT,    GTK_CSS_REPEAT_STYLE_NO_REPEAT },
131     { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT,    GTK_CSS_REPEAT_STYLE_REPEAT    },
132     { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT,    GTK_CSS_REPEAT_STYLE_ROUND     },
133     { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT,    GTK_CSS_REPEAT_STYLE_SPACE     }
134   } }, 
135   { "round",
136   { { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND,     GTK_CSS_REPEAT_STYLE_NO_REPEAT },
137     { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND,     GTK_CSS_REPEAT_STYLE_REPEAT    },
138     { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND,     GTK_CSS_REPEAT_STYLE_ROUND     },
139     { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND,     GTK_CSS_REPEAT_STYLE_SPACE     }
140   } }, 
141   { "space",
142   { { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE,     GTK_CSS_REPEAT_STYLE_NO_REPEAT },
143     { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE,     GTK_CSS_REPEAT_STYLE_REPEAT    },
144     { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE,     GTK_CSS_REPEAT_STYLE_ROUND     },
145     { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE,     GTK_CSS_REPEAT_STYLE_SPACE     }
146   } }
147 };
148
149 GtkCssValue *
150 _gtk_css_background_repeat_value_new (GtkCssRepeatStyle x,
151                                       GtkCssRepeatStyle y)
152 {
153   return _gtk_css_value_ref (&background_repeat_values[x].values[y]);
154 }
155
156 static gboolean
157 _gtk_css_background_repeat_style_try (GtkCssParser      *parser,
158                                       GtkCssRepeatStyle *result)
159 {
160   guint i;
161
162   for (i = 0; i < G_N_ELEMENTS (background_repeat_values); i++)
163     {
164       if (_gtk_css_parser_try (parser, background_repeat_values[i].name, TRUE))
165         {
166           *result = i;
167           return TRUE;
168         }
169     }
170
171   return FALSE;
172 }
173
174 GtkCssValue *
175 _gtk_css_background_repeat_value_try_parse (GtkCssParser *parser)
176 {
177   GtkCssRepeatStyle x, y;
178
179   g_return_val_if_fail (parser != NULL, NULL);
180
181   if (_gtk_css_parser_try (parser, "repeat-x", TRUE))
182     return _gtk_css_background_repeat_value_new (GTK_CSS_REPEAT_STYLE_REPEAT, GTK_CSS_REPEAT_STYLE_NO_REPEAT);
183   if (_gtk_css_parser_try (parser, "repeat-y", TRUE))
184     return _gtk_css_background_repeat_value_new (GTK_CSS_REPEAT_STYLE_NO_REPEAT, GTK_CSS_REPEAT_STYLE_REPEAT);
185
186   if (!_gtk_css_background_repeat_style_try (parser, &x))
187     return NULL;
188
189   if (!_gtk_css_background_repeat_style_try (parser, &y))
190     y = x;
191
192   return _gtk_css_background_repeat_value_new (x, y);
193 }
194
195 GtkCssRepeatStyle
196 _gtk_css_background_repeat_value_get_x (const GtkCssValue *repeat)
197 {
198   g_return_val_if_fail (repeat->class == &GTK_CSS_VALUE_BACKGROUND_REPEAT, GTK_CSS_REPEAT_STYLE_NO_REPEAT);
199
200   return repeat->x;
201 }
202
203 GtkCssRepeatStyle
204 _gtk_css_background_repeat_value_get_y (const GtkCssValue *repeat)
205 {
206   g_return_val_if_fail (repeat->class == &GTK_CSS_VALUE_BACKGROUND_REPEAT, GTK_CSS_REPEAT_STYLE_NO_REPEAT);
207
208   return repeat->y;
209 }
210
211 /* BORDER IMAGE REPEAT */
212
213 static struct {
214   const char *name;
215   GtkCssValue values[4];
216 } border_repeat_values[4] = {
217   { "stretch",
218   { { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_STRETCH },
219     { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_REPEAT  },
220     { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_ROUND   },
221     { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_SPACE   }
222   } },
223   { "repeat",
224   { { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT,  GTK_CSS_REPEAT_STYLE_STRETCH },
225     { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT,  GTK_CSS_REPEAT_STYLE_REPEAT  },
226     { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT,  GTK_CSS_REPEAT_STYLE_ROUND   },
227     { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT,  GTK_CSS_REPEAT_STYLE_SPACE   }
228   } }, 
229   { "round",
230   { { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND,   GTK_CSS_REPEAT_STYLE_STRETCH },
231     { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND,   GTK_CSS_REPEAT_STYLE_REPEAT  },
232     { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND,   GTK_CSS_REPEAT_STYLE_ROUND   },
233     { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND,   GTK_CSS_REPEAT_STYLE_SPACE   }
234   } }, 
235   { "space",
236   { { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE,   GTK_CSS_REPEAT_STYLE_STRETCH },
237     { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE,   GTK_CSS_REPEAT_STYLE_REPEAT  },
238     { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE,   GTK_CSS_REPEAT_STYLE_ROUND   },
239     { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE,   GTK_CSS_REPEAT_STYLE_SPACE   }
240   } }
241 };
242
243 GtkCssValue *
244 _gtk_css_border_repeat_value_new (GtkCssRepeatStyle x,
245                                   GtkCssRepeatStyle y)
246 {
247   return _gtk_css_value_ref (&border_repeat_values[x].values[y]);
248 }
249
250 static gboolean
251 _gtk_css_border_repeat_style_try (GtkCssParser      *parser,
252                                   GtkCssRepeatStyle *result)
253 {
254   guint i;
255
256   for (i = 0; i < G_N_ELEMENTS (border_repeat_values); i++)
257     {
258       if (_gtk_css_parser_try (parser, border_repeat_values[i].name, TRUE))
259         {
260           *result = i;
261           return TRUE;
262         }
263     }
264
265   return FALSE;
266 }
267
268 GtkCssValue *
269 _gtk_css_border_repeat_value_try_parse (GtkCssParser *parser)
270 {
271   GtkCssRepeatStyle x, y;
272
273   g_return_val_if_fail (parser != NULL, NULL);
274
275   if (!_gtk_css_border_repeat_style_try (parser, &x))
276     return NULL;
277
278   if (!_gtk_css_border_repeat_style_try (parser, &y))
279     y = x;
280
281   return _gtk_css_border_repeat_value_new (x, y);
282 }
283
284 GtkCssRepeatStyle
285 _gtk_css_border_repeat_value_get_x (const GtkCssValue *repeat)
286 {
287   g_return_val_if_fail (repeat->class == &GTK_CSS_VALUE_BORDER_REPEAT, GTK_CSS_REPEAT_STYLE_STRETCH);
288
289   return repeat->x;
290 }
291
292 GtkCssRepeatStyle
293 _gtk_css_border_repeat_value_get_y (const GtkCssValue *repeat)
294 {
295   g_return_val_if_fail (repeat->class == &GTK_CSS_VALUE_BORDER_REPEAT, GTK_CSS_REPEAT_STYLE_STRETCH);
296
297   return repeat->y;
298 }
299