diff options
author | Benjamin Otte <otte@redhat.com> | 2014-05-19 15:33:28 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2014-05-23 19:33:14 +0200 |
commit | 15a3f58bf92635143a35f7a946c63c0c0a4fc785 (patch) | |
tree | ec13b712e0276c0d160b8bd63e4ebb12159ef914 | |
parent | 6cdd7c002b218e9e8f809922b4d4d257bc3dcea3 (diff) | |
download | gtk+-15a3f58bf92635143a35f7a946c63c0c0a4fc785.tar.gz |
spinner: Implement clip
We now allow you to gtk-icon-transform() the spinner outside of the
spinners allocation.
-rw-r--r-- | gtk/gtkcssstylepropertyimpl.c | 2 | ||||
-rw-r--r-- | gtk/gtkspinner.c | 27 | ||||
-rw-r--r-- | gtk/gtkstylecontext.c | 79 | ||||
-rw-r--r-- | gtk/gtkstylecontextprivate.h | 6 |
4 files changed, 113 insertions, 1 deletions
diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c index c6dc8644c1..4bb8547738 100644 --- a/gtk/gtkcssstylepropertyimpl.c +++ b/gtk/gtkcssstylepropertyimpl.c @@ -1004,7 +1004,7 @@ _gtk_css_style_property_init_properties (void) gtk_css_style_property_register ("-gtk-icon-transform", GTK_CSS_PROPERTY_ICON_TRANSFORM, G_TYPE_NONE, - GTK_STYLE_PROPERTY_ANIMATED | GTK_STYLE_PROPERTY_NO_RESIZE, + GTK_STYLE_PROPERTY_ANIMATED, transform_value_parse, NULL, NULL, diff --git a/gtk/gtkspinner.c b/gtk/gtkspinner.c index fa6933ef73..d6ac9b8616 100644 --- a/gtk/gtkspinner.c +++ b/gtk/gtkspinner.c @@ -35,6 +35,7 @@ #include "gtkintl.h" #include "gtkstylecontext.h" #include "gtkstylecontextprivate.h" +#include "gtkwidgetprivate.h" #include "a11y/gtkspinneraccessible.h" @@ -67,6 +68,8 @@ struct _GtkSpinnerPrivate static gboolean gtk_spinner_draw (GtkWidget *widget, cairo_t *cr); +static void gtk_spinner_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); static void gtk_spinner_get_property (GObject *object, guint param_id, GValue *value, @@ -98,6 +101,7 @@ gtk_spinner_class_init (GtkSpinnerClass *klass) gobject_class->set_property = gtk_spinner_set_property; widget_class = GTK_WIDGET_CLASS(klass); + widget_class->size_allocate = gtk_spinner_size_allocate; widget_class->draw = gtk_spinner_draw; widget_class->get_preferred_width = gtk_spinner_get_preferred_width; widget_class->get_preferred_height = gtk_spinner_get_preferred_height; @@ -186,6 +190,29 @@ gtk_spinner_get_preferred_height (GtkWidget *widget, *natural_size = SPINNER_SIZE; } +static void +gtk_spinner_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkStyleContext *context; + GtkAllocation clip; + gint size; + + context = gtk_widget_get_style_context (widget); + size = MIN (allocation->width, allocation->height); + + _gtk_style_context_get_icon_extents (context, + &clip, + allocation->x + (allocation->width - size) / 2, + allocation->y + (allocation->height - size) / 2, + size, size); + + gdk_rectangle_union (&clip, allocation, &clip); + + gtk_widget_set_allocation (widget, allocation); + gtk_widget_set_clip (widget, &clip); +} + static gboolean gtk_spinner_draw (GtkWidget *widget, cairo_t *cr) diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index a93b1ac8b9..3da7d86a3b 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -28,8 +28,11 @@ #include "gtkcsscornervalueprivate.h" #include "gtkcssenginevalueprivate.h" #include "gtkcssenumvalueprivate.h" +#include "gtkcssimagevalueprivate.h" #include "gtkcssnumbervalueprivate.h" #include "gtkcssrgbavalueprivate.h" +#include "gtkcssshadowsvalueprivate.h" +#include "gtkcsstransformvalueprivate.h" #include "gtkdebug.h" #include "gtkstylepropertiesprivate.h" #include "gtktypebuiltins.h" @@ -4680,6 +4683,82 @@ _gtk_style_context_get_changes (GtkStyleContext *context) return context->priv->invalidating_context; } +void +gtk_cairo_rectangle_transform (cairo_rectangle_int_t *dest, + const cairo_rectangle_int_t *src, + const cairo_matrix_t *matrix) +{ + double x1, x2, x3, x4; + double y1, y2, y3, y4; + + g_return_if_fail (dest != NULL); + g_return_if_fail (src != NULL); + g_return_if_fail (matrix != NULL); + + x1 = src->x; + y1 = src->y; + x2 = src->x + src->width; + y2 = src->y; + x3 = src->x + src->width; + y3 = src->y + src->height; + x4 = src->x; + y4 = src->y + src->height; + + cairo_matrix_transform_point (matrix, &x1, &y1); + cairo_matrix_transform_point (matrix, &x2, &y2); + cairo_matrix_transform_point (matrix, &x3, &y3); + cairo_matrix_transform_point (matrix, &x4, &y4); + + dest->x = floor (MIN (MIN (x1, x2), MIN (x3, x4))); + dest->y = floor (MIN (MIN (y1, y2), MIN (y3, y4))); + dest->width = ceil (MAX (MAX (x1, x2), MAX (x3, x4))) - dest->x; + dest->height = ceil (MAX (MAX (y1, y2), MAX (y3, y4))) - dest->y; +} +void +_gtk_style_context_get_icon_extents (GtkStyleContext *context, + GdkRectangle *extents, + gint x, + gint y, + gint width, + gint height) +{ + cairo_matrix_t transform_matrix, matrix; + GtkBorder border; + GdkRectangle rect; + + g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); + g_return_if_fail (extents != NULL); + + rect.x = x; + rect.y = y; + rect.width = width; + rect.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) + return; + + if (!_gtk_css_transform_value_get_matrix (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_ICON_TRANSFORM), &transform_matrix)) + return; + + cairo_matrix_init_translate (&matrix, x + width / 2.0, y + height / 2.0); + cairo_matrix_multiply (&matrix, &transform_matrix, &matrix); + /* need to round to full pixels */ + rect.x = - (width + 1) / 2; + rect.y = - (height + 1) / 2; + rect.width = (width + 1) & ~1; + rect.height = (height + 1) & ~1; + gtk_cairo_rectangle_transform (extents, &rect, &matrix); + + _gtk_css_shadows_value_get_extents (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_ICON_SHADOW), &border); + + extents->x -= border.left; + extents->y -= border.top; + extents->width += border.left + border.right; + extents->height += border.top + border.bottom; +} + GtkIconLookupFlags _gtk_style_context_get_icon_lookup_flags (GtkStyleContext *context) { diff --git a/gtk/gtkstylecontextprivate.h b/gtk/gtkstylecontextprivate.h index 56b658c9fa..1fbe2695f6 100644 --- a/gtk/gtkstylecontextprivate.h +++ b/gtk/gtkstylecontextprivate.h @@ -56,6 +56,12 @@ void _gtk_style_context_get_cursor_color (GtkStyleContext void _gtk_style_context_update_animating (GtkStyleContext *context); +void _gtk_style_context_get_icon_extents (GtkStyleContext *context, + GdkRectangle *extents, + gint x, + gint y, + gint width, + gint height); GtkIconLookupFlags _gtk_style_context_get_icon_lookup_flags (GtkStyleContext *context); G_END_DECLS |