[gnome-photos/wip/baedert/gtkimageview: 43/47] WIP



commit cd061d65ef2eed5983471d2c200555750746402b
Author: Timm Bäder <mail baedert org>
Date:   Fri Apr 1 19:07:20 2016 +0200

    WIP

 src/Makefile.am           |    2 +
 src/photos-gegl-image.c   |  165 +++++++++++++++++++++++++++++
 src/photos-gegl-image.h   |   40 +++++++
 src/photos-image-view.c   |  252 +++++++++++++--------------------------------
 src/photos-image-view.h   |    6 +-
 src/photos-preview-view.c |   21 ----
 src/photos-tool-crop.c    |   56 +++++-----
 7 files changed, 312 insertions(+), 230 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..a8d8473
--- /dev/null
+++ b/src/photos-gegl-image.c
@@ -0,0 +1,165 @@
+#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 PHOTOS_GEGL_IMAGE (_image)->scale_factor;
+}
+
+static void
+photos_gegl_image_render_surface (PhotosGeglImage *image)
+{
+  GeglRectangle roi = image->roi;
+
+  roi.x *= image->view_scale;
+  roi.y *= image->view_scale;
+
+  gegl_node_blit (image->node,
+                  image->view_scale,
+                  &roi,
+                  image->format,
+                  image->buf,
+                  GEGL_AUTO_ROWSTRIDE,
+                  GEGL_BLIT_CACHE | GEGL_BLIT_DIRTY);
+
+  /*if (!image->surface)*/
+    /*{*/
+      image->surface = cairo_image_surface_create_for_data (image->buf,
+                                                            CAIRO_FORMAT_ARGB32,
+                                                            image->width,
+                                                            image->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);
+    }
+}
+
+static void
+photos_gegl_image_update_bbox (PhotosGeglImage *image)
+{
+  GeglRectangle box;
+
+  if (!image->node)
+    return;
+
+  box = gegl_node_get_bounding_box (image->node);
+
+#if 0
+  g_message ("old size: %d, %d; new size: %d, %d", image->width, image->height,
+             box.width, box.height);
+  g_message ("bbox: %d, %d, %d, %d", box.x, box.y, box.width, box.height);
+#endif
+
+  if (image->width != box.width || image->height != box.height ||
+      image->roi.x != box.x     || image->roi.y != box.y)
+    {
+      image->width = box.width;
+      image->height = box.height;
+
+      image->roi.x = box.x;
+      image->roi.y = box.y;
+      image->roi.width  = box.width  * image->scale_factor;
+      image->roi.height = box.height * image->scale_factor;
+
+      image->stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, image->roi.width);
+
+      g_clear_pointer (&image->buf, g_free);
+      g_clear_pointer (&image->buf, cairo_surface_destroy);
+
+      image->buf = g_malloc (image->stride * image->roi.height);
+    }
+}
+
+static void
+photos_gegl_image_computed (PhotosGeglImage *image)
+{
+  photos_gegl_image_update_bbox (image);
+  photos_gegl_image_render_surface (image);
+}
+
+
+PhotosGeglImage *
+photos_gegl_image_new (GeglNode *node, int scale_factor)
+{
+  PhotosGeglImage *image = (PhotosGeglImage *) g_object_new (PHOTOS_TYPE_GEGL_IMAGE, NULL);
+  g_signal_connect_object (node, "computed", G_CALLBACK (photos_gegl_image_computed), image, 
G_CONNECT_SWAPPED);
+
+  image->node = node;
+  image->scale_factor = scale_factor;
+  image->format = babl_format ("cairo-ARGB32");
+
+  photos_gegl_image_update_bbox (image);
+  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_finalize (GObject *_image)
+{
+  PhotosGeglImage *image = PHOTOS_GEGL_IMAGE (_image);
+
+  if (image->surface)
+    cairo_surface_destroy (image->surface);
+
+  if (image->buf)
+    g_free (image->buf);
+
+  G_OBJECT_CLASS (photos_gegl_image_parent_class)->finalize (_image);
+}
+
+static void
+photos_gegl_image_class_init (PhotosGeglImageClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkAbstractImageClass *image_class = GTK_ABSTRACT_IMAGE_CLASS (klass);
+
+  object_class->finalize = photos_gegl_image_finalize;
+
+  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..57c8e05
--- /dev/null
+++ b/src/photos-gegl-image.h
@@ -0,0 +1,40 @@
+
+
+#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;
+  int scale_factor;
+};
+
+struct _PhotosGeglImageClass
+{
+  GtkAbstractImageClass parent_class;
+};
+
+GType photos_gegl_image_get_type (void) G_GNUC_CONST;
+
+PhotosGeglImage *photos_gegl_image_new (GeglNode *node, int scale_factor);
+
+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 f7a1477..7951987 100644
--- a/src/photos-image-view.c
+++ b/src/photos-image-view.c
@@ -27,18 +27,14 @@
 #include "photos-debug.h"
 #include "photos-image-view.h"
 #include "photos-marshalers.h"
+#include "photos-gegl-image.h"
 
 
 struct _PhotosImageView
 {
   GtkImageView parent_instance;
   GeglNode *node;
-  gfloat x;
-  gfloat x_scaled;
-  gfloat y;
-  gfloat y_scaled;
-  gfloat zoom;
-  gfloat zoom_scaled;
+  PhotosGeglImage *image;
 };
 
 struct _PhotosImageViewClass
@@ -46,7 +42,6 @@ struct _PhotosImageViewClass
   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,115 +63,8 @@ enum
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
-
 G_DEFINE_TYPE (PhotosImageView, photos_image_view, GTK_TYPE_IMAGE_VIEW);
 
-
-static void
-photos_image_view_update (PhotosImageView *self)
-{
-  GdkRectangle viewport;
-  GeglRectangle bbox;
-  float zoom_scaled = 1.0;
-  gint scale_factor;
-  gint viewport_height_real;
-  gint viewport_width_real;
-
-  if (self->node == NULL)
-    return;
-
-  gtk_widget_get_allocation (GTK_WIDGET (self), &viewport);
-
-  if (viewport.width < 0 || viewport.height < 0)
-    return;
-
-  bbox = gegl_node_get_bounding_box (self->node);
-  if (bbox.width < 0 || bbox.height < 0)
-    return;
-
-  scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (self));
-  viewport_height_real = viewport.height * scale_factor;
-  viewport_width_real = viewport.width * scale_factor;
-
-  if (bbox.height > viewport_height_real || bbox.width > viewport_width_real)
-    {
-      gfloat height_ratio = bbox.height / (gfloat) viewport_height_real;
-      gfloat width_ratio = bbox.width / (gfloat) viewport_width_real;
-      gfloat max_ratio =  MAX (height_ratio, width_ratio);
-
-      zoom_scaled = 1.0 / max_ratio;
-
-      bbox.width = (gint) (zoom_scaled * bbox.width + 0.5);
-      bbox.height = (gint) (zoom_scaled * bbox.height + 0.5);
-      bbox.x = (gint) (zoom_scaled * bbox.x + 0.5);
-      bbox.y = (gint) (zoom_scaled * bbox.y + 0.5);
-    }
-
-  self->zoom_scaled = zoom_scaled;
-  self->zoom = self->zoom_scaled / (gfloat) scale_factor;
-
-  /* At this point, viewport is definitely bigger than bbox. */
-  self->x_scaled = (bbox.width - viewport_width_real) / 2.0 + bbox.x;
-  self->y_scaled = (bbox.height - viewport_height_real) / 2.0 + bbox.y;
-
-  self->x = self->x_scaled / (gfloat) scale_factor;
-  self->y = self->y_scaled / (gfloat) scale_factor;
-}
-
-
-static void
-photos_image_view_computed (PhotosImageView *self)
-{
-  photos_image_view_update (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)
 {
@@ -189,13 +77,7 @@ photos_image_view_draw (GtkWidget *widget, cairo_t *cr)
   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);
@@ -205,24 +87,13 @@ photos_image_view_draw (GtkWidget *widget, cairo_t *cr)
   return GDK_EVENT_PROPAGATE;
 }
 
-
-static void
-photos_image_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
-{
-  PhotosImageView *self = PHOTOS_IMAGE_VIEW (widget);
-
-  GTK_WIDGET_CLASS (photos_image_view_parent_class)->size_allocate (widget, allocation);
-
-  photos_image_view_update (self);
-}
-
-
 static void
 photos_image_view_dispose (GObject *object)
 {
   PhotosImageView *self = PHOTOS_IMAGE_VIEW (object);
 
   g_clear_object (&self->node);
+  g_clear_object (&self->image);
 
   G_OBJECT_CLASS (photos_image_view_parent_class)->dispose (object);
 }
@@ -240,15 +111,15 @@ photos_image_view_get_property (GObject *object, guint prop_id, GValue *value, G
       break;
 
     case PROP_X:
-      g_value_set_float (value, self->x);
+      g_value_set_float (value, 0);
       break;
 
     case PROP_Y:
-      g_value_set_float (value, self->y);
+      g_value_set_float (value, 0);
       break;
 
     case PROP_ZOOM:
-      g_value_set_float (value, self->zoom);
+      g_value_set_float (value, gtk_image_view_get_scale (GTK_IMAGE_VIEW (self)));
       break;
 
     default:
@@ -282,6 +153,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 +174,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);
 }
 
 
@@ -307,7 +189,6 @@ photos_image_view_class_init (PhotosImageViewClass *class)
   object_class->get_property = photos_image_view_get_property;
   object_class->set_property = photos_image_view_set_property;
   widget_class->draw = photos_image_view_draw;
-  widget_class->size_allocate = photos_image_view_size_allocate;
 
   g_object_class_install_property (object_class,
                                    PROP_NODE,
@@ -319,23 +200,23 @@ photos_image_view_class_init (PhotosImageViewClass *class)
 
   g_object_class_install_property (object_class,
                                    PROP_X,
-                                   g_param_spec_float ("x",
-                                                       "X",
-                                                       "X origin",
-                                                       -G_MAXFLOAT,
-                                                       G_MAXFLOAT,
-                                                       0.0,
-                                                       G_PARAM_READABLE));
+                                   g_param_spec_double ("x",
+                                                        "X",
+                                                        "X origin",
+                                                        -G_MAXDOUBLE,
+                                                        G_MAXDOUBLE,
+                                                        0.0,
+                                                        G_PARAM_READABLE));
 
   g_object_class_install_property (object_class,
                                    PROP_Y,
-                                   g_param_spec_float ("y",
-                                                       "Y",
-                                                       "Y origin",
-                                                       -G_MAXFLOAT,
-                                                       G_MAXFLOAT,
-                                                       0.0,
-                                                       G_PARAM_READABLE));
+                                   g_param_spec_double ("y",
+                                                        "Y",
+                                                        "Y origin",
+                                                        -G_MAXDOUBLE,
+                                                        G_MAXDOUBLE,
+                                                        0.0,
+                                                        G_PARAM_READABLE));
 
   g_object_class_install_property (object_class,
                                    PROP_ZOOM,
@@ -347,18 +228,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,
@@ -378,7 +247,7 @@ photos_image_view_new (void)
 {
   return g_object_new (PHOTOS_TYPE_IMAGE_VIEW,
                        "fit-allocation", TRUE,
-                       "zoomable", FALSE,
+                       /*"zoomable", FALSE,*/
                        "rotatable", FALSE,
                        NULL);
 }
@@ -400,50 +269,75 @@ photos_image_view_get_node (PhotosImageView *self)
 }
 
 
-gfloat
+double
 photos_image_view_get_x (PhotosImageView *self)
 {
+  double x;
+  int widget_width;
+  double image_width;
+
   g_return_val_if_fail (PHOTOS_IS_IMAGE_VIEW (self), 0.0);
-  return self->x;
+
+  widget_width = gtk_widget_get_allocated_width (GTK_WIDGET (self));
+
+  image_width = gtk_abstract_image_get_width (GTK_ABSTRACT_IMAGE (self->image)) *
+                gtk_image_view_get_scale (GTK_IMAGE_VIEW (self));
+
+
+  x = (widget_width - image_width) / 2.0;
+
+  return x;
 }
 
 
-gfloat
+double
 photos_image_view_get_y (PhotosImageView *self)
 {
+  double y;
+  int widget_height;
+  double image_height;
+
   g_return_val_if_fail (PHOTOS_IS_IMAGE_VIEW (self), 0.0);
-  return self->y;
+
+  widget_height = gtk_widget_get_allocated_height (GTK_WIDGET (self));
+
+  image_height = gtk_abstract_image_get_height (GTK_ABSTRACT_IMAGE (self->image)) *
+                gtk_image_view_get_scale (GTK_IMAGE_VIEW (self));
+
+
+  y = (widget_height - image_height) / 2.0;
+
+  return y;
 }
 
 
-gfloat
+double
 photos_image_view_get_zoom (PhotosImageView *self)
 {
   g_return_val_if_fail (PHOTOS_IS_IMAGE_VIEW (self), 0.0);
-  return self->zoom;
+
+  return gtk_image_view_get_scale (GTK_IMAGE_VIEW (self));
 }
 
 
 void
 photos_image_view_set_node (PhotosImageView *self, GeglNode *node)
 {
+  int scale_factor;
+
   g_return_if_fail (PHOTOS_IS_IMAGE_VIEW (self));
 
   if (self->node == node)
     return;
 
-  if (self->node != NULL)
-    g_signal_handlers_disconnect_by_func (self->node, photos_image_view_computed, self);
-
   g_clear_object (&self->node);
 
   if (node != NULL)
-    {
-      g_object_ref (node);
-      g_signal_connect_object (node, "computed", G_CALLBACK (photos_image_view_computed), self, 
G_CONNECT_SWAPPED);
-    }
+    g_object_ref (node);
+
+  scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (self));
 
   self->node = node;
-  photos_image_view_update (self);
-  gtk_widget_queue_draw (GTK_WIDGET (self));
+  self->image = photos_gegl_image_new (node, scale_factor);
+  gtk_image_view_set_abstract_image (GTK_IMAGE_VIEW (self), GTK_ABSTRACT_IMAGE (self->image));
 }
diff --git a/src/photos-image-view.h b/src/photos-image-view.h
index 65e54ea..2e1b0d7 100644
--- a/src/photos-image-view.h
+++ b/src/photos-image-view.h
@@ -59,11 +59,11 @@ GtkWidget          *photos_image_view_new_from_node      (GeglNode *node);
 
 GeglNode           *photos_image_view_get_node           (PhotosImageView *self);
 
-gfloat              photos_image_view_get_x              (PhotosImageView *self);
+double              photos_image_view_get_x              (PhotosImageView *self);
 
-gfloat              photos_image_view_get_y              (PhotosImageView *self);
+double              photos_image_view_get_y              (PhotosImageView *self);
 
-gfloat              photos_image_view_get_zoom           (PhotosImageView *self);
+double              photos_image_view_get_zoom           (PhotosImageView *self);
 
 void                photos_image_view_set_node           (PhotosImageView *self, GeglNode *node);
 
diff --git a/src/photos-preview-view.c b/src/photos-preview-view.c
index 0201146..6833aa1 100644
--- a/src/photos-preview-view.c
+++ b/src/photos-preview-view.c
@@ -122,26 +122,6 @@ photos_preview_view_button_release_event (PhotosPreviewView *self, GdkEvent *eve
 
 
 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)
 {
   if (self->current_tool == NULL)
@@ -246,7 +226,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. */
diff --git a/src/photos-tool-crop.c b/src/photos-tool-crop.c
index 5f5d24c..7120e77 100644
--- a/src/photos-tool-crop.c
+++ b/src/photos-tool-crop.c
@@ -197,6 +197,8 @@ photos_tool_crop_find_constraint (PhotosToolCrop *self, gdouble aspect_ratio)
 static void
 photos_tool_crop_redraw_damaged_area (PhotosToolCrop *self)
 {
+  gtk_widget_queue_draw (GTK_WIDGET (self->view));
+#if 0
   cairo_rectangle_int_t area;
   cairo_region_t *region;
   gdouble damage_offset = HANDLE_OFFSET + HANDLE_RADIUS;
@@ -204,10 +206,10 @@ photos_tool_crop_redraw_damaged_area (PhotosToolCrop *self)
   gdouble y;
 
   x = (gdouble) photos_image_view_get_x (PHOTOS_IMAGE_VIEW (self->view));
-  x = -x + self->crop_x - damage_offset;
+  /*x = -x + self->crop_x - damage_offset;*/
 
   y = (gdouble) photos_image_view_get_y (PHOTOS_IMAGE_VIEW (self->view));
-  y = -y + self->crop_y - damage_offset;
+  /*y = -y + self->crop_y - damage_offset;*/
 
   area.height = (gint) (self->crop_height + 2 * damage_offset + 0.5) + 2;
   area.width = (gint) (self->crop_width + 2 * damage_offset + 0.5) + 2;
@@ -217,6 +219,7 @@ photos_tool_crop_redraw_damaged_area (PhotosToolCrop *self)
   region = cairo_region_create_rectangle (&area);
   gtk_widget_queue_draw_region (self->view, region);
   cairo_region_destroy (region);
+#endif
 }
 
 
@@ -393,7 +396,7 @@ photos_tool_crop_set_vert_from_horiz (PhotosToolCrop *self, gboolean centered, g
 
 
 static void
-photos_tool_crop_set_crop (PhotosToolCrop *self, gdouble event_x, gdouble event_y)
+photos_tool_crop_set_crop (PhotosToolCrop *self, gdouble event_x, gdouble event_y, gdouble x, gdouble y)
 {
   PhotosToolCropLocation location;
   gboolean centered;
@@ -442,8 +445,8 @@ photos_tool_crop_set_crop (PhotosToolCrop *self, gdouble event_x, gdouble event_
     case PHOTOS_TOOL_CROP_LOCATION_BOTTOM_LEFT:
       if (self->crop_aspect_ratio < 0.0)
         {
-          self->crop_height = event_y - self->crop_y;
           self->crop_width -= event_x - self->crop_x;
+          self->crop_height = event_y - self->crop_y;
           self->crop_x = event_x;
           location = PHOTOS_TOOL_CROP_LOCATION_NONE;
         }
@@ -863,6 +866,7 @@ photos_tool_crop_set_active (PhotosToolCrop *self, gint active)
 static void
 photos_tool_crop_size_allocate (PhotosToolCrop *self, GdkRectangle *allocation)
 {
+#if 1
   gdouble crop_height_ratio;
   gdouble crop_width_ratio;
   gdouble crop_x_ratio;
@@ -881,6 +885,7 @@ photos_tool_crop_size_allocate (PhotosToolCrop *self, GdkRectangle *allocation)
   self->crop_y = crop_y_ratio * (gdouble) self->bbox_zoomed.height;
 
   photos_tool_crop_surface_draw (self);
+#endif
 }
 
 
@@ -1008,7 +1013,7 @@ photos_tool_crop_deactivate (PhotosTool *tool)
     {
       GVariantBuilder parameter;
       GVariantType *parameter_type;
-      gfloat zoom;
+      double zoom;
 
       zoom = photos_image_view_get_zoom (PHOTOS_IMAGE_VIEW (self->view));
 
@@ -1018,12 +1023,17 @@ photos_tool_crop_deactivate (PhotosTool *tool)
        * factor will cancel itself in the numerator and denominator,
        * so, in practice, the conversion is unnecessary.
        */
+
+      g_message ("Zoom: %f", zoom);
+      g_message ("unscaled: %f, %f, %f, %f", self->crop_x, self->crop_y, self->crop_width, 
self->crop_height);
+      g_message ("caled   : %f, %f, %f, %f", self->crop_x / zoom, self->crop_y / zoom, self->crop_width / 
zoom, self->crop_height / zoom);
+
       parameter_type = g_variant_type_new ("a{sd}");
       g_variant_builder_init (&parameter, parameter_type);
-      g_variant_builder_add (&parameter, "{sd}", "height", self->crop_height / zoom);
-      g_variant_builder_add (&parameter, "{sd}", "width", self->crop_width / zoom);
       g_variant_builder_add (&parameter, "{sd}", "x", self->crop_x / zoom);
       g_variant_builder_add (&parameter, "{sd}", "y", self->crop_y / zoom);
+      g_variant_builder_add (&parameter, "{sd}", "width", self->crop_width / zoom);
+      g_variant_builder_add (&parameter, "{sd}", "height", self->crop_height / zoom);
       g_action_activate (self->crop, g_variant_builder_end (&parameter));
 
       g_variant_type_free (parameter_type);
@@ -1044,20 +1054,12 @@ static void
 photos_tool_crop_draw (PhotosTool *tool, cairo_t *cr, GdkRectangle *rect)
 {
   PhotosToolCrop *self = PHOTOS_TOOL_CROP (tool);
-  gdouble x;
-  gdouble y;
 
   g_return_if_fail (self->activated);
   g_return_if_fail (self->view != NULL);
 
-  x = (gdouble) photos_image_view_get_x (PHOTOS_IMAGE_VIEW (self->view));
-  x = -x;
-
-  y = (gdouble) photos_image_view_get_y (PHOTOS_IMAGE_VIEW (self->view));
-  y = -y;
-
   cairo_save (cr);
-  cairo_set_source_surface (cr, self->surface, x, y);
+  cairo_set_source_surface (cr, self->surface, 0, 0);
   cairo_paint (cr);
   cairo_restore (cr);
 }
@@ -1075,18 +1077,18 @@ static gboolean
 photos_tool_crop_left_click_event (PhotosTool *tool, GdkEventButton *event)
 {
   PhotosToolCrop *self = PHOTOS_TOOL_CROP (tool);
-  gdouble x;
-  gdouble y;
+  double x, y;
 
   g_return_val_if_fail (self->activated, GDK_EVENT_PROPAGATE);
   g_return_val_if_fail (self->view != NULL, GDK_EVENT_PROPAGATE);
 
   self->grabbed = TRUE;
 
-  x = (gdouble) photos_image_view_get_x (PHOTOS_IMAGE_VIEW (self->view));
-  y = (gdouble) photos_image_view_get_y (PHOTOS_IMAGE_VIEW (self->view));
-  self->event_x_last = event->x + x;
-  self->event_y_last = event->y + y;
+  x = photos_image_view_get_x (PHOTOS_IMAGE_VIEW (self->view));
+  y = photos_image_view_get_y (PHOTOS_IMAGE_VIEW (self->view));
+
+  self->event_x_last = event->x - x;
+  self->event_y_last = event->y - y;
 
   return GDK_EVENT_PROPAGATE;
 }
@@ -1120,15 +1122,15 @@ photos_tool_crop_motion_event (PhotosTool *tool, GdkEventMotion *event)
   g_return_val_if_fail (self->activated, GDK_EVENT_PROPAGATE);
   g_return_val_if_fail (self->view != NULL, GDK_EVENT_PROPAGATE);
 
-  x = (gdouble) photos_image_view_get_x (PHOTOS_IMAGE_VIEW (self->view));
-  y = (gdouble) photos_image_view_get_y (PHOTOS_IMAGE_VIEW (self->view));
-  event_x = event->x + x;
-  event_y = event->y + y;
+  x = photos_image_view_get_x (PHOTOS_IMAGE_VIEW (self->view));
+  y = photos_image_view_get_y (PHOTOS_IMAGE_VIEW (self->view));
+  event_x = event->x - x;
+  event_y = event->y - y;
 
   if (self->grabbed)
     {
       if (self->location != PHOTOS_TOOL_CROP_LOCATION_NONE)
-        photos_tool_crop_set_crop (self, event_x, event_y);
+        photos_tool_crop_set_crop (self, event_x, event_y, x, y);
     }
   else
     {


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