[gtk+/picture: 5/22] gtk: Add the ability to set a GdkPicture on a GtkImage



commit 252ccb129fb744ba3849bd63c34ec86df8d2d2ec
Author: Benjamin Otte <otte redhat com>
Date:   Sat Feb 5 16:38:20 2011 +0100

    gtk: Add the ability to set a GdkPicture on a GtkImage

 gtk/gtkimage.c        |  163 ++++++++++++++++++++++++++++++++++++++++++++++++-
 gtk/gtkimage.h        |    9 +++-
 gtk/gtkimageprivate.h |    6 ++
 3 files changed, 175 insertions(+), 3 deletions(-)
---
diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c
index 25d4173..e300de2 100644
--- a/gtk/gtkimage.c
+++ b/gtk/gtkimage.c
@@ -35,6 +35,7 @@
 #include "gtkstock.h"
 #include "gtkicontheme.h"
 #include "gtksizerequest.h"
+#include "gtkstylablepicture.h"
 #include "gtkintl.h"
 #include "gtkprivate.h"
 #include "gtktypebuiltins.h"
@@ -43,11 +44,11 @@
  * SECTION:gtkimage
  * @Short_description: A widget displaying an image
  * @Title: GtkImage
- * @See_also:#GdkPixbuf
+ * @See_also:#GdkPixbuf, #GdkPicture
  *
  * The #GtkImage widget displays an image. Various kinds of object
  * can be displayed as an image; most typically, you would load a
- * #GdkPixbuf ("pixel buffer") from a file, and then display that.
+ * #GdkPicture ("pixel buffer") from a file, and then display that.
  * There's a convenience function to do this, gtk_image_new_from_file(),
  * used as follows:
  * <informalexample><programlisting>
@@ -137,6 +138,7 @@ struct _GtkImagePrivate
 
   union
   {
+    GtkImagePictureData    picture;
     GtkImagePixbufData     pixbuf;
     GtkImageStockData      stock;
     GtkImageIconSetData    icon_set;
@@ -194,6 +196,7 @@ static void icon_theme_changed             (GtkImage     *image);
 enum
 {
   PROP_0,
+  PROP_PICTURE,
   PROP_PIXBUF,
   PROP_FILE,
   PROP_STOCK,
@@ -231,6 +234,14 @@ gtk_image_class_init (GtkImageClass *class)
   widget_class->screen_changed = gtk_image_screen_changed;
   
   g_object_class_install_property (gobject_class,
+                                   PROP_PICTURE,
+                                   g_param_spec_object ("picture",
+                                                        P_("Picture"),
+                                                        P_("A GdkPicture to display"),
+                                                        GDK_TYPE_PICTURE,
+                                                        GTK_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
                                    PROP_PIXBUF,
                                    g_param_spec_object ("pixbuf",
                                                         P_("Pixbuf"),
@@ -401,6 +412,10 @@ gtk_image_set_property (GObject      *object,
 
   switch (prop_id)
     {
+    case PROP_PICTURE:
+      gtk_image_set_from_picture (image,
+                                  g_value_get_object (value));
+      break;
     case PROP_PIXBUF:
       gtk_image_set_from_pixbuf (image,
                                  g_value_get_object (value));
@@ -488,6 +503,13 @@ gtk_image_get_property (GObject     *object,
   
   switch (prop_id)
     {
+    case PROP_PICTURE:
+      if (priv->storage_type != GTK_IMAGE_PICTURE)
+        g_value_set_object (value, NULL);
+      else
+        g_value_set_object (value,
+                            gtk_image_get_picture (image));
+      break;
     case PROP_PIXBUF:
       if (priv->storage_type != GTK_IMAGE_PIXBUF)
         g_value_set_object (value, NULL);
@@ -590,6 +612,29 @@ gtk_image_new_from_file   (const gchar *filename)
 }
 
 /**
+ * gtk_image_new_from_picture:
+ * @picture: (allow-none): a #GdkPicture, or %NULL
+ *
+ * Creates a new #GtkImage displaying @picture.
+ * The #GtkImage does not assume a reference to the
+ * picture; you still need to unref it if you own references.
+ * #GtkImage will add its own reference rather than adopting yours.
+ * 
+ * Return value: a new #GtkImage
+ **/
+GtkWidget*
+gtk_image_new_from_picture (GdkPicture *picture)
+{
+  GtkImage *image;
+
+  image = g_object_new (GTK_TYPE_IMAGE, NULL);
+
+  gtk_image_set_from_picture (image, picture);
+
+  return GTK_WIDGET (image);  
+}
+
+/**
  * gtk_image_new_from_pixbuf:
  * @pixbuf: (allow-none): a #GdkPixbuf, or %NULL
  *
@@ -817,6 +862,67 @@ gtk_image_set_from_file   (GtkImage    *image,
   g_object_thaw_notify (G_OBJECT (image));
 }
 
+static void
+gtk_image_picture_resized (GdkPicture *picture, GtkImage *image)
+{
+  gtk_image_update_size (image,
+                         gdk_picture_get_width (picture),
+                         gdk_picture_get_height (picture));
+}
+
+static void
+gtk_image_picture_changed (GdkPicture           *picture,
+                           const cairo_region_t *region,
+                           GtkImage             *image)
+{
+  /* XXX: take region into account */
+  gtk_widget_queue_draw (GTK_WIDGET (image));
+}
+
+/**
+ * gtk_image_set_from_picture:
+ * @image: a #GtkImage
+ * @picture: (allow-none): a #GdkPicture or %NULL
+ *
+ * See gtk_image_new_from_picture() for details.
+ **/
+void
+gtk_image_set_from_picture (GtkImage  *image,
+                            GdkPicture *picture)
+{
+  GtkImagePrivate *priv;
+
+  g_return_if_fail (GTK_IS_IMAGE (image));
+  g_return_if_fail (picture == NULL || GDK_IS_PICTURE (picture));
+
+  priv = image->priv;
+
+  g_object_freeze_notify (G_OBJECT (image));
+  
+  if (picture)
+    picture = gtk_widget_style_picture (GTK_WIDGET (image), picture);
+
+  gtk_image_clear (image);
+
+  if (picture != NULL)
+    {
+      priv->storage_type = GTK_IMAGE_PICTURE;
+
+      g_signal_connect (picture, "resized", G_CALLBACK (gtk_image_picture_resized), image);
+      g_signal_connect (picture, "changed", G_CALLBACK (gtk_image_picture_changed), image);
+
+      priv->data.picture.picture = picture;
+
+      gtk_image_update_size (image,
+                             gdk_picture_get_width (picture),
+                             gdk_picture_get_height (picture));
+    }
+
+  g_object_notify (G_OBJECT (image), "picture");
+  
+  g_object_thaw_notify (G_OBJECT (image));
+}
+
 /**
  * gtk_image_set_from_pixbuf:
  * @image: a #GtkImage
@@ -1109,6 +1215,37 @@ gtk_image_get_storage_type (GtkImage *image)
 }
 
 /**
+ * gtk_image_get_picture:
+ * @image: a #GtkImage
+ *
+ * Gets the #GdkPicture being displayed by the #GtkImage.
+ * The storage type of the image must be %GTK_IMAGE_EMPTY or
+ * %GTK_IMAGE_PIXBUF (see gtk_image_get_storage_type()).
+ * The caller of this function does not own a reference to the
+ * returned picture.
+ * 
+ * Return value: (transfer none): the displayed picture, or %NULL if
+ * the image is empty
+ **/
+GdkPicture*
+gtk_image_get_picture (GtkImage *image)
+{
+  GtkImagePrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_IMAGE (image), NULL);
+
+  priv = image->priv;
+
+  g_return_val_if_fail (priv->storage_type == GTK_IMAGE_PICTURE ||
+                        priv->storage_type == GTK_IMAGE_EMPTY, NULL);
+
+  if (priv->storage_type == GTK_IMAGE_EMPTY)
+    return NULL;
+  
+  return gtk_picture_get_unstyled (priv->data.picture.picture);
+}
+
+/**
  * gtk_image_get_pixbuf:
  * @image: a #GtkImage
  *
@@ -1659,6 +1796,11 @@ gtk_image_draw (GtkWidget *widget,
 
       switch (priv->storage_type)
         {
+        case GTK_IMAGE_PICTURE:
+          cairo_translate (cr, x, y);
+          gdk_picture_draw (priv->data.picture.picture, cr);
+          pixbuf = NULL;
+          break;
 
         case GTK_IMAGE_PIXBUF:
           pixbuf = priv->data.pixbuf.pixbuf;
@@ -1804,6 +1946,23 @@ gtk_image_reset (GtkImage *image)
   
   switch (priv->storage_type)
     {
+    case GTK_IMAGE_PICTURE:
+
+      if (priv->data.picture.picture)
+        {
+          g_object_unref (priv->data.picture.picture);
+          g_signal_handlers_disconnect_by_func (priv->data.picture.picture,
+                                                gtk_image_picture_resized,
+                                                image);
+          g_signal_handlers_disconnect_by_func (priv->data.picture.picture,
+                                                gtk_image_picture_changed,
+                                                image);
+        }
+
+      g_object_notify (G_OBJECT (image), "picture");
+      
+      break;
+
 
     case GTK_IMAGE_PIXBUF:
 
diff --git a/gtk/gtkimage.h b/gtk/gtkimage.h
index bdd74e7..1bd1c85 100644
--- a/gtk/gtkimage.h
+++ b/gtk/gtkimage.h
@@ -62,6 +62,8 @@ typedef struct _GtkImageClass         GtkImageClass;
  *  This image type was added in GTK+ 2.6
  * @GTK_IMAGE_GICON: the widget contains a #GIcon.
  *  This image type was added in GTK+ 2.14
+ * @GTK_IMAGE_PICTURE: the widget contains a #GdkPicture.
+ *  This image type was added in GTK+ 3.2
  *
  * Describes the image data representation used by a #GtkImage. If you
  * want to get the image from the widget, you can only get the
@@ -79,7 +81,8 @@ typedef enum
   GTK_IMAGE_ICON_SET,
   GTK_IMAGE_ANIMATION,
   GTK_IMAGE_ICON_NAME,
-  GTK_IMAGE_GICON
+  GTK_IMAGE_GICON,
+  GTK_IMAGE_PICTURE
 } GtkImageType;
 
 /**
@@ -111,6 +114,7 @@ GType      gtk_image_get_type (void) G_GNUC_CONST;
 
 GtkWidget* gtk_image_new                (void);
 GtkWidget* gtk_image_new_from_file      (const gchar     *filename);
+GtkWidget* gtk_image_new_from_picture   (GdkPicture       *picture);
 GtkWidget* gtk_image_new_from_pixbuf    (GdkPixbuf       *pixbuf);
 GtkWidget* gtk_image_new_from_stock     (const gchar     *stock_id,
                                          GtkIconSize      size);
@@ -125,6 +129,8 @@ GtkWidget* gtk_image_new_from_gicon     (GIcon           *icon,
 void gtk_image_clear              (GtkImage        *image);
 void gtk_image_set_from_file      (GtkImage        *image,
                                    const gchar     *filename);
+void gtk_image_set_from_picture   (GtkImage        *image,
+                                   GdkPicture      *picture);
 void gtk_image_set_from_pixbuf    (GtkImage        *image,
                                    GdkPixbuf       *pixbuf);
 void gtk_image_set_from_stock     (GtkImage        *image,
@@ -147,6 +153,7 @@ void gtk_image_set_pixel_size     (GtkImage        *image,
 GtkImageType gtk_image_get_storage_type (GtkImage   *image);
 
 GdkPixbuf* gtk_image_get_pixbuf   (GtkImage         *image);
+GdkPicture*gtk_image_get_picture  (GtkImage         *image);
 void       gtk_image_get_stock    (GtkImage         *image,
                                    gchar           **stock_id,
                                    GtkIconSize      *size);
diff --git a/gtk/gtkimageprivate.h b/gtk/gtkimageprivate.h
index 2eb2238..e8d3de6 100644
--- a/gtk/gtkimageprivate.h
+++ b/gtk/gtkimageprivate.h
@@ -34,6 +34,7 @@
 G_BEGIN_DECLS
 
 typedef struct _GtkImagePixbufData  GtkImagePixbufData;
+typedef struct _GtkImagePictureData  GtkImagePictureData;
 typedef struct _GtkImageStockData   GtkImageStockData;
 typedef struct _GtkImageIconSetData GtkImageIconSetData;
 typedef struct _GtkImageAnimationData GtkImageAnimationData;
@@ -45,6 +46,11 @@ struct _GtkImagePixbufData
   GdkPixbuf *pixbuf;
 };
 
+struct _GtkImagePictureData
+{
+  GdkPicture *picture;
+};
+
 struct _GtkImageStockData
 {
   gchar *stock_id;



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