]> Pileus Git - ~andy/gtk/blob - gtk/gtkcssshadowsvalue.c
cssvalue: Add GtkCssShadowsValue
[~andy/gtk] / gtk / gtkcssshadowsvalue.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 2011 Red Hat, Inc.
3  *
4  * Author: Cosimo Cecchi <cosimoc@gnome.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "config.h"
21
22 #include "gtkcssshadowsvalueprivate.h"
23
24 #include "gtkcssshadowvalueprivate.h"
25
26 #include <string.h>
27
28 struct _GtkCssValue {
29   GTK_CSS_VALUE_BASE
30   guint         len;
31   GtkCssValue  *values[1];
32 };
33
34 static void
35 gtk_css_value_shadows_free (GtkCssValue *value)
36 {
37   guint i;
38
39   for (i = 0; i < value->len; i++)
40     {
41       _gtk_css_value_unref (value->values[i]);
42     }
43
44   g_slice_free1 (sizeof (GtkCssValue) + sizeof (GtkCssValue *) * (value->len - 1), value);
45 }
46
47 static gboolean
48 gtk_css_value_shadows_equal (const GtkCssValue *value1,
49                              const GtkCssValue *value2)
50 {
51   guint i;
52
53   /* XXX: Should we fill up here? */
54   if (value1->len != value2->len)
55     return FALSE;
56
57   for (i = 0; i < value1->len; i++)
58     {
59       if (!_gtk_css_value_equal (value1->values[i],
60                                  value2->values[i]))
61         return FALSE;
62     }
63
64   return TRUE;
65 }
66
67 static GtkCssValue *
68 gtk_css_value_shadows_transition (GtkCssValue *start,
69                                   GtkCssValue *end,
70                                   double       progress)
71 {
72   return NULL;
73 }
74
75 static void
76 gtk_css_value_shadows_print (const GtkCssValue *value,
77                              GString           *string)
78 {
79   guint i;
80
81   if (value->len == 0)
82     {
83       g_string_append (string, "none");
84       return;
85     }
86
87   for (i = 0; i < value->len; i++)
88     {
89       if (i > 0)
90         g_string_append (string, ", ");
91       _gtk_css_value_print (value->values[i], string);
92     }
93 }
94
95 static const GtkCssValueClass GTK_CSS_VALUE_SHADOWS = {
96   gtk_css_value_shadows_free,
97   gtk_css_value_shadows_equal,
98   gtk_css_value_shadows_transition,
99   gtk_css_value_shadows_print
100 };
101
102 static GtkCssValue none_singleton = { &GTK_CSS_VALUE_SHADOWS, 1, 0, { NULL } };
103
104 GtkCssValue *
105 _gtk_css_shadows_value_new_none (void)
106 {
107   return _gtk_css_value_ref (&none_singleton);
108 }
109
110 GtkCssValue *
111 gtk_css_shadows_value_new (GtkCssValue **values,
112                            guint         len)
113 {
114   GtkCssValue *result;
115            
116   g_return_val_if_fail (values != NULL, NULL);
117   g_return_val_if_fail (len > 0, NULL);
118          
119   result = _gtk_css_value_alloc (&GTK_CSS_VALUE_SHADOWS, sizeof (GtkCssValue) + sizeof (GtkCssValue *) * (len - 1));
120   result->len = len;
121   memcpy (&result->values[0], values, sizeof (GtkCssValue *) * len);
122             
123   return result;
124 }
125
126 GtkCssValue *
127 _gtk_css_shadows_value_parse (GtkCssParser *parser)
128 {
129   GtkCssValue *value, *result;
130   GPtrArray *values;
131
132   if (_gtk_css_parser_try (parser, "none", TRUE))
133     return _gtk_css_shadows_value_new_none ();
134
135   values = g_ptr_array_new ();
136
137   do {
138     value = _gtk_css_shadow_value_parse (parser);
139
140     if (value == NULL)
141       {
142         g_ptr_array_set_free_func (values, (GDestroyNotify) _gtk_css_value_unref);
143         g_ptr_array_free (values, TRUE);
144         return NULL;
145       }
146
147     g_ptr_array_add (values, value);
148   } while (_gtk_css_parser_try (parser, ",", TRUE));
149
150   result = gtk_css_shadows_value_new ((GtkCssValue **) values->pdata, values->len);
151   g_ptr_array_free (values, TRUE);
152   return result;
153 }
154
155 GtkCssValue *
156 _gtk_css_shadows_value_compute (GtkCssValue     *value,
157                                 GtkStyleContext *context)
158 {
159   GtkCssValue *result;
160   guint i;
161
162   g_return_val_if_fail (value->class == &GTK_CSS_VALUE_SHADOWS, NULL);
163
164   if (value->len == 0)
165     return _gtk_css_value_ref (value);
166
167   result = gtk_css_shadows_value_new (value->values, value->len);
168   for (i = 0; i < value->len; i++)
169     {
170       result->values[i] = _gtk_css_shadow_value_compute (value->values[i], context);
171     }
172
173   return result;
174 }
175
176 void
177 _gtk_css_shadows_value_paint_layout (const GtkCssValue *shadows,
178                                      cairo_t           *cr,
179                                      PangoLayout       *layout)
180 {
181   guint i;
182
183   g_return_if_fail (shadows->class == &GTK_CSS_VALUE_SHADOWS);
184
185   for (i = 0; i < shadows->len; i++)
186     {
187       _gtk_css_shadow_value_paint_layout (shadows->values[i], cr, layout);
188     }
189 }
190
191 void
192 _gtk_css_shadows_value_paint_icon (const GtkCssValue *shadows,
193                                    cairo_t           *cr)
194 {
195   guint i;
196
197   g_return_if_fail (shadows->class == &GTK_CSS_VALUE_SHADOWS);
198
199   for (i = 0; i < shadows->len; i++)
200     {
201       _gtk_css_shadow_value_paint_icon (shadows->values[i], cr);
202     }
203 }
204
205 void
206 _gtk_css_shadows_value_paint_spinner (const GtkCssValue *shadows,
207                                       cairo_t           *cr,
208                                       gdouble            radius,
209                                       gdouble            progress)
210 {
211   guint i;
212
213   g_return_if_fail (shadows->class == &GTK_CSS_VALUE_SHADOWS);
214
215   for (i = 0; i < shadows->len; i++)
216     {
217       _gtk_css_shadow_value_paint_spinner (shadows->values[i], cr, radius, progress);
218     }
219 }
220
221 void
222 _gtk_css_shadows_value_paint_box (const GtkCssValue   *shadows,
223                                   cairo_t             *cr,
224                                   const GtkRoundedBox *padding_box)
225 {
226   guint i;
227
228   g_return_if_fail (shadows->class == &GTK_CSS_VALUE_SHADOWS);
229
230   for (i = 0; i < shadows->len; i++)
231     {
232       _gtk_css_shadow_value_paint_box (shadows->values[i], cr, padding_box);
233     }
234 }