[gtk+/wip/baedert/gtkimageview: 99/118] add image abstraction
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/baedert/gtkimageview: 99/118] add image abstraction
- Date: Thu, 12 May 2016 20:03:41 +0000 (UTC)
commit 22b2139b7688c3811615da018c3b3d6bf0863bd5
Author: Timm Bäder <mail baedert org>
Date: Wed Feb 17 21:36:26 2016 +0100
add image abstraction
demos/gtk-demo/image_view.c | 20 +++++---
gtk/Makefile.am | 2 +
gtk/gtk.h | 1 +
gtk/gtkabstractimage.c | 121 +++++++++++++++++++++++++++++++++++++++++++
gtk/gtkabstractimage.h | 94 +++++++++++++++++++++++++++++++++
gtk/gtkimageview.c | 104 ++++++++++++++++++++++++-------------
gtk/gtkimageview.h | 4 ++
7 files changed, 302 insertions(+), 44 deletions(-)
---
diff --git a/demos/gtk-demo/image_view.c b/demos/gtk-demo/image_view.c
index 894c985..69173b5 100644
--- a/demos/gtk-demo/image_view.c
+++ b/demos/gtk-demo/image_view.c
@@ -154,16 +154,22 @@ scale_scale_format_value_cb (GtkScale *scale,
void
load_pixbuf_button_clicked_cb ()
{
- GdkPixbuf *pixbuf;
- /* I really hope you have this. */
- 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);
+ GtkPixbufImage *image = gtk_pixbuf_image_new ("/usr/share/backgrounds/gnome/Fabric.jpg", 1);
- g_object_unref (G_OBJECT (pixbuf));
+ 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));*/
}
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 49dc9ec..77c6948 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -124,6 +124,7 @@ gtk_public_h_sources = \
gtkx-autocleanups.h \
gtk-a11y.h \
gtkaboutdialog.h \
+ gtkabstractimage.h \
gtkaccelgroup.h \
gtkaccellabel.h \
gtkaccelmap.h \
@@ -605,6 +606,7 @@ gtk_base_c_sources = \
gtksearchenginemodel.c \
fnmatch.c \
gtkaboutdialog.c \
+ gtkabstractimage.c \
gtkaccelgroup.c \
gtkaccellabel.c \
gtkaccelmap.c \
diff --git a/gtk/gtk.h b/gtk/gtk.h
index a853459..8e1994a 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -29,6 +29,7 @@
#include <gdk/gdk.h>
#include <gtk/gtkaboutdialog.h>
+#include <gtk/gtkabstractimage.h>
#include <gtk/gtkaccelgroup.h>
#include <gtk/gtkaccellabel.h>
#include <gtk/gtkaccelmap.h>
diff --git a/gtk/gtkabstractimage.c b/gtk/gtkabstractimage.c
new file mode 100644
index 0000000..d073c3f
--- /dev/null
+++ b/gtk/gtkabstractimage.c
@@ -0,0 +1,121 @@
+/* Copyright 2016 Timm Bäder
+ *
+ * GTK+ is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GTK+; see the file COPYING. If not,
+ * see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include "gtkabstractimage.h"
+
+
+G_DEFINE_ABSTRACT_TYPE (GtkAbstractImage, gtk_abstract_image, G_TYPE_OBJECT)
+
+/* GtkAbstractImage {{{ */
+
+static void
+gtk_abstract_image_init (GtkAbstractImage *image)
+{}
+
+static void
+gtk_abstract_image_class_init (GtkAbstractImageClass *klass)
+{}
+
+int
+gtk_abstract_image_get_width (GtkAbstractImage *image)
+{
+ g_return_val_if_fail (GTK_IS_ABSTRACT_IMAGE (image), 0);
+
+ return GTK_ABSTRACT_IMAGE_GET_CLASS (image)->get_width (image);
+}
+
+int
+gtk_abstract_image_get_height (GtkAbstractImage *image)
+{
+ g_return_val_if_fail (GTK_IS_ABSTRACT_IMAGE (image), 0);
+
+ return GTK_ABSTRACT_IMAGE_GET_CLASS (image)->get_height (image);
+}
+
+void
+gtk_abstract_image_draw (GtkAbstractImage *image, cairo_t *ct)
+{
+ g_return_if_fail (GTK_IS_ABSTRACT_IMAGE (image));
+
+ GTK_ABSTRACT_IMAGE_GET_CLASS (image)->draw (image, ct);
+}
+
+/* }}} */
+
+
+/* GtkPixbufImage {{{ */
+
+G_DEFINE_TYPE (GtkPixbufImage, gtk_pixbuf_image, GTK_TYPE_ABSTRACT_IMAGE)
+
+
+GtkPixbufImage *
+gtk_pixbuf_image_new (const char *path, int scale_factor)
+{
+ GtkPixbufImage *image = g_object_new (GTK_TYPE_PIXBUF_IMAGE, NULL);
+ image->scale_factor = scale_factor;
+ image->pixbuf = gdk_pixbuf_new_from_file (path, NULL);
+
+ return image;
+}
+
+static int
+gtk_pixbuf_image_get_width (GtkAbstractImage *image)
+{
+ return gdk_pixbuf_get_width (GTK_PIXBUF_IMAGE (image)->pixbuf);
+}
+
+static int
+gtk_pixbuf_image_get_height (GtkAbstractImage *image)
+{
+ return gdk_pixbuf_get_height (GTK_PIXBUF_IMAGE (image)->pixbuf);
+}
+
+static int
+gtk_pixbuf_image_get_scale_factor (GtkAbstractImage *image)
+{
+ return GTK_PIXBUF_IMAGE (image)->scale_factor;
+}
+
+static void
+gtk_pixbuf_image_draw (GtkAbstractImage *image, cairo_t *ct)
+{
+ cairo_surface_t *surface = gdk_cairo_surface_create_from_pixbuf (
+ GTK_PIXBUF_IMAGE (image)->pixbuf, 1, NULL);
+
+ cairo_set_source_surface (ct, surface, 0, 0);
+}
+
+
+static void
+gtk_pixbuf_image_init (GtkPixbufImage *image)
+{
+}
+
+static void
+gtk_pixbuf_image_class_init (GtkPixbufImageClass *klass)
+{
+ GtkAbstractImageClass *image_class = GTK_ABSTRACT_IMAGE_CLASS (klass);
+
+ image_class->get_width = gtk_pixbuf_image_get_width;
+ image_class->get_height = gtk_pixbuf_image_get_height;
+ image_class->get_scale_factor = gtk_pixbuf_image_get_scale_factor;
+ image_class->draw = gtk_pixbuf_image_draw;
+}
+
+
+/* }}} */
diff --git a/gtk/gtkabstractimage.h b/gtk/gtkabstractimage.h
new file mode 100644
index 0000000..2eb9083
--- /dev/null
+++ b/gtk/gtkabstractimage.h
@@ -0,0 +1,94 @@
+/* Copyright 2016 Timm Bäder
+ *
+ * GTK+ is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GTK+; see the file COPYING. If not,
+ * see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GTK_ABSTRACT_IMAGE_H__
+#define __GTK_ABSTRACT_IMAGE_H__
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#include <gtk/gtkwidget.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GtkAbstractImage GtkAbstractImage;
+typedef struct _GtkAbstractImageClass GtkAbstractImageClass;
+
+#define GTK_TYPE_ABSTRACT_IMAGE (gtk_abstract_image_get_type ())
+#define GTK_ABSTRACT_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_ABSTRACT_IMAGE,
GtkAbstractImage))
+#define GTK_ABSTRACT_IMAGE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_ABSTRACT_IMAGE,
GtkAbstractImageClass))
+#define GTK_IS_ABSTRACT_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_ABSTRACT_IMAGE))
+#define GTK_IS_ABSTRACT_IMAGE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_ABSTRACT_IMAGE))
+#define GTK_ABSTRACT_IMAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_ABSTRACT_IMAGE,
GtkAbstractImageClass))
+
+
+struct _GtkAbstractImage
+{
+ GObject parent;
+};
+
+
+struct _GtkAbstractImageClass
+{
+ GObjectClass parent_class;
+ int (*get_width) (GtkAbstractImage *image);
+ int (*get_height) (GtkAbstractImage *image);
+ int (*get_scale_factor) (GtkAbstractImage *image);
+ void (*draw) (GtkAbstractImage *image, cairo_t *ct);
+};
+
+GDK_AVAILABLE_IN_3_20
+GType gtk_abstract_image_get_type (void) G_GNUC_CONST;
+
+int gtk_abstract_image_get_width (GtkAbstractImage *image);
+
+int gtk_abstract_image_get_height (GtkAbstractImage *image);
+
+void gtk_abstract_image_draw (GtkAbstractImage *image, cairo_t *ct);
+
+
+typedef struct _GtkPixbufImage GtkPixbufImage;
+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_PIXBUF_IMAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PIXBUF_IMAGE,
GtkPixbufImageClass))
+
+struct _GtkPixbufImage
+{
+ GtkAbstractImage parent;
+ GdkPixbuf *pixbuf;
+ int scale_factor;
+};
+
+struct _GtkPixbufImageClass
+{
+ GtkAbstractImageClass parent_class;
+};
+
+GDK_AVAILABLE_IN_3_20
+GtkPixbufImage *gtk_pixbuf_image_new (const char *path, int scale_factor);
+
+
+
+G_END_DECLS
+
+#endif
diff --git a/gtk/gtkimageview.c b/gtk/gtkimageview.c
index 7c32c0d..e79202e 100644
--- a/gtk/gtkimageview.c
+++ b/gtk/gtkimageview.c
@@ -123,9 +123,13 @@ struct _GtkImageViewPrivate
gboolean is_animation;
GdkPixbufAnimation *source_animation;
GdkPixbufAnimationIter *source_animation_iter;
- cairo_surface_t *image_surface;
+ /*cairo_surface_t *image_surface;*/
int animation_timeout;
+
+ GtkAbstractImage *image;
+
+
/* Transitions */
double transition_start_angle;
gint64 angle_transition_start;
@@ -271,7 +275,8 @@ gtk_image_view_transitions_enabled (GtkImageView *image_view)
"gtk-enable-animations", &animations_enabled,
NULL);
- return priv->transitions_enabled && animations_enabled && priv->image_surface;
+ /*return priv->transitions_enabled && animations_enabled && priv->image_surface;*/
+ return priv->transitions_enabled && animations_enabled && priv->image;
}
static gboolean
@@ -577,6 +582,7 @@ gtk_image_view_compute_bounding_box (GtkImageView *image_view,
double scale;
double angle;
+#if 0
if (priv->size_valid)
{
*width = priv->cached_width;
@@ -586,7 +592,10 @@ gtk_image_view_compute_bounding_box (GtkImageView *image_view,
return;
}
- if (!priv->image_surface)
+#endif
+
+ /*if (!priv->image_surface)*/
+ if (!priv->image)
{
*width = 0;
*height = 0;
@@ -596,8 +605,10 @@ 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);
- image_width = cairo_image_surface_get_width (priv->image_surface) / priv->scale_factor;
- image_height = cairo_image_surface_get_height (priv->image_surface) / priv->scale_factor;
+ 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) /
+ gtk_abstract_image_get_scale_factor (priv->image);
upper_right_degrees = DEG_TO_RAD (angle) + atan (image_height / image_width);
upper_left_degrees = DEG_TO_RAD (angle) + atan (image_height / -image_width);
@@ -669,7 +680,8 @@ gtk_image_view_update_adjustments (GtkImageView *image_view)
if (!priv->hadjustment && !priv->vadjustment)
return;
- if (!priv->image_surface)
+ /*if (!priv->image_surface)*/
+ if (!priv->image)
{
if (priv->hadjustment)
gtk_adjustment_configure (priv->hadjustment, 0, 0, 1, 0, 0, 1);
@@ -741,7 +753,8 @@ gesture_zoom_begin_cb (GtkGesture *gesture,
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (user_data);
if (!priv->zoomable ||
- !priv->image_surface)
+ !priv->image)
+ /*!priv->image_surface)*/
{
gtk_gesture_set_state (gesture, GTK_EVENT_SEQUENCE_DENIED);
return;
@@ -834,7 +847,8 @@ gesture_rotate_begin_cb (GtkGesture *gesture,
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (user_data);
if (!priv->rotatable ||
- !priv->image_surface)
+ /*!priv->image_surface)*/
+ !priv->image)
{
gtk_gesture_set_state (gesture, GTK_EVENT_SEQUENCE_DENIED);
return;
@@ -1075,7 +1089,7 @@ gtk_image_view_draw (GtkWidget *widget, cairo_t *ct)
gtk_render_frame (sc, ct, 0, 0, widget_width, widget_height);
}
- if (!priv->image_surface)
+ if (!priv->image)
return GDK_EVENT_PROPAGATE;
gtk_image_view_compute_bounding_box (image_view,
@@ -1085,8 +1099,10 @@ gtk_image_view_draw (GtkWidget *widget, cairo_t *ct)
if (draw_width == 0 || draw_height == 0)
return GDK_EVENT_PROPAGATE;
- image_width = cairo_image_surface_get_width (priv->image_surface) * scale / priv->scale_factor;
- image_height = cairo_image_surface_get_height (priv->image_surface) * scale / priv->scale_factor;
+ image_width = gtk_abstract_image_get_width (priv->image) * scale /
+ gtk_abstract_image_get_scale_factor (priv->image);
+ image_height = gtk_abstract_image_get_height (priv->image) * scale /
+ gtk_abstract_image_get_scale_factor (priv->image);
if (priv->hadjustment && priv->vadjustment)
{
@@ -1123,12 +1139,9 @@ gtk_image_view_draw (GtkWidget *widget, cairo_t *ct)
- draw_y - (image_height / 2.0));
cairo_scale (ct, scale , scale );
- cairo_set_source_surface (ct,
- priv->image_surface,
- draw_x / scale ,
- draw_y / scale);
- cairo_pattern_set_filter (cairo_get_source (ct), CAIRO_FILTER_FAST);
- cairo_fill (ct);
+ cairo_translate (ct, draw_x / scale, draw_y / scale);
+ gtk_abstract_image_draw (priv->image, ct);
+ cairo_paint (ct);
return GDK_EVENT_PROPAGATE;
}
@@ -1293,7 +1306,8 @@ gtk_image_view_set_scale (GtkImageView *image_view,
priv->size_valid = FALSE;
gtk_image_view_update_adjustments (image_view);
- if (!priv->image_surface)
+ /*if (!priv->image_surface)*/
+ if (!priv->image)
return;
if (priv->hadjustment != NULL && priv->vadjustment != NULL)
@@ -1378,7 +1392,8 @@ gtk_image_view_set_angle (GtkImageView *image_view,
g_object_notify_by_pspec (G_OBJECT (image_view),
widget_props[PROP_ANGLE]);
- if (!priv->image_surface)
+ /*if (!priv->image_surface)*/
+ if (!priv->image)
return;
if (priv->hadjustment && priv->vadjustment && !priv->fit_allocation)
@@ -1858,7 +1873,8 @@ gtk_image_view_scroll_event (GtkWidget *widget,
double new_scale = priv->scale - (0.1 * event->delta_y);
State state;
- if (!priv->image_surface ||
+ /*if (!priv->image_surface ||*/
+ if (!priv->image ||
!priv->zoomable)
return GDK_EVENT_PROPAGATE;
@@ -1997,8 +2013,8 @@ gtk_image_view_finalize (GObject *object)
g_clear_object (&priv->hadjustment);
g_clear_object (&priv->vadjustment);
- if (priv->image_surface)
- cairo_surface_destroy (priv->image_surface);
+ /*if (priv->image_surface)*/
+ /*cairo_surface_destroy (priv->image_surface);*/
G_OBJECT_CLASS (gtk_image_view_parent_class)->finalize (object);
}
@@ -2165,19 +2181,19 @@ gtk_image_view_replace_surface (GtkImageView *image_view,
{
GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
- if (priv->image_surface)
- cairo_surface_destroy (priv->image_surface);
+ /*if (priv->image_surface)*/
+ /*cairo_surface_destroy (priv->image_surface);*/
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_surface = surface;*/
priv->size_valid = FALSE;
- if (surface)
- cairo_surface_reference (priv->image_surface);
+ /*if (surface)*/
+ /*cairo_surface_reference (priv->image_surface);*/
}
static void
@@ -2194,14 +2210,14 @@ gtk_image_view_update_surface (GtkImageView *image_view,
scale_factor,
window);
- if (priv->image_surface)
- {
- size_changed = (cairo_image_surface_get_width (priv->image_surface) !=
- cairo_image_surface_get_width (new_surface)) ||
- (cairo_image_surface_get_height (priv->image_surface) !=
- cairo_image_surface_get_height (new_surface)) ||
- (scale_factor != priv->scale_factor);
- }
+ /*if (priv->image_surface)*/
+ /*{*/
+ /*size_changed = (cairo_image_surface_get_width (priv->image_surface) !=*/
+ /*cairo_image_surface_get_width (new_surface)) ||*/
+ /*(cairo_image_surface_get_height (priv->image_surface) !=*/
+ /*cairo_image_surface_get_height (new_surface)) ||*/
+ /*(scale_factor != priv->scale_factor);*/
+ /*}*/
gtk_image_view_replace_surface (image_view,
new_surface,
@@ -2212,7 +2228,7 @@ gtk_image_view_update_surface (GtkImageView *image_view,
else
gtk_widget_queue_resize (GTK_WIDGET (image_view));
- g_assert (priv->image_surface != NULL);
+ /*g_assert (priv->image_surface != NULL);*/
}
static void
@@ -2224,7 +2240,7 @@ gtk_image_view_replace_animation (GtkImageView *image_view,
if (priv->source_animation)
{
- g_assert (priv->image_surface);
+ /*g_assert (priv->image_surface);*/
if (priv->is_animation)
gtk_image_view_stop_animation (image_view);
}
@@ -2561,3 +2577,17 @@ gtk_image_view_set_animation (GtkImageView *image_view,
gtk_image_view_replace_animation (image_view, animation, scale_factor);
}
+
+void
+gtk_image_view_set_abstract_image (GtkImageView *image_view,
+ GtkAbstractImage *abstract_image)
+{
+ GtkImageViewPrivate *priv = gtk_image_view_get_instance_private (image_view);
+
+ g_return_if_fail (GTK_IS_IMAGE_VIEW (image_view));
+ g_return_if_fail (GTK_IS_ABSTRACT_IMAGE (abstract_image));
+
+ priv->image = abstract_image;
+
+ gtk_widget_queue_resize (GTK_WIDGET (image_view));
+}
diff --git a/gtk/gtkimageview.h b/gtk/gtkimageview.h
index 12b272c..3bcf63c 100644
--- a/gtk/gtkimageview.h
+++ b/gtk/gtkimageview.h
@@ -23,6 +23,7 @@
#endif
#include <gtk/gtkwidget.h>
+#include "gtkabstractimage.h"
G_BEGIN_DECLS
@@ -149,6 +150,9 @@ void gtk_image_view_set_transitions_enabled (GtkImageView *image_view,
GDK_AVAILABLE_IN_3_20
gboolean gtk_image_view_get_transitions_enabled (GtkImageView *image_view);
+GDK_AVAILABLE_IN_3_20
+void gtk_image_view_set_abstract_image (GtkImageView *image_view, GtkAbstractImage *abstract_image);
+
G_END_DECLS
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]