diff --git a/gtk/Makefile.am b/gtk/Makefile.am index d1b799c744..fe64e4afd1 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -598,6 +598,7 @@ gtk_base_c_sources = \ gtkcssshorthandpropertyimpl.c \ gtkcssstylefuncs.c \ gtkcssstyleproperty.c \ + gtkcssstylepropertyimpl.c \ gtkcsstypes.c \ gtkdialog.c \ gtkdrawingarea.c \ diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c new file mode 100644 index 0000000000..61ab4d5194 --- /dev/null +++ b/gtk/gtkcssstylepropertyimpl.c @@ -0,0 +1,666 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2010 Carlos Garnacho + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include "gtkstylepropertyprivate.h" + +#include +#include + +#include "gtkcssparserprivate.h" +#include "gtkcssstylefuncsprivate.h" +#include "gtkcssstylepropertyprivate.h" +#include "gtkcsstypesprivate.h" +#include "gtkintl.h" +#include "gtkprivatetypebuiltins.h" +#include "gtkstylepropertiesprivate.h" + +/* the actual parsers we have */ +#include "gtkanimationdescription.h" +#include "gtkbindings.h" +#include "gtkgradient.h" +#include "gtkshadowprivate.h" +#include "gtkthemingengine.h" +#include "gtktypebuiltins.h" +#include "gtkwin32themeprivate.h" + +/*** REGISTRATION ***/ + +static void +_gtk_style_property_register (GParamSpec *pspec, + GtkStylePropertyFlags flags, + GtkStylePropertyParser property_parse_func, + GtkStyleParseFunc parse_func, + GtkStylePrintFunc print_func, + const GValue * initial_value) +{ + GtkStyleProperty *node; + GValue initial_fallback = { 0, }; + + if (initial_value == NULL) + { + g_value_init (&initial_fallback, pspec->value_type); + if (pspec->value_type == GTK_TYPE_THEMING_ENGINE) + g_value_set_object (&initial_fallback, gtk_theming_engine_load (NULL)); + else if (pspec->value_type == PANGO_TYPE_FONT_DESCRIPTION) + g_value_take_boxed (&initial_fallback, pango_font_description_from_string ("Sans 10")); + else if (pspec->value_type == GDK_TYPE_RGBA) + { + GdkRGBA color; + gdk_rgba_parse (&color, "pink"); + g_value_set_boxed (&initial_fallback, &color); + } + else if (pspec->value_type == GTK_TYPE_BORDER) + { + g_value_take_boxed (&initial_fallback, gtk_border_new ()); + } + else + g_param_value_set_default (pspec, &initial_fallback); + + initial_value = &initial_fallback; + } + + node = g_object_new (GTK_TYPE_CSS_STYLE_PROPERTY, + "inherit", (flags & GTK_STYLE_PROPERTY_INHERIT) ? TRUE : FALSE, + "initial-value", initial_value, + "name", pspec->name, + "value-type", pspec->value_type, + NULL); + g_assert (node->value_type == pspec->value_type); + GTK_CSS_STYLE_PROPERTY (node)->pspec = pspec; + node->property_parse_func = property_parse_func; + node->parse_func = parse_func; + node->print_func = print_func; + + if (G_IS_VALUE (&initial_fallback)) + g_value_unset (&initial_fallback); +} + +/*** HELPERS ***/ + +static void +string_append_double (GString *string, + double d) +{ + char buf[G_ASCII_DTOSTR_BUF_SIZE]; + + g_ascii_dtostr (buf, sizeof (buf), d); + g_string_append (string, buf); +} + +static void +string_append_string (GString *str, + const char *string) +{ + gsize len; + + g_string_append_c (str, '"'); + + do { + len = strcspn (string, "\"\n\r\f"); + g_string_append (str, string); + string += len; + switch (*string) + { + case '\0': + break; + case '\n': + g_string_append (str, "\\A "); + break; + case '\r': + g_string_append (str, "\\D "); + break; + case '\f': + g_string_append (str, "\\C "); + break; + case '\"': + g_string_append (str, "\\\""); + break; + default: + g_assert_not_reached (); + break; + } + } while (*string); + + g_string_append_c (str, '"'); +} + +/*** IMPLEMENTATIONS ***/ + +static gboolean +font_family_parse (GtkCssParser *parser, + GFile *base, + GValue *value) +{ + GPtrArray *names; + char *name; + + /* We don't special case generic families. Pango should do + * that for us */ + + names = g_ptr_array_new (); + + do { + name = _gtk_css_parser_try_ident (parser, TRUE); + if (name) + { + GString *string = g_string_new (name); + g_free (name); + while ((name = _gtk_css_parser_try_ident (parser, TRUE))) + { + g_string_append_c (string, ' '); + g_string_append (string, name); + g_free (name); + } + name = g_string_free (string, FALSE); + } + else + { + name = _gtk_css_parser_read_string (parser); + if (name == NULL) + { + g_ptr_array_free (names, TRUE); + return FALSE; + } + } + + g_ptr_array_add (names, name); + } while (_gtk_css_parser_try (parser, ",", TRUE)); + + /* NULL-terminate array */ + g_ptr_array_add (names, NULL); + g_value_set_boxed (value, g_ptr_array_free (names, FALSE)); + return TRUE; +} + +static void +font_family_value_print (const GValue *value, + GString *string) +{ + const char **names = g_value_get_boxed (value); + + if (names == NULL || *names == NULL) + { + g_string_append (string, "none"); + return; + } + + string_append_string (string, *names); + names++; + while (*names) + { + g_string_append (string, ", "); + string_append_string (string, *names); + names++; + } +} + +static gboolean +bindings_value_parse (GtkCssParser *parser, + GFile *base, + GValue *value) +{ + GPtrArray *array; + GtkBindingSet *binding_set; + char *name; + + array = g_ptr_array_new (); + + do { + name = _gtk_css_parser_try_ident (parser, TRUE); + if (name == NULL) + { + _gtk_css_parser_error (parser, "Not a valid binding name"); + g_ptr_array_free (array, TRUE); + return FALSE; + } + + binding_set = gtk_binding_set_find (name); + + if (!binding_set) + { + _gtk_css_parser_error (parser, "No binding set named '%s'", name); + g_free (name); + continue; + } + + g_ptr_array_add (array, binding_set); + g_free (name); + } + while (_gtk_css_parser_try (parser, ",", TRUE)); + + g_value_take_boxed (value, array); + + return TRUE; +} + +static void +bindings_value_print (const GValue *value, + GString *string) +{ + GPtrArray *array; + guint i; + + array = g_value_get_boxed (value); + + for (i = 0; i < array->len; i++) + { + GtkBindingSet *binding_set = g_ptr_array_index (array, i); + + if (i > 0) + g_string_append (string, ", "); + g_string_append (string, binding_set->set_name); + } +} + +static gboolean +border_corner_radius_value_parse (GtkCssParser *parser, + GFile *base, + GValue *value) +{ + GtkCssBorderCornerRadius corner; + + if (!_gtk_css_parser_try_double (parser, &corner.horizontal)) + { + _gtk_css_parser_error (parser, "Expected a number"); + return FALSE; + } + else if (corner.horizontal < 0) + goto negative; + + if (!_gtk_css_parser_try_double (parser, &corner.vertical)) + corner.vertical = corner.horizontal; + else if (corner.vertical < 0) + goto negative; + + g_value_set_boxed (value, &corner); + return TRUE; + +negative: + _gtk_css_parser_error (parser, "Border radius values cannot be negative"); + return FALSE; +} + +static void +border_corner_radius_value_print (const GValue *value, + GString *string) +{ + GtkCssBorderCornerRadius *corner; + + corner = g_value_get_boxed (value); + + if (corner == NULL) + { + g_string_append (string, "none"); + return; + } + + string_append_double (string, corner->horizontal); + if (corner->horizontal != corner->vertical) + { + g_string_append_c (string, ' '); + string_append_double (string, corner->vertical); + } +} + +/*** REGISTRATION ***/ + +#define rgba_init(rgba, r, g, b, a) G_STMT_START{ \ + (rgba)->red = (r); \ + (rgba)->green = (g); \ + (rgba)->blue = (b); \ + (rgba)->alpha = (a); \ +}G_STMT_END +void +_gtk_css_style_property_init_properties (void) +{ + GValue value = { 0, }; + char *default_font_family[] = { "Sans", NULL }; + GdkRGBA rgba; + GtkCssBorderCornerRadius no_corner_radius = { 0, }; + + /* note that gtk_style_properties_register_property() calls this function, + * so make sure we're sanely inited to avoid infloops */ + + g_value_init (&value, GDK_TYPE_RGBA); + rgba_init (&rgba, 1, 1, 1, 1); + g_value_set_boxed (&value, &rgba); + _gtk_style_property_register (g_param_spec_boxed ("color", + "Foreground color", + "Foreground color", + GDK_TYPE_RGBA, 0), + GTK_STYLE_PROPERTY_INHERIT, + NULL, + NULL, + NULL, + &value); + rgba_init (&rgba, 0, 0, 0, 0); + g_value_set_boxed (&value, &rgba); + _gtk_style_property_register (g_param_spec_boxed ("background-color", + "Background color", + "Background color", + GDK_TYPE_RGBA, 0), + 0, + NULL, + NULL, + NULL, + &value); + g_value_unset (&value); + + g_value_init (&value, G_TYPE_STRV); + g_value_set_boxed (&value, default_font_family); + _gtk_style_property_register (g_param_spec_boxed ("font-family", + "Font family", + "Font family", + G_TYPE_STRV, 0), + GTK_STYLE_PROPERTY_INHERIT, + NULL, + font_family_parse, + font_family_value_print, + &value); + g_value_unset (&value); + _gtk_style_property_register (g_param_spec_enum ("font-style", + "Font style", + "Font style", + PANGO_TYPE_STYLE, + PANGO_STYLE_NORMAL, 0), + GTK_STYLE_PROPERTY_INHERIT, + NULL, + NULL, + NULL, + NULL); + _gtk_style_property_register (g_param_spec_enum ("font-variant", + "Font variant", + "Font variant", + PANGO_TYPE_VARIANT, + PANGO_VARIANT_NORMAL, 0), + GTK_STYLE_PROPERTY_INHERIT, + NULL, + NULL, + NULL, + NULL); + /* xxx: need to parse this properly, ie parse the numbers */ + _gtk_style_property_register (g_param_spec_enum ("font-weight", + "Font weight", + "Font weight", + PANGO_TYPE_WEIGHT, + PANGO_WEIGHT_NORMAL, 0), + GTK_STYLE_PROPERTY_INHERIT, + NULL, + NULL, + NULL, + NULL); + g_value_init (&value, G_TYPE_DOUBLE); + g_value_set_double (&value, 10); + _gtk_style_property_register (g_param_spec_double ("font-size", + "Font size", + "Font size", + 0, G_MAXDOUBLE, 0, 0), + GTK_STYLE_PROPERTY_INHERIT, + NULL, + NULL, + NULL, + &value); + g_value_unset (&value); + + _gtk_style_property_register (g_param_spec_boxed ("text-shadow", + "Text shadow", + "Text shadow", + GTK_TYPE_SHADOW, 0), + GTK_STYLE_PROPERTY_INHERIT, + NULL, + NULL, + NULL, + NULL); + + _gtk_style_property_register (g_param_spec_boxed ("icon-shadow", + "Icon shadow", + "Icon shadow", + GTK_TYPE_SHADOW, 0), + GTK_STYLE_PROPERTY_INHERIT, + NULL, + NULL, + NULL, + NULL); + + gtk_style_properties_register_property (NULL, + g_param_spec_boxed ("box-shadow", + "Box shadow", + "Box shadow", + GTK_TYPE_SHADOW, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_int ("margin-top", + "margin top", + "Margin at top", + 0, G_MAXINT, 0, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_int ("margin-left", + "margin left", + "Margin at left", + 0, G_MAXINT, 0, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_int ("margin-bottom", + "margin bottom", + "Margin at bottom", + 0, G_MAXINT, 0, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_int ("margin-right", + "margin right", + "Margin at right", + 0, G_MAXINT, 0, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_int ("padding-top", + "padding top", + "Padding at top", + 0, G_MAXINT, 0, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_int ("padding-left", + "padding left", + "Padding at left", + 0, G_MAXINT, 0, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_int ("padding-bottom", + "padding bottom", + "Padding at bottom", + 0, G_MAXINT, 0, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_int ("padding-right", + "padding right", + "Padding at right", + 0, G_MAXINT, 0, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_int ("border-top-width", + "border top width", + "Border width at top", + 0, G_MAXINT, 0, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_int ("border-left-width", + "border left width", + "Border width at left", + 0, G_MAXINT, 0, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_int ("border-bottom-width", + "border bottom width", + "Border width at bottom", + 0, G_MAXINT, 0, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_int ("border-right-width", + "border right width", + "Border width at right", + 0, G_MAXINT, 0, 0)); + + g_value_init (&value, GTK_TYPE_CSS_BORDER_CORNER_RADIUS); + g_value_set_boxed (&value, &no_corner_radius); + _gtk_style_property_register (g_param_spec_boxed ("border-top-left-radius", + "Border top left radius", + "Border radius of top left corner, in pixels", + GTK_TYPE_CSS_BORDER_CORNER_RADIUS, 0), + 0, + NULL, + border_corner_radius_value_parse, + border_corner_radius_value_print, + &value); + _gtk_style_property_register (g_param_spec_boxed ("border-top-right-radius", + "Border top right radius", + "Border radius of top right corner, in pixels", + GTK_TYPE_CSS_BORDER_CORNER_RADIUS, 0), + 0, + NULL, + border_corner_radius_value_parse, + border_corner_radius_value_print, + &value); + _gtk_style_property_register (g_param_spec_boxed ("border-bottom-right-radius", + "Border bottom right radius", + "Border radius of bottom right corner, in pixels", + GTK_TYPE_CSS_BORDER_CORNER_RADIUS, 0), + 0, + NULL, + border_corner_radius_value_parse, + border_corner_radius_value_print, + &value); + _gtk_style_property_register (g_param_spec_boxed ("border-bottom-left-radius", + "Border bottom left radius", + "Border radius of bottom left corner, in pixels", + GTK_TYPE_CSS_BORDER_CORNER_RADIUS, 0), + 0, + NULL, + border_corner_radius_value_parse, + border_corner_radius_value_print, + &value); + g_value_unset (&value); + + gtk_style_properties_register_property (NULL, + g_param_spec_enum ("border-style", + "Border style", + "Border style", + GTK_TYPE_BORDER_STYLE, + GTK_BORDER_STYLE_NONE, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_enum ("background-clip", + "Background clip", + "Background clip", + GTK_TYPE_CSS_AREA, + GTK_CSS_AREA_BORDER_BOX, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_enum ("background-origin", + "Background origin", + "Background origin", + GTK_TYPE_CSS_AREA, + GTK_CSS_AREA_PADDING_BOX, 0)); + g_value_init (&value, GTK_TYPE_CSS_SPECIAL_VALUE); + g_value_set_enum (&value, GTK_CSS_CURRENT_COLOR); + _gtk_style_property_register (g_param_spec_boxed ("border-top-color", + "Border top color", + "Border top color", + GDK_TYPE_RGBA, 0), + 0, + NULL, + NULL, + NULL, + &value); + _gtk_style_property_register (g_param_spec_boxed ("border-right-color", + "Border right color", + "Border right color", + GDK_TYPE_RGBA, 0), + 0, + NULL, + NULL, + NULL, + &value); + _gtk_style_property_register (g_param_spec_boxed ("border-bottom-color", + "Border bottom color", + "Border bottom color", + GDK_TYPE_RGBA, 0), + 0, + NULL, + NULL, + NULL, + &value); + _gtk_style_property_register (g_param_spec_boxed ("border-left-color", + "Border left color", + "Border left color", + GDK_TYPE_RGBA, 0), + 0, + NULL, + NULL, + NULL, + &value); + g_value_unset (&value); + + gtk_style_properties_register_property (NULL, + g_param_spec_boxed ("background-image", + "Background Image", + "Background Image", + CAIRO_GOBJECT_TYPE_PATTERN, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_boxed ("background-repeat", + "Background repeat", + "Background repeat", + GTK_TYPE_CSS_BACKGROUND_REPEAT, 0)); + + gtk_style_properties_register_property (NULL, + g_param_spec_boxed ("border-image-source", + "Border image source", + "Border image source", + CAIRO_GOBJECT_TYPE_PATTERN, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_boxed ("border-image-repeat", + "Border image repeat", + "Border image repeat", + GTK_TYPE_CSS_BORDER_IMAGE_REPEAT, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_boxed ("border-image-slice", + "Border image slice", + "Border image slice", + GTK_TYPE_BORDER, 0)); + g_value_init (&value, GTK_TYPE_BORDER); + _gtk_style_property_register (g_param_spec_boxed ("border-image-width", + "Border image width", + "Border image width", + GTK_TYPE_BORDER, 0), + 0, + NULL, + NULL, + NULL, + &value); + g_value_unset (&value); + gtk_style_properties_register_property (NULL, + g_param_spec_object ("engine", + "Theming Engine", + "Theming Engine", + GTK_TYPE_THEMING_ENGINE, 0)); + gtk_style_properties_register_property (NULL, + g_param_spec_boxed ("transition", + "Transition animation description", + "Transition animation description", + GTK_TYPE_ANIMATION_DESCRIPTION, 0)); + + /* Private property holding the binding sets */ + _gtk_style_property_register (g_param_spec_boxed ("gtk-key-bindings", + "Key bindings", + "Key bindings", + G_TYPE_PTR_ARRAY, 0), + 0, + NULL, + bindings_value_parse, + bindings_value_print, + NULL); +} + diff --git a/gtk/gtkcssstylepropertyprivate.h b/gtk/gtkcssstylepropertyprivate.h index de84786d83..3fe477e9a1 100644 --- a/gtk/gtkcssstylepropertyprivate.h +++ b/gtk/gtkcssstylepropertyprivate.h @@ -54,6 +54,8 @@ struct _GtkCssStylePropertyClass GType _gtk_css_style_property_get_type (void) G_GNUC_CONST; +void _gtk_css_style_property_init_properties (void); + guint _gtk_css_style_property_get_n_properties(void); GtkCssStyleProperty * _gtk_css_style_property_lookup_by_id (guint id); diff --git a/gtk/gtkstyleproperty.c b/gtk/gtkstyleproperty.c index b181be9065..2a53cfd00e 100644 --- a/gtk/gtkstyleproperty.c +++ b/gtk/gtkstyleproperty.c @@ -21,14 +21,6 @@ #include "gtkstylepropertyprivate.h" -#include -#include -#include -#include - -#include -#include - #include "gtkcssprovider.h" #include "gtkcssparserprivate.h" #include "gtkcssshorthandpropertyprivate.h" @@ -39,20 +31,6 @@ #include "gtkprivatetypebuiltins.h" #include "gtkstylepropertiesprivate.h" -/* the actual parsers we have */ -#include "gtkanimationdescription.h" -#include "gtkbindings.h" -#include "gtkgradient.h" -#include "gtkshadowprivate.h" -#include "gtkthemingengine.h" -#include "gtktypebuiltins.h" -#include "gtkwin32themeprivate.h" - -/* this is in case round() is not provided by the compiler, - * such as in the case of C89 compilers, like MSVC - */ -#include "fallback-c89.c" - enum { PROP_0, PROP_NAME, @@ -152,233 +130,6 @@ _gtk_style_property_init (GtkStyleProperty *property) property->value_type = G_TYPE_NONE; } -static void -string_append_double (GString *string, - double d) -{ - char buf[G_ASCII_DTOSTR_BUF_SIZE]; - - g_ascii_dtostr (buf, sizeof (buf), d); - g_string_append (string, buf); -} - -static void -string_append_string (GString *str, - const char *string) -{ - gsize len; - - g_string_append_c (str, '"'); - - do { - len = strcspn (string, "\"\n\r\f"); - g_string_append (str, string); - string += len; - switch (*string) - { - case '\0': - break; - case '\n': - g_string_append (str, "\\A "); - break; - case '\r': - g_string_append (str, "\\D "); - break; - case '\f': - g_string_append (str, "\\C "); - break; - case '\"': - g_string_append (str, "\\\""); - break; - default: - g_assert_not_reached (); - break; - } - } while (*string); - - g_string_append_c (str, '"'); -} - -/*** IMPLEMENTATIONS ***/ - -static gboolean -font_family_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - GPtrArray *names; - char *name; - - /* We don't special case generic families. Pango should do - * that for us */ - - names = g_ptr_array_new (); - - do { - name = _gtk_css_parser_try_ident (parser, TRUE); - if (name) - { - GString *string = g_string_new (name); - g_free (name); - while ((name = _gtk_css_parser_try_ident (parser, TRUE))) - { - g_string_append_c (string, ' '); - g_string_append (string, name); - g_free (name); - } - name = g_string_free (string, FALSE); - } - else - { - name = _gtk_css_parser_read_string (parser); - if (name == NULL) - { - g_ptr_array_free (names, TRUE); - return FALSE; - } - } - - g_ptr_array_add (names, name); - } while (_gtk_css_parser_try (parser, ",", TRUE)); - - /* NULL-terminate array */ - g_ptr_array_add (names, NULL); - g_value_set_boxed (value, g_ptr_array_free (names, FALSE)); - return TRUE; -} - -static void -font_family_value_print (const GValue *value, - GString *string) -{ - const char **names = g_value_get_boxed (value); - - if (names == NULL || *names == NULL) - { - g_string_append (string, "none"); - return; - } - - string_append_string (string, *names); - names++; - while (*names) - { - g_string_append (string, ", "); - string_append_string (string, *names); - names++; - } -} - -static gboolean -bindings_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - GPtrArray *array; - GtkBindingSet *binding_set; - char *name; - - array = g_ptr_array_new (); - - do { - name = _gtk_css_parser_try_ident (parser, TRUE); - if (name == NULL) - { - _gtk_css_parser_error (parser, "Not a valid binding name"); - g_ptr_array_free (array, TRUE); - return FALSE; - } - - binding_set = gtk_binding_set_find (name); - - if (!binding_set) - { - _gtk_css_parser_error (parser, "No binding set named '%s'", name); - g_free (name); - continue; - } - - g_ptr_array_add (array, binding_set); - g_free (name); - } - while (_gtk_css_parser_try (parser, ",", TRUE)); - - g_value_take_boxed (value, array); - - return TRUE; -} - -static void -bindings_value_print (const GValue *value, - GString *string) -{ - GPtrArray *array; - guint i; - - array = g_value_get_boxed (value); - - for (i = 0; i < array->len; i++) - { - GtkBindingSet *binding_set = g_ptr_array_index (array, i); - - if (i > 0) - g_string_append (string, ", "); - g_string_append (string, binding_set->set_name); - } -} - -static gboolean -border_corner_radius_value_parse (GtkCssParser *parser, - GFile *base, - GValue *value) -{ - GtkCssBorderCornerRadius corner; - - if (!_gtk_css_parser_try_double (parser, &corner.horizontal)) - { - _gtk_css_parser_error (parser, "Expected a number"); - return FALSE; - } - else if (corner.horizontal < 0) - goto negative; - - if (!_gtk_css_parser_try_double (parser, &corner.vertical)) - corner.vertical = corner.horizontal; - else if (corner.vertical < 0) - goto negative; - - g_value_set_boxed (value, &corner); - return TRUE; - -negative: - _gtk_css_parser_error (parser, "Border radius values cannot be negative"); - return FALSE; -} - -static void -border_corner_radius_value_print (const GValue *value, - GString *string) -{ - GtkCssBorderCornerRadius *corner; - - corner = g_value_get_boxed (value); - - if (corner == NULL) - { - g_string_append (string, "none"); - return; - } - - string_append_double (string, corner->horizontal); - if (corner->horizontal != corner->vertical) - { - g_string_append_c (string, ' '); - string_append_double (string, corner->vertical); - } -} - -/*** API ***/ - /** * _gtk_style_property_parse_value: * @property: the property @@ -477,350 +228,17 @@ _gtk_style_property_query (GtkStyleProperty *property, klass->query (property, props, state, context, value); } -#define rgba_init(rgba, r, g, b, a) G_STMT_START{ \ - (rgba)->red = (r); \ - (rgba)->green = (g); \ - (rgba)->blue = (b); \ - (rgba)->alpha = (a); \ -}G_STMT_END static void gtk_style_property_init_properties (void) { static gboolean initialized = FALSE; - GValue value = { 0, }; - char *default_font_family[] = { "Sans", NULL }; - GdkRGBA rgba; - GtkCssBorderCornerRadius no_corner_radius = { 0, }; if (G_LIKELY (initialized)) return; initialized = TRUE; - g_value_init (&value, GDK_TYPE_RGBA); - rgba_init (&rgba, 1, 1, 1, 1); - g_value_set_boxed (&value, &rgba); - _gtk_style_property_register (g_param_spec_boxed ("color", - "Foreground color", - "Foreground color", - GDK_TYPE_RGBA, 0), - GTK_STYLE_PROPERTY_INHERIT, - NULL, - NULL, - NULL, - &value); - rgba_init (&rgba, 0, 0, 0, 0); - g_value_set_boxed (&value, &rgba); - _gtk_style_property_register (g_param_spec_boxed ("background-color", - "Background color", - "Background color", - GDK_TYPE_RGBA, 0), - 0, - NULL, - NULL, - NULL, - &value); - g_value_unset (&value); - - g_value_init (&value, G_TYPE_STRV); - g_value_set_boxed (&value, default_font_family); - _gtk_style_property_register (g_param_spec_boxed ("font-family", - "Font family", - "Font family", - G_TYPE_STRV, 0), - GTK_STYLE_PROPERTY_INHERIT, - NULL, - font_family_parse, - font_family_value_print, - &value); - g_value_unset (&value); - _gtk_style_property_register (g_param_spec_enum ("font-style", - "Font style", - "Font style", - PANGO_TYPE_STYLE, - PANGO_STYLE_NORMAL, 0), - GTK_STYLE_PROPERTY_INHERIT, - NULL, - NULL, - NULL, - NULL); - _gtk_style_property_register (g_param_spec_enum ("font-variant", - "Font variant", - "Font variant", - PANGO_TYPE_VARIANT, - PANGO_VARIANT_NORMAL, 0), - GTK_STYLE_PROPERTY_INHERIT, - NULL, - NULL, - NULL, - NULL); - /* xxx: need to parse this properly, ie parse the numbers */ - _gtk_style_property_register (g_param_spec_enum ("font-weight", - "Font weight", - "Font weight", - PANGO_TYPE_WEIGHT, - PANGO_WEIGHT_NORMAL, 0), - GTK_STYLE_PROPERTY_INHERIT, - NULL, - NULL, - NULL, - NULL); - g_value_init (&value, G_TYPE_DOUBLE); - g_value_set_double (&value, 10); - _gtk_style_property_register (g_param_spec_double ("font-size", - "Font size", - "Font size", - 0, G_MAXDOUBLE, 0, 0), - GTK_STYLE_PROPERTY_INHERIT, - NULL, - NULL, - NULL, - &value); - g_value_unset (&value); - - _gtk_style_property_register (g_param_spec_boxed ("text-shadow", - "Text shadow", - "Text shadow", - GTK_TYPE_SHADOW, 0), - GTK_STYLE_PROPERTY_INHERIT, - NULL, - NULL, - NULL, - NULL); - - _gtk_style_property_register (g_param_spec_boxed ("icon-shadow", - "Icon shadow", - "Icon shadow", - GTK_TYPE_SHADOW, 0), - GTK_STYLE_PROPERTY_INHERIT, - NULL, - NULL, - NULL, - NULL); - - gtk_style_properties_register_property (NULL, - g_param_spec_boxed ("box-shadow", - "Box shadow", - "Box shadow", - GTK_TYPE_SHADOW, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_int ("margin-top", - "margin top", - "Margin at top", - 0, G_MAXINT, 0, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_int ("margin-left", - "margin left", - "Margin at left", - 0, G_MAXINT, 0, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_int ("margin-bottom", - "margin bottom", - "Margin at bottom", - 0, G_MAXINT, 0, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_int ("margin-right", - "margin right", - "Margin at right", - 0, G_MAXINT, 0, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_int ("padding-top", - "padding top", - "Padding at top", - 0, G_MAXINT, 0, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_int ("padding-left", - "padding left", - "Padding at left", - 0, G_MAXINT, 0, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_int ("padding-bottom", - "padding bottom", - "Padding at bottom", - 0, G_MAXINT, 0, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_int ("padding-right", - "padding right", - "Padding at right", - 0, G_MAXINT, 0, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_int ("border-top-width", - "border top width", - "Border width at top", - 0, G_MAXINT, 0, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_int ("border-left-width", - "border left width", - "Border width at left", - 0, G_MAXINT, 0, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_int ("border-bottom-width", - "border bottom width", - "Border width at bottom", - 0, G_MAXINT, 0, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_int ("border-right-width", - "border right width", - "Border width at right", - 0, G_MAXINT, 0, 0)); - - g_value_init (&value, GTK_TYPE_CSS_BORDER_CORNER_RADIUS); - g_value_set_boxed (&value, &no_corner_radius); - _gtk_style_property_register (g_param_spec_boxed ("border-top-left-radius", - "Border top left radius", - "Border radius of top left corner, in pixels", - GTK_TYPE_CSS_BORDER_CORNER_RADIUS, 0), - 0, - NULL, - border_corner_radius_value_parse, - border_corner_radius_value_print, - &value); - _gtk_style_property_register (g_param_spec_boxed ("border-top-right-radius", - "Border top right radius", - "Border radius of top right corner, in pixels", - GTK_TYPE_CSS_BORDER_CORNER_RADIUS, 0), - 0, - NULL, - border_corner_radius_value_parse, - border_corner_radius_value_print, - &value); - _gtk_style_property_register (g_param_spec_boxed ("border-bottom-right-radius", - "Border bottom right radius", - "Border radius of bottom right corner, in pixels", - GTK_TYPE_CSS_BORDER_CORNER_RADIUS, 0), - 0, - NULL, - border_corner_radius_value_parse, - border_corner_radius_value_print, - &value); - _gtk_style_property_register (g_param_spec_boxed ("border-bottom-left-radius", - "Border bottom left radius", - "Border radius of bottom left corner, in pixels", - GTK_TYPE_CSS_BORDER_CORNER_RADIUS, 0), - 0, - NULL, - border_corner_radius_value_parse, - border_corner_radius_value_print, - &value); - g_value_unset (&value); - - gtk_style_properties_register_property (NULL, - g_param_spec_enum ("border-style", - "Border style", - "Border style", - GTK_TYPE_BORDER_STYLE, - GTK_BORDER_STYLE_NONE, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_enum ("background-clip", - "Background clip", - "Background clip", - GTK_TYPE_CSS_AREA, - GTK_CSS_AREA_BORDER_BOX, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_enum ("background-origin", - "Background origin", - "Background origin", - GTK_TYPE_CSS_AREA, - GTK_CSS_AREA_PADDING_BOX, 0)); - g_value_init (&value, GTK_TYPE_CSS_SPECIAL_VALUE); - g_value_set_enum (&value, GTK_CSS_CURRENT_COLOR); - _gtk_style_property_register (g_param_spec_boxed ("border-top-color", - "Border top color", - "Border top color", - GDK_TYPE_RGBA, 0), - 0, - NULL, - NULL, - NULL, - &value); - _gtk_style_property_register (g_param_spec_boxed ("border-right-color", - "Border right color", - "Border right color", - GDK_TYPE_RGBA, 0), - 0, - NULL, - NULL, - NULL, - &value); - _gtk_style_property_register (g_param_spec_boxed ("border-bottom-color", - "Border bottom color", - "Border bottom color", - GDK_TYPE_RGBA, 0), - 0, - NULL, - NULL, - NULL, - &value); - _gtk_style_property_register (g_param_spec_boxed ("border-left-color", - "Border left color", - "Border left color", - GDK_TYPE_RGBA, 0), - 0, - NULL, - NULL, - NULL, - &value); - g_value_unset (&value); - - gtk_style_properties_register_property (NULL, - g_param_spec_boxed ("background-image", - "Background Image", - "Background Image", - CAIRO_GOBJECT_TYPE_PATTERN, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_boxed ("background-repeat", - "Background repeat", - "Background repeat", - GTK_TYPE_CSS_BACKGROUND_REPEAT, 0)); - - gtk_style_properties_register_property (NULL, - g_param_spec_boxed ("border-image-source", - "Border image source", - "Border image source", - CAIRO_GOBJECT_TYPE_PATTERN, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_boxed ("border-image-repeat", - "Border image repeat", - "Border image repeat", - GTK_TYPE_CSS_BORDER_IMAGE_REPEAT, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_boxed ("border-image-slice", - "Border image slice", - "Border image slice", - GTK_TYPE_BORDER, 0)); - g_value_init (&value, GTK_TYPE_BORDER); - _gtk_style_property_register (g_param_spec_boxed ("border-image-width", - "Border image width", - "Border image width", - GTK_TYPE_BORDER, 0), - 0, - NULL, - NULL, - NULL, - &value); - g_value_unset (&value); - gtk_style_properties_register_property (NULL, - g_param_spec_object ("engine", - "Theming Engine", - "Theming Engine", - GTK_TYPE_THEMING_ENGINE, 0)); - gtk_style_properties_register_property (NULL, - g_param_spec_boxed ("transition", - "Transition animation description", - "Transition animation description", - GTK_TYPE_ANIMATION_DESCRIPTION, 0)); - - /* Private property holding the binding sets */ - _gtk_style_property_register (g_param_spec_boxed ("gtk-key-bindings", - "Key bindings", - "Key bindings", - G_TYPE_PTR_ARRAY, 0), - 0, - NULL, - bindings_value_parse, - bindings_value_print, - NULL); - + _gtk_css_style_property_init_properties (); /* initialize shorthands last, they depend on the real properties existing */ _gtk_css_shorthand_property_init_properties (); } @@ -883,54 +301,3 @@ _gtk_style_property_get_value_type (GtkStyleProperty *property) return property->value_type; } - - -void -_gtk_style_property_register (GParamSpec *pspec, - GtkStylePropertyFlags flags, - GtkStylePropertyParser property_parse_func, - GtkStyleParseFunc parse_func, - GtkStylePrintFunc print_func, - const GValue * initial_value) -{ - GtkStyleProperty *node; - GValue initial_fallback = { 0, }; - - if (initial_value == NULL) - { - g_value_init (&initial_fallback, pspec->value_type); - if (pspec->value_type == GTK_TYPE_THEMING_ENGINE) - g_value_set_object (&initial_fallback, gtk_theming_engine_load (NULL)); - else if (pspec->value_type == PANGO_TYPE_FONT_DESCRIPTION) - g_value_take_boxed (&initial_fallback, pango_font_description_from_string ("Sans 10")); - else if (pspec->value_type == GDK_TYPE_RGBA) - { - GdkRGBA color; - gdk_rgba_parse (&color, "pink"); - g_value_set_boxed (&initial_fallback, &color); - } - else if (pspec->value_type == GTK_TYPE_BORDER) - { - g_value_take_boxed (&initial_fallback, gtk_border_new ()); - } - else - g_param_value_set_default (pspec, &initial_fallback); - - initial_value = &initial_fallback; - } - - node = g_object_new (GTK_TYPE_CSS_STYLE_PROPERTY, - "inherit", (flags & GTK_STYLE_PROPERTY_INHERIT) ? TRUE : FALSE, - "initial-value", initial_value, - "name", pspec->name, - "value-type", pspec->value_type, - NULL); - g_assert (node->value_type == pspec->value_type); - GTK_CSS_STYLE_PROPERTY (node)->pspec = pspec; - node->property_parse_func = property_parse_func; - node->parse_func = parse_func; - node->print_func = print_func; - - if (G_IS_VALUE (&initial_fallback)) - g_value_unset (&initial_fallback); -} diff --git a/gtk/gtkstylepropertyprivate.h b/gtk/gtkstylepropertyprivate.h index e50e453684..60701992ad 100644 --- a/gtk/gtkstylepropertyprivate.h +++ b/gtk/gtkstylepropertyprivate.h @@ -92,13 +92,6 @@ GtkStyleProperty * _gtk_style_property_lookup (const char const char * _gtk_style_property_get_name (GtkStyleProperty *property); -void _gtk_style_property_register (GParamSpec *pspec, - GtkStylePropertyFlags flags, - GtkStylePropertyParser property_parse_func, - GtkStyleParseFunc parse_func, - GtkStylePrintFunc print_func, - const GValue *initial_value); - gboolean _gtk_style_property_parse_value (GtkStyleProperty * property, GValue *value, GtkCssParser *parser,