1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 2010 Carlos Garnacho <carlosg@gnome.org>
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.
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, see <http://www.gnu.org/licenses/>.
20 #include "gtkstylepropertyprivate.h"
22 #include <gobject/gvaluecollector.h>
23 #include <gdk-pixbuf/gdk-pixbuf.h>
24 #include <cairo-gobject.h>
27 #include "gtkcssparserprivate.h"
28 #include "gtkcssstylefuncsprivate.h"
29 #include "gtkcssstylepropertyprivate.h"
30 #include "gtkcsstypesprivate.h"
32 #include "gtkprivatetypebuiltins.h"
33 #include "gtkstylepropertiesprivate.h"
35 /* this is in case round() is not provided by the compiler,
36 * such as in the case of C89 compilers, like MSVC
38 #include "fallback-c89.c"
40 /* the actual parsers we have */
41 #include "gtkanimationdescription.h"
42 #include "gtkbindings.h"
43 #include "gtkcssarrayvalueprivate.h"
44 #include "gtkcsscornervalueprivate.h"
45 #include "gtkcsseasevalueprivate.h"
46 #include "gtkcssimagegradientprivate.h"
47 #include "gtkcssimageprivate.h"
48 #include "gtkcssimagevalueprivate.h"
49 #include "gtkcssenumvalueprivate.h"
50 #include "gtkcssnumbervalueprivate.h"
51 #include "gtkcssrgbavalueprivate.h"
52 #include "gtkcssshadowsvalueprivate.h"
53 #include "gtkcssstringvalueprivate.h"
54 #include "gtksymboliccolorprivate.h"
55 #include "gtkthemingengine.h"
56 #include "gtktypebuiltins.h"
57 #include "gtkwin32themeprivate.h"
59 /*** REGISTRATION ***/
62 GTK_STYLE_PROPERTY_INHERIT = (1 << 0),
63 GTK_STYLE_PROPERTY_ANIMATED = (1 << 1)
64 } GtkStylePropertyFlags;
67 gtk_css_style_property_register (const char * name,
70 GtkStylePropertyFlags flags,
71 GtkCssStylePropertyParseFunc parse_value,
72 GtkCssStylePropertyPrintFunc print_value,
73 GtkCssStylePropertyComputeFunc compute_value,
74 GtkCssStylePropertyQueryFunc query_value,
75 GtkCssStylePropertyAssignFunc assign_value,
76 GtkCssStylePropertyEqualFunc equal_func,
77 GtkCssValue * initial_value)
79 GtkCssStyleProperty *node;
81 g_assert (initial_value != NULL);
82 g_assert (parse_value != NULL);
83 g_assert (value_type == G_TYPE_NONE || query_value != NULL);
84 g_assert (value_type == G_TYPE_NONE || assign_value != NULL);
86 node = g_object_new (GTK_TYPE_CSS_STYLE_PROPERTY,
87 "value-type", value_type,
88 "animated", (flags & GTK_STYLE_PROPERTY_ANIMATED) ? TRUE : FALSE,
89 "inherit", (flags & GTK_STYLE_PROPERTY_INHERIT) ? TRUE : FALSE,
90 "initial-value", initial_value,
94 node->parse_value = parse_value;
96 node->print_value = print_value;
98 node->compute_value = compute_value;
99 node->query_value = query_value;
100 node->assign_value = assign_value;
102 node->equal_func = equal_func;
104 _gtk_css_value_unref (initial_value);
106 g_assert (_gtk_css_style_property_get_id (node) == expected_id);
109 /*** IMPLEMENTATIONS ***/
112 query_simple (GtkCssStyleProperty *property,
113 const GtkCssValue *css_value,
116 _gtk_css_value_init_gvalue (css_value, value);
120 assign_simple (GtkCssStyleProperty *property,
123 return _gtk_css_value_new_from_gvalue (value);
127 query_length_as_int (GtkCssStyleProperty *property,
128 const GtkCssValue *css_value,
131 g_value_init (value, G_TYPE_INT);
132 g_value_set_int (value, round (_gtk_css_number_value_get (css_value, 100)));
136 assign_length_from_int (GtkCssStyleProperty *property,
139 return _gtk_css_number_value_new (g_value_get_int (value), GTK_CSS_PX);
143 query_length_as_double (GtkCssStyleProperty *property,
144 const GtkCssValue *css_value,
147 g_value_init (value, G_TYPE_DOUBLE);
148 g_value_set_double (value, _gtk_css_number_value_get (css_value, 100));
152 assign_length_from_double (GtkCssStyleProperty *property,
155 return _gtk_css_number_value_new (g_value_get_double (value), GTK_CSS_PX);
159 color_parse (GtkCssStyleProperty *property,
160 GtkCssParser *parser,
163 GtkSymbolicColor *symbolic;
165 if (_gtk_css_parser_try (parser, "currentcolor", TRUE))
167 symbolic = gtk_symbolic_color_ref (_gtk_symbolic_color_get_current_color ());
171 symbolic = _gtk_css_parser_read_symbolic_color (parser);
172 if (symbolic == NULL)
176 return _gtk_css_value_new_take_symbolic_color (symbolic);
180 color_compute (GtkCssStyleProperty *property,
181 GtkStyleContext *context,
182 GtkCssValue *specified)
184 return _gtk_css_rgba_value_compute_from_symbolic (specified,
185 _gtk_css_style_property_get_initial_value (property),
191 color_property_compute (GtkCssStyleProperty *property,
192 GtkStyleContext *context,
193 GtkCssValue *specified)
197 value = _gtk_css_rgba_value_compute_from_symbolic (specified,
198 _gtk_css_style_property_get_initial_value (property),
201 _gtk_css_rgba_value_get_rgba (value);
206 color_query (GtkCssStyleProperty *property,
207 const GtkCssValue *css_value,
210 g_value_init (value, GDK_TYPE_RGBA);
211 g_value_set_boxed (value, _gtk_css_rgba_value_get_rgba (css_value));
215 color_assign (GtkCssStyleProperty *property,
218 return _gtk_css_rgba_value_new_from_rgba (g_value_get_boxed (value));
222 font_family_parse_one (GtkCssParser *parser)
226 name = _gtk_css_parser_try_ident (parser, TRUE);
229 GString *string = g_string_new (name);
231 while ((name = _gtk_css_parser_try_ident (parser, TRUE)))
233 g_string_append_c (string, ' ');
234 g_string_append (string, name);
237 name = g_string_free (string, FALSE);
241 name = _gtk_css_parser_read_string (parser);
246 return _gtk_css_string_value_new_take (name);
250 font_family_parse (GtkCssStyleProperty *property,
251 GtkCssParser *parser,
254 return _gtk_css_array_value_parse (parser, font_family_parse_one, FALSE);
258 font_family_query (GtkCssStyleProperty *property,
259 const GtkCssValue *css_value,
265 array = g_ptr_array_new ();
267 for (i = 0; i < _gtk_css_array_value_get_n_values (css_value); i++)
269 g_ptr_array_add (array, g_strdup (_gtk_css_string_value_get (_gtk_css_array_value_get_nth (css_value, i))));
273 g_ptr_array_add (array, NULL);
275 g_value_init (value, G_TYPE_STRV);
276 g_value_set_boxed (value, g_ptr_array_free (array, FALSE));
280 font_family_assign (GtkCssStyleProperty *property,
283 const char **names = g_value_get_boxed (value);
287 array = g_ptr_array_new ();
289 for (names = g_value_get_boxed (value); *names; names++)
291 g_ptr_array_add (array, _gtk_css_string_value_new (*names));
294 result = _gtk_css_array_value_new_from_array ((GtkCssValue **) array->pdata, array->len);
295 g_ptr_array_free (array, TRUE);
300 parse_pango_style (GtkCssStyleProperty *property,
301 GtkCssParser *parser,
304 GtkCssValue *value = _gtk_css_font_style_value_try_parse (parser);
307 _gtk_css_parser_error (parser, "unknown value for property");
313 query_pango_style (GtkCssStyleProperty *property,
314 const GtkCssValue *css_value,
317 g_value_init (value, PANGO_TYPE_STYLE);
318 g_value_set_enum (value, _gtk_css_font_style_value_get (css_value));
322 assign_pango_style (GtkCssStyleProperty *property,
325 return _gtk_css_font_style_value_new (g_value_get_enum (value));
329 parse_pango_weight (GtkCssStyleProperty *property,
330 GtkCssParser *parser,
333 GtkCssValue *value = _gtk_css_font_weight_value_try_parse (parser);
336 _gtk_css_parser_error (parser, "unknown value for property");
342 query_pango_weight (GtkCssStyleProperty *property,
343 const GtkCssValue *css_value,
346 g_value_init (value, PANGO_TYPE_WEIGHT);
347 g_value_set_enum (value, _gtk_css_font_weight_value_get (css_value));
351 assign_pango_weight (GtkCssStyleProperty *property,
354 return _gtk_css_font_weight_value_new (g_value_get_enum (value));
358 parse_pango_variant (GtkCssStyleProperty *property,
359 GtkCssParser *parser,
362 GtkCssValue *value = _gtk_css_font_variant_value_try_parse (parser);
365 _gtk_css_parser_error (parser, "unknown value for property");
371 query_pango_variant (GtkCssStyleProperty *property,
372 const GtkCssValue *css_value,
375 g_value_init (value, PANGO_TYPE_VARIANT);
376 g_value_set_enum (value, _gtk_css_font_variant_value_get (css_value));
380 assign_pango_variant (GtkCssStyleProperty *property,
383 return _gtk_css_font_variant_value_new (g_value_get_enum (value));
387 parse_border_style (GtkCssStyleProperty *property,
388 GtkCssParser *parser,
391 GtkCssValue *value = _gtk_css_border_style_value_try_parse (parser);
394 _gtk_css_parser_error (parser, "unknown value for property");
400 query_border_style (GtkCssStyleProperty *property,
401 const GtkCssValue *css_value,
404 g_value_init (value, GTK_TYPE_BORDER_STYLE);
405 g_value_set_enum (value, _gtk_css_border_style_value_get (css_value));
409 assign_border_style (GtkCssStyleProperty *property,
412 return _gtk_css_border_style_value_new (g_value_get_enum (value));
416 parse_css_area (GtkCssStyleProperty *property,
417 GtkCssParser *parser,
420 GtkCssValue *value = _gtk_css_area_value_try_parse (parser);
423 _gtk_css_parser_error (parser, "unknown value for property");
429 bindings_value_parse_one (GtkCssParser *parser)
433 name = _gtk_css_parser_try_ident (parser, TRUE);
436 _gtk_css_parser_error (parser, "Not a valid binding name");
441 if (!gtk_binding_set_find (name))
443 _gtk_css_parser_error (parser, "No binding set named '%s'", name);
448 return _gtk_css_string_value_new_take (name);
452 bindings_value_parse (GtkCssStyleProperty *property,
453 GtkCssParser *parser,
456 return _gtk_css_array_value_parse (parser, bindings_value_parse_one, TRUE);
460 bindings_value_query (GtkCssStyleProperty *property,
461 const GtkCssValue *css_value,
467 g_value_init (value, G_TYPE_PTR_ARRAY);
469 if (_gtk_css_array_value_get_n_values (css_value) == 0)
472 array = g_ptr_array_new ();
474 for (i = 0; i < _gtk_css_array_value_get_n_values (css_value); i++)
476 GtkBindingSet *binding_set = gtk_binding_set_find (_gtk_css_string_value_get (_gtk_css_array_value_get_nth (css_value, i)));
478 g_ptr_array_add (array, binding_set);
481 g_value_take_boxed (value, array);
485 bindings_value_assign (GtkCssStyleProperty *property,
488 GPtrArray *binding_sets = g_value_get_boxed (value);
489 GtkCssValue **values, *result;
492 if (binding_sets == NULL || binding_sets->len == 0)
493 return _gtk_css_array_value_new (NULL);
495 values = g_new (GtkCssValue *, binding_sets->len);
497 for (i = 0; i < binding_sets->len; i++)
499 GtkBindingSet *binding_set = g_ptr_array_index (binding_sets, i);
500 values[i] = _gtk_css_string_value_new (binding_set->set_name);
503 result = _gtk_css_array_value_new_from_array (values, binding_sets->len);
509 shadow_value_parse (GtkCssStyleProperty *property,
510 GtkCssParser *parser,
513 return _gtk_css_shadows_value_parse (parser);
517 shadow_value_compute (GtkCssStyleProperty *property,
518 GtkStyleContext *context,
519 GtkCssValue *specified)
521 return _gtk_css_shadows_value_compute (specified, context);
525 border_corner_radius_value_parse (GtkCssStyleProperty *property,
526 GtkCssParser *parser,
529 return _gtk_css_corner_value_parse (parser);
533 border_corner_radius_value_compute (GtkCssStyleProperty *property,
534 GtkStyleContext *context,
535 GtkCssValue *specified)
537 return _gtk_css_corner_value_compute (specified, context);
541 css_image_value_parse (GtkCssStyleProperty *property,
542 GtkCssParser *parser,
547 if (_gtk_css_parser_try (parser, "none", TRUE))
551 image = _gtk_css_image_new_parse (parser, base);
556 return _gtk_css_image_value_new (image);
560 css_image_value_compute (GtkCssStyleProperty *property,
561 GtkStyleContext *context,
562 GtkCssValue *specified)
564 GtkCssImage *image, *computed;
566 image = _gtk_css_image_value_get_image (specified);
569 return _gtk_css_value_ref (specified);
571 computed = _gtk_css_image_compute (image, context);
573 if (computed == image)
575 g_object_unref (computed);
576 return _gtk_css_value_ref (specified);
579 return _gtk_css_image_value_new (computed);
583 css_image_value_query (GtkCssStyleProperty *property,
584 const GtkCssValue *css_value,
587 GtkCssImage *image = _gtk_css_image_value_get_image (css_value);
588 cairo_pattern_t *pattern;
589 cairo_surface_t *surface;
590 cairo_matrix_t matrix;
592 g_value_init (value, CAIRO_GOBJECT_TYPE_PATTERN);
594 if (GTK_IS_CSS_IMAGE_GRADIENT (image))
595 g_value_set_boxed (value, GTK_CSS_IMAGE_GRADIENT (image)->pattern);
596 else if (image != NULL)
598 double width, height;
600 /* the 100, 100 is rather random */
601 _gtk_css_image_get_concrete_size (image, 0, 0, 100, 100, &width, &height);
602 surface = _gtk_css_image_get_surface (image, NULL, width, height);
603 pattern = cairo_pattern_create_for_surface (surface);
604 cairo_matrix_init_scale (&matrix, width, height);
605 cairo_pattern_set_matrix (pattern, &matrix);
606 cairo_surface_destroy (surface);
607 g_value_take_boxed (value, pattern);
612 css_image_value_assign (GtkCssStyleProperty *property,
615 g_warning ("FIXME: assigning images is not implemented");
616 return _gtk_css_image_value_new (NULL);
620 font_size_parse (GtkCssStyleProperty *property,
621 GtkCssParser *parser,
626 if (!_gtk_css_parser_try_double (parser, &d))
628 _gtk_css_parser_error (parser, "Expected a number");
632 return _gtk_css_number_value_new (d, GTK_CSS_PX);
636 font_size_compute (GtkCssStyleProperty *property,
637 GtkStyleContext *context,
638 GtkCssValue *specified)
640 return _gtk_css_number_value_compute (specified, context);
644 outline_parse (GtkCssStyleProperty *property,
645 GtkCssParser *parser,
648 return _gtk_css_number_value_parse (parser,
649 GTK_CSS_NUMBER_AS_PIXELS
650 | GTK_CSS_PARSE_LENGTH);
654 outline_compute (GtkCssStyleProperty *property,
655 GtkStyleContext *context,
656 GtkCssValue *specified)
658 return _gtk_css_number_value_compute (specified, context);
662 border_image_repeat_parse (GtkCssStyleProperty *property,
663 GtkCssParser *parser,
666 GValue value = G_VALUE_INIT;
669 g_value_init (&value, GTK_TYPE_CSS_BORDER_IMAGE_REPEAT);
670 if (!_gtk_css_style_parse_value (&value, parser, base))
672 g_value_unset (&value);
676 result = _gtk_css_value_new_from_gvalue (&value);
677 g_value_unset (&value);
683 border_image_slice_parse (GtkCssStyleProperty *property,
684 GtkCssParser *parser,
687 GValue value = G_VALUE_INIT;
690 g_value_init (&value, GTK_TYPE_BORDER);
691 if (!_gtk_css_style_parse_value (&value, parser, base))
693 g_value_unset (&value);
697 result = _gtk_css_value_new_from_gvalue (&value);
698 g_value_unset (&value);
704 border_image_width_parse (GtkCssStyleProperty *property,
705 GtkCssParser *parser,
708 GValue value = G_VALUE_INIT;
711 g_value_init (&value, GTK_TYPE_BORDER);
712 if (!_gtk_css_style_parse_value (&value, parser, base))
714 g_value_unset (&value);
718 result = _gtk_css_value_new_from_gvalue (&value);
719 g_value_unset (&value);
725 transition_property_parse_one (GtkCssParser *parser)
729 value = _gtk_css_ident_value_try_parse (parser);
733 _gtk_css_parser_error (parser, "Expected an identifier");
741 transition_property_parse (GtkCssStyleProperty *property,
742 GtkCssParser *parser,
745 return _gtk_css_array_value_parse (parser, transition_property_parse_one, FALSE);
749 transition_time_parse_one (GtkCssParser *parser)
751 return _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_TIME);
755 transition_time_parse (GtkCssStyleProperty *property,
756 GtkCssParser *parser,
759 return _gtk_css_array_value_parse (parser, transition_time_parse_one, FALSE);
763 transition_timing_function_parse (GtkCssStyleProperty *property,
764 GtkCssParser *parser,
767 return _gtk_css_array_value_parse (parser, _gtk_css_ease_value_parse, FALSE);
771 engine_parse (GtkCssStyleProperty *property,
772 GtkCssParser *parser,
775 GtkThemingEngine *engine;
778 if (_gtk_css_parser_try (parser, "none", TRUE))
779 return _gtk_css_value_new_from_theming_engine (gtk_theming_engine_load (NULL));
781 str = _gtk_css_parser_try_ident (parser, TRUE);
784 _gtk_css_parser_error (parser, "Expected a valid theme name");
788 engine = gtk_theming_engine_load (str);
792 _gtk_css_parser_error (parser, "Theming engine '%s' not found", str);
799 return _gtk_css_value_new_from_theming_engine (engine);
803 transition_parse (GtkCssStyleProperty *property,
804 GtkCssParser *parser,
807 GValue value = G_VALUE_INIT;
810 g_value_init (&value, GTK_TYPE_ANIMATION_DESCRIPTION);
811 if (!_gtk_css_style_parse_value (&value, parser, base))
813 g_value_unset (&value);
817 result = _gtk_css_value_new_from_gvalue (&value);
818 g_value_unset (&value);
824 parse_margin (GtkCssStyleProperty *property,
825 GtkCssParser *parser,
828 return _gtk_css_number_value_parse (parser,
829 GTK_CSS_NUMBER_AS_PIXELS
830 | GTK_CSS_PARSE_LENGTH);
834 compute_margin (GtkCssStyleProperty *property,
835 GtkStyleContext *context,
836 GtkCssValue *specified)
838 return _gtk_css_number_value_compute (specified, context);
842 parse_padding (GtkCssStyleProperty *property,
843 GtkCssParser *parser,
846 return _gtk_css_number_value_parse (parser,
847 GTK_CSS_POSITIVE_ONLY
848 | GTK_CSS_NUMBER_AS_PIXELS
849 | GTK_CSS_PARSE_LENGTH);
853 compute_padding (GtkCssStyleProperty *property,
854 GtkStyleContext *context,
855 GtkCssValue *specified)
857 return _gtk_css_number_value_compute (specified, context);
861 parse_border_width (GtkCssStyleProperty *property,
862 GtkCssParser *parser,
865 return _gtk_css_number_value_parse (parser,
866 GTK_CSS_POSITIVE_ONLY
867 | GTK_CSS_NUMBER_AS_PIXELS
868 | GTK_CSS_PARSE_LENGTH);
872 compute_border_width (GtkCssStyleProperty *property,
873 GtkStyleContext *context,
874 GtkCssValue *specified)
876 GtkBorderStyle border_style;
878 /* The -1 is magic that is only true because we register the style
879 * properties directly after the width properties.
881 border_style = _gtk_css_border_style_value_get (_gtk_style_context_peek_property (context, _gtk_css_style_property_get_id (property) - 1));
883 if (border_style == GTK_BORDER_STYLE_NONE ||
884 border_style == GTK_BORDER_STYLE_HIDDEN)
885 return _gtk_css_number_value_new (0, GTK_CSS_PX);
887 return _gtk_css_number_value_compute (specified, context);
891 background_repeat_value_parse (GtkCssStyleProperty *property,
892 GtkCssParser *parser,
895 int repeat, vertical;
897 if (!_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BACKGROUND_REPEAT, &repeat))
899 _gtk_css_parser_error (parser, "Not a valid value");
903 if (repeat <= GTK_CSS_BACKGROUND_REPEAT_MASK)
905 if (_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BACKGROUND_REPEAT, &vertical))
907 if (vertical >= GTK_CSS_BACKGROUND_REPEAT_MASK)
909 _gtk_css_parser_error (parser, "Not a valid 2nd value");
913 repeat |= vertical << GTK_CSS_BACKGROUND_REPEAT_SHIFT;
916 repeat |= repeat << GTK_CSS_BACKGROUND_REPEAT_SHIFT;
919 return _gtk_css_value_new_from_enum (GTK_TYPE_CSS_BACKGROUND_REPEAT, repeat);
923 background_repeat_value_print (GtkCssStyleProperty *property,
924 const GtkCssValue *value,
927 GEnumClass *enum_class;
928 GEnumValue *enum_value;
929 GtkCssBackgroundRepeat repeat;
931 repeat = _gtk_css_value_get_enum (value);
932 enum_class = g_type_class_ref (GTK_TYPE_CSS_BACKGROUND_REPEAT);
933 enum_value = g_enum_get_value (enum_class, repeat);
935 /* only triggers for 'repeat-x' and 'repeat-y' */
937 g_string_append (string, enum_value->value_nick);
940 enum_value = g_enum_get_value (enum_class, GTK_CSS_BACKGROUND_HORIZONTAL (repeat));
941 g_string_append (string, enum_value->value_nick);
943 if (GTK_CSS_BACKGROUND_HORIZONTAL (repeat) != GTK_CSS_BACKGROUND_VERTICAL (repeat))
945 enum_value = g_enum_get_value (enum_class, GTK_CSS_BACKGROUND_VERTICAL (repeat));
946 g_string_append (string, " ");
947 g_string_append (string, enum_value->value_nick);
951 g_type_class_unref (enum_class);
955 background_size_parse (GtkCssStyleProperty *property,
956 GtkCssParser *parser,
959 GtkCssBackgroundSize size = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), FALSE, FALSE};
961 if (_gtk_css_parser_try (parser, "cover", TRUE))
963 else if (_gtk_css_parser_try (parser, "contain", TRUE))
967 if (_gtk_css_parser_try (parser, "auto", TRUE))
968 _gtk_css_number_init (&size.width, 0, GTK_CSS_PX);
969 else if (!_gtk_css_parser_read_number (parser,
971 GTK_CSS_POSITIVE_ONLY
972 | GTK_CSS_PARSE_PERCENT
973 | GTK_CSS_PARSE_LENGTH))
976 if (_gtk_css_parser_try (parser, "auto", TRUE))
977 _gtk_css_number_init (&size.height, 0, GTK_CSS_PX);
978 else if (_gtk_css_parser_has_number (parser))
980 if (!_gtk_css_parser_read_number (parser,
982 GTK_CSS_POSITIVE_ONLY
983 | GTK_CSS_PARSE_PERCENT
984 | GTK_CSS_PARSE_LENGTH))
988 _gtk_css_number_init (&size.height, 0, GTK_CSS_PX);
991 return _gtk_css_value_new_from_background_size (&size);
995 background_size_print (GtkCssStyleProperty *property,
996 const GtkCssValue *value,
999 const GtkCssBackgroundSize *size = _gtk_css_value_get_background_size (value);
1002 g_string_append (string, "cover");
1003 else if (size->contain)
1004 g_string_append (string, "contain");
1007 if (size->width.value == 0)
1008 g_string_append (string, "auto");
1010 _gtk_css_number_print (&size->width, string);
1012 if (size->height.value != 0)
1014 g_string_append (string, " ");
1015 _gtk_css_number_print (&size->height, string);
1020 static GtkCssValue *
1021 background_size_compute (GtkCssStyleProperty *property,
1022 GtkStyleContext *context,
1023 GtkCssValue *specified)
1025 const GtkCssBackgroundSize *ssize = _gtk_css_value_get_background_size (specified);
1026 GtkCssBackgroundSize csize;
1029 csize.cover = ssize->cover;
1030 csize.contain = ssize->contain;
1031 changed = _gtk_css_number_compute (&csize.width,
1034 changed |= _gtk_css_number_compute (&csize.height,
1038 return _gtk_css_value_new_from_background_size (&csize);
1039 return _gtk_css_value_ref (specified);
1042 static GtkCssValue *
1043 background_position_parse (GtkCssStyleProperty *property,
1044 GtkCssParser *parser,
1047 static const struct {
1050 gboolean horizontal;
1053 { "left", 0, TRUE, FALSE },
1054 { "right", 100, TRUE, FALSE },
1055 { "center", 50, TRUE, TRUE },
1056 { "top", 0, FALSE, TRUE },
1057 { "bottom", 100, FALSE, TRUE },
1058 { NULL , 0, TRUE, FALSE }, /* used for numbers */
1059 { NULL , 50, TRUE, TRUE } /* used for no value */
1061 GtkCssBackgroundPosition pos;
1062 GtkCssNumber *missing;
1063 guint first, second;
1065 for (first = 0; names[first].name != NULL; first++)
1067 if (_gtk_css_parser_try (parser, names[first].name, TRUE))
1069 if (names[first].horizontal)
1071 _gtk_css_number_init (&pos.x, names[first].percentage, GTK_CSS_PERCENT);
1076 _gtk_css_number_init (&pos.y, names[first].percentage, GTK_CSS_PERCENT);
1082 if (names[first].name == NULL)
1085 if (!_gtk_css_parser_read_number (parser,
1087 GTK_CSS_PARSE_PERCENT
1088 | GTK_CSS_PARSE_LENGTH))
1092 for (second = 0; names[second].name != NULL; second++)
1094 if (_gtk_css_parser_try (parser, names[second].name, TRUE))
1096 _gtk_css_number_init (missing, names[second].percentage, GTK_CSS_PERCENT);
1101 if (names[second].name == NULL)
1103 if (_gtk_css_parser_has_number (parser))
1105 if (missing != &pos.y)
1107 _gtk_css_parser_error (parser, "Invalid combination of values");
1110 if (!_gtk_css_parser_read_number (parser,
1112 GTK_CSS_PARSE_PERCENT
1113 | GTK_CSS_PARSE_LENGTH))
1119 _gtk_css_number_init (missing, 50, GTK_CSS_PERCENT);
1124 if ((names[first].horizontal && !names[second].vertical) ||
1125 (!names[first].horizontal && !names[second].horizontal))
1127 _gtk_css_parser_error (parser, "Invalid combination of values");
1132 return _gtk_css_value_new_from_background_position (&pos);
1136 background_position_print (GtkCssStyleProperty *property,
1137 const GtkCssValue *value,
1140 const GtkCssBackgroundPosition *pos = _gtk_css_value_get_background_position (value);
1141 static const GtkCssNumber center = GTK_CSS_NUMBER_INIT (50, GTK_CSS_PERCENT);
1142 static const struct {
1145 GtkCssNumber number;
1147 { "left", "top", GTK_CSS_NUMBER_INIT (0, GTK_CSS_PERCENT) },
1148 { "right", "bottom", GTK_CSS_NUMBER_INIT (100, GTK_CSS_PERCENT) }
1152 if (_gtk_css_number_equal (&pos->x, ¢er))
1154 if (_gtk_css_number_equal (&pos->y, ¢er))
1156 g_string_append (string, "center");
1162 for (i = 0; i < G_N_ELEMENTS (values); i++)
1164 if (_gtk_css_number_equal (&pos->x, &values[i].number))
1166 g_string_append (string, values[i].x_name);
1170 if (i == G_N_ELEMENTS (values))
1171 _gtk_css_number_print (&pos->x, string);
1173 if (_gtk_css_number_equal (&pos->y, ¢er))
1176 g_string_append_c (string, ' ');
1179 for (i = 0; i < G_N_ELEMENTS (values); i++)
1181 if (_gtk_css_number_equal (&pos->y, &values[i].number))
1183 g_string_append (string, values[i].y_name);
1187 if (i == G_N_ELEMENTS (values))
1189 if (_gtk_css_number_equal (&pos->x, ¢er))
1190 g_string_append (string, "center ");
1191 _gtk_css_number_print (&pos->y, string);
1195 static GtkCssValue *
1196 background_position_compute (GtkCssStyleProperty *property,
1197 GtkStyleContext *context,
1198 GtkCssValue *specified)
1200 const GtkCssBackgroundPosition *spos = _gtk_css_value_get_background_position (specified);
1201 GtkCssBackgroundPosition cpos;
1204 changed = _gtk_css_number_compute (&cpos.x,
1207 changed |= _gtk_css_number_compute (&cpos.y,
1211 return _gtk_css_value_new_from_background_position (&cpos);
1212 return _gtk_css_value_ref (specified);
1215 /*** REGISTRATION ***/
1217 static GtkSymbolicColor *
1218 gtk_symbolic_color_new_rgba (double red,
1223 GdkRGBA rgba = { red, green, blue, alpha };
1225 return gtk_symbolic_color_new_literal (&rgba);
1229 _gtk_css_style_property_init_properties (void)
1231 GtkCssBackgroundSize default_background_size = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), FALSE, FALSE };
1232 GtkCssBackgroundPosition default_background_position = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PERCENT), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PERCENT)};
1233 GtkBorder border_of_ones = { 1, 1, 1, 1 };
1234 GtkCssBorderImageRepeat border_image_repeat = { GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_STRETCH };
1236 /* Initialize "color" and "font-size" first,
1237 * so that when computing values later they are
1238 * done first. That way, 'currentColor' and font
1239 * sizes in em can be looked up properly */
1240 gtk_css_style_property_register ("color",
1241 GTK_CSS_PROPERTY_COLOR,
1243 GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
1246 color_property_compute,
1250 _gtk_css_value_new_take_symbolic_color (
1251 gtk_symbolic_color_new_rgba (1, 1, 1, 1)));
1252 gtk_css_style_property_register ("font-size",
1253 GTK_CSS_PROPERTY_FONT_SIZE,
1255 GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
1259 query_length_as_double,
1260 assign_length_from_double,
1262 /* XXX: This should be 'normal' */
1263 _gtk_css_number_value_new (10.0, GTK_CSS_PX));
1265 /* properties that aren't referenced when computing values
1267 gtk_css_style_property_register ("background-color",
1268 GTK_CSS_PROPERTY_BACKGROUND_COLOR,
1270 GTK_STYLE_PROPERTY_ANIMATED,
1277 _gtk_css_value_new_take_symbolic_color (
1278 gtk_symbolic_color_new_rgba (0, 0, 0, 0)));
1280 gtk_css_style_property_register ("font-family",
1281 GTK_CSS_PROPERTY_FONT_FAMILY,
1283 GTK_STYLE_PROPERTY_INHERIT,
1290 _gtk_css_array_value_new (_gtk_css_string_value_new ("Sans")));
1291 gtk_css_style_property_register ("font-style",
1292 GTK_CSS_PROPERTY_FONT_STYLE,
1294 GTK_STYLE_PROPERTY_INHERIT,
1301 _gtk_css_font_style_value_new (PANGO_STYLE_NORMAL));
1302 gtk_css_style_property_register ("font-variant",
1303 GTK_CSS_PROPERTY_FONT_VARIANT,
1305 GTK_STYLE_PROPERTY_INHERIT,
1306 parse_pango_variant,
1309 query_pango_variant,
1310 assign_pango_variant,
1312 _gtk_css_font_variant_value_new (PANGO_VARIANT_NORMAL));
1313 gtk_css_style_property_register ("font-weight",
1314 GTK_CSS_PROPERTY_FONT_WEIGHT,
1316 GTK_STYLE_PROPERTY_INHERIT,
1321 assign_pango_weight,
1323 _gtk_css_font_weight_value_new (PANGO_WEIGHT_NORMAL));
1325 gtk_css_style_property_register ("text-shadow",
1326 GTK_CSS_PROPERTY_TEXT_SHADOW,
1328 GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
1331 shadow_value_compute,
1335 _gtk_css_shadows_value_new_none ());
1337 gtk_css_style_property_register ("icon-shadow",
1338 GTK_CSS_PROPERTY_ICON_SHADOW,
1340 GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
1343 shadow_value_compute,
1347 _gtk_css_shadows_value_new_none ());
1349 gtk_css_style_property_register ("box-shadow",
1350 GTK_CSS_PROPERTY_BOX_SHADOW,
1352 GTK_STYLE_PROPERTY_ANIMATED,
1355 shadow_value_compute,
1359 _gtk_css_shadows_value_new_none ());
1361 gtk_css_style_property_register ("margin-top",
1362 GTK_CSS_PROPERTY_MARGIN_TOP,
1364 GTK_STYLE_PROPERTY_ANIMATED,
1368 query_length_as_int,
1369 assign_length_from_int,
1371 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1372 gtk_css_style_property_register ("margin-left",
1373 GTK_CSS_PROPERTY_MARGIN_LEFT,
1375 GTK_STYLE_PROPERTY_ANIMATED,
1379 query_length_as_int,
1380 assign_length_from_int,
1382 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1383 gtk_css_style_property_register ("margin-bottom",
1384 GTK_CSS_PROPERTY_MARGIN_BOTTOM,
1386 GTK_STYLE_PROPERTY_ANIMATED,
1390 query_length_as_int,
1391 assign_length_from_int,
1393 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1394 gtk_css_style_property_register ("margin-right",
1395 GTK_CSS_PROPERTY_MARGIN_RIGHT,
1397 GTK_STYLE_PROPERTY_ANIMATED,
1401 query_length_as_int,
1402 assign_length_from_int,
1404 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1405 gtk_css_style_property_register ("padding-top",
1406 GTK_CSS_PROPERTY_PADDING_TOP,
1408 GTK_STYLE_PROPERTY_ANIMATED,
1412 query_length_as_int,
1413 assign_length_from_int,
1415 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1416 gtk_css_style_property_register ("padding-left",
1417 GTK_CSS_PROPERTY_PADDING_LEFT,
1419 GTK_STYLE_PROPERTY_ANIMATED,
1423 query_length_as_int,
1424 assign_length_from_int,
1426 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1427 gtk_css_style_property_register ("padding-bottom",
1428 GTK_CSS_PROPERTY_PADDING_BOTTOM,
1430 GTK_STYLE_PROPERTY_ANIMATED,
1434 query_length_as_int,
1435 assign_length_from_int,
1437 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1438 gtk_css_style_property_register ("padding-right",
1439 GTK_CSS_PROPERTY_PADDING_RIGHT,
1441 GTK_STYLE_PROPERTY_ANIMATED,
1445 query_length_as_int,
1446 assign_length_from_int,
1448 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1449 /* IMPORTANT: compute_border_width() requires that the border-width
1450 * properties be immeditaly followed by the border-style properties
1452 gtk_css_style_property_register ("border-top-style",
1453 GTK_CSS_PROPERTY_BORDER_TOP_STYLE,
1454 GTK_TYPE_BORDER_STYLE,
1460 assign_border_style,
1462 _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE));
1463 gtk_css_style_property_register ("border-top-width",
1464 GTK_CSS_PROPERTY_BORDER_TOP_WIDTH,
1466 GTK_STYLE_PROPERTY_ANIMATED,
1469 compute_border_width,
1470 query_length_as_int,
1471 assign_length_from_int,
1473 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1474 gtk_css_style_property_register ("border-left-style",
1475 GTK_CSS_PROPERTY_BORDER_LEFT_STYLE,
1476 GTK_TYPE_BORDER_STYLE,
1482 assign_border_style,
1484 _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE));
1485 gtk_css_style_property_register ("border-left-width",
1486 GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH,
1488 GTK_STYLE_PROPERTY_ANIMATED,
1491 compute_border_width,
1492 query_length_as_int,
1493 assign_length_from_int,
1495 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1496 gtk_css_style_property_register ("border-bottom-style",
1497 GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE,
1498 GTK_TYPE_BORDER_STYLE,
1504 assign_border_style,
1506 _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE));
1507 gtk_css_style_property_register ("border-bottom-width",
1508 GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH,
1510 GTK_STYLE_PROPERTY_ANIMATED,
1513 compute_border_width,
1514 query_length_as_int,
1515 assign_length_from_int,
1517 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1518 gtk_css_style_property_register ("border-right-style",
1519 GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE,
1520 GTK_TYPE_BORDER_STYLE,
1526 assign_border_style,
1528 _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE));
1529 gtk_css_style_property_register ("border-right-width",
1530 GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH,
1532 GTK_STYLE_PROPERTY_ANIMATED,
1535 compute_border_width,
1536 query_length_as_int,
1537 assign_length_from_int,
1539 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1541 gtk_css_style_property_register ("border-top-left-radius",
1542 GTK_CSS_PROPERTY_BORDER_TOP_LEFT_RADIUS,
1544 GTK_STYLE_PROPERTY_ANIMATED,
1545 border_corner_radius_value_parse,
1547 border_corner_radius_value_compute,
1551 _gtk_css_corner_value_new (_gtk_css_number_value_new (0, GTK_CSS_PX),
1552 _gtk_css_number_value_new (0, GTK_CSS_PX)));
1553 gtk_css_style_property_register ("border-top-right-radius",
1554 GTK_CSS_PROPERTY_BORDER_TOP_RIGHT_RADIUS,
1556 GTK_STYLE_PROPERTY_ANIMATED,
1557 border_corner_radius_value_parse,
1559 border_corner_radius_value_compute,
1563 _gtk_css_corner_value_new (_gtk_css_number_value_new (0, GTK_CSS_PX),
1564 _gtk_css_number_value_new (0, GTK_CSS_PX)));
1565 gtk_css_style_property_register ("border-bottom-right-radius",
1566 GTK_CSS_PROPERTY_BORDER_BOTTOM_RIGHT_RADIUS,
1568 GTK_STYLE_PROPERTY_ANIMATED,
1569 border_corner_radius_value_parse,
1571 border_corner_radius_value_compute,
1575 _gtk_css_corner_value_new (_gtk_css_number_value_new (0, GTK_CSS_PX),
1576 _gtk_css_number_value_new (0, GTK_CSS_PX)));
1577 gtk_css_style_property_register ("border-bottom-left-radius",
1578 GTK_CSS_PROPERTY_BORDER_BOTTOM_LEFT_RADIUS,
1580 GTK_STYLE_PROPERTY_ANIMATED,
1581 border_corner_radius_value_parse,
1583 border_corner_radius_value_compute,
1587 _gtk_css_corner_value_new (_gtk_css_number_value_new (0, GTK_CSS_PX),
1588 _gtk_css_number_value_new (0, GTK_CSS_PX)));
1590 gtk_css_style_property_register ("outline-style",
1591 GTK_CSS_PROPERTY_OUTLINE_STYLE,
1592 GTK_TYPE_BORDER_STYLE,
1598 assign_border_style,
1600 _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE));
1601 gtk_css_style_property_register ("outline-width",
1602 GTK_CSS_PROPERTY_OUTLINE_WIDTH,
1604 GTK_STYLE_PROPERTY_ANIMATED,
1607 compute_border_width,
1608 query_length_as_int,
1609 assign_length_from_int,
1611 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1612 gtk_css_style_property_register ("outline-offset",
1613 GTK_CSS_PROPERTY_OUTLINE_OFFSET,
1619 query_length_as_int,
1620 assign_length_from_int,
1622 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1624 gtk_css_style_property_register ("background-clip",
1625 GTK_CSS_PROPERTY_BACKGROUND_CLIP,
1634 _gtk_css_area_value_new (GTK_CSS_AREA_BORDER_BOX));
1635 gtk_css_style_property_register ("background-origin",
1636 GTK_CSS_PROPERTY_BACKGROUND_ORIGIN,
1645 _gtk_css_area_value_new (GTK_CSS_AREA_PADDING_BOX));
1646 gtk_css_style_property_register ("background-size",
1647 GTK_CSS_PROPERTY_BACKGROUND_SIZE,
1650 background_size_parse,
1651 background_size_print,
1652 background_size_compute,
1656 _gtk_css_value_new_from_background_size (&default_background_size));
1657 gtk_css_style_property_register ("background-position",
1658 GTK_CSS_PROPERTY_BACKGROUND_POSITION,
1661 background_position_parse,
1662 background_position_print,
1663 background_position_compute,
1667 _gtk_css_value_new_from_background_position (&default_background_position));
1669 gtk_css_style_property_register ("border-top-color",
1670 GTK_CSS_PROPERTY_BORDER_TOP_COLOR,
1672 GTK_STYLE_PROPERTY_ANIMATED,
1679 _gtk_css_value_new_take_symbolic_color (
1680 gtk_symbolic_color_ref (
1681 _gtk_symbolic_color_get_current_color ())));
1682 gtk_css_style_property_register ("border-right-color",
1683 GTK_CSS_PROPERTY_BORDER_RIGHT_COLOR,
1685 GTK_STYLE_PROPERTY_ANIMATED,
1692 _gtk_css_value_new_take_symbolic_color (
1693 gtk_symbolic_color_ref (
1694 _gtk_symbolic_color_get_current_color ())));
1695 gtk_css_style_property_register ("border-bottom-color",
1696 GTK_CSS_PROPERTY_BORDER_BOTTOM_COLOR,
1698 GTK_STYLE_PROPERTY_ANIMATED,
1705 _gtk_css_value_new_take_symbolic_color (
1706 gtk_symbolic_color_ref (
1707 _gtk_symbolic_color_get_current_color ())));
1708 gtk_css_style_property_register ("border-left-color",
1709 GTK_CSS_PROPERTY_BORDER_LEFT_COLOR,
1711 GTK_STYLE_PROPERTY_ANIMATED,
1718 _gtk_css_value_new_take_symbolic_color (
1719 gtk_symbolic_color_ref (
1720 _gtk_symbolic_color_get_current_color ())));
1721 gtk_css_style_property_register ("outline-color",
1722 GTK_CSS_PROPERTY_OUTLINE_COLOR,
1724 GTK_STYLE_PROPERTY_ANIMATED,
1731 _gtk_css_value_new_take_symbolic_color (
1732 gtk_symbolic_color_ref (
1733 _gtk_symbolic_color_get_current_color ())));
1735 gtk_css_style_property_register ("background-repeat",
1736 GTK_CSS_PROPERTY_BACKGROUND_REPEAT,
1737 GTK_TYPE_CSS_BACKGROUND_REPEAT,
1739 background_repeat_value_parse,
1740 background_repeat_value_print,
1745 _gtk_css_value_new_from_enum (GTK_TYPE_CSS_BACKGROUND_REPEAT,
1746 GTK_CSS_BACKGROUND_REPEAT |
1747 (GTK_CSS_BACKGROUND_REPEAT << GTK_CSS_BACKGROUND_REPEAT_SHIFT)));
1748 gtk_css_style_property_register ("background-image",
1749 GTK_CSS_PROPERTY_BACKGROUND_IMAGE,
1750 CAIRO_GOBJECT_TYPE_PATTERN,
1751 GTK_STYLE_PROPERTY_ANIMATED,
1752 css_image_value_parse,
1754 css_image_value_compute,
1755 css_image_value_query,
1756 css_image_value_assign,
1758 _gtk_css_image_value_new (NULL));
1760 gtk_css_style_property_register ("border-image-source",
1761 GTK_CSS_PROPERTY_BORDER_IMAGE_SOURCE,
1762 CAIRO_GOBJECT_TYPE_PATTERN,
1763 GTK_STYLE_PROPERTY_ANIMATED,
1764 css_image_value_parse,
1766 css_image_value_compute,
1767 css_image_value_query,
1768 css_image_value_assign,
1770 _gtk_css_image_value_new (NULL));
1771 gtk_css_style_property_register ("border-image-repeat",
1772 GTK_CSS_PROPERTY_BORDER_IMAGE_REPEAT,
1773 GTK_TYPE_CSS_BORDER_IMAGE_REPEAT,
1775 border_image_repeat_parse,
1781 _gtk_css_value_new_from_border_image_repeat (&border_image_repeat));
1783 /* XXX: The initial value is wrong, it should be 100% */
1784 gtk_css_style_property_register ("border-image-slice",
1785 GTK_CSS_PROPERTY_BORDER_IMAGE_SLICE,
1788 border_image_slice_parse,
1794 _gtk_css_value_new_from_boxed (GTK_TYPE_BORDER, &border_of_ones));
1795 gtk_css_style_property_register ("border-image-width",
1796 GTK_CSS_PROPERTY_BORDER_IMAGE_WIDTH,
1799 border_image_width_parse,
1805 _gtk_css_value_new_from_boxed (GTK_TYPE_BORDER, NULL));
1807 gtk_css_style_property_register ("transition-property",
1808 GTK_CSS_PROPERTY_TRANSITION_PROPERTY,
1811 transition_property_parse,
1817 _gtk_css_array_value_new (_gtk_css_ident_value_new ("all")));
1818 gtk_css_style_property_register ("transition-duration",
1819 GTK_CSS_PROPERTY_TRANSITION_DURATION,
1822 transition_time_parse,
1828 _gtk_css_array_value_new (_gtk_css_number_value_new (0, GTK_CSS_S)));
1829 gtk_css_style_property_register ("transition-timing-function",
1830 GTK_CSS_PROPERTY_TRANSITION_TIMING_FUNCTION,
1833 transition_timing_function_parse,
1839 _gtk_css_array_value_new (
1840 _gtk_css_ease_value_new_cubic_bezier (0.25, 0.1, 0.25, 1.0)));
1841 gtk_css_style_property_register ("transition-delay",
1842 GTK_CSS_PROPERTY_TRANSITION_DELAY,
1845 transition_time_parse,
1851 _gtk_css_array_value_new (_gtk_css_number_value_new (0, GTK_CSS_S)));
1853 gtk_css_style_property_register ("engine",
1854 GTK_CSS_PROPERTY_ENGINE,
1855 GTK_TYPE_THEMING_ENGINE,
1863 _gtk_css_value_new_from_theming_engine (gtk_theming_engine_load (NULL)));
1864 gtk_css_style_property_register ("transition",
1865 GTK_CSS_PROPERTY_TRANSITION,
1866 GTK_TYPE_ANIMATION_DESCRIPTION,
1874 _gtk_css_value_new_from_boxed (GTK_TYPE_ANIMATION_DESCRIPTION, NULL));
1876 /* Private property holding the binding sets */
1877 gtk_css_style_property_register ("gtk-key-bindings",
1878 GTK_CSS_PROPERTY_GTK_KEY_BINDINGS,
1881 bindings_value_parse,
1884 bindings_value_query,
1885 bindings_value_assign,
1887 _gtk_css_array_value_new (NULL));