[gnome-photos/wip/baedert/gtkimageview] Use GtkImageView
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-photos/wip/baedert/gtkimageview] Use GtkImageView
- Date: Wed, 23 Mar 2016 18:20:22 +0000 (UTC)
commit fa304e01f79a013d81eac53045e1237d9818cd09
Author: Timm Bäder <mail baedert org>
Date: Wed Mar 23 19:19:42 2016 +0100
Use GtkImageView
src/Makefile.am | 2 +
src/photos-gegl-image.c | 119 +++++++++++++++++++++++++++++++++++++++++++++
src/photos-gegl-image.h | 39 +++++++++++++++
src/photos-image-view.c | 100 +++++++++-----------------------------
src/photos-main-window.c | 4 +-
src/photos-preview-view.c | 29 +-----------
src/photos-spinner-box.c | 1 +
7 files changed, 187 insertions(+), 107 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 0cb21e6..015f477 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -247,6 +247,8 @@ gnome_photos_SOURCES = \
photos-widget-shader.c \
photos-widget-shader.h \
photos-main.c \
+ photos-gegl-image.c \
+ photos-gegl-image.h \
$(NULL)
BUILT_SOURCES = \
diff --git a/src/photos-gegl-image.c b/src/photos-gegl-image.c
new file mode 100644
index 0000000..c531cea
--- /dev/null
+++ b/src/photos-gegl-image.c
@@ -0,0 +1,119 @@
+#include "photos-gegl-image.h"
+
+
+
+G_DEFINE_TYPE(PhotosGeglImage, photos_gegl_image, GTK_TYPE_ABSTRACT_IMAGE)
+
+static int
+__get_width (GtkAbstractImage *_image)
+{
+ return PHOTOS_GEGL_IMAGE (_image)->width;
+}
+
+static int
+__get_height (GtkAbstractImage *_image)
+{
+ return PHOTOS_GEGL_IMAGE (_image)->height;
+}
+
+static int
+__get_scale_factor (GtkAbstractImage *_image)
+{
+ return 1;
+}
+
+static void
+photos_gegl_image_render_surface (PhotosGeglImage *image)
+{
+
+ /* TODO: buffer size only depends on roi.height and stride, which basically never change(?), so reuse it.
*/
+ if (image->buf)
+ g_free (image->buf);
+
+ image->buf = g_malloc0 (image->stride * image->roi.height);
+
+ gegl_node_blit (image->node,
+ image->view_scale,
+ &image->roi,
+ image->format,
+ image->buf,
+ GEGL_AUTO_ROWSTRIDE,
+ GEGL_BLIT_CACHE | GEGL_BLIT_DIRTY);
+
+ image->surface = cairo_image_surface_create_for_data (image->buf,
+ CAIRO_FORMAT_ARGB32,
+ image->roi.width,
+ image->roi.height,
+ image->stride);
+
+ g_signal_emit_by_name (G_OBJECT (image), "changed", 0);
+}
+
+static void
+__draw (GtkAbstractImage *_image, cairo_t *ct)
+{
+ PhotosGeglImage *image = PHOTOS_GEGL_IMAGE (_image);
+
+ if (image->surface)
+ {
+ cairo_scale (ct, 1.0 / image->view_scale, 1.0 / image->view_scale);
+ cairo_set_source_surface (ct, image->surface, 0, 0);
+ }
+}
+
+
+
+
+PhotosGeglImage *
+photos_gegl_image_new (GeglNode *node)
+{
+ PhotosGeglImage *image = (PhotosGeglImage *) g_object_new (PHOTOS_TYPE_GEGL_IMAGE, NULL);
+ GeglRectangle box;
+
+ box = gegl_node_get_bounding_box (node);
+ image->width = box.width;
+ image->height = box.height;
+ image->node = node;
+
+
+ image->roi.x = 0;
+ image->roi.y = 0;
+ image->roi.width = image->width * /*scale_factor*/ 1;
+ image->roi.height = image->height * /*scale_factor*/ 1;
+
+ image->format = babl_format ("cairo-ARGB32");
+ image->stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, image->roi.width);
+
+
+
+ photos_gegl_image_render_surface (image);
+
+ return image;
+}
+
+static void
+photos_gegl_image_init (PhotosGeglImage *image)
+{
+ image->surface = NULL;
+ image->view_scale = 1.0;
+}
+
+static void
+photos_gegl_image_class_init (PhotosGeglImageClass *klass)
+{
+ GtkAbstractImageClass *image_class = GTK_ABSTRACT_IMAGE_CLASS (klass);
+
+ image_class->draw = __draw;
+ image_class->get_width = __get_width;
+ image_class->get_height = __get_height;
+ image_class->get_scale_factor = __get_scale_factor;
+}
+
+void
+photos_gegl_image_set_view_scale (PhotosGeglImage *image, double view_scale)
+{
+ image->view_scale = view_scale;
+ photos_gegl_image_render_surface (image);
+}
+
+
diff --git a/src/photos-gegl-image.h b/src/photos-gegl-image.h
new file mode 100644
index 0000000..5cc479b
--- /dev/null
+++ b/src/photos-gegl-image.h
@@ -0,0 +1,39 @@
+
+
+#include <gtk/gtk.h>
+#include <gegl.h>
+
+typedef struct _PhotosGeglImage PhotosGeglImage;
+typedef struct _PhotosGeglImageClass PhotosGeglImageClass;
+
+#define PHOTOS_TYPE_GEGL_IMAGE (photos_gegl_image_get_type ())
+#define PHOTOS_GEGL_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, PHOTOS_TYPE_GEGL_IMAGE,
PhotosGeglImage))
+#define PHOTOS_GEGL_IMAGE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST(cls, PHOTOS_TYPE_GEGL_IMAGE,
PhotosGeglImageClass))
+#define PHOTOS_IS_GEGL_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, PHOTOS_TYPE_GEGL_IMAGE))
+#define PHOTOS_IS_GEGL_IMAGE_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE(cls, PHOTOS_TYPE_GEGL_IMAGE))
+#define PHOTOS_GEGL_IMAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS(obj, PHOTOS_TYPE_GEGL_IMAGE,
PhotosGeglImageClass))
+
+struct _PhotosGeglImage
+{
+ GtkAbstractImage parent_instance;
+ GeglNode *node;
+ int width;
+ int height;
+ double view_scale;
+ cairo_surface_t *surface;
+ guchar *buf;
+ const Babl *format;
+ GeglRectangle roi;
+ int stride;
+};
+
+struct _PhotosGeglImageClass
+{
+ GtkAbstractImageClass parent_class;
+};
+
+GType photos_gegl_image_get_type (void) G_GNUC_CONST;
+
+PhotosGeglImage *photos_gegl_image_new (GeglNode *node);
+
+void photos_gegl_image_set_view_scale (PhotosGeglImage *image, double view_scale);
diff --git a/src/photos-image-view.c b/src/photos-image-view.c
index 59bdbd6..1c966f4 100644
--- a/src/photos-image-view.c
+++ b/src/photos-image-view.c
@@ -27,12 +27,15 @@
#include "photos-debug.h"
#include "photos-image-view.h"
#include "photos-marshalers.h"
+#include "photos-gegl-image.h"
struct _PhotosImageView
{
- GtkDrawingArea parent_instance;
+ /*GtkDrawingArea parent_instance;*/
+ GtkImageView parent_instance;
GeglNode *node;
+ PhotosGeglImage *image;
gfloat x;
gfloat x_scaled;
gfloat y;
@@ -43,10 +46,9 @@ struct _PhotosImageView
struct _PhotosImageViewClass
{
- GtkDrawingAreaClass parent_class;
+ GtkImageViewClass parent_class;
/* signals */
- void (*draw_background) (PhotosImageView *self, cairo_t *cr, GdkRectangle *rect);
void (*draw_overlay) (PhotosImageView *self, cairo_t *cr, GdkRectangle *rect);
};
@@ -68,9 +70,7 @@ enum
static guint signals[LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (PhotosImageView, photos_image_view, GTK_TYPE_DRAWING_AREA);
-
+G_DEFINE_TYPE (PhotosImageView, photos_image_view, GTK_TYPE_IMAGE_VIEW);
static void
photos_image_view_update (PhotosImageView *self)
@@ -131,52 +131,6 @@ photos_image_view_computed (PhotosImageView *self)
}
-static void
-photos_image_view_draw_node (PhotosImageView *self, cairo_t *cr, GdkRectangle *rect)
-{
- const Babl *format;
- GeglRectangle roi;
- cairo_surface_t *surface = NULL;
- guchar *buf = NULL;
- gint scale_factor;
- gint stride;
- gint64 end;
- gint64 start;
-
- scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (self));
-
- roi.x = (gint) self->x_scaled + rect->x * scale_factor;
- roi.y = (gint) self->y_scaled + rect->y * scale_factor;
- roi.width = rect->width * scale_factor;
- roi.height = rect->height * scale_factor;
-
- format = babl_format ("cairo-ARGB32");
- stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, roi.width);
- buf = g_malloc0 (stride * roi.height);
-
- start = g_get_monotonic_time ();
-
- gegl_node_blit (self->node,
- (gdouble) self->zoom_scaled,
- &roi,
- format,
- buf,
- GEGL_AUTO_ROWSTRIDE,
- GEGL_BLIT_CACHE | GEGL_BLIT_DIRTY);
-
- end = g_get_monotonic_time ();
- photos_debug (PHOTOS_DEBUG_GEGL, "PhotosImageView: Node Blit: %" G_GINT64_FORMAT, end - start);
-
- surface = cairo_image_surface_create_for_data (buf, CAIRO_FORMAT_ARGB32, roi.width, roi.height, stride);
- cairo_surface_set_device_scale (surface, (gdouble) scale_factor, (gdouble) scale_factor);
- cairo_set_source_surface (cr, surface, rect->x, rect->y);
- cairo_paint (cr);
-
- cairo_surface_destroy (surface);
- g_free (buf);
-}
-
-
static gboolean
photos_image_view_draw (GtkWidget *widget, cairo_t *cr)
{
@@ -186,16 +140,7 @@ photos_image_view_draw (GtkWidget *widget, cairo_t *cr)
if (self->node == NULL)
goto out;
- if (!gdk_cairo_get_clip_rectangle (cr, &rect))
- goto out;
-
- cairo_save (cr);
- g_signal_emit (self, signals[DRAW_BACKGROUND], 0, cr, &rect);
- cairo_restore(cr);
-
- cairo_save (cr);
- photos_image_view_draw_node (self, cr, &rect);
- cairo_restore (cr);
+ GTK_WIDGET_CLASS (photos_image_view_parent_class)->draw (widget, cr);
cairo_save (cr);
g_signal_emit (self, signals[DRAW_OVERLAY], 0, cr, &rect);
@@ -282,6 +227,15 @@ photos_image_view_set_property (GObject *object, guint prop_id, const GValue *va
static void
+view_scale_changed_cb (GObject *source, GParamSpec *spec, gpointer user_data)
+{
+ PhotosImageView *view = PHOTOS_IMAGE_VIEW (source);
+ double scale = gtk_image_view_get_scale (GTK_IMAGE_VIEW (source));
+
+ photos_gegl_image_set_view_scale (view->image, scale);
+}
+
+static void
photos_image_view_init (PhotosImageView *self)
{
GtkStyleContext *context;
@@ -294,6 +248,8 @@ photos_image_view_init (PhotosImageView *self)
context = gtk_widget_get_style_context (GTK_WIDGET (self));
gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW);
gtk_style_context_add_class (context, "content-view");
+
+ g_signal_connect (G_OBJECT (self), "notify::scale", G_CALLBACK (view_scale_changed_cb), NULL);
}
@@ -347,18 +303,6 @@ photos_image_view_class_init (PhotosImageViewClass *class)
1.0f,
G_PARAM_READABLE));
- signals[DRAW_BACKGROUND] = g_signal_new ("draw-background",
- G_TYPE_FROM_CLASS (class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (PhotosImageViewClass, draw_background),
- NULL, /* accumulator */
- NULL, /* accu_data */
- _photos_marshal_VOID__BOXED_BOXED,
- G_TYPE_NONE,
- 2,
- CAIRO_GOBJECT_TYPE_CONTEXT,
- GDK_TYPE_RECTANGLE);
-
signals[DRAW_OVERLAY] = g_signal_new ("draw-overlay",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
@@ -376,7 +320,9 @@ photos_image_view_class_init (PhotosImageViewClass *class)
GtkWidget *
photos_image_view_new (void)
{
- return g_object_new (PHOTOS_TYPE_IMAGE_VIEW, NULL);
+ return g_object_new (PHOTOS_TYPE_IMAGE_VIEW,
+ "fit-allocation", TRUE,
+ NULL);
}
@@ -440,6 +386,6 @@ photos_image_view_set_node (PhotosImageView *self, GeglNode *node)
}
self->node = node;
- photos_image_view_update (self);
- gtk_widget_queue_draw (GTK_WIDGET (self));
+ self->image = photos_gegl_image_new (node);
+ gtk_image_view_set_abstract_image (GTK_IMAGE_VIEW (self), GTK_ABSTRACT_IMAGE (self->image));
}
diff --git a/src/photos-main-window.c b/src/photos-main-window.c
index 09cbacc..16521d4 100644
--- a/src/photos-main-window.c
+++ b/src/photos-main-window.c
@@ -472,8 +472,8 @@ photos_main_window_new (GtkApplication *application)
g_return_val_if_fail (GTK_IS_APPLICATION (application), NULL);
return g_object_new (PHOTOS_TYPE_MAIN_WINDOW,
- "width_request", WINDOW_MIN_WIDTH,
- "height_request", WINDOW_MIN_HEIGHT,
+ /*"width_request", WINDOW_MIN_WIDTH,*/
+ /*"height_request", WINDOW_MIN_HEIGHT,*/
"application", application,
"title", _(PACKAGE_NAME),
"window-position", GTK_WIN_POS_CENTER,
diff --git a/src/photos-preview-view.c b/src/photos-preview-view.c
index 1afc1a7..7b29856 100644
--- a/src/photos-preview-view.c
+++ b/src/photos-preview-view.c
@@ -119,27 +119,6 @@ photos_preview_view_button_release_event (PhotosPreviewView *self, GdkEvent *eve
return ret_val;
}
-
-static void
-photos_preview_view_draw_background (PhotosPreviewView *self, cairo_t *cr, GdkRectangle *rect, gpointer
user_data)
-{
- GtkStyleContext *context;
- GtkStateFlags flags;
- GtkWidget *view = GTK_WIDGET (user_data);
- gint height;
- gint width;
-
- context = gtk_widget_get_style_context (view);
- flags = gtk_widget_get_state_flags (view);
- gtk_style_context_save (context);
- gtk_style_context_set_state (context, flags);
- height = gtk_widget_get_allocated_height (view);
- width = gtk_widget_get_allocated_width (view);
- gtk_render_background (context, cr, 0, 0, width, height);
- gtk_style_context_restore (context);
-}
-
-
static void
photos_preview_view_draw_overlay (PhotosPreviewView *self, cairo_t *cr, GdkRectangle *rect, gpointer
user_data)
{
@@ -245,7 +224,6 @@ photos_preview_view_create_view_with_container (PhotosPreviewView *self)
G_CALLBACK (photos_preview_view_button_release_event),
self);
g_signal_connect_swapped (view, "motion-notify-event", G_CALLBACK
(photos_preview_view_motion_notify_event), self);
- g_signal_connect_swapped (view, "draw-background", G_CALLBACK (photos_preview_view_draw_background), self);
g_signal_connect_swapped (view, "draw-overlay", G_CALLBACK (photos_preview_view_draw_overlay), self);
/* It has to be visible to become the visible child of self->stack. */
@@ -258,12 +236,7 @@ photos_preview_view_create_view_with_container (PhotosPreviewView *self)
static GtkWidget *
photos_preview_view_get_view_from_view_container (GtkWidget *view_container)
{
- GtkWidget *view;
- GtkWidget *viewport;
-
- viewport = gtk_bin_get_child (GTK_BIN (view_container));
- view = gtk_bin_get_child (GTK_BIN (viewport));
- return view;
+ return GTK_WIDGET (gtk_bin_get_child (GTK_BIN (view_container)));
}
diff --git a/src/photos-spinner-box.c b/src/photos-spinner-box.c
index 930be61..6e9649f 100644
--- a/src/photos-spinner-box.c
+++ b/src/photos-spinner-box.c
@@ -109,6 +109,7 @@ photos_spinner_box_start (PhotosSpinnerBox *self)
void
photos_spinner_box_stop (PhotosSpinnerBox *self)
{
+ gtk_widget_hide (GTK_WIDGET (self));
gtk_revealer_set_reveal_child (GTK_REVEALER (self), FALSE);
g_signal_connect (self, "notify::child-revealed", G_CALLBACK (photos_spinner_box_notify_child_revealed),
NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]