[gtk+] styleproperty: turn border-image into a shorthand property
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] styleproperty: turn border-image into a shorthand property
- Date: Thu, 9 Jun 2011 04:24:07 +0000 (UTC)
commit e3dd437b67ca859d311979b880baba9d67d44fdf
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Thu May 26 15:54:38 2011 -0400
styleproperty: turn border-image into a shorthand property
It's composed by
- border-image-source: a cairo_pattern_t holding an image from file or a
gradient
- border-image-slice: a GtkBorder containing the slice offsets to apply
on the image
- border-image-repeat: a GtkRepeatType for the image
We deviate from pure CSS3 in the following ways:
* border-image-width is assumed to be always 1, i.e. always equal to
what's specified by border-width. I don't think it's a particularly
useful property to have, but we could add it later if needed.
* border-image-outset is absent, as we can't render outside of the
allocation yet.
https://bugzilla.gnome.org/show_bug.cgi?id=651194
gtk/gtkstyleproperties.c | 1 +
gtk/gtkstyleproperty.c | 218 +++++++++++++++++++++++++++++++++++-----------
2 files changed, 169 insertions(+), 50 deletions(-)
---
diff --git a/gtk/gtkstyleproperties.c b/gtk/gtkstyleproperties.c
index 6cf4973..6af179b 100644
--- a/gtk/gtkstyleproperties.c
+++ b/gtk/gtkstyleproperties.c
@@ -32,6 +32,7 @@
#include "gtkgradient.h"
#include "gtkshadowprivate.h"
#include "gtkcsstypesprivate.h"
+#include "gtkborderimageprivate.h"
#include "gtkstylepropertyprivate.h"
#include "gtkintl.h"
diff --git a/gtk/gtkstyleproperty.c b/gtk/gtkstyleproperty.c
index 7b4e092..f825db3 100644
--- a/gtk/gtkstyleproperty.c
+++ b/gtk/gtkstyleproperty.c
@@ -35,7 +35,7 @@
/* the actual parsers we have */
#include "gtkanimationdescription.h"
#include "gtkbindings.h"
-#include "gtk9slice.h"
+#include "gtkborderimageprivate.h"
#include "gtkgradient.h"
#include "gtkshadowprivate.h"
#include "gtkthemingengine.h"
@@ -948,69 +948,135 @@ shadow_value_print (const GValue *value,
_gtk_shadow_print (shadow, string);
}
-static gboolean
-slice_value_parse (GtkCssParser *parser,
- GFile *base,
- GValue *value)
+static gboolean
+border_image_repeat_value_parse (GtkCssParser *parser,
+ GFile *file,
+ GValue *value)
{
- gdouble distance_top, distance_bottom;
- gdouble distance_left, distance_right;
- GtkSliceSideModifier mods[2];
- GdkPixbuf *pixbuf;
- Gtk9Slice *slice;
- GFile *file;
- GError *error = NULL;
+ GtkBorderImageRepeat image_repeat;
+ GtkRepeatStyle styles[2];
gint i;
- char *path;
-
- /* Parse image url */
- file = gtk_css_parse_url (parser, base);
- if (!file)
- return FALSE;
-
- if (!_gtk_css_parser_try_double (parser, &distance_top) ||
- !_gtk_css_parser_try_double (parser, &distance_right) ||
- !_gtk_css_parser_try_double (parser, &distance_bottom) ||
- !_gtk_css_parser_try_double (parser, &distance_left))
- {
- _gtk_css_parser_error (parser, "Expected a number");
- g_object_unref (file);
- return FALSE;
- }
for (i = 0; i < 2; i++)
{
if (_gtk_css_parser_try (parser, "stretch", TRUE))
- mods[i] = GTK_SLICE_STRETCH;
+ styles[i] = GTK_REPEAT_STYLE_NONE;
else if (_gtk_css_parser_try (parser, "repeat", TRUE))
- mods[i] = GTK_SLICE_REPEAT;
+ styles[i] = GTK_REPEAT_STYLE_REPEAT;
+ else if (_gtk_css_parser_try (parser, "round", TRUE))
+ styles[i] = GTK_REPEAT_STYLE_ROUND;
+ else if (_gtk_css_parser_try (parser, "space", TRUE))
+ styles[i] = GTK_REPEAT_STYLE_SPACE;
else if (i == 0)
{
- mods[1] = mods[0] = GTK_SLICE_STRETCH;
+ styles[1] = styles[0] = GTK_REPEAT_STYLE_NONE;
break;
}
else
- mods[i] = mods[0];
+ styles[i] = styles[0];
}
- path = g_file_get_path (file);
- g_object_unref (file);
- pixbuf = gdk_pixbuf_new_from_file (path, &error);
- g_free (path);
- if (!pixbuf)
+ image_repeat.vrepeat = styles[0];
+ image_repeat.hrepeat = styles[1];
+
+ g_value_set_boxed (value, &image_repeat);
+
+ return TRUE;
+}
+
+static const gchar *
+border_image_repeat_style_to_string (GtkRepeatStyle repeat)
+{
+ switch (repeat)
{
- _gtk_css_parser_take_error (parser, error);
- return FALSE;
+ case GTK_REPEAT_STYLE_NONE:
+ return "stretch";
+ case GTK_REPEAT_STYLE_REPEAT:
+ return "repeat";
+ case GTK_REPEAT_STYLE_ROUND:
+ return "round";
+ case GTK_REPEAT_STYLE_SPACE:
+ return "space";
+ default:
+ return NULL;
}
+}
- slice = _gtk_9slice_new (pixbuf,
- distance_top, distance_bottom,
- distance_left, distance_right,
- mods[0], mods[1]);
- g_object_unref (pixbuf);
+static void
+border_image_repeat_value_print (const GValue *value,
+ GString *string)
+{
+ GtkBorderImageRepeat *image_repeat;
- g_value_take_boxed (value, slice);
- return TRUE;
+ image_repeat = g_value_get_boxed (value);
+
+ g_string_append_printf (string, "%s %s",
+ border_image_repeat_style_to_string (image_repeat->vrepeat),
+ border_image_repeat_style_to_string (image_repeat->hrepeat));
+}
+
+static gboolean
+border_image_value_parse (GtkCssParser *parser,
+ GFile *base,
+ GValue *value)
+{
+ GValue temp = { 0, };
+ cairo_pattern_t *pattern = NULL;
+ GtkGradient *gradient = NULL;
+ GtkBorder border, *parsed_border;
+ GtkBorderImageRepeat repeat, *parsed_repeat;
+ gboolean retval = FALSE;
+ GtkBorderImage *image = NULL;
+
+ g_value_init (&temp, CAIRO_GOBJECT_TYPE_PATTERN);
+
+ if (!pattern_value_parse (parser, base, &temp))
+ return FALSE;
+
+ if (G_VALUE_TYPE (&temp) == GTK_TYPE_GRADIENT)
+ gradient = g_value_dup_boxed (&temp);
+ else
+ pattern = g_value_dup_boxed (&temp);
+
+ g_value_unset (&temp);
+ g_value_init (&temp, GTK_TYPE_BORDER);
+
+ if (!border_value_parse (parser, base, &temp))
+ goto out;
+
+ parsed_border = g_value_get_boxed (&temp);
+ border = *parsed_border;
+
+ g_value_unset (&temp);
+ g_value_init (&temp, GTK_TYPE_BORDER_IMAGE_REPEAT);
+
+ if (!border_image_repeat_value_parse (parser, base, &temp))
+ goto out;
+
+ parsed_repeat = g_value_get_boxed (&temp);
+ repeat = *parsed_repeat;
+
+ g_value_unset (&temp);
+
+ if (gradient != NULL)
+ image = _gtk_border_image_new_for_gradient (gradient, &border, &repeat);
+ else if (pattern != NULL)
+ image = _gtk_border_image_new (pattern, &border, &repeat);
+
+ if (image != NULL)
+ {
+ retval = TRUE;
+ g_value_take_boxed (value, image);
+ }
+
+ out:
+ if (pattern != NULL)
+ cairo_pattern_destroy (pattern);
+
+ if (gradient != NULL)
+ gtk_gradient_unref (gradient);
+
+ return retval;
}
static gboolean
@@ -1625,9 +1691,12 @@ css_string_funcs_init (void)
register_conversion_function (CAIRO_GOBJECT_TYPE_PATTERN,
pattern_value_parse,
NULL);
- register_conversion_function (GTK_TYPE_9SLICE,
- slice_value_parse,
+ register_conversion_function (GTK_TYPE_BORDER_IMAGE,
+ border_image_value_parse,
NULL);
+ register_conversion_function (GTK_TYPE_BORDER_IMAGE_REPEAT,
+ border_image_repeat_value_parse,
+ border_image_repeat_value_print);
register_conversion_function (GTK_TYPE_SHADOW,
shadow_value_parse,
shadow_value_print);
@@ -1846,6 +1915,29 @@ resolve_shadow (GtkStyleProperties *props,
return TRUE;
}
+static gboolean
+resolve_border_image (GtkStyleProperties *props,
+ GValue *value)
+{
+ GtkBorderImage *resolved, *base;
+
+ base = g_value_get_boxed (value);
+
+ if (base == NULL)
+ return FALSE;
+
+ if (_gtk_border_image_get_resolved (base))
+ return TRUE;
+
+ resolved = _gtk_border_image_resolve (base, props);
+ if (resolved == NULL)
+ return FALSE;
+
+ g_value_take_boxed (value, resolved);
+
+ return TRUE;
+}
+
void
_gtk_style_property_resolve (const GtkStyleProperty *property,
GtkStyleProperties *props,
@@ -1878,6 +1970,11 @@ _gtk_style_property_resolve (const GtkStyleProperty *property,
if (!resolve_shadow (props, val))
_gtk_style_property_resolve (property, props, val);
}
+ else if (G_VALUE_TYPE (val) == GTK_TYPE_BORDER_IMAGE)
+ {
+ if (!resolve_border_image (props, val))
+ _gtk_style_property_resolve (property, props, val);
+ }
}
gboolean
@@ -2136,10 +2233,31 @@ gtk_style_property_init (void)
"Background Image",
CAIRO_GOBJECT_TYPE_PATTERN, 0));
gtk_style_properties_register_property (NULL,
- g_param_spec_boxed ("border-image",
+ 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_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));
+ _gtk_style_property_register (g_param_spec_boxed ("border-image",
"Border Image",
"Border Image",
- GTK_TYPE_9SLICE, 0));
+ GTK_TYPE_BORDER_IMAGE, 0),
+ 0,
+ NULL,
+ _gtk_border_image_unpack,
+ _gtk_border_image_pack,
+ NULL,
+ NULL,
+ NULL);
gtk_style_properties_register_property (NULL,
g_param_spec_object ("engine",
"Theming Engine",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]