[Xfce4-commits] <ristretto:master> Add rotation to the image-viewer widget

Stephan Arts noreply at xfce.org
Mon Aug 8 15:04:30 CEST 2011


Updating branch refs/heads/master
         to 0baa638b40c5bdf3bf73c4440625022504680e4c (commit)
       from dce4a45dd28776e3c1ab7b5acd98c8f08a20904d (commit)

commit 0baa638b40c5bdf3bf73c4440625022504680e4c
Author: Stephan Arts <stephan at xfce.org>
Date:   Sun Aug 7 08:02:13 2011 +0200

    Add rotation to the image-viewer widget

 src/image_viewer.c |  230 +++++++++++++++++++++++++++++++++++++++++++++-------
 src/image_viewer.h |   13 +++-
 src/main_window.c  |    4 +-
 3 files changed, 213 insertions(+), 34 deletions(-)

diff --git a/src/image_viewer.c b/src/image_viewer.c
index 0108814..97efbfb 100644
--- a/src/image_viewer.c
+++ b/src/image_viewer.c
@@ -53,6 +53,7 @@ struct _RsttoImageViewerPriv
     RsttoImageViewerTransaction *transaction;
     GdkPixbuf                   *pixbuf;
     GdkPixbuf                   *dst_pixbuf;
+    RsttoImageViewerOrientation  orientation;
 
     /* Animation data for animated images (like .gif/.mng) */
     /*******************************************************/
@@ -839,10 +840,18 @@ rstto_image_viewer_new (void)
  *  - cancellable...
  */
 void
-rstto_image_viewer_set_file (RsttoImageViewer *viewer, GFile *file, gdouble scale)
+rstto_image_viewer_set_file (RsttoImageViewer *viewer,
+                             GFile *file,
+                             gdouble scale,
+                             RsttoImageViewerOrientation orientation)
 {
 
     /*
+     * Set the image-orientation
+     */
+    viewer->priv->orientation = orientation;
+
+    /*
      * Check if a file is set, or unset.
      */
     if (file)
@@ -951,6 +960,21 @@ void
 rstto_image_viewer_set_scale (RsttoImageViewer *viewer, gdouble scale)
 {
     gdouble tmp_x, tmp_y;
+    GtkAdjustment *vadjustment, *hadjustment;
+
+    switch (viewer->priv->orientation)
+    {
+        case RSTTO_IMAGE_VIEWER_ORIENT_NONE:
+        case RSTTO_IMAGE_VIEWER_ORIENT_180:
+            hadjustment = viewer->hadjustment;
+            vadjustment = viewer->vadjustment;
+            break;
+        case RSTTO_IMAGE_VIEWER_ORIENT_270:
+        case RSTTO_IMAGE_VIEWER_ORIENT_90:
+            hadjustment = viewer->vadjustment;
+            vadjustment = viewer->hadjustment;
+            break;
+    }
 
 
     if (scale == 0)
@@ -1041,12 +1065,12 @@ rstto_image_viewer_set_scale (RsttoImageViewer *viewer, gdouble scale)
          * When zooming in or out, 
          * try keeping the center of the viewport in the center.
          */
-        tmp_y = (gtk_adjustment_get_value(viewer->vadjustment) + (gtk_adjustment_get_page_size (viewer->vadjustment) / 2)) / viewer->priv->scale;
-        gtk_adjustment_set_value (viewer->vadjustment, (tmp_y*scale - (gtk_adjustment_get_page_size(viewer->vadjustment)/2)));
+        tmp_y = (gtk_adjustment_get_value(vadjustment) + (gtk_adjustment_get_page_size (vadjustment) / 2)) / viewer->priv->scale;
+        gtk_adjustment_set_value (vadjustment, (tmp_y*scale - (gtk_adjustment_get_page_size(vadjustment)/2)));
 
 
-        tmp_x = (gtk_adjustment_get_value(viewer->hadjustment) + (gtk_adjustment_get_page_size (viewer->hadjustment) / 2)) / viewer->priv->scale;
-        gtk_adjustment_set_value (viewer->hadjustment, (tmp_x*scale - (gtk_adjustment_get_page_size(viewer->hadjustment)/2)));
+        tmp_x = (gtk_adjustment_get_value(hadjustment) + (gtk_adjustment_get_page_size (hadjustment) / 2)) / viewer->priv->scale;
+        gtk_adjustment_set_value (hadjustment, (tmp_x*scale - (gtk_adjustment_get_page_size(hadjustment)/2)));
 
     }
 
@@ -1280,6 +1304,11 @@ cb_rstto_image_viewer_queued_repaint (RsttoImageViewer *viewer)
 {
     gint width, height;
     gdouble v_scale, h_scale;
+    GtkAdjustment *hadjustment, *vadjustment;
+    gint subpixbuf_x_offset = 0;
+    gint subpixbuf_y_offset = 0;
+    gint subpixbuf_width = 0;
+    gint subpixbuf_height = 0;
 
     /*
      * relative_scale contains viewer->priv->scale / viewer->priv->image_scale
@@ -1294,14 +1323,36 @@ cb_rstto_image_viewer_queued_repaint (RsttoImageViewer *viewer)
     viewer->priv->repaint.idle_id = -1;
     viewer->priv->repaint.refresh = FALSE;
 
+
+    g_object_freeze_notify(G_OBJECT(viewer->hadjustment));
+    g_object_freeze_notify(G_OBJECT(viewer->vadjustment));
+
     if (viewer->priv->pixbuf)
     {
+        switch (viewer->priv->orientation)
+        {
+            case RSTTO_IMAGE_VIEWER_ORIENT_NONE:
+            case RSTTO_IMAGE_VIEWER_ORIENT_180:
+                hadjustment = viewer->hadjustment;
+                vadjustment = viewer->vadjustment;
+
+                v_scale = (gdouble)(GTK_WIDGET (viewer)->allocation.height) / (gdouble)viewer->priv->image_height;
+                h_scale = (gdouble)(GTK_WIDGET (viewer)->allocation.width) / (gdouble)viewer->priv->image_width;
+                break;
+
+            case RSTTO_IMAGE_VIEWER_ORIENT_90:
+            case RSTTO_IMAGE_VIEWER_ORIENT_270:
+                hadjustment = viewer->vadjustment;
+                vadjustment = viewer->hadjustment;
+
+                v_scale = (gdouble)(GTK_WIDGET (viewer)->allocation.height) / (gdouble)viewer->priv->image_width;
+                h_scale = (gdouble)(GTK_WIDGET (viewer)->allocation.width) / (gdouble)viewer->priv->image_height;
+                break;
+        }
+
         width = gdk_pixbuf_get_width (viewer->priv->pixbuf);
         height = gdk_pixbuf_get_height (viewer->priv->pixbuf);
 
-        v_scale = (gdouble)(GTK_WIDGET (viewer)->allocation.height) / (gdouble)viewer->priv->image_height;
-        h_scale = (gdouble)(GTK_WIDGET (viewer)->allocation.width) / (gdouble)viewer->priv->image_width;
-
         /*
          * Scale == -1, this means the image is not loaded before, 
          * and it should be rendered at the best possible quality.
@@ -1368,28 +1419,121 @@ cb_rstto_image_viewer_queued_repaint (RsttoImageViewer *viewer)
             }
         }
 
+
         relative_scale = viewer->priv->scale / viewer->priv->image_scale;
 
         /*
          *
          *
          */
-        if ((gtk_adjustment_get_page_size (viewer->vadjustment) + 
-                gtk_adjustment_get_value(viewer->vadjustment)) > (viewer->priv->image_height*viewer->priv->scale))
+        switch (viewer->priv->orientation)
+        {
+            case RSTTO_IMAGE_VIEWER_ORIENT_NONE:
+                if ((gtk_adjustment_get_page_size (vadjustment) + 
+                        gtk_adjustment_get_value(vadjustment)) > (viewer->priv->image_height*viewer->priv->scale))
+                {
+                    gtk_adjustment_set_value (vadjustment,
+                            (height*relative_scale) -
+                            gtk_adjustment_get_page_size (vadjustment));
+                }
+                if ((gtk_adjustment_get_page_size (hadjustment) + 
+                        gtk_adjustment_get_value(hadjustment)) > (viewer->priv->image_width*viewer->priv->scale))
+                {
+                    gtk_adjustment_set_value (hadjustment,
+                            (width*relative_scale) - 
+                            gtk_adjustment_get_page_size (hadjustment));
+                }
+                gtk_adjustment_set_upper (hadjustment, (gdouble)width*(viewer->priv->scale/viewer->priv->image_scale));
+                gtk_adjustment_set_upper (vadjustment, (gdouble)height*(viewer->priv->scale/viewer->priv->image_scale));
+                subpixbuf_x_offset = (gint)(gtk_adjustment_get_value (hadjustment) / relative_scale);
+                subpixbuf_y_offset = (gint)(gtk_adjustment_get_value (vadjustment) / relative_scale);
+                subpixbuf_width = (gint)((gtk_adjustment_get_page_size (hadjustment) / relative_scale) < width)?
+                               (gtk_adjustment_get_page_size (hadjustment) / relative_scale)+1:(width);
+                subpixbuf_height = (gint)((gtk_adjustment_get_page_size (vadjustment) / relative_scale) < height)?
+                               (gtk_adjustment_get_page_size (vadjustment) / relative_scale)+1:(width);
+                break;
+            case RSTTO_IMAGE_VIEWER_ORIENT_180:
+                gtk_adjustment_set_upper (hadjustment, (gdouble)width*(viewer->priv->scale/viewer->priv->image_scale));
+                gtk_adjustment_set_upper (vadjustment, (gdouble)height*(viewer->priv->scale/viewer->priv->image_scale));
+                subpixbuf_x_offset = (gint)((gtk_adjustment_get_upper(hadjustment) - 
+                                             gtk_adjustment_get_page_size(hadjustment) - 
+                                             gtk_adjustment_get_value (hadjustment)) / relative_scale);
+                subpixbuf_y_offset = (gint)((gtk_adjustment_get_upper(vadjustment) - 
+                                             gtk_adjustment_get_page_size(vadjustment) - 
+                                             gtk_adjustment_get_value (vadjustment)) / relative_scale);
+                subpixbuf_width = (gint)((gtk_adjustment_get_page_size (hadjustment) / relative_scale) < width)?
+                               (gtk_adjustment_get_page_size (hadjustment) / relative_scale)+1:(width);
+                subpixbuf_height = (gint)((gtk_adjustment_get_page_size (vadjustment) / relative_scale) < height)?
+                               (gtk_adjustment_get_page_size (vadjustment) / relative_scale)+1:(height);
+                break;
+            case RSTTO_IMAGE_VIEWER_ORIENT_270:
+                gtk_adjustment_set_upper (hadjustment, (gdouble)width*(viewer->priv->scale/viewer->priv->image_scale));
+                gtk_adjustment_set_upper (vadjustment, (gdouble)height*(viewer->priv->scale/viewer->priv->image_scale));
+
+                if ((gtk_adjustment_get_page_size (hadjustment) + 
+                        gtk_adjustment_get_value(hadjustment)) > (viewer->priv->image_width*viewer->priv->scale))
+                {
+                    gtk_adjustment_set_value (hadjustment,
+                            (width*relative_scale) -
+                            gtk_adjustment_get_page_size (vadjustment));
+                }
+                if ((gtk_adjustment_get_page_size (vadjustment) + 
+                        gtk_adjustment_get_value(vadjustment)) > (viewer->priv->image_height*viewer->priv->scale))
+                {
+                    gtk_adjustment_set_value (vadjustment,
+                            (height*relative_scale) - 
+                            gtk_adjustment_get_page_size (vadjustment));
+                }
+
+                subpixbuf_x_offset = (gint)((gtk_adjustment_get_upper(hadjustment) - 
+                                             (gtk_adjustment_get_page_size(hadjustment) + 
+                                             gtk_adjustment_get_value (hadjustment))) / relative_scale);
+                subpixbuf_y_offset = (gint)(gtk_adjustment_get_value (vadjustment) / relative_scale);
+                subpixbuf_width = (gint)((gtk_adjustment_get_page_size (hadjustment) / relative_scale) < width)?
+                               (gtk_adjustment_get_page_size (hadjustment) / relative_scale)+1:(width);
+                subpixbuf_height = (gint)((gtk_adjustment_get_page_size (vadjustment) / relative_scale) < height)?
+                               (gtk_adjustment_get_page_size (vadjustment) / relative_scale)+1:(height);
+                break;
+            case RSTTO_IMAGE_VIEWER_ORIENT_90:
+                gtk_adjustment_set_upper (hadjustment, (gdouble)width*(viewer->priv->scale/viewer->priv->image_scale));
+                gtk_adjustment_set_upper (vadjustment, (gdouble)height*(viewer->priv->scale/viewer->priv->image_scale));
+
+                if ((gtk_adjustment_get_page_size (hadjustment) + 
+                        gtk_adjustment_get_value(hadjustment)) > (viewer->priv->image_width*viewer->priv->scale))
+                {
+                    gtk_adjustment_set_value (hadjustment,
+                            (width*relative_scale) -
+                            gtk_adjustment_get_page_size (vadjustment));
+                }
+                if ((gtk_adjustment_get_page_size (vadjustment) + 
+                        gtk_adjustment_get_value(vadjustment)) > (viewer->priv->image_height*viewer->priv->scale))
+                {
+                    gtk_adjustment_set_value (vadjustment,
+                            (height*relative_scale) - 
+                            gtk_adjustment_get_page_size (vadjustment));
+                }
+
+                subpixbuf_x_offset = (gint)(gtk_adjustment_get_value (hadjustment) / relative_scale);
+                subpixbuf_y_offset = (gint)((gtk_adjustment_get_upper(vadjustment) - 
+                                             (gtk_adjustment_get_page_size(vadjustment) + 
+                                             gtk_adjustment_get_value (vadjustment))) / relative_scale);
+                subpixbuf_width = (gint)((gtk_adjustment_get_page_size (hadjustment) / relative_scale) < width)?
+                               (gtk_adjustment_get_page_size (hadjustment) / relative_scale)+1:(width);
+                subpixbuf_height = (gint)((gtk_adjustment_get_page_size (vadjustment) / relative_scale) < height)?
+                               (gtk_adjustment_get_page_size (vadjustment) / relative_scale)+1:(height);
+                break;
+        }
+
+        if (subpixbuf_x_offset < 0)
         {
-            gtk_adjustment_set_value (viewer->vadjustment,
-                    (height*relative_scale) -
-                    gtk_adjustment_get_page_size (viewer->vadjustment));
+            subpixbuf_x_offset = 0;
         }
-        if ((gtk_adjustment_get_page_size (viewer->hadjustment) + 
-                gtk_adjustment_get_value(viewer->hadjustment)) > (viewer->priv->image_width*viewer->priv->scale))
+        if (subpixbuf_y_offset < 0)
         {
-            gtk_adjustment_set_value (viewer->hadjustment,
-                    (width*relative_scale) - 
-                    gtk_adjustment_get_page_size (viewer->hadjustment));
+            subpixbuf_y_offset = 0;
         }
 
-        if (gtk_adjustment_get_page_size (viewer->vadjustment) > 0)
+        if (gtk_adjustment_get_page_size (vadjustment) > 0)
         {
 
             /*
@@ -1401,15 +1545,8 @@ cb_rstto_image_viewer_queued_repaint (RsttoImageViewer *viewer)
              * Adding '1' when the tmp_pixbuf is smaller then the full width or
              * height of the image solves this.
              */
-            GdkPixbuf *tmp_pixbuf = gdk_pixbuf_new_subpixbuf (viewer->priv->pixbuf,
-                    (gint)(gtk_adjustment_get_value (viewer->hadjustment) / relative_scale),
-                    (gint)(gtk_adjustment_get_value (viewer->vadjustment) / relative_scale),
-                    (gint)((gtk_adjustment_get_page_size (viewer->hadjustment) / relative_scale) < width)?
-                           (gtk_adjustment_get_page_size (viewer->hadjustment) / relative_scale)+1:
-                           (width),
-                    (gint)((gtk_adjustment_get_page_size (viewer->vadjustment) / relative_scale) < height)?
-                           (gtk_adjustment_get_page_size (viewer->vadjustment) / relative_scale)+1:
-                           (height));
+            GdkPixbuf *tmp_pixbuf2;
+            GdkPixbuf *tmp_pixbuf;
 
             if (viewer->priv->dst_pixbuf)
             {
@@ -1417,6 +1554,32 @@ cb_rstto_image_viewer_queued_repaint (RsttoImageViewer *viewer)
                 viewer->priv->dst_pixbuf = NULL;
             }
 
+
+            tmp_pixbuf = gdk_pixbuf_new_subpixbuf (viewer->priv->pixbuf,
+                    subpixbuf_x_offset,
+                    subpixbuf_y_offset,
+                    subpixbuf_width,
+                    subpixbuf_height);
+
+            switch (viewer->priv->orientation)
+            {
+                case RSTTO_IMAGE_VIEWER_ORIENT_180:
+                    tmp_pixbuf2 = gdk_pixbuf_rotate_simple (tmp_pixbuf, GDK_PIXBUF_ROTATE_UPSIDEDOWN);
+                    g_object_unref (tmp_pixbuf);
+                    tmp_pixbuf = tmp_pixbuf2;
+                    break;
+                case RSTTO_IMAGE_VIEWER_ORIENT_270:
+                    tmp_pixbuf2 = gdk_pixbuf_rotate_simple (tmp_pixbuf, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
+                    g_object_unref (tmp_pixbuf);
+                    tmp_pixbuf = tmp_pixbuf2;
+                    break;
+                case RSTTO_IMAGE_VIEWER_ORIENT_90:
+                    tmp_pixbuf2 = gdk_pixbuf_rotate_simple (tmp_pixbuf, GDK_PIXBUF_ROTATE_CLOCKWISE);
+                    g_object_unref (tmp_pixbuf);
+                    tmp_pixbuf = tmp_pixbuf2;
+                    break;
+            }
+
             viewer->priv->dst_pixbuf = gdk_pixbuf_scale_simple (tmp_pixbuf,
                                        (gint)(gdk_pixbuf_get_width(tmp_pixbuf) * relative_scale),
                                        (gint)(gdk_pixbuf_get_height(tmp_pixbuf) * relative_scale),
@@ -1428,9 +1591,8 @@ cb_rstto_image_viewer_queued_repaint (RsttoImageViewer *viewer)
         /* 
          * Set adjustments
          */
-        gtk_adjustment_set_upper (viewer->hadjustment, (gdouble)width*(viewer->priv->scale/viewer->priv->image_scale));
-        gtk_adjustment_set_upper (viewer->vadjustment, (gdouble)height*(viewer->priv->scale/viewer->priv->image_scale));
-
+        gtk_adjustment_set_upper (hadjustment, (gdouble)width*(viewer->priv->scale/viewer->priv->image_scale));
+        gtk_adjustment_set_upper (vadjustment, (gdouble)height*(viewer->priv->scale/viewer->priv->image_scale));
     }
     else
     {
@@ -1447,6 +1609,12 @@ cb_rstto_image_viewer_queued_repaint (RsttoImageViewer *viewer)
         gtk_adjustment_set_upper (viewer->vadjustment, 0);
     }
 
+    g_object_thaw_notify(G_OBJECT(viewer->hadjustment));
+    g_object_thaw_notify(G_OBJECT(viewer->vadjustment));
+
+    gtk_adjustment_changed(viewer->hadjustment);
+    gtk_adjustment_changed(viewer->vadjustment);
+
 
     rstto_image_viewer_paint (GTK_WIDGET (viewer));
 }
diff --git a/src/image_viewer.h b/src/image_viewer.h
index 497a108..533d9e2 100644
--- a/src/image_viewer.h
+++ b/src/image_viewer.h
@@ -21,6 +21,14 @@
 
 G_BEGIN_DECLS
 
+typedef enum
+{
+  RSTTO_IMAGE_VIEWER_ORIENT_NONE,
+  RSTTO_IMAGE_VIEWER_ORIENT_90,
+  RSTTO_IMAGE_VIEWER_ORIENT_180,
+  RSTTO_IMAGE_VIEWER_ORIENT_270
+} RsttoImageViewerOrientation;
+
 #define RSTTO_TYPE_IMAGE_VIEWER rstto_image_viewer_get_type()
 
 #define RSTTO_IMAGE_VIEWER(obj)( \
@@ -68,7 +76,10 @@ struct _RsttoImageViewerClass
 GType      rstto_image_viewer_get_type();
 
 GtkWidget *rstto_image_viewer_new ();
-void       rstto_image_viewer_set_file (RsttoImageViewer *viewer, GFile *file, gdouble scale);
+void       rstto_image_viewer_set_file (RsttoImageViewer *viewer,
+                                        GFile *file,
+                                        gdouble scale,
+                                        RsttoImageViewerOrientation orientation);
 
 void       rstto_image_viewer_set_scale (RsttoImageViewer *viewer, gdouble scale);
 gdouble    rstto_image_viewer_get_scale (RsttoImageViewer *viewer);
diff --git a/src/main_window.c b/src/main_window.c
index 07fea6b..2f32fd0 100644
--- a/src/main_window.c
+++ b/src/main_window.c
@@ -824,7 +824,7 @@ rstto_main_window_image_list_iter_changed (RsttoMainWindow *window)
             file_info = g_file_query_info (file, "standard::content-type", 0, NULL, NULL);
             content_type  = g_file_info_get_content_type (file_info);
 
-            rstto_image_viewer_set_file (RSTTO_IMAGE_VIEWER(window->priv->image_viewer), file, -1);
+            rstto_image_viewer_set_file (RSTTO_IMAGE_VIEWER(window->priv->image_viewer), file, -1, RSTTO_IMAGE_VIEWER_ORIENT_270);
 
             app_list = g_app_info_get_all_for_type (content_type);
 
@@ -865,7 +865,7 @@ rstto_main_window_image_list_iter_changed (RsttoMainWindow *window)
             gtk_menu_shell_append (GTK_MENU_SHELL (open_with_menu), menu_item);
             gtk_widget_set_sensitive (menu_item, FALSE);
 
-            rstto_image_viewer_set_file (RSTTO_IMAGE_VIEWER(window->priv->image_viewer), NULL, -1);
+            rstto_image_viewer_set_file (RSTTO_IMAGE_VIEWER(window->priv->image_viewer), NULL, -1, RSTTO_IMAGE_VIEWER_ORIENT_270);
 
 
             menu_item = gtk_image_menu_item_new_with_label (_("Empty"));


More information about the Xfce4-commits mailing list