[gtk+/wip/clip: 2/5] spinner: Implement clip



commit 15a3f58bf92635143a35f7a946c63c0c0a4fc785
Author: Benjamin Otte <otte redhat com>
Date:   Mon May 19 15:33:28 2014 +0200

    spinner: Implement clip
    
    We now allow you to gtk-icon-transform() the spinner outside of the
    spinners allocation.

 gtk/gtkcssstylepropertyimpl.c |    2 +-
 gtk/gtkspinner.c              |   27 ++++++++++++++
 gtk/gtkstylecontext.c         |   79 +++++++++++++++++++++++++++++++++++++++++
 gtk/gtkstylecontextprivate.h  |    6 +++
 4 files changed, 113 insertions(+), 1 deletions(-)
---
diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c
index c6dc864..4bb8547 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 fa6933e..d6ac9b8 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 a93b1ac..3da7d86 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 56b658c..1fbe269 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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]