[gtk+/wip/baedert/gtkimageview: 138/160] Implement image abstraction for pixbuf images
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/baedert/gtkimageview: 138/160] Implement image abstraction for pixbuf images
- Date: Sun, 5 Jun 2016 14:34:17 +0000 (UTC)
commit ce9f8a5454e50cbd97013cf20f9c006ad28728f7
Author: Timm Bäder <mail baedert org>
Date: Sun Apr 17 10:36:16 2016 +0200
Implement image abstraction for pixbuf images
demos/gtk-demo/image_view.c | 27 ++-----
gtk/gtkabstractimage.c | 179 ++++++++++++++++++++++++++++++++++++++++++-
gtk/gtkabstractimage.h | 77 ++++++++++++++++++-
gtk/gtkimageview.c | 57 +++++++++-----
4 files changed, 297 insertions(+), 43 deletions(-)
---
diff --git a/demos/gtk-demo/image_view.c b/demos/gtk-demo/image_view.c
index 69173b5..6f1a68c 100644
--- a/demos/gtk-demo/image_view.c
+++ b/demos/gtk-demo/image_view.c
@@ -154,38 +154,27 @@ scale_scale_format_value_cb (GtkScale *scale,
void
load_pixbuf_button_clicked_cb ()
{
-
-
GtkPixbufImage *image = gtk_pixbuf_image_new ("/usr/share/backgrounds/gnome/Fabric.jpg", 1);
gtk_image_view_set_abstract_image (GTK_IMAGE_VIEW (image_view),
GTK_ABSTRACT_IMAGE (image));
-
- /*GdkPixbuf *pixbuf;*/
-
- /*pixbuf = gdk_pixbuf_new_from_file ("/usr/share/backgrounds/gnome/Fabric.jpg",*/
- /*NULL);*/
-
- /*g_assert (pixbuf != NULL);*/
- /*gtk_image_view_set_pixbuf (GTK_IMAGE_VIEW (image_view), pixbuf, 0);*/
-
- /*g_object_unref (G_OBJECT (pixbuf));*/
}
void
load_hidpi_pixbuf_button_clicked_cb ()
{
- GdkPixbuf *pixbuf;
+ GdkPixbufAnimation *animation;
+ GtkPixbufAnimationImage *image;
- /* I really hope you have this. */
- pixbuf = gdk_pixbuf_new_from_file ("/usr/share/backgrounds/gnome/Fabric.jpg",
- NULL);
+ g_warning ("Reminder: This just loads an animation right now.");
- g_assert (pixbuf != NULL);
- gtk_image_view_set_pixbuf (GTK_IMAGE_VIEW (image_view), pixbuf, 2);
+ animation = gdk_pixbuf_animation_new_from_file ("/home/baedert/0mKXcg1.gif", NULL);
+ image = gtk_pixbuf_animation_image_new (animation, 1);
- g_object_unref (G_OBJECT (pixbuf));
+ g_message ("%s", g_type_name (G_TYPE_FROM_INSTANCE (image)));
+
+ gtk_image_view_set_abstract_image (GTK_IMAGE_VIEW (image_view), GTK_ABSTRACT_IMAGE (image));
}
void
diff --git a/gtk/gtkabstractimage.c b/gtk/gtkabstractimage.c
index d073c3f..82d40ed 100644
--- a/gtk/gtkabstractimage.c
+++ b/gtk/gtkabstractimage.c
@@ -17,19 +17,37 @@
#include "config.h"
#include "gtkabstractimage.h"
+#include "gtkmarshalers.h"
+#include "gtkintl.h"
G_DEFINE_ABSTRACT_TYPE (GtkAbstractImage, gtk_abstract_image, G_TYPE_OBJECT)
/* GtkAbstractImage {{{ */
+enum
+{
+ CHANGED,
+ LAST_SIGNAL
+};
+
+static guint image_signals[LAST_SIGNAL] = { 0 };
+
static void
gtk_abstract_image_init (GtkAbstractImage *image)
{}
static void
gtk_abstract_image_class_init (GtkAbstractImageClass *klass)
-{}
+{
+ image_signals[CHANGED] = g_signal_new (I_("changed"),
+ G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GtkAbstractImageClass, changed),
+ NULL, NULL,
+ _gtk_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
int
gtk_abstract_image_get_width (GtkAbstractImage *image)
@@ -55,11 +73,17 @@ gtk_abstract_image_draw (GtkAbstractImage *image, cairo_t *ct)
GTK_ABSTRACT_IMAGE_GET_CLASS (image)->draw (image, ct);
}
-/* }}} */
+int
+gtk_abstract_image_get_scale_factor (GtkAbstractImage *image)
+{
+ g_return_val_if_fail (GTK_IS_ABSTRACT_IMAGE (image), 1);
+ return GTK_ABSTRACT_IMAGE_GET_CLASS (image)->get_scale_factor (image);
+}
-/* GtkPixbufImage {{{ */
+/* }}} */
+/* GtkPixbufImage {{{ */
G_DEFINE_TYPE (GtkPixbufImage, gtk_pixbuf_image, GTK_TYPE_ABSTRACT_IMAGE)
@@ -116,6 +140,155 @@ gtk_pixbuf_image_class_init (GtkPixbufImageClass *klass)
image_class->get_scale_factor = gtk_pixbuf_image_get_scale_factor;
image_class->draw = gtk_pixbuf_image_draw;
}
+/* }}} */
+
+/* GtkPixbufAnimationImage {{{ */
+G_DEFINE_TYPE (GtkPixbufAnimationImage, gtk_pixbuf_animation_image, GTK_TYPE_ABSTRACT_IMAGE)
+
+GtkPixbufAnimationImage *
+gtk_pixbuf_animation_image_new (GdkPixbufAnimation *animation, int scale_factor)
+{
+ GtkPixbufAnimationImage *image = g_object_new (GTK_TYPE_PIXBUF_ANIMATION_IMAGE, NULL);
+ g_assert (animation);
+
+ image->scale_factor = scale_factor;
+ image->animation = animation;
+ image->iter = gdk_pixbuf_animation_get_iter (animation, NULL);
+ /* TODO: Use the delay for the CURRENT iter... */
+ image->delay_ms = gdk_pixbuf_animation_iter_get_delay_time (image->iter);
+ g_assert (image->iter);
+ g_assert (gdk_pixbuf_animation_iter_get_pixbuf (image->iter));
+ image->frame = gdk_cairo_surface_create_from_pixbuf (gdk_pixbuf_animation_iter_get_pixbuf (image->iter),
+ scale_factor, NULL);
+
+ g_assert (image->frame);
+
+ g_message ("CTOR");
+ return image;
+}
+
+static int
+gtk_pixbuf_animation_image_get_width (GtkAbstractImage *image)
+{
+ return gdk_pixbuf_animation_get_width (GTK_PIXBUF_ANIMATION_IMAGE (image)->animation);
+}
+
+static int
+gtk_pixbuf_animation_image_get_height (GtkAbstractImage *image)
+{
+ return gdk_pixbuf_animation_get_height (GTK_PIXBUF_ANIMATION_IMAGE (image)->animation);
+}
+
+static int
+gtk_pixbuf_animation_image_get_scale_factor (GtkAbstractImage *image)
+{
+ /*return GTK_PIXBUF_ANIMATION_IMAGE (image)->scale_factor;*/
+ return 1;
+}
+
+static gboolean
+gtk_pixbuf_animation_image_advance (gpointer user_data)
+{
+ GtkPixbufAnimationImage *image = user_data;
+
+ gdk_pixbuf_animation_iter_advance (image->iter, NULL);
+ image->frame = gdk_cairo_surface_create_from_pixbuf (gdk_pixbuf_animation_iter_get_pixbuf (image->iter),
+ image->scale_factor, NULL);
+
+ g_signal_emit (image, image_signals[CHANGED], 0);
+
+ return G_SOURCE_CONTINUE;
+}
+
+static void
+gtk_pixbuf_animation_image_draw (GtkAbstractImage *_image, cairo_t *ct)
+{
+ GtkPixbufAnimationImage *image = GTK_PIXBUF_ANIMATION_IMAGE (_image);
+
+ /* We start the animation at the first draw() call... */
+ if (image->timeout_id == 0)
+ {
+ image->timeout_id = g_timeout_add (image->delay_ms, gtk_pixbuf_animation_image_advance, image);
+ }
+
+ cairo_set_source_surface (ct, image->frame, 0, 0);
+}
+static void
+gtk_pixbuf_animation_image_init (GtkPixbufAnimationImage *image)
+{
+ image->timeout_id = 0;
+}
+
+static void
+gtk_pixbuf_animation_image_class_init (GtkPixbufAnimationImageClass *klass)
+{
+ GtkAbstractImageClass *image_class = GTK_ABSTRACT_IMAGE_CLASS (klass);
+
+ image_class->get_width = gtk_pixbuf_animation_image_get_width;
+ image_class->get_height = gtk_pixbuf_animation_image_get_height;
+ image_class->get_scale_factor = gtk_pixbuf_animation_image_get_scale_factor;
+ image_class->draw = gtk_pixbuf_animation_image_draw;
+}
+/* }}} */
+
+/* GtkSurfaceImage {{{ */
+
+G_DEFINE_TYPE (GtkSurfaceImage, gtk_surface_image, GTK_TYPE_ABSTRACT_IMAGE)
+
+static int
+gtk_surface_image_get_width (GtkAbstractImage *image)
+{
+ return cairo_image_surface_get_width (GTK_SURFACE_IMAGE (image)->surface);
+}
+
+static int
+gtk_surface_image_get_height (GtkAbstractImage *image)
+{
+ return cairo_image_surface_get_height (GTK_SURFACE_IMAGE (image)->surface);
+}
+
+static int
+gtk_surface_image_get_scale_factor (GtkAbstractImage *image)
+{
+ double sx, sy;
+ cairo_surface_t *surface = GTK_SURFACE_IMAGE (image)->surface;
+
+ cairo_surface_get_device_scale (surface, &sx, &sy);
+
+ return (int)sx;
+}
+
+static void
+gtk_surface_image_draw (GtkAbstractImage *image, cairo_t *ct)
+{
+ cairo_set_source_surface (ct, GTK_SURFACE_IMAGE (image)->surface, 0, 0);
+}
+
+GtkSurfaceImage *
+gtk_surface_image_new (cairo_surface_t *surface)
+{
+ GtkSurfaceImage *image = g_object_new (GTK_TYPE_SURFACE_IMAGE, NULL);
+ image->surface = surface;
+
+ return image;
+}
+
+static void
+gtk_surface_image_init (GtkSurfaceImage *image)
+{
+
+}
+
+static void
+gtk_surface_image_class_init (GtkSurfaceImageClass *klass)
+{
+ GtkAbstractImageClass *image_class = GTK_ABSTRACT_IMAGE_CLASS (klass);
+
+ image_class->get_width = gtk_surface_image_get_width;
+ image_class->get_height = gtk_surface_image_get_height;
+ image_class->get_scale_factor = gtk_surface_image_get_scale_factor;
+ image_class->draw = gtk_surface_image_draw;
+}
/* }}} */
diff --git a/gtk/gtkabstractimage.h b/gtk/gtkabstractimage.h
index 2eb9083..1e1569a 100644
--- a/gtk/gtkabstractimage.h
+++ b/gtk/gtkabstractimage.h
@@ -50,6 +50,8 @@ struct _GtkAbstractImageClass
int (*get_height) (GtkAbstractImage *image);
int (*get_scale_factor) (GtkAbstractImage *image);
void (*draw) (GtkAbstractImage *image, cairo_t *ct);
+
+ void (*changed) (GtkAbstractImage image);
};
GDK_AVAILABLE_IN_3_20
@@ -61,6 +63,9 @@ int gtk_abstract_image_get_height (GtkAbstractImage *image);
void gtk_abstract_image_draw (GtkAbstractImage *image, cairo_t *ct);
+int gtk_abstract_image_get_scale_factor (GtkAbstractImage *image);
+
+/* ------------------------------------------------------------------------------------ */
typedef struct _GtkPixbufImage GtkPixbufImage;
typedef struct _GtkPixbufImageClass GtkPixbufImageClass;
@@ -68,8 +73,8 @@ typedef struct _GtkPixbufImageClass GtkPixbufImageClass;
#define GTK_TYPE_PIXBUF_IMAGE (gtk_pixbuf_image_get_type ())
#define GTK_PIXBUF_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_PIXBUF_IMAGE,
GtkPixbufImage))
#define GTK_PIXBUF_IMAGE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_PIXBUF_IMAGE,
GtkPixbufImageClass))
-#define GTK_IS_pixbuf_image(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_PIXBUF_IMAGE))
-#define GTK_IS_pixbuf_image_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_PIXBUF_IMAGE))
+#define GTK_IS_PIXBUF_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_PIXBUF_IMAGE))
+#define GTK_IS_PIXBUF_IMAGE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_PIXBUF_IMAGE))
#define GTK_PIXBUF_IMAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PIXBUF_IMAGE,
GtkPixbufImageClass))
struct _GtkPixbufImage
@@ -85,9 +90,77 @@ struct _GtkPixbufImageClass
};
GDK_AVAILABLE_IN_3_20
+GType gtk_pixbuf_image_get_type (void) G_GNUC_CONST;
+
+GDK_AVAILABLE_IN_3_20
GtkPixbufImage *gtk_pixbuf_image_new (const char *path, int scale_factor);
+/* ------------------------------------------------------------------------------------ */
+
+
+typedef struct _GtkPixbufAnimationImage GtkPixbufAnimationImage;
+typedef struct _GtkPixbufAnimationImageClass GtkPixbufAnimationImageClass;
+
+#define GTK_TYPE_PIXBUF_ANIMATION_IMAGE (gtk_pixbuf_animation_image_get_type ())
+#define GTK_PIXBUF_ANIMATION_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj,
GTK_TYPE_PIXBUF_ANIMATION_IMAGE, GtkPixbufAnimationImage))
+#define GTK_PIXBUF_ANIMATION_IMAGE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls,
GTK_TYPE_PIXBUF_ANIMATION_IMAGE, GtkPixbufAnimationImageClass))
+#define GTK_IS_PIXBUX_ANIMATION_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj,
GTK_TYPE_PIXBUF_ANIMATION_IMAGE))
+#define GTK_IS_PIXBUX_ANIMATION_IMAGE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj,
GTK_TYPE_PIXBUF_ANIMATION_IMAGE))
+#define GTK_PIXBUF_ANIMATION_IMAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
GTK_TYPE_PIXBUF_ANIMATION_IMAGE, GtkPixbufAnimationImageClass))
+
+struct _GtkPixbufAnimationImage
+{
+ GtkAbstractImage parent;
+ GdkPixbufAnimation *animation;
+ GdkPixbufAnimationIter *iter;
+ cairo_surface_t *frame;
+ int scale_factor;
+ int delay_ms;
+ guint timeout_id;
+};
+
+struct _GtkPixbufAnimationImageClass
+{
+ GtkAbstractImageClass parent_class;
+};
+
+GDK_AVAILABLE_IN_3_20
+GType gtk_pixbuf_animation_image_get_type (void) G_GNUC_CONST;
+
+GDK_AVAILABLE_IN_3_20
+GtkPixbufAnimationImage *gtk_pixbuf_animation_image_new (GdkPixbufAnimation *animation,
+ int scale_factor);
+
+
+/* ------------------------------------------------------------------------------------ */
+
+typedef struct _GtkSurfaceImage GtkSurfaceImage;
+typedef struct _GtkSurfaceImageClass GtkSurfaceImageClass;
+
+
+#define GTK_TYPE_SURFACE_IMAGE (gtk_surface_image_get_type ())
+#define GTK_SURFACE_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_SURFACE_IMAGE,
GtkSurfaceImage))
+#define GTK_SURFACE_IMAGE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_SURFACE_IMAGE,
GtkSurfaceImageClass))
+#define GTK_IS_SURFACE_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_SURFACE_IMAGE))
+#define GTK_IS_SURFACE_IMAGE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_SURFACE_IMAGE))
+#define GTK_SURFACE_IMAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SURFACE_IMAGE,
GtkSurfaceImageClass))
+
+struct _GtkSurfaceImage
+{
+ GtkAbstractImage parent;
+ cairo_surface_t *surface;
+};
+
+struct _GtkSurfaceImageClass
+{
+ GtkAbstractImageClass parent_class;
+};
+
+GDK_AVAILABLE_IN_3_20
+GType gtk_surface_image_get_type (void) G_GNUC_CONST;
+
+GtkSurfaceImage *gtk_surface_image_new (cairo_surface_t *surface);
G_END_DECLS
diff --git a/gtk/gtkimageview.c b/gtk/gtkimageview.c
index e79202e..424dfbb 100644
--- a/gtk/gtkimageview.c
+++ b/gtk/gtkimageview.c
@@ -51,6 +51,7 @@
#include "gtkgesturezoom.h"
#include "gtkscrollable.h"
#include "gtkadjustment.h"
+#include "gtkabstractimage.h"
#include <gdk/gdkcairo.h>
#include <math.h>
@@ -605,6 +606,7 @@ gtk_image_view_compute_bounding_box (GtkImageView *image_view,
gtk_widget_get_allocation (GTK_WIDGET (image_view), &alloc);
angle = gtk_image_view_get_real_angle (image_view);
+ g_message ("%s", g_type_name (G_TYPE_FROM_INSTANCE (priv->image)));
image_width = gtk_abstract_image_get_width (priv->image) /
gtk_abstract_image_get_scale_factor (priv->image);
image_height = gtk_abstract_image_get_height (priv->image) /
@@ -2175,25 +2177,24 @@ gtk_image_view_new ()
}
static void
-gtk_image_view_replace_surface (GtkImageView *image_view,
- cairo_surface_t *surface,
- int scale_factor)
+gtk_image_view_replace_image (GtkImageView *image_view,
+ GtkAbstractImage *image)
{
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
- /*if (priv->image_surface)*/
- /*cairo_surface_destroy (priv->image_surface);*/
+ if (priv->image)
+ g_object_unref (priv->image);
- if (scale_factor == 0)
- priv->scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (image_view));
- else
- priv->scale_factor = scale_factor;
+ /*if (scale_factor == 0)*/
+ /*priv->scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (image_view));*/
+ /*else*/
+ /*priv->scale_factor = scale_factor;*/
- /*priv->image_surface = surface;*/
+ priv->image = image;
priv->size_valid = FALSE;
- /*if (surface)*/
- /*cairo_surface_reference (priv->image_surface);*/
+ if (priv->image)
+ g_object_ref (priv->image);
}
static void
@@ -2219,9 +2220,9 @@ gtk_image_view_update_surface (GtkImageView *image_view,
/*(scale_factor != priv->scale_factor);*/
/*}*/
- gtk_image_view_replace_surface (image_view,
- new_surface,
- scale_factor);
+ /*gtk_image_view_replace_image (image_view,*/
+ /*new_surface,*/
+ /*scale_factor);*/
if (priv->fit_allocation || !size_changed)
gtk_widget_queue_draw (GTK_WIDGET (image_view));
@@ -2520,6 +2521,7 @@ gtk_image_view_set_surface (GtkImageView *image_view,
cairo_surface_t *surface)
{
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
+ GtkSurfaceImage *image;
double scale_x = 0.0;
double scale_y;
@@ -2541,9 +2543,9 @@ gtk_image_view_set_surface (GtkImageView *image_view,
priv->is_animation = FALSE;
}
- gtk_image_view_replace_surface (image_view,
- surface,
- scale_x);
+ image = gtk_surface_image_new (surface);
+
+ gtk_image_view_replace_image (image_view, GTK_ABSTRACT_IMAGE (image));
gtk_image_view_update_adjustments (image_view);
@@ -2571,11 +2573,22 @@ gtk_image_view_set_animation (GtkImageView *image_view,
GdkPixbufAnimation *animation,
int scale_factor)
{
+ /*GtkPixbufAnimationImage *image;*/
g_return_if_fail (GTK_IS_IMAGE_VIEW (image_view));
g_return_if_fail (GDK_IS_PIXBUF_ANIMATION (animation));
g_return_if_fail (scale_factor >= 0);
- gtk_image_view_replace_animation (image_view, animation, scale_factor);
+ /*gtk_image_view_replace_animation (image_view, animation, scale_factor);*/
+
+ /*image = gtk_pixbuf_animation_image-nwe (animation, scale_factor);*/
+}
+
+void
+image_changed_cb (GtkAbstractImage *image, gpointer user_data)
+{
+ GtkImageView *image_view = user_data;
+
+ gtk_widget_queue_draw (GTK_WIDGET (image_view));
}
void
@@ -2587,7 +2600,13 @@ gtk_image_view_set_abstract_image (GtkImageView *image_view,
g_return_if_fail (GTK_IS_IMAGE_VIEW (image_view));
g_return_if_fail (GTK_IS_ABSTRACT_IMAGE (abstract_image));
+
+ g_message ("%s", g_type_name (G_TYPE_FROM_INSTANCE (abstract_image)));
+
priv->image = abstract_image;
+ g_signal_connect (G_OBJECT (priv->image),
+ "changed", G_CALLBACK (image_changed_cb), image_view);
+
gtk_widget_queue_resize (GTK_WIDGET (image_view));
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]