diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 41943da5cb..89140dbff6 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -543,6 +543,7 @@ gtk_private_h_sources = \ gtkcsseasevalueprivate.h \ gtkcssenginevalueprivate.h \ gtkcssenumvalueprivate.h \ + gtkcssimagebuiltinprivate.h \ gtkcssimagecrossfadeprivate.h \ gtkcssimagegradientprivate.h \ gtkcssimageiconthemeprivate.h \ @@ -868,6 +869,7 @@ gtk_base_c_sources = \ gtkcssenumvalue.c \ gtkcssenginevalue.c \ gtkcssimage.c \ + gtkcssimagebuiltin.c \ gtkcssimagecrossfade.c \ gtkcssimagegradient.c \ gtkcssimageicontheme.c \ diff --git a/gtk/gtkcssimagebuiltin.c b/gtk/gtkcssimagebuiltin.c new file mode 100644 index 0000000000..87995a5a32 --- /dev/null +++ b/gtk/gtkcssimagebuiltin.c @@ -0,0 +1,127 @@ +/* + * Copyright © 2012 Red Hat Inc. + * + * 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.1 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, see . + * + * Authors: Benjamin Otte + */ + +#include "config.h" + +#include "gtkcssimagebuiltinprivate.h" + +G_DEFINE_TYPE (GtkCssImageBuiltin, gtk_css_image_builtin, GTK_TYPE_CSS_IMAGE) + +static GtkCssImage *the_one_true_image; + +static void +gtk_css_image_builtin_draw (GtkCssImage *image, + cairo_t *cr, + double width, + double height) +{ + /* It's a builtin image, other code will draw things */ +} + + +static gboolean +gtk_css_image_builtin_parse (GtkCssImage *image, + GtkCssParser *parser) +{ + if (!_gtk_css_parser_try (parser, "builtin", TRUE)) + { + _gtk_css_parser_error (parser, "Expected 'builtin'"); + return FALSE; + } + + return TRUE; +} + +static void +gtk_css_image_builtin_print (GtkCssImage *image, + GString *string) +{ + g_string_append (string, "builtin"); +} + +static GtkCssImage * +gtk_css_image_builtin_compute (GtkCssImage *image, + guint property_id, + GtkStyleProviderPrivate *provider, + int scale, + GtkCssComputedValues *values, + GtkCssComputedValues *parent_values, + GtkCssDependencies *dependencies) +{ + return g_object_ref (image); +} + +static gboolean +gtk_css_image_builtin_equal (GtkCssImage *image1, + GtkCssImage *image2) +{ + return TRUE; +} + +static GtkCssImage * +gtk_css_image_builtin_transition (GtkCssImage *start, + GtkCssImage *end, + guint property_id, + double progress) +{ + /* builtin images always look the same, so start == end */ + return g_object_ref (start); +} + +static void +gtk_css_image_builtin_dispose (GObject *object) +{ + if (the_one_true_image == GTK_CSS_IMAGE (object)) + the_one_true_image = NULL; + + G_OBJECT_CLASS (gtk_css_image_builtin_parent_class)->dispose (object); +} + +static void +gtk_css_image_builtin_class_init (GtkCssImageBuiltinClass *klass) +{ + GtkCssImageClass *image_class = GTK_CSS_IMAGE_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + image_class->draw = gtk_css_image_builtin_draw; + image_class->parse = gtk_css_image_builtin_parse; + image_class->print = gtk_css_image_builtin_print; + image_class->compute = gtk_css_image_builtin_compute; + image_class->equal = gtk_css_image_builtin_equal; + image_class->transition = gtk_css_image_builtin_transition; + + object_class->dispose = gtk_css_image_builtin_dispose; +} + +static void +gtk_css_image_builtin_init (GtkCssImageBuiltin *builtin) +{ +} + +GtkCssImage * +gtk_css_image_builtin_new (void) +{ + if (the_one_true_image == NULL) + the_one_true_image = g_object_new (GTK_TYPE_CSS_IMAGE_BUILTIN, NULL); + else + g_object_ref (the_one_true_image); + + return the_one_true_image; +} + diff --git a/gtk/gtkcssimagebuiltinprivate.h b/gtk/gtkcssimagebuiltinprivate.h new file mode 100644 index 0000000000..294a83b8d5 --- /dev/null +++ b/gtk/gtkcssimagebuiltinprivate.h @@ -0,0 +1,54 @@ +/* + * Copyright © 2012 Red Hat Inc. + * + * 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.1 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, see . + * + * Authors: Benjamin Otte + */ + +#ifndef __GTK_CSS_IMAGE_BUILTIN_PRIVATE_H__ +#define __GTK_CSS_IMAGE_BUILTIN_PRIVATE_H__ + +#include "gtk/gtkcssimageprivate.h" +#include "gtk/gtkicontheme.h" + +G_BEGIN_DECLS + +#define GTK_TYPE_CSS_IMAGE_BUILTIN (gtk_css_image_builtin_get_type ()) +#define GTK_CSS_IMAGE_BUILTIN(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_IMAGE_BUILTIN, GtkCssImageBuiltin)) +#define GTK_CSS_IMAGE_BUILTIN_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_IMAGE_BUILTIN, GtkCssImageBuiltinClass)) +#define GTK_IS_CSS_IMAGE_BUILTIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_IMAGE_BUILTIN)) +#define GTK_IS_CSS_IMAGE_BUILTIN_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_IMAGE_BUILTIN)) +#define GTK_CSS_IMAGE_BUILTIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_IMAGE_BUILTIN, GtkCssImageBuiltinClass)) + +typedef struct _GtkCssImageBuiltin GtkCssImageBuiltin; +typedef struct _GtkCssImageBuiltinClass GtkCssImageBuiltinClass; + +struct _GtkCssImageBuiltin +{ + GtkCssImage parent; +}; + +struct _GtkCssImageBuiltinClass +{ + GtkCssImageClass parent_class; +}; + +GType gtk_css_image_builtin_get_type (void) G_GNUC_CONST; + +GtkCssImage * gtk_css_image_builtin_new (void); + +G_END_DECLS + +#endif /* __GTK_CSS_IMAGE_BUILTIN_PRIVATE_H__ */ diff --git a/gtk/gtkcssimageprivate.h b/gtk/gtkcssimageprivate.h index e9a39bfb9f..23188e79bc 100644 --- a/gtk/gtkcssimageprivate.h +++ b/gtk/gtkcssimageprivate.h @@ -65,7 +65,7 @@ struct _GtkCssImageClass /* compare two images for equality */ gboolean (* equal) (GtkCssImage *image1, GtkCssImage *image2); - /* transition between start and end image (end may be NULL), returns new reference */ + /* transition between start and end image (end may be NULL), returns new reference (optional) */ GtkCssImage *(* transition) (GtkCssImage *start, GtkCssImage *end, guint property_id, diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c index 3b4186c74b..005ed9fe16 100644 --- a/gtk/gtkcssstylepropertyimpl.c +++ b/gtk/gtkcssstylepropertyimpl.c @@ -47,6 +47,7 @@ #include "gtkcsseasevalueprivate.h" #include "gtkcssenginevalueprivate.h" #include "gtkcssimageprivate.h" +#include "gtkcssimagebuiltinprivate.h" #include "gtkcssimagegradientprivate.h" #include "gtkcssimagevalueprivate.h" #include "gtkcssinitialvalueprivate.h" @@ -656,6 +657,16 @@ css_image_value_parse (GtkCssStyleProperty *property, return _gtk_css_image_value_new (image); } +static GtkCssValue * +css_image_value_parse_with_builtin (GtkCssStyleProperty *property, + GtkCssParser *parser) +{ + if (_gtk_css_parser_try (parser, "builtin", TRUE)) + return _gtk_css_image_value_new (gtk_css_image_builtin_new ()); + + return css_image_value_parse (property, parser); +} + static void css_image_value_query (GtkCssStyleProperty *property, const GtkCssValue *css_value, @@ -1036,10 +1047,10 @@ _gtk_css_style_property_init_properties (void) G_TYPE_NONE, GTK_STYLE_PROPERTY_ANIMATED, GTK_CSS_AFFECTS_ICON, - css_image_value_parse, + css_image_value_parse_with_builtin, NULL, NULL, - _gtk_css_image_value_new (NULL)); + _gtk_css_image_value_new (gtk_css_image_builtin_new ())); gtk_css_style_property_register ("icon-shadow", GTK_CSS_PROPERTY_ICON_SHADOW, G_TYPE_NONE, diff --git a/gtk/gtkrender.c b/gtk/gtkrender.c index 5861cb35d7..17efbed9f7 100644 --- a/gtk/gtkrender.c +++ b/gtk/gtkrender.c @@ -26,6 +26,7 @@ #include "gtkcsscornervalueprivate.h" #include "gtkcssenginevalueprivate.h" #include "gtkcssenumvalueprivate.h" +#include "gtkcssimagebuiltinprivate.h" #include "gtkcssimagevalueprivate.h" #include "gtkcssnumbervalueprivate.h" #include "gtkcssrgbavalueprivate.h" @@ -51,6 +52,9 @@ render_icon_image (GtkStyleContext *context, image = _gtk_css_image_value_get_image (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_ICON_SOURCE)); if (image == NULL) + return TRUE; + + if (GTK_IS_CSS_IMAGE_BUILTIN (image)) return FALSE; shadows = _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_ICON_SHADOW); diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index dff7a6eb2b..9b8a4212f3 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -27,6 +27,7 @@ #include "gtkcsscolorvalueprivate.h" #include "gtkcsscornervalueprivate.h" #include "gtkcssenumvalueprivate.h" +#include "gtkcssimagebuiltinprivate.h" #include "gtkcssimagevalueprivate.h" #include "gtkcssnodedeclarationprivate.h" #include "gtkcssnumbervalueprivate.h" @@ -3548,14 +3549,19 @@ _gtk_style_context_get_icon_extents (GtkStyleContext *context, g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); g_return_if_fail (extents != NULL); + if (_gtk_css_image_value_get_image (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_ICON_SOURCE)) == NULL) + { + extents->x = extents->y = extents->width = extents->height = 0; + return; + } + extents->x = x; extents->y = y; extents->width = width; extents->height = height; - /* strictly speaking we should return an empty rect here, - * but most code still draws a fallback in this case */ - if (_gtk_css_image_value_get_image (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_ICON_SOURCE)) == NULL) + /* builtin images can't be transformed */ + if (GTK_IS_CSS_IMAGE_BUILTIN (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_ICON_SOURCE))) return; if (!_gtk_css_transform_value_get_matrix (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_ICON_TRANSFORM), &transform_matrix))