2 * Copyright © 2011 Red Hat Inc.
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.
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.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 * Authors: Benjamin Otte <otte@gnome.org>
23 #include "gtkcssstylepropertyprivate.h"
25 #include "gtkcssstylefuncsprivate.h"
26 #include "gtkcsstypesprivate.h"
28 #include "gtkprivatetypebuiltins.h"
29 #include "gtkstylepropertiesprivate.h"
32 #include <cairo-gobject.h>
33 #include "gtkgradient.h"
34 #include "gtkshadowprivate.h"
35 #include "gtkwin32themeprivate.h"
45 G_DEFINE_TYPE (GtkCssStyleProperty, _gtk_css_style_property, GTK_TYPE_STYLE_PROPERTY)
48 gtk_css_style_property_constructed (GObject *object)
50 GtkCssStyleProperty *property = GTK_CSS_STYLE_PROPERTY (object);
51 GtkCssStylePropertyClass *klass = GTK_CSS_STYLE_PROPERTY_GET_CLASS (property);
53 property->id = klass->style_properties->len;
54 g_ptr_array_add (klass->style_properties, property);
56 G_OBJECT_CLASS (_gtk_css_style_property_parent_class)->constructed (object);
60 gtk_css_style_property_set_property (GObject *object,
65 GtkCssStyleProperty *property = GTK_CSS_STYLE_PROPERTY (object);
66 const GValue *initial;
71 property->inherit = g_value_get_boolean (value);
74 initial = g_value_get_boxed (value);
76 g_value_init (&property->initial_value, G_VALUE_TYPE (initial));
77 g_value_copy (initial, &property->initial_value);
80 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
86 gtk_css_style_property_get_property (GObject *object,
91 GtkCssStyleProperty *property = GTK_CSS_STYLE_PROPERTY (object);
96 g_value_set_boolean (value, property->id);
99 g_value_set_boolean (value, property->inherit);
102 g_value_set_boxed (value, &property->initial_value);
105 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
111 _gtk_css_style_property_assign (GtkStyleProperty *property,
112 GtkStyleProperties *props,
116 _gtk_style_properties_set_property_by_property (props,
117 GTK_CSS_STYLE_PROPERTY (property),
123 _gtk_style_property_default_value (GtkStyleProperty *property,
124 GtkStyleProperties *properties,
128 g_value_copy (_gtk_css_style_property_get_initial_value (GTK_CSS_STYLE_PROPERTY (property)), value);
132 resolve_color (GtkStyleProperties *props,
137 /* Resolve symbolic color to GdkRGBA */
138 if (!gtk_symbolic_color_resolve (g_value_get_boxed (value), props, &color))
141 /* Store it back, this is where GdkRGBA caching happens */
142 g_value_unset (value);
143 g_value_init (value, GDK_TYPE_RGBA);
144 g_value_set_boxed (value, &color);
150 resolve_color_rgb (GtkStyleProperties *props,
153 GdkColor color = { 0 };
156 if (!gtk_symbolic_color_resolve (g_value_get_boxed (value), props, &rgba))
159 color.red = rgba.red * 65535. + 0.5;
160 color.green = rgba.green * 65535. + 0.5;
161 color.blue = rgba.blue * 65535. + 0.5;
163 g_value_unset (value);
164 g_value_init (value, GDK_TYPE_COLOR);
165 g_value_set_boxed (value, &color);
171 resolve_win32_theme_part (GtkStyleProperties *props,
174 GtkStylePropertyContext *context)
176 GtkWin32ThemePart *part;
177 cairo_pattern_t *pattern;
179 part = g_value_get_boxed (value);
183 pattern = _gtk_win32_theme_part_render (part, context->width, context->height);
185 g_value_take_boxed (value_out, pattern);
192 resolve_gradient (GtkStyleProperties *props,
195 cairo_pattern_t *gradient;
197 if (!gtk_gradient_resolve (g_value_get_boxed (value), props, &gradient))
200 /* Store it back, this is where cairo_pattern_t caching happens */
201 g_value_unset (value);
202 g_value_init (value, CAIRO_GOBJECT_TYPE_PATTERN);
203 g_value_take_boxed (value, gradient);
209 resolve_shadow (GtkStyleProperties *props,
212 GtkShadow *resolved, *base;
214 base = g_value_get_boxed (value);
219 if (_gtk_shadow_get_resolved (base))
222 resolved = _gtk_shadow_resolve (base, props);
223 if (resolved == NULL)
226 g_value_take_boxed (value, resolved);
232 _gtk_style_property_resolve (GtkStyleProperty *property,
233 GtkStyleProperties *props,
235 GtkStylePropertyContext *context,
239 if (G_VALUE_TYPE (val) == GTK_TYPE_CSS_SPECIAL_VALUE)
241 GtkCssSpecialValue special = g_value_get_enum (val);
246 case GTK_CSS_CURRENT_COLOR:
247 g_assert (property->pspec->value_type == GDK_TYPE_RGBA);
248 gtk_style_properties_get_property (props, "color", state, val);
250 case GTK_CSS_INHERIT:
251 case GTK_CSS_INITIAL:
253 g_assert_not_reached ();
256 else if (G_VALUE_TYPE (val) == GTK_TYPE_SYMBOLIC_COLOR)
258 if (property->pspec->value_type == GDK_TYPE_RGBA)
260 if (resolve_color (props, val))
263 else if (property->pspec->value_type == GDK_TYPE_COLOR)
265 if (resolve_color_rgb (props, val))
270 g_value_init (val, property->pspec->value_type);
271 _gtk_style_property_default_value (property, props, state, val);
273 else if (G_VALUE_TYPE (val) == GDK_TYPE_RGBA)
275 if (g_value_get_boxed (val) == NULL)
276 _gtk_style_property_default_value (property, props, state, val);
278 else if (G_VALUE_TYPE (val) == GTK_TYPE_GRADIENT)
280 g_return_if_fail (property->pspec->value_type == CAIRO_GOBJECT_TYPE_PATTERN);
282 if (!resolve_gradient (props, val))
285 g_value_init (val, CAIRO_GOBJECT_TYPE_PATTERN);
286 _gtk_style_property_default_value (property, props, state, val);
289 else if (G_VALUE_TYPE (val) == GTK_TYPE_SHADOW)
291 if (!resolve_shadow (props, val))
292 _gtk_style_property_default_value (property, props, state, val);
294 else if (G_VALUE_TYPE (val) == GTK_TYPE_WIN32_THEME_PART)
296 if (resolve_win32_theme_part (props, val, val_out, context))
297 return; /* Don't copy val, this sets val_out */
298 _gtk_style_property_default_value (property, props, state, val);
302 g_value_copy (val, val_out);
306 _gtk_css_style_property_query (GtkStyleProperty *property,
307 GtkStyleProperties *props,
309 GtkStylePropertyContext *context,
314 val = _gtk_style_properties_peek_property (props, GTK_CSS_STYLE_PROPERTY (property), state);
316 _gtk_style_property_resolve (property, props, state, context, (GValue *) val, value);
318 _gtk_style_property_default_value (property, props, state, value);
322 _gtk_css_style_property_class_init (GtkCssStylePropertyClass *klass)
324 GObjectClass *object_class = G_OBJECT_CLASS (klass);
325 GtkStylePropertyClass *property_class = GTK_STYLE_PROPERTY_CLASS (klass);
327 object_class->constructed = gtk_css_style_property_constructed;
328 object_class->set_property = gtk_css_style_property_set_property;
329 object_class->get_property = gtk_css_style_property_get_property;
331 g_object_class_install_property (object_class,
333 g_param_spec_uint ("id",
335 P_("The numeric id for quick access"),
338 g_object_class_install_property (object_class,
340 g_param_spec_boolean ("inherit",
342 P_("Set if the value is inherited by default"),
344 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
345 g_object_class_install_property (object_class,
347 g_param_spec_boxed ("initial-value",
349 P_("The initial specified value used for this property"),
351 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
353 property_class->assign = _gtk_css_style_property_assign;
354 property_class->query = _gtk_css_style_property_query;
356 klass->style_properties = g_ptr_array_new ();
361 _gtk_css_style_property_init (GtkCssStyleProperty *style_property)
366 * _gtk_css_style_property_get_n_properties:
368 * Gets the number of style properties. This number can increase when new
369 * theme engines are loaded. Shorthand properties are not included here.
371 * Returns: The number of style properties.
374 _gtk_css_style_property_get_n_properties (void)
376 GtkCssStylePropertyClass *klass;
378 klass = g_type_class_peek (GTK_TYPE_CSS_STYLE_PROPERTY);
380 return klass->style_properties->len;
384 * _gtk_css_style_property_lookup_by_id:
385 * @id: the id of the property
387 * Gets the style property with the given id. All style properties (but not
388 * shorthand properties) are indexable by id so that it's easy to use arrays
389 * when doing style lookups.
391 * Returns: (transfer none): The style property with the given id
393 GtkCssStyleProperty *
394 _gtk_css_style_property_lookup_by_id (guint id)
396 GtkCssStylePropertyClass *klass;
398 klass = g_type_class_peek (GTK_TYPE_CSS_STYLE_PROPERTY);
400 return g_ptr_array_index (klass->style_properties, id);
404 * _gtk_css_style_property_is_inherit:
405 * @property: the property
407 * Queries if the given @property is inherited. See
408 * <ulink url="http://www.w3.org/TR/css3-cascade/#inheritance>
409 * the CSS documentation</ulink> for an explanation of this concept.
411 * Returns: %TRUE if the property is inherited by default.
414 _gtk_css_style_property_is_inherit (GtkCssStyleProperty *property)
416 g_return_val_if_fail (GTK_IS_CSS_STYLE_PROPERTY (property), 0);
418 return property->inherit;
422 * _gtk_css_style_property_get_id:
423 * @property: the property
425 * Gets the id for the given property. IDs are used to allow using arrays
428 * Returns: The id of the property
431 _gtk_css_style_property_get_id (GtkCssStyleProperty *property)
433 g_return_val_if_fail (GTK_IS_CSS_STYLE_PROPERTY (property), 0);
439 * _gtk_css_style_property_get_initial_value:
440 * @property: the property
442 * Queries the initial value of the given @property. See
443 * <ulink url="http://www.w3.org/TR/css3-cascade/#intial>
444 * the CSS documentation</ulink> for an explanation of this concept.
446 * Returns: a reference to the initial value. The value will never change.
449 _gtk_css_style_property_get_initial_value (GtkCssStyleProperty *property)
451 g_return_val_if_fail (GTK_IS_CSS_STYLE_PROPERTY (property), NULL);
453 return &property->initial_value;
457 * _gtk_css_style_property_print_value:
458 * @property: the property
459 * @value: the value to print
460 * @string: the string to print to
462 * Prints @value to the given @string in CSS format. The @value must be a
463 * valid specified value as parsed using the parse functions or as assigned
464 * via _gtk_style_property_assign().
467 _gtk_css_style_property_print_value (GtkCssStyleProperty *property,
471 g_return_if_fail (GTK_IS_CSS_STYLE_PROPERTY (property));
472 g_return_if_fail (value != NULL);
473 g_return_if_fail (string != NULL);
475 if (G_VALUE_HOLDS (value, GTK_TYPE_CSS_SPECIAL_VALUE))
477 GEnumClass *enum_class;
478 GEnumValue *enum_value;
480 enum_class = g_type_class_ref (GTK_TYPE_CSS_SPECIAL_VALUE);
481 enum_value = g_enum_get_value (enum_class, g_value_get_enum (value));
483 g_string_append (string, enum_value->value_nick);
485 g_type_class_unref (enum_class);
487 else if (GTK_STYLE_PROPERTY (property)->print_func)
488 (* GTK_STYLE_PROPERTY (property)->print_func) (value, string);
490 _gtk_css_style_print_value (value, string);