1/*
2 * Copyright © 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.1 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 * Authors: Benjamin Otte <otte@gnome.org>
18 */
19
20#include "config.h"
21
22#include "gtkcssstylepropertyprivate.h"
23
24#include "gtkcssenumvalueprivate.h"
25#include "gtkcssinheritvalueprivate.h"
26#include "gtkcssinitialvalueprivate.h"
27#include "gtkcsstypesprivate.h"
28#include "gtkcssunsetvalueprivate.h"
29#include "gtkintl.h"
30#include "gtkprivatetypebuiltins.h"
31#include "gtkprivate.h"
32
33enum {
34 PROP_0,
35 PROP_ANIMATED,
36 PROP_AFFECTS,
37 PROP_ID,
38 PROP_INHERIT,
39 PROP_INITIAL
40};
41
42G_DEFINE_TYPE (GtkCssStyleProperty, _gtk_css_style_property, GTK_TYPE_STYLE_PROPERTY)
43
44static GtkCssStylePropertyClass *gtk_css_style_property_class = NULL;
45
46static void
47gtk_css_style_property_constructed (GObject *object)
48{
49 GtkCssStyleProperty *property = GTK_CSS_STYLE_PROPERTY (object);
50 GtkCssStylePropertyClass *klass = GTK_CSS_STYLE_PROPERTY_GET_CLASS (property);
51
52 property->id = klass->style_properties->len;
53 g_ptr_array_add (array: klass->style_properties, data: property);
54
55 G_OBJECT_CLASS (_gtk_css_style_property_parent_class)->constructed (object);
56}
57
58static void
59gtk_css_style_property_set_property (GObject *object,
60 guint prop_id,
61 const GValue *value,
62 GParamSpec *pspec)
63{
64 GtkCssStyleProperty *property = GTK_CSS_STYLE_PROPERTY (object);
65
66 switch (prop_id)
67 {
68 case PROP_ANIMATED:
69 property->animated = g_value_get_boolean (value);
70 break;
71 case PROP_AFFECTS:
72 property->affects = g_value_get_flags (value);
73 break;
74 case PROP_INHERIT:
75 property->inherit = g_value_get_boolean (value);
76 break;
77 case PROP_INITIAL:
78 property->initial_value = g_value_dup_boxed (value);
79 g_assert (property->initial_value != NULL);
80 break;
81 default:
82 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
83 break;
84 }
85}
86
87static void
88gtk_css_style_property_get_property (GObject *object,
89 guint prop_id,
90 GValue *value,
91 GParamSpec *pspec)
92{
93 GtkCssStyleProperty *property = GTK_CSS_STYLE_PROPERTY (object);
94
95 switch (prop_id)
96 {
97 case PROP_ANIMATED:
98 g_value_set_boolean (value, v_boolean: property->animated);
99 break;
100 case PROP_AFFECTS:
101 g_value_set_flags (value, v_flags: property->affects);
102 break;
103 case PROP_ID:
104 g_value_set_boolean (value, v_boolean: property->id);
105 break;
106 case PROP_INHERIT:
107 g_value_set_boolean (value, v_boolean: property->inherit);
108 break;
109 case PROP_INITIAL:
110 g_value_set_boxed (value, v_boxed: property->initial_value);
111 break;
112 default:
113 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
114 break;
115 }
116}
117
118static GtkCssValue *
119gtk_css_style_property_parse_value (GtkStyleProperty *property,
120 GtkCssParser *parser)
121{
122 GtkCssStyleProperty *style_property = GTK_CSS_STYLE_PROPERTY (property);
123
124 if (gtk_css_parser_try_ident (self: parser, ident: "initial"))
125 {
126 /* the initial value can be explicitly specified with the
127 * ‘initial’ keyword which all properties accept.
128 */
129 return _gtk_css_initial_value_new ();
130 }
131 else if (gtk_css_parser_try_ident (self: parser, ident: "inherit"))
132 {
133 /* All properties accept the ‘inherit’ value which
134 * explicitly specifies that the value will be determined
135 * by inheritance. The ‘inherit’ value can be used to
136 * strengthen inherited values in the cascade, and it can
137 * also be used on properties that are not normally inherited.
138 */
139 return _gtk_css_inherit_value_new ();
140 }
141 else if (gtk_css_parser_try_ident (self: parser, ident: "unset"))
142 {
143 /* If the cascaded value of a property is the unset keyword,
144 * then if it is an inherited property, this is treated as
145 * inherit, and if it is not, this is treated as initial.
146 */
147 return _gtk_css_unset_value_new ();
148 }
149
150 return (* style_property->parse_value) (style_property, parser);
151}
152
153static void
154_gtk_css_style_property_class_init (GtkCssStylePropertyClass *klass)
155{
156 GObjectClass *object_class = G_OBJECT_CLASS (klass);
157 GtkStylePropertyClass *property_class = GTK_STYLE_PROPERTY_CLASS (klass);
158
159 object_class->constructed = gtk_css_style_property_constructed;
160 object_class->set_property = gtk_css_style_property_set_property;
161 object_class->get_property = gtk_css_style_property_get_property;
162
163 g_object_class_install_property (oclass: object_class,
164 property_id: PROP_ANIMATED,
165 pspec: g_param_spec_boolean (name: "animated",
166 P_("Animated"),
167 P_("Set if the value can be animated"),
168 FALSE,
169 flags: G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
170 g_object_class_install_property (oclass: object_class,
171 property_id: PROP_AFFECTS,
172 pspec: g_param_spec_flags (name: "affects",
173 P_("Affects"),
174 P_("Set if the value affects the sizing of elements"),
175 flags_type: GTK_TYPE_CSS_AFFECTS,
176 default_value: 0,
177 flags: G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
178 g_object_class_install_property (oclass: object_class,
179 property_id: PROP_ID,
180 pspec: g_param_spec_uint (name: "id",
181 P_("ID"),
182 P_("The numeric id for quick access"),
183 minimum: 0, G_MAXUINT, default_value: 0,
184 flags: G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
185 g_object_class_install_property (oclass: object_class,
186 property_id: PROP_INHERIT,
187 pspec: g_param_spec_boolean (name: "inherit",
188 P_("Inherit"),
189 P_("Set if the value is inherited by default"),
190 FALSE,
191 flags: G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
192 g_object_class_install_property (oclass: object_class,
193 property_id: PROP_INITIAL,
194 pspec: g_param_spec_boxed (name: "initial-value",
195 P_("Initial value"),
196 P_("The initial specified value used for this property"),
197 GTK_TYPE_CSS_VALUE,
198 flags: G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
199
200 property_class->parse_value = gtk_css_style_property_parse_value;
201
202 klass->style_properties = g_ptr_array_new ();
203
204 gtk_css_style_property_class = klass;
205}
206
207static GtkCssValue *
208gtk_css_style_property_real_parse_value (GtkCssStyleProperty *property,
209 GtkCssParser *parser)
210{
211 g_assert_not_reached ();
212 return NULL;
213}
214
215static void
216_gtk_css_style_property_init (GtkCssStyleProperty *property)
217{
218 property->parse_value = gtk_css_style_property_real_parse_value;
219}
220
221/**
222 * _gtk_css_style_property_get_n_properties:
223 *
224 * Gets the number of style properties. This number can increase when new
225 * theme engines are loaded. Shorthand properties are not included here.
226 *
227 * Returns: The number of style properties.
228 **/
229guint
230_gtk_css_style_property_get_n_properties (void)
231{
232 if (G_UNLIKELY (gtk_css_style_property_class == NULL))
233 {
234 _gtk_style_property_init_properties ();
235 g_assert (gtk_css_style_property_class);
236 }
237
238 return gtk_css_style_property_class->style_properties->len;
239}
240
241/**
242 * _gtk_css_style_property_lookup_by_id:
243 * @id: the id of the property
244 *
245 * Gets the style property with the given id. All style properties (but not
246 * shorthand properties) are indexable by id so that it’s easy to use arrays
247 * when doing style lookups.
248 *
249 * Returns: (transfer none): The style property with the given id
250 **/
251GtkCssStyleProperty *
252_gtk_css_style_property_lookup_by_id (guint id)
253{
254
255 if (G_UNLIKELY (gtk_css_style_property_class == NULL))
256 {
257 _gtk_style_property_init_properties ();
258 g_assert (gtk_css_style_property_class);
259 }
260
261 gtk_internal_return_val_if_fail (id < gtk_css_style_property_class->style_properties->len, NULL);
262
263 return g_ptr_array_index (gtk_css_style_property_class->style_properties, id);
264}
265
266/**
267 * _gtk_css_style_property_is_inherit:
268 * @property: the property
269 *
270 * Queries if the given @property is inherited. See the
271 * [CSS Documentation](http://www.w3.org/TR/css3-cascade/#inheritance)
272 * for an explanation of this concept.
273 *
274 * Returns: %TRUE if the property is inherited by default.
275 **/
276gboolean
277_gtk_css_style_property_is_inherit (GtkCssStyleProperty *property)
278{
279 gtk_internal_return_val_if_fail (GTK_IS_CSS_STYLE_PROPERTY (property), FALSE);
280
281 return property->inherit;
282}
283
284/**
285 * _gtk_css_style_property_is_animated:
286 * @property: the property
287 *
288 * Queries if the given @property can be is animated. See the
289 * [CSS Documentation](http://www.w3.org/TR/css3-transitions/#animatable-css)
290 * for animatable properties.
291 *
292 * Returns: %TRUE if the property can be animated.
293 **/
294gboolean
295_gtk_css_style_property_is_animated (GtkCssStyleProperty *property)
296{
297 gtk_internal_return_val_if_fail (GTK_IS_CSS_STYLE_PROPERTY (property), FALSE);
298
299 return property->animated;
300}
301
302/**
303 * _gtk_css_style_property_get_affects:
304 * @property: the property
305 *
306 * Returns all the things this property affects. See @GtkCssAffects for what
307 * the flags mean.
308 *
309 * Returns: The things this property affects.
310 **/
311GtkCssAffects
312_gtk_css_style_property_get_affects (GtkCssStyleProperty *property)
313{
314 gtk_internal_return_val_if_fail (GTK_IS_CSS_STYLE_PROPERTY (property), 0);
315
316 return property->affects;
317}
318
319/**
320 * _gtk_css_style_property_get_id:
321 * @property: the property
322 *
323 * Gets the id for the given property. IDs are used to allow using arrays
324 * for style lookups.
325 *
326 * Returns: The id of the property
327 **/
328guint
329_gtk_css_style_property_get_id (GtkCssStyleProperty *property)
330{
331 gtk_internal_return_val_if_fail (GTK_IS_CSS_STYLE_PROPERTY (property), 0);
332
333 return property->id;
334}
335
336/**
337 * _gtk_css_style_property_get_initial_value:
338 * @property: the property
339 *
340 * Queries the initial value of the given @property. See the
341 * [CSS Documentation](http://www.w3.org/TR/css3-cascade/#initial)
342 * for an explanation of this concept.
343 *
344 * Returns: (transfer none): the initial value. The value will never change.
345 **/
346GtkCssValue *
347_gtk_css_style_property_get_initial_value (GtkCssStyleProperty *property)
348{
349 gtk_internal_return_val_if_fail (GTK_IS_CSS_STYLE_PROPERTY (property), NULL);
350
351 return property->initial_value;
352}
353

source code of gtk/gtk/gtkcssstyleproperty.c