[Xfce4-commits] <ristretto:master> Constrain zoom-box to image dimensions.

Stephan Arts noreply at xfce.org
Fri Oct 21 17:38:07 CEST 2011


Updating branch refs/heads/master
         to 4c3ca6d8b452a802bbfce16f9f51595182f5ef4d (commit)
       from a862815f7fa6c907744f91333df487ff7c9b0a29 (commit)

commit 4c3ca6d8b452a802bbfce16f9f51595182f5ef4d
Author: Stephan Arts <stephan at xfce.org>
Date:   Fri Oct 21 15:30:15 2011 +0200

    Constrain zoom-box to image dimensions.
    
    - Clear release_event handler

 src/image_viewer.c |  338 +++++++++++++++++-----------------------------------
 1 files changed, 110 insertions(+), 228 deletions(-)

diff --git a/src/image_viewer.c b/src/image_viewer.c
index df1d5bc..273e306 100644
--- a/src/image_viewer.c
+++ b/src/image_viewer.c
@@ -74,9 +74,14 @@ struct _RsttoImageViewerPriv
 
     RsttoImageViewerTransaction *transaction;
     GdkPixbuf                   *pixbuf;
-    GdkPixbuf                   *dst_pixbuf;
     RsttoImageOrientation        orientation;
-    gdouble                      quality;
+    struct
+    {
+        gdouble x_offset;
+        gdouble y_offset;
+        gdouble width;
+        gdouble height;
+    } rendering;
 
 
     GtkMenu                     *menu;
@@ -903,11 +908,50 @@ paint_image (
         cairo_t *ctx )
 {
     RsttoImageViewer *viewer = RSTTO_IMAGE_VIEWER (widget);
-    gdouble x_offset = 0.0;
-    gdouble y_offset = 0.0;
 
     if (viewer->priv->pixbuf)
     {
+        switch (viewer->priv->orientation)
+        {
+            case RSTTO_IMAGE_ORIENT_90:
+            case RSTTO_IMAGE_ORIENT_270:
+                viewer->priv->rendering.x_offset = ((gdouble)widget->allocation.width - (
+                            (gdouble)viewer->priv->image_height * 
+                                viewer->priv->scale) ) / 2.0;
+                viewer->priv->rendering.y_offset = ((gdouble)widget->allocation.height - (
+                            (gdouble)viewer->priv->image_width * 
+                                viewer->priv->scale) ) / 2.0;
+                viewer->priv->rendering.width = 
+                        (gdouble)viewer->priv->image_height * viewer->priv->scale;
+                viewer->priv->rendering.height = 
+                        (gdouble)viewer->priv->image_width * viewer->priv->scale;
+                break;
+            case RSTTO_IMAGE_ORIENT_NONE:
+            case RSTTO_IMAGE_ORIENT_180:
+            default:
+                viewer->priv->rendering.x_offset = ((gdouble)widget->allocation.width - (
+                            (gdouble)viewer->priv->image_width * 
+                                viewer->priv->scale) ) / 2.0;
+                viewer->priv->rendering.y_offset = ((gdouble)widget->allocation.height - (
+                            (gdouble)viewer->priv->image_height * 
+                                viewer->priv->scale) ) / 2.0;
+                viewer->priv->rendering.width = 
+                        (gdouble)viewer->priv->image_width * viewer->priv->scale;
+                viewer->priv->rendering.height = 
+                        (gdouble)viewer->priv->image_height * viewer->priv->scale;
+                break;
+
+        }
+
+        if (viewer->priv->rendering.x_offset < 0.0)
+        {
+            viewer->priv->rendering.x_offset = 0.0;
+        }
+        if (viewer->priv->rendering.y_offset < 0.0)
+        {
+            viewer->priv->rendering.y_offset = 0.0;
+        }
+
         /* TODO: make this work for all rotations */
         switch (viewer->priv->orientation)
         {
@@ -923,21 +967,10 @@ paint_image (
                         ctx,
                         0.0,
                         -1.0 * viewer->priv->image_height * viewer->priv->scale);
-
-                y_offset = -1.0 * (((gdouble)widget->allocation.width - (
-                            (gdouble)viewer->priv->image_height * 
-                                viewer->priv->scale) ) / 2.0);
-                x_offset =  ((gdouble)widget->allocation.height - (
-                            (gdouble)viewer->priv->image_width * 
-                                viewer->priv->scale) ) / 2.0;
-                if (x_offset < 0.0)
-                {
-                    x_offset = 0.0;
-                }
-                if (y_offset > 0.0)
-                {
-                    y_offset = 0.0;
-                }
+                cairo_translate (
+                        ctx,
+                        -1.0 * viewer->priv->rendering.y_offset,
+                        viewer->priv->rendering.x_offset);
                 break;
             case RSTTO_IMAGE_ORIENT_270:
                 cairo_rotate (
@@ -952,20 +985,10 @@ paint_image (
                         -1.0 * viewer->priv->image_width * viewer->priv->scale,
                         0.0);
 
-                y_offset = (((gdouble)widget->allocation.width - (
-                            (gdouble)viewer->priv->image_height * 
-                                viewer->priv->scale) ) / 2.0);
-                x_offset = -1.0 * ((gdouble)widget->allocation.height - (
-                            (gdouble)viewer->priv->image_width * 
-                                viewer->priv->scale) ) / 2.0;
-                if (x_offset > 0.0)
-                {
-                    x_offset = 0.0;
-                }
-                if (y_offset < 0.0)
-                {
-                    y_offset = 0.0;
-                }
+                cairo_translate (
+                        ctx,
+                        viewer->priv->rendering.y_offset,
+                        -1.0 * viewer->priv->rendering.x_offset);
                 break;
             case RSTTO_IMAGE_ORIENT_180:
                 cairo_rotate (
@@ -980,21 +1003,10 @@ paint_image (
                         -1.0 * viewer->priv->image_width * viewer->priv->scale,
                         -1.0 * viewer->priv->image_height * viewer->priv->scale);
 
-                x_offset = -1.0 * ((gdouble)widget->allocation.width - (
-                            (gdouble)viewer->priv->image_width * 
-                                viewer->priv->scale) ) / 2.0;
-                y_offset = -1.0 * ((gdouble)widget->allocation.height - (
-                            (gdouble)viewer->priv->image_height * 
-                                viewer->priv->scale) ) / 2.0;
-
-                if (x_offset > 0.0)
-                {
-                    x_offset = 0.0;
-                }
-                if (y_offset > 0.0)
-                {
-                    y_offset = 0.0;
-                }
+                cairo_translate (
+                        ctx,
+                        -1.0 * viewer->priv->rendering.x_offset,
+                        -1.0 * viewer->priv->rendering.y_offset);
                 break;
             case RSTTO_IMAGE_ORIENT_NONE:
             default:
@@ -1002,30 +1014,15 @@ paint_image (
                         ctx,
                         0.0 - gtk_adjustment_get_value (viewer->hadjustment),
                         0.0 - gtk_adjustment_get_value (viewer->vadjustment));
-                x_offset = ((gdouble)widget->allocation.width - (
-                            (gdouble)viewer->priv->image_width * 
-                                viewer->priv->scale) ) / 2.0;
-                y_offset = ((gdouble)widget->allocation.height - (
-                            (gdouble)viewer->priv->image_height * 
-                                viewer->priv->scale) ) / 2.0;
-                if (x_offset < 0.0)
-                {
-                    x_offset = 0.0;
-                }
-                if (y_offset < 0.0)
-                {
-                    y_offset = 0.0;
-                }
+
+                cairo_translate (
+                        ctx,
+                        viewer->priv->rendering.x_offset,
+                        viewer->priv->rendering.y_offset);
                 break;
 
         }
 
-
-        cairo_translate (
-                ctx,
-                x_offset,
-                y_offset);
-
         cairo_scale (
                 ctx,
                 (viewer->priv->scale/viewer->priv->image_scale),
@@ -1051,7 +1048,16 @@ paint_selection_box (
     gdouble box_x = 0.0;
     gdouble box_width = 0.0;
     gdouble box_height = 0.0;
-
+    gdouble x_offset = viewer->priv->rendering.x_offset;
+    gdouble y_offset = viewer->priv->rendering.y_offset;
+    gdouble image_width = viewer->priv->rendering.width;
+    gdouble image_height = viewer->priv->rendering.height;
+
+    /* A selection-box can be created moving the cursor from
+     * left to right, aswell as from right to left.
+     * 
+     * Calculate the box dimensions accordingly.
+     */
     if (viewer->priv->motion.y < viewer->priv->motion.current_y)
     {
         box_y = (gdouble)viewer->priv->motion.y;
@@ -1063,6 +1069,11 @@ paint_selection_box (
         box_height = (gdouble)viewer->priv->motion.y - box_y;
     }
 
+    /* A selection-box can be created moving the cursor from
+     * top to bottom, aswell as from bottom to top.
+     * 
+     * Calculate the box dimensions accordingly.
+     */
     if (viewer->priv->motion.x < viewer->priv->motion.current_x)
     {
         box_x = (gdouble)viewer->priv->motion.x;
@@ -1074,9 +1085,33 @@ paint_selection_box (
         box_width = (gdouble)viewer->priv->motion.x - box_x;
     }
 
+    /*
+     * Constrain the selection-box to the left
+     * and top sides of the image.
+     */
+    if (box_x < x_offset)
+    {
+        box_width = box_width - (x_offset - box_x);
+        box_x = x_offset;
+    }
+    if (box_y < y_offset)
+    {
+        box_height = box_height - (y_offset - box_y);
+        box_y = y_offset;
+    }
+
+    if ((x_offset + image_width) < (box_x + box_width))
+    {
+        box_width = (x_offset + image_width) - box_x - 1;
+    }
+    if ((y_offset + image_height) < (box_y + box_height))
+    {
+        box_height = (y_offset + image_height) - box_y - 1;
+    }
+
     cairo_rectangle (
         ctx,
-        box_x-0.5, box_y-0.5,
+        box_x+0.5, box_y+0.5,
         box_width, box_height);
 
     cairo_set_source_rgba (ctx, 0.9, 0.9, 0.9, 0.2);
@@ -1854,164 +1889,11 @@ rstto_button_release_event (
         GdkEventButton *event)
 {
     RsttoImageViewer *viewer = RSTTO_IMAGE_VIEWER (widget);
-    gint box_x;
-    gint box_y;
-    gint box_width;
-    gint box_height;
-    gint pixbuf_width;
-    gint pixbuf_height;
-    gint pixbuf_x_offset;
-    gint pixbuf_y_offset;
-    gint width;
-    gint height;
-    gdouble tmp_x, tmp_y, scale;
-
-    if ( NULL != viewer->priv->dst_pixbuf )
-    {
-        pixbuf_width = gdk_pixbuf_get_width(viewer->priv->dst_pixbuf);
-        pixbuf_height = gdk_pixbuf_get_height(viewer->priv->dst_pixbuf);
-        pixbuf_x_offset = ((widget->allocation.width - pixbuf_width)/2);
-        pixbuf_y_offset = ((widget->allocation.height - pixbuf_height)/2);
-
-        width = gdk_pixbuf_get_width (viewer->priv->pixbuf);
-        height = gdk_pixbuf_get_height (viewer->priv->pixbuf);
-
-        if (viewer->priv->motion.y < viewer->priv->motion.current_y)
-        {
-            box_y = viewer->priv->motion.y;
-            box_height = viewer->priv->motion.current_y - box_y;
-        }
-        else
-        {
-            box_y = viewer->priv->motion.current_y;
-            box_height = viewer->priv->motion.y - box_y;
-        }
-
-        if (viewer->priv->motion.x < viewer->priv->motion.current_x)
-        {
-            box_x = viewer->priv->motion.x;
-            box_width = viewer->priv->motion.current_x - box_x;
-        }
-        else
-        {
-            box_x = viewer->priv->motion.current_x;
-            box_width = viewer->priv->motion.x - box_x;
-        }
-    }
-
-
-    switch (event->button)
-    {
-        case 1:
-            gdk_window_set_cursor(widget->window, NULL);
-            switch (viewer->priv->motion.state)
-            {
-                case RSTTO_IMAGE_VIEWER_MOTION_STATE_BOX_ZOOM:
-                    /*
-                     * Constrain the selection-box to the left
-                     * and top sides of the image.
-                     */
-                    if (box_x < pixbuf_x_offset)
-                    {
-                        box_width -= (pixbuf_x_offset - box_x);
-                        box_x = pixbuf_x_offset;
-                    }
-                    if (box_y < pixbuf_y_offset)
-                    {
-                        box_height -= (pixbuf_y_offset - box_y);
-                        box_y = pixbuf_y_offset;
-                    }
-
-                    /*
-                     * Constrain the selection-box to the right
-                     * and bottom sides of the image.
-                     */
-                    if ((box_x + box_width) > (pixbuf_x_offset+pixbuf_width))
-                    {
-                        box_width = (pixbuf_x_offset+pixbuf_width)-box_x;
-                    }
-                    if ((box_y + box_height) > (pixbuf_y_offset+pixbuf_height))
-                    {
-                        box_height = (pixbuf_y_offset+pixbuf_height)-box_y;
-                    }
-
-                    if ((box_width > 0) && (box_height > 0))
-                    {
-                        /*
-                         * Using BOX_ZOOM disables auto-scale (zoom-to-fit-widget)
-                         */
-                        viewer->priv->auto_scale = FALSE;
-                        
-                        /*
-                         * Calculate the center of the selection-box.
-                         */
-
-                        tmp_y = (gtk_adjustment_get_value(viewer->vadjustment) + (gdouble)box_y + ((gdouble)box_height/ 2) - pixbuf_y_offset) / viewer->priv->scale;
-
-                        tmp_x = (gtk_adjustment_get_value(viewer->hadjustment) + (gdouble)box_x + ((gdouble)box_width / 2) - pixbuf_x_offset) / viewer->priv->scale;
-
-                        /*
-                         * Calculate the new scale
-                         */
-                        if ((gtk_adjustment_get_page_size(viewer->hadjustment) / box_width) < 
-                            (gtk_adjustment_get_page_size(viewer->vadjustment) / box_height))
-                        {
-                            scale = viewer->priv->scale * (gtk_adjustment_get_page_size(viewer->hadjustment) / box_width);
-                        }
-                        else
-                        {
-                            scale = viewer->priv->scale * (gtk_adjustment_get_page_size(viewer->vadjustment) / box_height);
-                        }
-
-                        /*
-                         * Prevent the widget from zooming in beyond the MAX_SCALE.
-                         */
-                        if (scale > RSTTO_MAX_SCALE)
-                        {
-                            scale = RSTTO_MAX_SCALE;
-                        }
-
-                        viewer->priv->scale = scale;
-
-                        
-                        /*
-                         * Prevent the adjustments from emitting the 'changed' signal,
-                         * this way both the upper-limit and value can be changed before the
-                         * rest of the application is informed.
-                         */
-                        g_object_freeze_notify(G_OBJECT(viewer->hadjustment));
-                        g_object_freeze_notify(G_OBJECT(viewer->vadjustment));
-
-                        gtk_adjustment_set_upper (viewer->hadjustment, (gdouble)width*(viewer->priv->scale/viewer->priv->image_scale));
-                        gtk_adjustment_set_value (viewer->hadjustment, (tmp_x * scale - ((gdouble)gtk_adjustment_get_page_size(viewer->hadjustment)/2)));
-                        gtk_adjustment_set_upper (viewer->vadjustment, (gdouble)height*(viewer->priv->scale/viewer->priv->image_scale));
-                        gtk_adjustment_set_value (viewer->vadjustment, (tmp_y * scale - ((gdouble)gtk_adjustment_get_page_size(viewer->vadjustment)/2)));
-
-                        /*
-                         * Enable signals on the adjustments.
-                         */
-                        g_object_thaw_notify(G_OBJECT(viewer->vadjustment));
-                        g_object_thaw_notify(G_OBJECT(viewer->hadjustment));
-
-                        /*
-                         * Trigger the 'changed' signal, update the rest of
-                         * the appliaction.
-                         */
-                        gtk_adjustment_changed(viewer->hadjustment);
-                        gtk_adjustment_changed(viewer->vadjustment);
-
-                    }
-                    break;
-                default:
-                    break;
-            }
-            rstto_image_viewer_set_motion_state (viewer, RSTTO_IMAGE_VIEWER_MOTION_STATE_NORMAL);
-            gdk_window_invalidate_rect (
-                    widget->window,
-                    NULL,
-                    FALSE);
-            break;
-    }
+    rstto_image_viewer_set_motion_state (viewer, RSTTO_IMAGE_VIEWER_MOTION_STATE_NORMAL);
+    gdk_window_invalidate_rect (
+            widget->window,
+            NULL,
+            FALSE);
     return FALSE;
 }
 


More information about the Xfce4-commits mailing list