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 "gtkcsseasevalueprivate.h"
45 #include "gtkcssimagegradientprivate.h"
46 #include "gtkcssimageprivate.h"
47 #include "gtkcssimagevalueprivate.h"
48 #include "gtkcssenumvalueprivate.h"
49 #include "gtkcssnumbervalueprivate.h"
50 #include "gtkcssrgbavalueprivate.h"
51 #include "gtkcssshadowvalueprivate.h"
52 #include "gtkcssstringvalueprivate.h"
53 #include "gtksymboliccolorprivate.h"
54 #include "gtkthemingengine.h"
55 #include "gtktypebuiltins.h"
56 #include "gtkwin32themeprivate.h"
58 /*** REGISTRATION ***/
61 GTK_STYLE_PROPERTY_INHERIT = (1 << 0),
62 GTK_STYLE_PROPERTY_ANIMATED = (1 << 1)
63 } GtkStylePropertyFlags;
66 gtk_css_style_property_register (const char * name,
69 GtkStylePropertyFlags flags,
70 GtkCssStylePropertyParseFunc parse_value,
71 GtkCssStylePropertyPrintFunc print_value,
72 GtkCssStylePropertyComputeFunc compute_value,
73 GtkCssStylePropertyQueryFunc query_value,
74 GtkCssStylePropertyAssignFunc assign_value,
75 GtkCssStylePropertyEqualFunc equal_func,
76 GtkCssValue * initial_value)
78 GtkCssStyleProperty *node;
80 g_assert (initial_value != NULL);
81 g_assert (parse_value != NULL);
82 g_assert (value_type == G_TYPE_NONE || query_value != NULL);
83 g_assert (value_type == G_TYPE_NONE || assign_value != NULL);
85 node = g_object_new (GTK_TYPE_CSS_STYLE_PROPERTY,
86 "value-type", value_type,
87 "animated", (flags & GTK_STYLE_PROPERTY_ANIMATED) ? TRUE : FALSE,
88 "inherit", (flags & GTK_STYLE_PROPERTY_INHERIT) ? TRUE : FALSE,
89 "initial-value", initial_value,
93 node->parse_value = parse_value;
95 node->print_value = print_value;
97 node->compute_value = compute_value;
98 node->query_value = query_value;
99 node->assign_value = assign_value;
101 node->equal_func = equal_func;
103 _gtk_css_value_unref (initial_value);
105 g_assert (_gtk_css_style_property_get_id (node) == expected_id);
108 /*** IMPLEMENTATIONS ***/
111 query_simple (GtkCssStyleProperty *property,
112 const GtkCssValue *css_value,
115 _gtk_css_value_init_gvalue (css_value, value);
119 assign_simple (GtkCssStyleProperty *property,
122 return _gtk_css_value_new_from_gvalue (value);
126 query_length_as_int (GtkCssStyleProperty *property,
127 const GtkCssValue *css_value,
130 g_value_init (value, G_TYPE_INT);
131 g_value_set_int (value, round (_gtk_css_number_value_get (css_value, 100)));
135 assign_length_from_int (GtkCssStyleProperty *property,
138 return _gtk_css_number_value_new (g_value_get_int (value), GTK_CSS_PX);
142 query_length_as_double (GtkCssStyleProperty *property,
143 const GtkCssValue *css_value,
146 g_value_init (value, G_TYPE_DOUBLE);
147 g_value_set_double (value, _gtk_css_number_value_get (css_value, 100));
151 assign_length_from_double (GtkCssStyleProperty *property,
154 return _gtk_css_number_value_new (g_value_get_double (value), GTK_CSS_PX);
158 color_parse (GtkCssStyleProperty *property,
159 GtkCssParser *parser,
162 GtkSymbolicColor *symbolic;
164 if (_gtk_css_parser_try (parser, "currentcolor", TRUE))
166 symbolic = gtk_symbolic_color_ref (_gtk_symbolic_color_get_current_color ());
170 symbolic = _gtk_css_parser_read_symbolic_color (parser);
171 if (symbolic == NULL)
175 return _gtk_css_value_new_take_symbolic_color (symbolic);
179 color_compute (GtkCssStyleProperty *property,
180 GtkStyleContext *context,
181 GtkCssValue *specified)
183 return _gtk_css_rgba_value_compute_from_symbolic (specified,
184 _gtk_css_style_property_get_initial_value (property),
190 color_property_compute (GtkCssStyleProperty *property,
191 GtkStyleContext *context,
192 GtkCssValue *specified)
196 value = _gtk_css_rgba_value_compute_from_symbolic (specified,
197 _gtk_css_style_property_get_initial_value (property),
200 _gtk_css_rgba_value_get_rgba (value);
205 color_query (GtkCssStyleProperty *property,
206 const GtkCssValue *css_value,
209 g_value_init (value, GDK_TYPE_RGBA);
210 g_value_set_boxed (value, _gtk_css_rgba_value_get_rgba (css_value));
214 color_assign (GtkCssStyleProperty *property,
217 return _gtk_css_rgba_value_new_from_rgba (g_value_get_boxed (value));
221 font_family_parse (GtkCssStyleProperty *property,
222 GtkCssParser *parser,
229 /* We don't special case generic families. Pango should do
232 names = g_ptr_array_new ();
235 name = _gtk_css_parser_try_ident (parser, TRUE);
238 GString *string = g_string_new (name);
240 while ((name = _gtk_css_parser_try_ident (parser, TRUE)))
242 g_string_append_c (string, ' ');
243 g_string_append (string, name);
246 name = g_string_free (string, FALSE);
250 name = _gtk_css_parser_read_string (parser);
253 g_ptr_array_free (names, TRUE);
258 g_ptr_array_add (names, _gtk_css_string_value_new_take (name));
259 } while (_gtk_css_parser_try (parser, ",", TRUE));
261 result = _gtk_css_array_value_new ((GtkCssValue **) names->pdata, names->len);
262 g_ptr_array_free (names, TRUE);
267 font_family_query (GtkCssStyleProperty *property,
268 const GtkCssValue *css_value,
274 array = g_ptr_array_new ();
276 for (i = 0; i < _gtk_css_array_value_get_n_values (css_value); i++)
278 g_ptr_array_add (array, g_strdup (_gtk_css_string_value_get (_gtk_css_array_value_get_nth (css_value, i))));
282 g_ptr_array_add (array, NULL);
284 g_value_init (value, G_TYPE_STRV);
285 g_value_set_boxed (value, g_ptr_array_free (array, FALSE));
289 font_family_assign (GtkCssStyleProperty *property,
292 const char **names = g_value_get_boxed (value);
296 array = g_ptr_array_new ();
298 for (names = g_value_get_boxed (value); *names; names++)
300 g_ptr_array_add (array, _gtk_css_string_value_new (*names));
303 result = _gtk_css_array_value_new ((GtkCssValue **) array->pdata, array->len);
304 g_ptr_array_free (array, TRUE);
309 parse_pango_style (GtkCssStyleProperty *property,
310 GtkCssParser *parser,
313 GtkCssValue *value = _gtk_css_font_style_value_try_parse (parser);
316 _gtk_css_parser_error (parser, "unknown value for property");
322 query_pango_style (GtkCssStyleProperty *property,
323 const GtkCssValue *css_value,
326 g_value_init (value, PANGO_TYPE_STYLE);
327 g_value_set_enum (value, _gtk_css_font_style_value_get (css_value));
331 assign_pango_style (GtkCssStyleProperty *property,
334 return _gtk_css_font_style_value_new (g_value_get_enum (value));
338 parse_pango_weight (GtkCssStyleProperty *property,
339 GtkCssParser *parser,
342 GtkCssValue *value = _gtk_css_font_weight_value_try_parse (parser);
345 _gtk_css_parser_error (parser, "unknown value for property");
351 query_pango_weight (GtkCssStyleProperty *property,
352 const GtkCssValue *css_value,
355 g_value_init (value, PANGO_TYPE_WEIGHT);
356 g_value_set_enum (value, _gtk_css_font_weight_value_get (css_value));
360 assign_pango_weight (GtkCssStyleProperty *property,
363 return _gtk_css_font_weight_value_new (g_value_get_enum (value));
367 parse_pango_variant (GtkCssStyleProperty *property,
368 GtkCssParser *parser,
371 GtkCssValue *value = _gtk_css_font_variant_value_try_parse (parser);
374 _gtk_css_parser_error (parser, "unknown value for property");
380 query_pango_variant (GtkCssStyleProperty *property,
381 const GtkCssValue *css_value,
384 g_value_init (value, PANGO_TYPE_VARIANT);
385 g_value_set_enum (value, _gtk_css_font_variant_value_get (css_value));
389 assign_pango_variant (GtkCssStyleProperty *property,
392 return _gtk_css_font_variant_value_new (g_value_get_enum (value));
396 parse_border_style (GtkCssStyleProperty *property,
397 GtkCssParser *parser,
400 GtkCssValue *value = _gtk_css_border_style_value_try_parse (parser);
403 _gtk_css_parser_error (parser, "unknown value for property");
409 query_border_style (GtkCssStyleProperty *property,
410 const GtkCssValue *css_value,
413 g_value_init (value, GTK_TYPE_BORDER_STYLE);
414 g_value_set_enum (value, _gtk_css_border_style_value_get (css_value));
418 assign_border_style (GtkCssStyleProperty *property,
421 return _gtk_css_border_style_value_new (g_value_get_enum (value));
425 parse_css_area (GtkCssStyleProperty *property,
426 GtkCssParser *parser,
429 GtkCssValue *value = _gtk_css_area_value_try_parse (parser);
432 _gtk_css_parser_error (parser, "unknown value for property");
438 bindings_value_parse (GtkCssStyleProperty *property,
439 GtkCssParser *parser,
443 GtkBindingSet *binding_set;
446 array = g_ptr_array_new ();
449 name = _gtk_css_parser_try_ident (parser, TRUE);
452 _gtk_css_parser_error (parser, "Not a valid binding name");
453 g_ptr_array_free (array, TRUE);
457 binding_set = gtk_binding_set_find (name);
461 _gtk_css_parser_error (parser, "No binding set named '%s'", name);
466 g_ptr_array_add (array, binding_set);
469 while (_gtk_css_parser_try (parser, ",", TRUE));
471 return _gtk_css_value_new_take_binding_sets (array);
475 bindings_value_print (GtkCssStyleProperty *property,
476 const GtkCssValue *value,
482 array = _gtk_css_value_get_boxed (value);
484 for (i = 0; i < array->len; i++)
486 GtkBindingSet *binding_set = g_ptr_array_index (array, i);
489 g_string_append (string, ", ");
490 g_string_append (string, binding_set->set_name);
495 shadow_value_parse (GtkCssStyleProperty *property,
496 GtkCssParser *parser,
499 return _gtk_css_shadow_value_parse (parser);
503 shadow_value_compute (GtkCssStyleProperty *property,
504 GtkStyleContext *context,
505 GtkCssValue *specified)
507 return _gtk_css_shadow_value_compute (specified, context);
511 border_corner_radius_value_parse (GtkCssStyleProperty *property,
512 GtkCssParser *parser,
515 GtkCssBorderCornerRadius corner;
517 if (!_gtk_css_parser_read_number (parser,
519 GTK_CSS_POSITIVE_ONLY
520 | GTK_CSS_PARSE_PERCENT
521 | GTK_CSS_NUMBER_AS_PIXELS
522 | GTK_CSS_PARSE_LENGTH))
525 if (!_gtk_css_parser_has_number (parser))
526 corner.vertical = corner.horizontal;
527 else if (!_gtk_css_parser_read_number (parser,
529 GTK_CSS_POSITIVE_ONLY
530 | GTK_CSS_PARSE_PERCENT
531 | GTK_CSS_NUMBER_AS_PIXELS
532 | GTK_CSS_PARSE_LENGTH))
535 return _gtk_css_value_new_from_border_corner_radius (&corner);
539 border_corner_radius_value_print (GtkCssStyleProperty *property,
540 const GtkCssValue *value,
543 const GtkCssBorderCornerRadius *corner;
545 corner = _gtk_css_value_get_border_corner_radius (value);
547 _gtk_css_number_print (&corner->horizontal, string);
549 if (!_gtk_css_number_equal (&corner->horizontal, &corner->vertical))
551 g_string_append_c (string, ' ');
552 _gtk_css_number_print (&corner->vertical, string);
557 css_image_value_parse (GtkCssStyleProperty *property,
558 GtkCssParser *parser,
563 if (_gtk_css_parser_try (parser, "none", TRUE))
567 image = _gtk_css_image_new_parse (parser, base);
572 return _gtk_css_image_value_new (image);
576 css_image_value_compute (GtkCssStyleProperty *property,
577 GtkStyleContext *context,
578 GtkCssValue *specified)
580 GtkCssImage *image, *computed;
582 image = _gtk_css_image_value_get_image (specified);
585 return _gtk_css_value_ref (specified);
587 computed = _gtk_css_image_compute (image, context);
589 if (computed == image)
591 g_object_unref (computed);
592 return _gtk_css_value_ref (specified);
595 return _gtk_css_image_value_new (computed);
599 css_image_value_query (GtkCssStyleProperty *property,
600 const GtkCssValue *css_value,
603 GtkCssImage *image = _gtk_css_image_value_get_image (css_value);
604 cairo_pattern_t *pattern;
605 cairo_surface_t *surface;
606 cairo_matrix_t matrix;
608 g_value_init (value, CAIRO_GOBJECT_TYPE_PATTERN);
610 if (GTK_IS_CSS_IMAGE_GRADIENT (image))
611 g_value_set_boxed (value, GTK_CSS_IMAGE_GRADIENT (image)->pattern);
612 else if (image != NULL)
614 double width, height;
616 /* the 100, 100 is rather random */
617 _gtk_css_image_get_concrete_size (image, 0, 0, 100, 100, &width, &height);
618 surface = _gtk_css_image_get_surface (image, NULL, width, height);
619 pattern = cairo_pattern_create_for_surface (surface);
620 cairo_matrix_init_scale (&matrix, width, height);
621 cairo_pattern_set_matrix (pattern, &matrix);
622 cairo_surface_destroy (surface);
623 g_value_take_boxed (value, pattern);
628 css_image_value_assign (GtkCssStyleProperty *property,
631 g_warning ("FIXME: assigning images is not implemented");
632 return _gtk_css_image_value_new (NULL);
636 font_size_parse (GtkCssStyleProperty *property,
637 GtkCssParser *parser,
642 if (!_gtk_css_parser_try_double (parser, &d))
644 _gtk_css_parser_error (parser, "Expected a number");
648 return _gtk_css_number_value_new (d, GTK_CSS_PX);
652 font_size_compute (GtkCssStyleProperty *property,
653 GtkStyleContext *context,
654 GtkCssValue *specified)
656 return _gtk_css_number_value_compute (specified, context);
660 outline_parse (GtkCssStyleProperty *property,
661 GtkCssParser *parser,
666 if (!_gtk_css_parser_try_int (parser, &i))
668 _gtk_css_parser_error (parser, "Expected an integer");
672 return _gtk_css_value_new_from_int (i);
676 border_image_repeat_parse (GtkCssStyleProperty *property,
677 GtkCssParser *parser,
680 GValue value = G_VALUE_INIT;
683 g_value_init (&value, GTK_TYPE_CSS_BORDER_IMAGE_REPEAT);
684 if (!_gtk_css_style_parse_value (&value, parser, base))
686 g_value_unset (&value);
690 result = _gtk_css_value_new_from_gvalue (&value);
691 g_value_unset (&value);
697 border_image_slice_parse (GtkCssStyleProperty *property,
698 GtkCssParser *parser,
701 GValue value = G_VALUE_INIT;
704 g_value_init (&value, GTK_TYPE_BORDER);
705 if (!_gtk_css_style_parse_value (&value, parser, base))
707 g_value_unset (&value);
711 result = _gtk_css_value_new_from_gvalue (&value);
712 g_value_unset (&value);
718 border_image_width_parse (GtkCssStyleProperty *property,
719 GtkCssParser *parser,
722 GValue value = G_VALUE_INIT;
725 g_value_init (&value, GTK_TYPE_BORDER);
726 if (!_gtk_css_style_parse_value (&value, parser, base))
728 g_value_unset (&value);
732 result = _gtk_css_value_new_from_gvalue (&value);
733 g_value_unset (&value);
739 transition_property_parse (GtkCssStyleProperty *property,
740 GtkCssParser *parser,
744 GtkCssValue *result, *value;
746 if (_gtk_css_parser_try (parser, "none", TRUE))
747 return _gtk_css_array_value_new (NULL, 0);
749 names = g_ptr_array_new ();
752 value = _gtk_css_ident_value_try_parse (parser);
756 _gtk_css_parser_error (parser, "Expected an identifier");
757 g_ptr_array_free (names, TRUE);
761 g_ptr_array_add (names, value);
762 } while (_gtk_css_parser_try (parser, ",", TRUE));
764 result = _gtk_css_array_value_new ((GtkCssValue **) names->pdata, names->len);
765 g_ptr_array_free (names, TRUE);
770 transition_time_parse (GtkCssStyleProperty *property,
771 GtkCssParser *parser,
775 GtkCssValue *result, *next;
777 times = g_ptr_array_new ();
780 next = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_TIME);
784 g_ptr_array_free (times, TRUE);
788 g_ptr_array_add (times, next);
789 } while (_gtk_css_parser_try (parser, ",", TRUE));
791 result = _gtk_css_array_value_new ((GtkCssValue **) times->pdata, times->len);
792 g_ptr_array_free (times, TRUE);
797 transition_timing_function_parse (GtkCssStyleProperty *property,
798 GtkCssParser *parser,
802 GtkCssValue *result, *next;
804 funcs = g_ptr_array_new ();
807 next = _gtk_css_ease_value_parse (parser);
811 g_ptr_array_free (funcs, TRUE);
815 g_ptr_array_add (funcs, next);
816 } while (_gtk_css_parser_try (parser, ",", TRUE));
818 result = _gtk_css_array_value_new ((GtkCssValue **) funcs->pdata, funcs->len);
819 g_ptr_array_free (funcs, TRUE);
824 engine_parse (GtkCssStyleProperty *property,
825 GtkCssParser *parser,
828 GtkThemingEngine *engine;
831 if (_gtk_css_parser_try (parser, "none", TRUE))
832 return _gtk_css_value_new_from_theming_engine (gtk_theming_engine_load (NULL));
834 str = _gtk_css_parser_try_ident (parser, TRUE);
837 _gtk_css_parser_error (parser, "Expected a valid theme name");
841 engine = gtk_theming_engine_load (str);
845 _gtk_css_parser_error (parser, "Theming engine '%s' not found", str);
852 return _gtk_css_value_new_from_theming_engine (engine);
856 transition_parse (GtkCssStyleProperty *property,
857 GtkCssParser *parser,
860 GValue value = G_VALUE_INIT;
863 g_value_init (&value, GTK_TYPE_ANIMATION_DESCRIPTION);
864 if (!_gtk_css_style_parse_value (&value, parser, base))
866 g_value_unset (&value);
870 result = _gtk_css_value_new_from_gvalue (&value);
871 g_value_unset (&value);
877 parse_margin (GtkCssStyleProperty *property,
878 GtkCssParser *parser,
881 return _gtk_css_number_value_parse (parser,
882 GTK_CSS_NUMBER_AS_PIXELS
883 | GTK_CSS_PARSE_LENGTH);
887 compute_margin (GtkCssStyleProperty *property,
888 GtkStyleContext *context,
889 GtkCssValue *specified)
891 return _gtk_css_number_value_compute (specified, context);
895 parse_padding (GtkCssStyleProperty *property,
896 GtkCssParser *parser,
899 return _gtk_css_number_value_parse (parser,
900 GTK_CSS_POSITIVE_ONLY
901 | GTK_CSS_NUMBER_AS_PIXELS
902 | GTK_CSS_PARSE_LENGTH);
906 compute_padding (GtkCssStyleProperty *property,
907 GtkStyleContext *context,
908 GtkCssValue *specified)
910 return _gtk_css_number_value_compute (specified, context);
914 parse_border_width (GtkCssStyleProperty *property,
915 GtkCssParser *parser,
918 return _gtk_css_number_value_parse (parser,
919 GTK_CSS_POSITIVE_ONLY
920 | GTK_CSS_NUMBER_AS_PIXELS
921 | GTK_CSS_PARSE_LENGTH);
925 compute_border_width (GtkCssStyleProperty *property,
926 GtkStyleContext *context,
927 GtkCssValue *specified)
929 GtkBorderStyle border_style;
931 /* The -1 is magic that is only true because we register the style
932 * properties directly after the width properties.
934 border_style = _gtk_css_border_style_value_get (_gtk_style_context_peek_property (context, _gtk_css_style_property_get_id (property) - 1));
936 if (border_style == GTK_BORDER_STYLE_NONE ||
937 border_style == GTK_BORDER_STYLE_HIDDEN)
938 return _gtk_css_number_value_new (0, GTK_CSS_PX);
940 return _gtk_css_number_value_compute (specified, context);
944 background_repeat_value_parse (GtkCssStyleProperty *property,
945 GtkCssParser *parser,
948 int repeat, vertical;
950 if (!_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BACKGROUND_REPEAT, &repeat))
952 _gtk_css_parser_error (parser, "Not a valid value");
956 if (repeat <= GTK_CSS_BACKGROUND_REPEAT_MASK)
958 if (_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BACKGROUND_REPEAT, &vertical))
960 if (vertical >= GTK_CSS_BACKGROUND_REPEAT_MASK)
962 _gtk_css_parser_error (parser, "Not a valid 2nd value");
966 repeat |= vertical << GTK_CSS_BACKGROUND_REPEAT_SHIFT;
969 repeat |= repeat << GTK_CSS_BACKGROUND_REPEAT_SHIFT;
972 return _gtk_css_value_new_from_enum (GTK_TYPE_CSS_BACKGROUND_REPEAT, repeat);
976 background_repeat_value_print (GtkCssStyleProperty *property,
977 const GtkCssValue *value,
980 GEnumClass *enum_class;
981 GEnumValue *enum_value;
982 GtkCssBackgroundRepeat repeat;
984 repeat = _gtk_css_value_get_enum (value);
985 enum_class = g_type_class_ref (GTK_TYPE_CSS_BACKGROUND_REPEAT);
986 enum_value = g_enum_get_value (enum_class, repeat);
988 /* only triggers for 'repeat-x' and 'repeat-y' */
990 g_string_append (string, enum_value->value_nick);
993 enum_value = g_enum_get_value (enum_class, GTK_CSS_BACKGROUND_HORIZONTAL (repeat));
994 g_string_append (string, enum_value->value_nick);
996 if (GTK_CSS_BACKGROUND_HORIZONTAL (repeat) != GTK_CSS_BACKGROUND_VERTICAL (repeat))
998 enum_value = g_enum_get_value (enum_class, GTK_CSS_BACKGROUND_VERTICAL (repeat));
999 g_string_append (string, " ");
1000 g_string_append (string, enum_value->value_nick);
1004 g_type_class_unref (enum_class);
1007 static GtkCssValue *
1008 background_size_parse (GtkCssStyleProperty *property,
1009 GtkCssParser *parser,
1012 GtkCssBackgroundSize size = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), FALSE, FALSE};
1014 if (_gtk_css_parser_try (parser, "cover", TRUE))
1016 else if (_gtk_css_parser_try (parser, "contain", TRUE))
1017 size.contain = TRUE;
1020 if (_gtk_css_parser_try (parser, "auto", TRUE))
1021 _gtk_css_number_init (&size.width, 0, GTK_CSS_PX);
1022 else if (!_gtk_css_parser_read_number (parser,
1024 GTK_CSS_POSITIVE_ONLY
1025 | GTK_CSS_PARSE_PERCENT
1026 | GTK_CSS_PARSE_LENGTH))
1029 if (_gtk_css_parser_try (parser, "auto", TRUE))
1030 _gtk_css_number_init (&size.height, 0, GTK_CSS_PX);
1031 else if (_gtk_css_parser_has_number (parser))
1033 if (!_gtk_css_parser_read_number (parser,
1035 GTK_CSS_POSITIVE_ONLY
1036 | GTK_CSS_PARSE_PERCENT
1037 | GTK_CSS_PARSE_LENGTH))
1041 _gtk_css_number_init (&size.height, 0, GTK_CSS_PX);
1044 return _gtk_css_value_new_from_background_size (&size);
1048 background_size_print (GtkCssStyleProperty *property,
1049 const GtkCssValue *value,
1052 const GtkCssBackgroundSize *size = _gtk_css_value_get_background_size (value);
1055 g_string_append (string, "cover");
1056 else if (size->contain)
1057 g_string_append (string, "contain");
1060 if (size->width.value == 0)
1061 g_string_append (string, "auto");
1063 _gtk_css_number_print (&size->width, string);
1065 if (size->height.value != 0)
1067 g_string_append (string, " ");
1068 _gtk_css_number_print (&size->height, string);
1073 static GtkCssValue *
1074 background_size_compute (GtkCssStyleProperty *property,
1075 GtkStyleContext *context,
1076 GtkCssValue *specified)
1078 const GtkCssBackgroundSize *ssize = _gtk_css_value_get_background_size (specified);
1079 GtkCssBackgroundSize csize;
1082 csize.cover = ssize->cover;
1083 csize.contain = ssize->contain;
1084 changed = _gtk_css_number_compute (&csize.width,
1087 changed |= _gtk_css_number_compute (&csize.height,
1091 return _gtk_css_value_new_from_background_size (&csize);
1092 return _gtk_css_value_ref (specified);
1095 static GtkCssValue *
1096 background_position_parse (GtkCssStyleProperty *property,
1097 GtkCssParser *parser,
1100 static const struct {
1103 gboolean horizontal;
1106 { "left", 0, TRUE, FALSE },
1107 { "right", 100, TRUE, FALSE },
1108 { "center", 50, TRUE, TRUE },
1109 { "top", 0, FALSE, TRUE },
1110 { "bottom", 100, FALSE, TRUE },
1111 { NULL , 0, TRUE, FALSE }, /* used for numbers */
1112 { NULL , 50, TRUE, TRUE } /* used for no value */
1114 GtkCssBackgroundPosition pos;
1115 GtkCssNumber *missing;
1116 guint first, second;
1118 for (first = 0; names[first].name != NULL; first++)
1120 if (_gtk_css_parser_try (parser, names[first].name, TRUE))
1122 if (names[first].horizontal)
1124 _gtk_css_number_init (&pos.x, names[first].percentage, GTK_CSS_PERCENT);
1129 _gtk_css_number_init (&pos.y, names[first].percentage, GTK_CSS_PERCENT);
1135 if (names[first].name == NULL)
1138 if (!_gtk_css_parser_read_number (parser,
1140 GTK_CSS_PARSE_PERCENT
1141 | GTK_CSS_PARSE_LENGTH))
1145 for (second = 0; names[second].name != NULL; second++)
1147 if (_gtk_css_parser_try (parser, names[second].name, TRUE))
1149 _gtk_css_number_init (missing, names[second].percentage, GTK_CSS_PERCENT);
1154 if (names[second].name == NULL)
1156 if (_gtk_css_parser_has_number (parser))
1158 if (missing != &pos.y)
1160 _gtk_css_parser_error (parser, "Invalid combination of values");
1163 if (!_gtk_css_parser_read_number (parser,
1165 GTK_CSS_PARSE_PERCENT
1166 | GTK_CSS_PARSE_LENGTH))
1172 _gtk_css_number_init (missing, 50, GTK_CSS_PERCENT);
1177 if ((names[first].horizontal && !names[second].vertical) ||
1178 (!names[first].horizontal && !names[second].horizontal))
1180 _gtk_css_parser_error (parser, "Invalid combination of values");
1185 return _gtk_css_value_new_from_background_position (&pos);
1189 background_position_print (GtkCssStyleProperty *property,
1190 const GtkCssValue *value,
1193 const GtkCssBackgroundPosition *pos = _gtk_css_value_get_background_position (value);
1194 static const GtkCssNumber center = GTK_CSS_NUMBER_INIT (50, GTK_CSS_PERCENT);
1195 static const struct {
1198 GtkCssNumber number;
1200 { "left", "top", GTK_CSS_NUMBER_INIT (0, GTK_CSS_PERCENT) },
1201 { "right", "bottom", GTK_CSS_NUMBER_INIT (100, GTK_CSS_PERCENT) }
1205 if (_gtk_css_number_equal (&pos->x, ¢er))
1207 if (_gtk_css_number_equal (&pos->y, ¢er))
1209 g_string_append (string, "center");
1215 for (i = 0; i < G_N_ELEMENTS (values); i++)
1217 if (_gtk_css_number_equal (&pos->x, &values[i].number))
1219 g_string_append (string, values[i].x_name);
1223 if (i == G_N_ELEMENTS (values))
1224 _gtk_css_number_print (&pos->x, string);
1226 if (_gtk_css_number_equal (&pos->y, ¢er))
1229 g_string_append_c (string, ' ');
1232 for (i = 0; i < G_N_ELEMENTS (values); i++)
1234 if (_gtk_css_number_equal (&pos->y, &values[i].number))
1236 g_string_append (string, values[i].y_name);
1240 if (i == G_N_ELEMENTS (values))
1242 if (_gtk_css_number_equal (&pos->x, ¢er))
1243 g_string_append (string, "center ");
1244 _gtk_css_number_print (&pos->y, string);
1248 static GtkCssValue *
1249 background_position_compute (GtkCssStyleProperty *property,
1250 GtkStyleContext *context,
1251 GtkCssValue *specified)
1253 const GtkCssBackgroundPosition *spos = _gtk_css_value_get_background_position (specified);
1254 GtkCssBackgroundPosition cpos;
1257 changed = _gtk_css_number_compute (&cpos.x,
1260 changed |= _gtk_css_number_compute (&cpos.y,
1264 return _gtk_css_value_new_from_background_position (&cpos);
1265 return _gtk_css_value_ref (specified);
1268 /*** REGISTRATION ***/
1270 static GtkSymbolicColor *
1271 gtk_symbolic_color_new_rgba (double red,
1276 GdkRGBA rgba = { red, green, blue, alpha };
1278 return gtk_symbolic_color_new_literal (&rgba);
1282 _gtk_css_style_property_init_properties (void)
1285 GtkCssBackgroundSize default_background_size = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), FALSE, FALSE };
1286 GtkCssBackgroundPosition default_background_position = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PERCENT), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PERCENT)};
1287 GtkCssBorderCornerRadius no_corner_radius = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX) };
1288 GtkBorder border_of_ones = { 1, 1, 1, 1 };
1289 GtkCssBorderImageRepeat border_image_repeat = { GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_STRETCH };
1291 /* Initialize "color" and "font-size" first,
1292 * so that when computing values later they are
1293 * done first. That way, 'currentColor' and font
1294 * sizes in em can be looked up properly */
1295 gtk_css_style_property_register ("color",
1296 GTK_CSS_PROPERTY_COLOR,
1298 GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
1301 color_property_compute,
1305 _gtk_css_value_new_take_symbolic_color (
1306 gtk_symbolic_color_new_rgba (1, 1, 1, 1)));
1307 gtk_css_style_property_register ("font-size",
1308 GTK_CSS_PROPERTY_FONT_SIZE,
1310 GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
1314 query_length_as_double,
1315 assign_length_from_double,
1317 /* XXX: This should be 'normal' */
1318 _gtk_css_number_value_new (10.0, GTK_CSS_PX));
1320 /* properties that aren't referenced when computing values
1322 gtk_css_style_property_register ("background-color",
1323 GTK_CSS_PROPERTY_BACKGROUND_COLOR,
1325 GTK_STYLE_PROPERTY_ANIMATED,
1332 _gtk_css_value_new_take_symbolic_color (
1333 gtk_symbolic_color_new_rgba (0, 0, 0, 0)));
1335 value = _gtk_css_string_value_new ("Sans");
1336 gtk_css_style_property_register ("font-family",
1337 GTK_CSS_PROPERTY_FONT_FAMILY,
1339 GTK_STYLE_PROPERTY_INHERIT,
1346 _gtk_css_array_value_new (&value, 1));
1347 gtk_css_style_property_register ("font-style",
1348 GTK_CSS_PROPERTY_FONT_STYLE,
1350 GTK_STYLE_PROPERTY_INHERIT,
1357 _gtk_css_font_style_value_new (PANGO_STYLE_NORMAL));
1358 gtk_css_style_property_register ("font-variant",
1359 GTK_CSS_PROPERTY_FONT_VARIANT,
1361 GTK_STYLE_PROPERTY_INHERIT,
1362 parse_pango_variant,
1365 query_pango_variant,
1366 assign_pango_variant,
1368 _gtk_css_font_variant_value_new (PANGO_VARIANT_NORMAL));
1369 gtk_css_style_property_register ("font-weight",
1370 GTK_CSS_PROPERTY_FONT_WEIGHT,
1372 GTK_STYLE_PROPERTY_INHERIT,
1377 assign_pango_weight,
1379 _gtk_css_font_weight_value_new (PANGO_WEIGHT_NORMAL));
1381 gtk_css_style_property_register ("text-shadow",
1382 GTK_CSS_PROPERTY_TEXT_SHADOW,
1384 GTK_STYLE_PROPERTY_INHERIT,
1387 shadow_value_compute,
1391 _gtk_css_shadow_value_new_none ());
1393 gtk_css_style_property_register ("icon-shadow",
1394 GTK_CSS_PROPERTY_ICON_SHADOW,
1396 GTK_STYLE_PROPERTY_INHERIT,
1399 shadow_value_compute,
1403 _gtk_css_shadow_value_new_none ());
1405 gtk_css_style_property_register ("box-shadow",
1406 GTK_CSS_PROPERTY_BOX_SHADOW,
1411 shadow_value_compute,
1415 _gtk_css_shadow_value_new_none ());
1417 gtk_css_style_property_register ("margin-top",
1418 GTK_CSS_PROPERTY_MARGIN_TOP,
1420 GTK_STYLE_PROPERTY_ANIMATED,
1424 query_length_as_int,
1425 assign_length_from_int,
1427 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1428 gtk_css_style_property_register ("margin-left",
1429 GTK_CSS_PROPERTY_MARGIN_LEFT,
1431 GTK_STYLE_PROPERTY_ANIMATED,
1435 query_length_as_int,
1436 assign_length_from_int,
1438 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1439 gtk_css_style_property_register ("margin-bottom",
1440 GTK_CSS_PROPERTY_MARGIN_BOTTOM,
1442 GTK_STYLE_PROPERTY_ANIMATED,
1446 query_length_as_int,
1447 assign_length_from_int,
1449 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1450 gtk_css_style_property_register ("margin-right",
1451 GTK_CSS_PROPERTY_MARGIN_RIGHT,
1453 GTK_STYLE_PROPERTY_ANIMATED,
1457 query_length_as_int,
1458 assign_length_from_int,
1460 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1461 gtk_css_style_property_register ("padding-top",
1462 GTK_CSS_PROPERTY_PADDING_TOP,
1464 GTK_STYLE_PROPERTY_ANIMATED,
1468 query_length_as_int,
1469 assign_length_from_int,
1471 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1472 gtk_css_style_property_register ("padding-left",
1473 GTK_CSS_PROPERTY_PADDING_LEFT,
1475 GTK_STYLE_PROPERTY_ANIMATED,
1479 query_length_as_int,
1480 assign_length_from_int,
1482 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1483 gtk_css_style_property_register ("padding-bottom",
1484 GTK_CSS_PROPERTY_PADDING_BOTTOM,
1486 GTK_STYLE_PROPERTY_ANIMATED,
1490 query_length_as_int,
1491 assign_length_from_int,
1493 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1494 gtk_css_style_property_register ("padding-right",
1495 GTK_CSS_PROPERTY_PADDING_RIGHT,
1497 GTK_STYLE_PROPERTY_ANIMATED,
1501 query_length_as_int,
1502 assign_length_from_int,
1504 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1505 /* IMPORTANT: compute_border_width() requires that the border-width
1506 * properties be immeditaly followed by the border-style properties
1508 gtk_css_style_property_register ("border-top-style",
1509 GTK_CSS_PROPERTY_BORDER_TOP_STYLE,
1510 GTK_TYPE_BORDER_STYLE,
1516 assign_border_style,
1518 _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE));
1519 gtk_css_style_property_register ("border-top-width",
1520 GTK_CSS_PROPERTY_BORDER_TOP_WIDTH,
1522 GTK_STYLE_PROPERTY_ANIMATED,
1525 compute_border_width,
1526 query_length_as_int,
1527 assign_length_from_int,
1529 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1530 gtk_css_style_property_register ("border-left-style",
1531 GTK_CSS_PROPERTY_BORDER_LEFT_STYLE,
1532 GTK_TYPE_BORDER_STYLE,
1538 assign_border_style,
1540 _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE));
1541 gtk_css_style_property_register ("border-left-width",
1542 GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH,
1544 GTK_STYLE_PROPERTY_ANIMATED,
1547 compute_border_width,
1548 query_length_as_int,
1549 assign_length_from_int,
1551 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1552 gtk_css_style_property_register ("border-bottom-style",
1553 GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE,
1554 GTK_TYPE_BORDER_STYLE,
1560 assign_border_style,
1562 _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE));
1563 gtk_css_style_property_register ("border-bottom-width",
1564 GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH,
1566 GTK_STYLE_PROPERTY_ANIMATED,
1569 compute_border_width,
1570 query_length_as_int,
1571 assign_length_from_int,
1573 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1574 gtk_css_style_property_register ("border-right-style",
1575 GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE,
1576 GTK_TYPE_BORDER_STYLE,
1582 assign_border_style,
1584 _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE));
1585 gtk_css_style_property_register ("border-right-width",
1586 GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH,
1588 GTK_STYLE_PROPERTY_ANIMATED,
1591 compute_border_width,
1592 query_length_as_int,
1593 assign_length_from_int,
1595 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1597 gtk_css_style_property_register ("border-top-left-radius",
1598 GTK_CSS_PROPERTY_BORDER_TOP_LEFT_RADIUS,
1599 GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
1601 border_corner_radius_value_parse,
1602 border_corner_radius_value_print,
1607 _gtk_css_value_new_from_border_corner_radius (&no_corner_radius));
1608 gtk_css_style_property_register ("border-top-right-radius",
1609 GTK_CSS_PROPERTY_BORDER_TOP_RIGHT_RADIUS,
1610 GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
1612 border_corner_radius_value_parse,
1613 border_corner_radius_value_print,
1618 _gtk_css_value_new_from_border_corner_radius (&no_corner_radius));
1619 gtk_css_style_property_register ("border-bottom-right-radius",
1620 GTK_CSS_PROPERTY_BORDER_BOTTOM_RIGHT_RADIUS,
1621 GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
1623 border_corner_radius_value_parse,
1624 border_corner_radius_value_print,
1629 _gtk_css_value_new_from_border_corner_radius (&no_corner_radius));
1630 gtk_css_style_property_register ("border-bottom-left-radius",
1631 GTK_CSS_PROPERTY_BORDER_BOTTOM_LEFT_RADIUS,
1632 GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
1634 border_corner_radius_value_parse,
1635 border_corner_radius_value_print,
1640 _gtk_css_value_new_from_border_corner_radius (&no_corner_radius));
1642 gtk_css_style_property_register ("outline-style",
1643 GTK_CSS_PROPERTY_OUTLINE_STYLE,
1644 GTK_TYPE_BORDER_STYLE,
1650 assign_border_style,
1652 _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE));
1653 gtk_css_style_property_register ("outline-width",
1654 GTK_CSS_PROPERTY_OUTLINE_WIDTH,
1656 GTK_STYLE_PROPERTY_ANIMATED,
1659 compute_border_width,
1660 query_length_as_int,
1661 assign_length_from_int,
1663 _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1664 gtk_css_style_property_register ("outline-offset",
1665 GTK_CSS_PROPERTY_OUTLINE_OFFSET,
1674 _gtk_css_value_new_from_int (0));
1676 gtk_css_style_property_register ("background-clip",
1677 GTK_CSS_PROPERTY_BACKGROUND_CLIP,
1686 _gtk_css_area_value_new (GTK_CSS_AREA_BORDER_BOX));
1687 gtk_css_style_property_register ("background-origin",
1688 GTK_CSS_PROPERTY_BACKGROUND_ORIGIN,
1697 _gtk_css_area_value_new (GTK_CSS_AREA_PADDING_BOX));
1698 gtk_css_style_property_register ("background-size",
1699 GTK_CSS_PROPERTY_BACKGROUND_SIZE,
1702 background_size_parse,
1703 background_size_print,
1704 background_size_compute,
1708 _gtk_css_value_new_from_background_size (&default_background_size));
1709 gtk_css_style_property_register ("background-position",
1710 GTK_CSS_PROPERTY_BACKGROUND_POSITION,
1713 background_position_parse,
1714 background_position_print,
1715 background_position_compute,
1719 _gtk_css_value_new_from_background_position (&default_background_position));
1721 gtk_css_style_property_register ("border-top-color",
1722 GTK_CSS_PROPERTY_BORDER_TOP_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 ())));
1734 gtk_css_style_property_register ("border-right-color",
1735 GTK_CSS_PROPERTY_BORDER_RIGHT_COLOR,
1737 GTK_STYLE_PROPERTY_ANIMATED,
1744 _gtk_css_value_new_take_symbolic_color (
1745 gtk_symbolic_color_ref (
1746 _gtk_symbolic_color_get_current_color ())));
1747 gtk_css_style_property_register ("border-bottom-color",
1748 GTK_CSS_PROPERTY_BORDER_BOTTOM_COLOR,
1750 GTK_STYLE_PROPERTY_ANIMATED,
1757 _gtk_css_value_new_take_symbolic_color (
1758 gtk_symbolic_color_ref (
1759 _gtk_symbolic_color_get_current_color ())));
1760 gtk_css_style_property_register ("border-left-color",
1761 GTK_CSS_PROPERTY_BORDER_LEFT_COLOR,
1763 GTK_STYLE_PROPERTY_ANIMATED,
1770 _gtk_css_value_new_take_symbolic_color (
1771 gtk_symbolic_color_ref (
1772 _gtk_symbolic_color_get_current_color ())));
1773 gtk_css_style_property_register ("outline-color",
1774 GTK_CSS_PROPERTY_OUTLINE_COLOR,
1776 GTK_STYLE_PROPERTY_ANIMATED,
1783 _gtk_css_value_new_take_symbolic_color (
1784 gtk_symbolic_color_ref (
1785 _gtk_symbolic_color_get_current_color ())));
1787 gtk_css_style_property_register ("background-repeat",
1788 GTK_CSS_PROPERTY_BACKGROUND_REPEAT,
1789 GTK_TYPE_CSS_BACKGROUND_REPEAT,
1791 background_repeat_value_parse,
1792 background_repeat_value_print,
1797 _gtk_css_value_new_from_enum (GTK_TYPE_CSS_BACKGROUND_REPEAT,
1798 GTK_CSS_BACKGROUND_REPEAT |
1799 (GTK_CSS_BACKGROUND_REPEAT << GTK_CSS_BACKGROUND_REPEAT_SHIFT)));
1800 gtk_css_style_property_register ("background-image",
1801 GTK_CSS_PROPERTY_BACKGROUND_IMAGE,
1802 CAIRO_GOBJECT_TYPE_PATTERN,
1803 GTK_STYLE_PROPERTY_ANIMATED,
1804 css_image_value_parse,
1806 css_image_value_compute,
1807 css_image_value_query,
1808 css_image_value_assign,
1810 _gtk_css_image_value_new (NULL));
1812 gtk_css_style_property_register ("border-image-source",
1813 GTK_CSS_PROPERTY_BORDER_IMAGE_SOURCE,
1814 CAIRO_GOBJECT_TYPE_PATTERN,
1815 GTK_STYLE_PROPERTY_ANIMATED,
1816 css_image_value_parse,
1818 css_image_value_compute,
1819 css_image_value_query,
1820 css_image_value_assign,
1822 _gtk_css_image_value_new (NULL));
1823 gtk_css_style_property_register ("border-image-repeat",
1824 GTK_CSS_PROPERTY_BORDER_IMAGE_REPEAT,
1825 GTK_TYPE_CSS_BORDER_IMAGE_REPEAT,
1827 border_image_repeat_parse,
1833 _gtk_css_value_new_from_border_image_repeat (&border_image_repeat));
1835 /* XXX: The initial value is wrong, it should be 100% */
1836 gtk_css_style_property_register ("border-image-slice",
1837 GTK_CSS_PROPERTY_BORDER_IMAGE_SLICE,
1840 border_image_slice_parse,
1846 _gtk_css_value_new_from_boxed (GTK_TYPE_BORDER, &border_of_ones));
1847 gtk_css_style_property_register ("border-image-width",
1848 GTK_CSS_PROPERTY_BORDER_IMAGE_WIDTH,
1851 border_image_width_parse,
1857 _gtk_css_value_new_from_boxed (GTK_TYPE_BORDER, NULL));
1859 value = _gtk_css_ident_value_new ("all");
1860 gtk_css_style_property_register ("transition-property",
1861 GTK_CSS_PROPERTY_TRANSITION_PROPERTY,
1864 transition_property_parse,
1870 _gtk_css_array_value_new (&value, 1));
1871 value = _gtk_css_number_value_new (0, GTK_CSS_S);
1872 gtk_css_style_property_register ("transition-duration",
1873 GTK_CSS_PROPERTY_TRANSITION_DURATION,
1876 transition_time_parse,
1882 _gtk_css_array_value_new (&value, 1));
1883 value = _gtk_css_ease_value_new_cubic_bezier (0.25, 0.1, 0.25, 1.0);
1884 gtk_css_style_property_register ("transition-timing-function",
1885 GTK_CSS_PROPERTY_TRANSITION_TIMING_FUNCTION,
1888 transition_timing_function_parse,
1894 _gtk_css_array_value_new (&value, 1));
1895 gtk_css_style_property_register ("transition-delay",
1896 GTK_CSS_PROPERTY_TRANSITION_DELAY,
1899 transition_time_parse,
1905 _gtk_css_array_value_new (&value, 1));
1907 gtk_css_style_property_register ("engine",
1908 GTK_CSS_PROPERTY_ENGINE,
1909 GTK_TYPE_THEMING_ENGINE,
1917 _gtk_css_value_new_from_theming_engine (gtk_theming_engine_load (NULL)));
1918 gtk_css_style_property_register ("transition",
1919 GTK_CSS_PROPERTY_TRANSITION,
1920 GTK_TYPE_ANIMATION_DESCRIPTION,
1928 _gtk_css_value_new_from_boxed (GTK_TYPE_ANIMATION_DESCRIPTION, NULL));
1930 /* Private property holding the binding sets */
1931 gtk_css_style_property_register ("gtk-key-bindings",
1932 GTK_CSS_PROPERTY_GTK_KEY_BINDINGS,
1935 bindings_value_parse,
1936 bindings_value_print,
1941 _gtk_css_value_new_take_binding_sets (NULL));