iconhelper: Implement GdkPaintable
authorBenjamin Otte <otte@redhat.com>
Thu, 15 Mar 2018 08:40:52 +0000 (09:40 +0100)
committerBenjamin Otte <otte@redhat.com>
Fri, 16 Mar 2018 05:04:45 +0000 (06:04 +0100)
This only implements the vfuncs, but does not actually emit signals
yet.

It's also not useed for anything other than snapshot() so far, this
will come in later commits.

gtk/gtkcellrendererpixbuf.c
gtk/gtkiconhelper.c
gtk/gtkiconhelperprivate.h
gtk/gtkimage.c

index 1426fef268953e38c1a3b703e091b93e4522f43d..3cca5e5555d397ec2b29e261bb31062616a7899d 100644 (file)
@@ -551,7 +551,7 @@ gtk_cell_renderer_pixbuf_snapshot (GtkCellRenderer      *cell,
     }
 
   gtk_snapshot_offset (snapshot, pix_rect.x, pix_rect.y);
-  gtk_icon_helper_snapshot (icon_helper, snapshot, pix_rect.width, pix_rect.height);
+  gdk_paintable_snapshot (GDK_PAINTABLE (icon_helper), snapshot, pix_rect.width, pix_rect.height);
   gtk_snapshot_offset (snapshot, - pix_rect.x, - pix_rect.y);
 
   g_object_unref (icon_helper);
index 5904fe3faa9f368a0d051f968b5b2c71c989103d..5a38f2aea2dc074dcdaf516f8500e99819f51f94 100644 (file)
@@ -53,116 +53,6 @@ struct _GtkIconHelper
   int texture_scale;
 };
 
-G_DEFINE_TYPE (GtkIconHelper, gtk_icon_helper, G_TYPE_OBJECT)
-
-void
-gtk_icon_helper_invalidate (GtkIconHelper *self)
-{
-  g_clear_object (&self->paintable);
-  self->texture_scale = 1;
-  self->texture_is_symbolic = FALSE;
-
-  if (!GTK_IS_CSS_TRANSIENT_NODE (self->node))
-    gtk_widget_queue_resize (self->owner);
-}
-
-void
-gtk_icon_helper_invalidate_for_change (GtkIconHelper     *self,
-                                       GtkCssStyleChange *change)
-{
-  if (change == NULL ||
-      ((gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_SYMBOLIC_ICON) &&
-        self->texture_is_symbolic) ||
-       (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON) &&
-        !self->texture_is_symbolic)))
-    {
-      /* Avoid the queue_resize in gtk_icon_helper_invalidate */
-      g_clear_object (&self->paintable);
-      self->texture_scale = 1;
-      self->texture_is_symbolic = FALSE;
-
-      if (change == NULL ||
-          (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON_SIZE) &&
-          !GTK_IS_CSS_TRANSIENT_NODE (self->node)))
-        gtk_widget_queue_resize (self->owner);
-    }
-}
-
-static void
-gtk_icon_helper_take_definition (GtkIconHelper      *self,
-                                 GtkImageDefinition *def)
-{
-  _gtk_icon_helper_clear (self);
-
-  if (def == NULL)
-    return;
-
-  gtk_image_definition_unref (self->def);
-  self->def = def;
-
-  gtk_icon_helper_invalidate (self);
-}
-
-void
-_gtk_icon_helper_clear (GtkIconHelper *self)
-{
-  g_clear_object (&self->paintable);
-  self->texture_scale = 1;
-  self->texture_is_symbolic = FALSE;
-
-  if (gtk_image_definition_get_storage_type (self->def) != GTK_IMAGE_EMPTY)
-    {
-      gtk_image_definition_unref (self->def);
-      self->def = gtk_image_definition_new_empty ();
-      gtk_icon_helper_invalidate (self);
-    }
-}
-
-static void
-gtk_icon_helper_finalize (GObject *object)
-{
-  GtkIconHelper *self = GTK_ICON_HELPER (object);
-
-  _gtk_icon_helper_clear (self);
-  g_signal_handlers_disconnect_by_func (self->owner, G_CALLBACK (gtk_icon_helper_invalidate), self);
-  gtk_image_definition_unref (self->def);
-
-  G_OBJECT_CLASS (gtk_icon_helper_parent_class)->finalize (object);
-}
-
-void
-gtk_icon_helper_class_init (GtkIconHelperClass *klass)
-{
-  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
-  gobject_class->finalize = gtk_icon_helper_finalize;
-}
-
-void
-gtk_icon_helper_init (GtkIconHelper *self)
-{
-  self->def = gtk_image_definition_new_empty ();
-}
-
-GtkIconHelper *
-gtk_icon_helper_new (GtkCssNode *css_node,
-                     GtkWidget  *owner)
-{
-  GtkIconHelper *self;
-  
-  self = g_object_new (GTK_TYPE_ICON_HELPER, NULL);
-
-  self->pixel_size = -1;
-  self->texture_is_symbolic = FALSE;
-
-  self->node = css_node;
-  self->owner = owner;
-  g_signal_connect_swapped (owner, "direction-changed", G_CALLBACK (gtk_icon_helper_invalidate), self);
-  g_signal_connect_swapped (owner, "notify::scale-factor", G_CALLBACK (gtk_icon_helper_invalidate), self);
-
-  return self;
-}
-
 static int
 get_default_size (GtkIconHelper *self)
 {
@@ -344,6 +234,251 @@ gtk_icon_helper_ensure_paintable (GtkIconHelper *self)
   self->texture_is_symbolic = symbolic;
 }
 
+static void
+gtk_icon_helper_paintable_snapshot (GdkPaintable *paintable,
+                                    GdkSnapshot  *snapshot,
+                                    double        width,
+                                    double        height)
+{
+  GtkIconHelper *self = GTK_ICON_HELPER (paintable);
+  GtkCssStyle *style;
+
+  style = gtk_css_node_get_style (self->node);
+
+  gtk_icon_helper_ensure_paintable (self);
+  if (self->paintable == NULL)
+    return;
+
+  gtk_css_style_snapshot_icon_paintable (style,
+                                         snapshot,
+                                         self->paintable,
+                                         width, height,
+                                         self->texture_is_symbolic);
+}
+
+static GdkPaintable *
+gtk_icon_helper_paintable_get_current_image (GdkPaintable *paintable)
+{
+  GtkIconHelper *self = GTK_ICON_HELPER (paintable);
+
+  gtk_icon_helper_ensure_paintable (self);
+  if (self->paintable == NULL)
+    return NULL;
+
+  return gtk_icon_helper_paintable_get_current_image (self->paintable);
+}
+
+static int
+gtk_icon_helper_paintable_get_intrinsic_width (GdkPaintable *paintable)
+{
+  GtkIconHelper *self = GTK_ICON_HELPER (paintable);
+
+  switch (gtk_image_definition_get_storage_type (self->def))
+    {
+    case GTK_IMAGE_TEXTURE:
+      return gdk_paintable_get_intrinsic_width (GDK_PAINTABLE (gtk_image_definition_get_texture (self->def)));
+
+    case GTK_IMAGE_PAINTABLE:
+      return gdk_paintable_get_intrinsic_width (gtk_image_definition_get_paintable (self->def));
+
+    case GTK_IMAGE_ICON_NAME:
+    case GTK_IMAGE_GICON:
+      if (self->pixel_size != -1 || self->force_scale_pixbuf)
+        return get_default_size (self);
+      gtk_icon_helper_ensure_paintable (self);
+      if (self->paintable)
+        return gdk_paintable_get_intrinsic_width (self->paintable);
+      else
+        return 0;
+
+    case GTK_IMAGE_EMPTY:
+      return 0;
+
+    default:
+      g_assert_not_reached ();
+      return 0;
+    }
+}
+
+static int
+gtk_icon_helper_paintable_get_intrinsic_height (GdkPaintable *paintable)
+{
+  GtkIconHelper *self = GTK_ICON_HELPER (paintable);
+
+  switch (gtk_image_definition_get_storage_type (self->def))
+    {
+    case GTK_IMAGE_TEXTURE:
+      return gdk_paintable_get_intrinsic_height (GDK_PAINTABLE (gtk_image_definition_get_texture (self->def)));
+
+    case GTK_IMAGE_PAINTABLE:
+      return gdk_paintable_get_intrinsic_height (gtk_image_definition_get_paintable (self->def));
+
+    case GTK_IMAGE_ICON_NAME:
+    case GTK_IMAGE_GICON:
+      if (self->pixel_size != -1 || self->force_scale_pixbuf)
+        return get_default_size (self);
+      gtk_icon_helper_ensure_paintable (self);
+      if (self->paintable)
+        return gdk_paintable_get_intrinsic_height (self->paintable);
+      else
+        return 0;
+
+    case GTK_IMAGE_EMPTY:
+      return 0;
+
+    default:
+      g_assert_not_reached ();
+      return 0;
+    }
+}
+
+static double gtk_icon_helper_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable)
+{
+  GtkIconHelper *self = GTK_ICON_HELPER (paintable);
+
+  switch (gtk_image_definition_get_storage_type (self->def))
+    {
+    case GTK_IMAGE_TEXTURE:
+      return gdk_paintable_get_intrinsic_aspect_ratio (GDK_PAINTABLE (gtk_image_definition_get_texture (self->def)));
+
+    case GTK_IMAGE_PAINTABLE:
+      return gdk_paintable_get_intrinsic_aspect_ratio (gtk_image_definition_get_paintable (self->def));
+
+    case GTK_IMAGE_ICON_NAME:
+    case GTK_IMAGE_GICON:
+      return 1.0;
+
+    case GTK_IMAGE_EMPTY:
+      return 0.0;
+
+    default:
+      g_assert_not_reached ();
+      return 0.0;
+    }
+};
+
+static void
+gtk_icon_helper_paintable_init (GdkPaintableInterface *iface)
+{
+  iface->snapshot = gtk_icon_helper_paintable_snapshot;
+  iface->get_current_image = gtk_icon_helper_paintable_get_current_image;
+  iface->get_intrinsic_width = gtk_icon_helper_paintable_get_intrinsic_width;
+  iface->get_intrinsic_height = gtk_icon_helper_paintable_get_intrinsic_height;
+  iface->get_intrinsic_aspect_ratio = gtk_icon_helper_paintable_get_intrinsic_aspect_ratio;
+}
+
+G_DEFINE_TYPE_WITH_CODE (GtkIconHelper, gtk_icon_helper, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
+                                               gtk_icon_helper_paintable_init))
+
+void
+gtk_icon_helper_invalidate (GtkIconHelper *self)
+{
+  g_clear_object (&self->paintable);
+  self->texture_scale = 1;
+  self->texture_is_symbolic = FALSE;
+
+  if (!GTK_IS_CSS_TRANSIENT_NODE (self->node))
+    gtk_widget_queue_resize (self->owner);
+}
+
+void
+gtk_icon_helper_invalidate_for_change (GtkIconHelper     *self,
+                                       GtkCssStyleChange *change)
+{
+  if (change == NULL ||
+      ((gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_SYMBOLIC_ICON) &&
+        self->texture_is_symbolic) ||
+       (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON) &&
+        !self->texture_is_symbolic)))
+    {
+      /* Avoid the queue_resize in gtk_icon_helper_invalidate */
+      g_clear_object (&self->paintable);
+      self->texture_scale = 1;
+      self->texture_is_symbolic = FALSE;
+
+      if (change == NULL ||
+          (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON_SIZE) &&
+          !GTK_IS_CSS_TRANSIENT_NODE (self->node)))
+        gtk_widget_queue_resize (self->owner);
+    }
+}
+
+static void
+gtk_icon_helper_take_definition (GtkIconHelper      *self,
+                                 GtkImageDefinition *def)
+{
+  _gtk_icon_helper_clear (self);
+
+  if (def == NULL)
+    return;
+
+  gtk_image_definition_unref (self->def);
+  self->def = def;
+
+  gtk_icon_helper_invalidate (self);
+}
+
+void
+_gtk_icon_helper_clear (GtkIconHelper *self)
+{
+  g_clear_object (&self->paintable);
+  self->texture_scale = 1;
+  self->texture_is_symbolic = FALSE;
+
+  if (gtk_image_definition_get_storage_type (self->def) != GTK_IMAGE_EMPTY)
+    {
+      gtk_image_definition_unref (self->def);
+      self->def = gtk_image_definition_new_empty ();
+      gtk_icon_helper_invalidate (self);
+    }
+}
+
+static void
+gtk_icon_helper_finalize (GObject *object)
+{
+  GtkIconHelper *self = GTK_ICON_HELPER (object);
+
+  _gtk_icon_helper_clear (self);
+  g_signal_handlers_disconnect_by_func (self->owner, G_CALLBACK (gtk_icon_helper_invalidate), self);
+  gtk_image_definition_unref (self->def);
+
+  G_OBJECT_CLASS (gtk_icon_helper_parent_class)->finalize (object);
+}
+
+void
+gtk_icon_helper_class_init (GtkIconHelperClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->finalize = gtk_icon_helper_finalize;
+}
+
+void
+gtk_icon_helper_init (GtkIconHelper *self)
+{
+  self->def = gtk_image_definition_new_empty ();
+}
+
+GtkIconHelper *
+gtk_icon_helper_new (GtkCssNode *css_node,
+                     GtkWidget  *owner)
+{
+  GtkIconHelper *self;
+  
+  self = g_object_new (GTK_TYPE_ICON_HELPER, NULL);
+
+  self->pixel_size = -1;
+  self->texture_is_symbolic = FALSE;
+
+  self->node = css_node;
+  self->owner = owner;
+  g_signal_connect_swapped (owner, "direction-changed", G_CALLBACK (gtk_icon_helper_invalidate), self);
+  g_signal_connect_swapped (owner, "notify::scale-factor", G_CALLBACK (gtk_icon_helper_invalidate), self);
+
+  return self;
+}
+
 void
 gtk_icon_helper_measure (GtkIconHelper *self,
                          GtkOrientation orientation,
@@ -615,27 +750,6 @@ _gtk_icon_helper_get_icon_name (GtkIconHelper *self)
   return gtk_image_definition_get_icon_name (self->def);
 }
 
-void
-gtk_icon_helper_snapshot (GtkIconHelper *self,
-                          GtkSnapshot   *snapshot,
-                          double         width,
-                          double         height)
-{
-  GtkCssStyle *style;
-
-  style = gtk_css_node_get_style (self->node);
-
-  gtk_icon_helper_ensure_paintable (self);
-  if (self->paintable == NULL)
-    return;
-
-  gtk_css_style_snapshot_icon_paintable (style,
-                                         snapshot,
-                                         self->paintable,
-                                         width, height,
-                                         self->texture_is_symbolic);
-}
-
 gboolean
 _gtk_icon_helper_get_is_empty (GtkIconHelper *self)
 {
index 2a14a61d654fb442a2b419ef2917779ecd5ecc77..2e6846c266a3ad6445e7ed96e61d7bb33c7e538f 100644 (file)
@@ -76,11 +76,6 @@ void _gtk_icon_helper_get_size (GtkIconHelper *self,
                                 gint *width_out,
                                 gint *height_out);
 
-void gtk_icon_helper_snapshot (GtkIconHelper *self,
-                               GtkSnapshot *snapshot,
-                               double       width,
-                               double       height);
-
 gboolean _gtk_icon_helper_get_force_scale_pixbuf (GtkIconHelper *self);
 void     _gtk_icon_helper_set_force_scale_pixbuf (GtkIconHelper *self,
                                                   gboolean       force_scale);
index 5502cba89b9f0d5d6a777a99976178cbed022b5d..2d4d5a0dbb250f53056e379f88abc6ca8daad6db 100644 (file)
@@ -1211,7 +1211,7 @@ gtk_image_snapshot (GtkWidget   *widget,
 
   if (_gtk_icon_helper_get_storage_type (priv->icon_helper) == GTK_IMAGE_PAINTABLE)
     {
-      gtk_icon_helper_snapshot (priv->icon_helper, snapshot, width, height);
+      gdk_paintable_snapshot (GDK_PAINTABLE (priv->icon_helper), snapshot, width, height);
     }
   else
     {
@@ -1226,7 +1226,7 @@ gtk_image_snapshot (GtkWidget   *widget,
         y = CLAMP (baseline - h * gtk_image_get_baseline_align (image), 0, height - h);
 
       gtk_snapshot_offset (snapshot, x, y);
-      gtk_icon_helper_snapshot (priv->icon_helper, snapshot, w, h);
+      gdk_paintable_snapshot (GDK_PAINTABLE (priv->icon_helper), snapshot, w, h);
       gtk_snapshot_offset (snapshot, -x, -y);
     }
 }