[gnome-photos/wip/rishi/zoom: 4/4] image-view: photos_image_view_set_zoom



commit 04a70f416bc8f87ca870c1faa627fd1336ac43ea
Author: Debarshi Ray <debarshir gnome org>
Date:   Thu Mar 30 10:46:17 2017 +0200

    image-view: photos_image_view_set_zoom

 src/photos-image-view.c |  103 ++++++++++++++++++++++++++++++++++++++++-------
 src/photos-image-view.h |    6 +++
 2 files changed, 94 insertions(+), 15 deletions(-)
---
diff --git a/src/photos-image-view.c b/src/photos-image-view.c
index a411bc7..13ad5f6 100644
--- a/src/photos-image-view.c
+++ b/src/photos-image-view.c
@@ -29,6 +29,7 @@
 #include "photos-gegl.h"
 #include "photos-image-view.h"
 #include "photos-marshalers.h"
+#include "photos-utils.h"
 
 
 struct _PhotosImageView
@@ -38,6 +39,7 @@ struct _PhotosImageView
   GeglNode *node;
   cairo_region_t *bbox_region;
   cairo_region_t *region;
+  gboolean best_fit;
   gdouble x;
   gdouble x_scaled;
   gdouble y;
@@ -138,22 +140,32 @@ photos_image_view_update (PhotosImageView *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)
+  if (self->best_fit)
     {
-      gdouble height_ratio = bbox.height / (gdouble) viewport_height_real;
-      gdouble width_ratio = bbox.width / (gdouble) viewport_width_real;
-      gdouble 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);
+      if (bbox.height > viewport_height_real || bbox.width > viewport_width_real)
+        {
+          gdouble height_ratio = bbox.height / (gdouble) viewport_height_real;
+          gdouble width_ratio = bbox.width / (gdouble) viewport_width_real;
+          gdouble 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 / (gdouble) scale_factor;
+    }
+  else
+    {
+      bbox.width = (gint) (self->zoom_scaled * bbox.width + 0.5);
+      bbox.height = (gint) (self->zoom_scaled * bbox.height + 0.5);
+      bbox.x = (gint) (self->zoom_scaled * bbox.x + 0.5);
+      bbox.y = (gint) (self->zoom_scaled * bbox.y + 0.5);
     }
-
-  self->zoom_scaled = zoom_scaled;
-  self->zoom = self->zoom_scaled / (gdouble) scale_factor;
 
   /* At this point, viewport is definitely bigger than bbox. */
   self->x_scaled = (bbox.width - viewport_width_real) / 2.0 + bbox.x;
@@ -222,6 +234,8 @@ photos_image_view_draw_node (PhotosImageView *self, cairo_t *cr, GdkRectangle *r
   gint64 start;
 
   g_return_if_fail (GEGL_IS_BUFFER (self->buffer));
+  g_return_if_fail (self->zoom > 0.0);
+  g_return_if_fail (self->zoom_scaled > 0.0);
 
   scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (self));
 
@@ -369,6 +383,15 @@ photos_image_view_set_property (GObject *object, guint prop_id, const GValue *va
         break;
       }
 
+    case PROP_ZOOM:
+      {
+        gdouble zoom;
+
+        zoom = g_value_get_double (value);
+        photos_image_view_set_zoom (self, zoom);
+        break;
+      }
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -441,7 +464,7 @@ photos_image_view_class_init (PhotosImageViewClass *class)
                                                         0.0,
                                                         100.0,
                                                         1.0,
-                                                        G_PARAM_READABLE));
+                                                        G_PARAM_READWRITE));
 
   signals[DRAW_BACKGROUND] = g_signal_new ("draw-background",
                                            G_TYPE_FROM_CLASS (class),
@@ -484,6 +507,14 @@ photos_image_view_new_from_node (GeglNode *node)
 }
 
 
+gboolean
+photos_image_view_get_best_fit (PhotosImageView *self)
+{
+  g_return_val_if_fail (PHOTOS_IS_IMAGE_VIEW (self), FALSE);
+  return self->best_fit;
+}
+
+
 GeglNode *
 photos_image_view_get_node (PhotosImageView *self)
 {
@@ -517,9 +548,29 @@ photos_image_view_get_zoom (PhotosImageView *self)
 
 
 void
+photos_image_view_set_best_fit (PhotosImageView *self, gboolean best_fit)
+{
+  g_return_if_fail (PHOTOS_IS_IMAGE_VIEW (self));
+
+  if (self->best_fit == best_fit)
+    return;
+
+  self->best_fit = best_fit;
+
+  if (self->best_fit)
+    {
+      self->zoom = -1.0;
+      self->zoom_scaled = -1.0;
+      gtk_widget_queue_resize (GTK_WIDGET (self));
+    }
+}
+
+
+void
 photos_image_view_set_node (PhotosImageView *self, GeglNode *node)
 {
   g_return_if_fail (PHOTOS_IS_IMAGE_VIEW (self));
+  g_return_if_fail (node == NULL || GEGL_IS_NODE (node));
 
   if (self->node == node)
     return;
@@ -535,6 +586,8 @@ photos_image_view_set_node (PhotosImageView *self, GeglNode *node)
   g_clear_pointer (&self->bbox_region, (GDestroyNotify) cairo_region_destroy);
   g_clear_pointer (&self->region, (GDestroyNotify) cairo_region_destroy);
 
+  self->best_fit = TRUE;
+
   if (node != NULL)
     {
       self->node = g_object_ref (node);
@@ -553,3 +606,23 @@ photos_image_view_set_node (PhotosImageView *self, GeglNode *node)
   photos_image_view_update (self);
   gtk_widget_queue_draw (GTK_WIDGET (self));
 }
+
+
+void
+photos_image_view_set_zoom (PhotosImageView *self, gdouble zoom)
+{
+  gint scale_factor;
+
+  g_return_if_fail (PHOTOS_IS_IMAGE_VIEW (self));
+
+  if (photos_utils_equal_double (self->zoom, zoom))
+    return;
+
+  self->best_fit = FALSE;
+  self->zoom = zoom;
+
+  scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (self));
+  self->zoom_scaled = self->zoom * scale_factor;
+
+  gtk_widget_queue_resize (GTK_WIDGET (self));
+}
diff --git a/src/photos-image-view.h b/src/photos-image-view.h
index 0ba8708..5cf0e82 100644
--- a/src/photos-image-view.h
+++ b/src/photos-image-view.h
@@ -33,6 +33,8 @@ GtkWidget          *photos_image_view_new                (void);
 
 GtkWidget          *photos_image_view_new_from_node      (GeglNode *node);
 
+gboolean            photos_image_view_get_best_fit       (PhotosImageView *self);
+
 GeglNode           *photos_image_view_get_node           (PhotosImageView *self);
 
 gdouble             photos_image_view_get_x              (PhotosImageView *self);
@@ -41,8 +43,12 @@ gdouble             photos_image_view_get_y              (PhotosImageView *self)
 
 gdouble             photos_image_view_get_zoom           (PhotosImageView *self);
 
+void                photos_image_view_set_best_fit       (PhotosImageView *self, gboolean best_fit);
+
 void                photos_image_view_set_node           (PhotosImageView *self, GeglNode *node);
 
+void                photos_image_view_set_zoom           (PhotosImageView *self, gdouble zoom);
+
 G_END_DECLS
 
 #endif /* PHOTOS_IMAGE_VIEW_H */


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