[Xfce4-commits] <ristretto:master> Add 'scale' variable to image-viewer and move the paint-checkered-background to a separate function.

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


Updating branch refs/heads/master
         to 3f5abc2e48471965d17d7ce327f17de13970f907 (commit)
       from e4bf2eab287dc9e06b35083f88caa829e5ed9db4 (commit)

commit 3f5abc2e48471965d17d7ce327f17de13970f907
Author: Stephan Arts <stephan at xfce.org>
Date:   Sun Jul 17 22:49:35 2011 +0200

    Add 'scale' variable to image-viewer and move the paint-checkered-background to a separate function.

 src/image_viewer.c |  202 ++++++++++++++++++++++++++++++++++++++++------------
 src/image_viewer.h |    3 +
 src/main_window.c  |   13 ++--
 3 files changed, 166 insertions(+), 52 deletions(-)

diff --git a/src/image_viewer.c b/src/image_viewer.c
index 34833ff..0dcb7e3 100644
--- a/src/image_viewer.c
+++ b/src/image_viewer.c
@@ -60,6 +60,9 @@ struct _RsttoImageViewerPriv
     GdkPixbufAnimationIter *iter;
     gint                    animation_timeout_id;
 
+    gdouble                 scale;
+    gboolean                auto_scale;
+
     struct
     {
         gint idle_id;
@@ -118,6 +121,8 @@ static gboolean
 rstto_image_viewer_set_scroll_adjustments(RsttoImageViewer *, GtkAdjustment *, GtkAdjustment *);
 static void
 rstto_image_viewer_queued_repaint (RsttoImageViewer *viewer, gboolean);
+static void
+rstto_image_viewer_paint_checkers (GdkDrawable *drawable, GdkGC *gc, gint width, gint height, gint x_offset, gint y_offset);
 
 static void
 cb_rstto_image_viewer_value_changed(GtkAdjustment *adjustment, RsttoImageViewer *viewer);
@@ -383,7 +388,6 @@ rstto_image_viewer_set_scroll_adjustments(RsttoImageViewer *viewer, GtkAdjustmen
 static void
 rstto_image_viewer_paint (GtkWidget *widget)
 {
-    g_debug("%s", __FUNCTION__);
 
     RsttoImageViewer *viewer = RSTTO_IMAGE_VIEWER (widget);
 
@@ -391,7 +395,6 @@ rstto_image_viewer_paint (GtkWidget *widget)
     GValue val_bg_color = {0, }, val_bg_color_override = {0, }, val_bg_color_fs = {0, };
     GdkPixbuf *pixbuf = viewer->priv->dst_pixbuf;
     /** BELOW THIS LINE THE VARIABLE_NAMES GET MESSY **/
-    GdkColor color;
     GdkColor line_color;
     GdkPixbuf *n_pixbuf = NULL;
     gint width, height;
@@ -440,7 +443,6 @@ rstto_image_viewer_paint (GtkWidget *widget)
         /* Check if there is a destination pixbuf */
         if(pixbuf)
         {
-            g_debug ("Draw image");
             x1 = (widget->allocation.width-gdk_pixbuf_get_width(pixbuf))<0?0:(widget->allocation.width-gdk_pixbuf_get_width(pixbuf))/2;
             y1 = (widget->allocation.height-gdk_pixbuf_get_height(pixbuf))<0?0:(widget->allocation.height-gdk_pixbuf_get_height(pixbuf))/2;
             x2 = gdk_pixbuf_get_width(pixbuf);
@@ -449,41 +451,8 @@ rstto_image_viewer_paint (GtkWidget *widget)
             /* We only need to paint a checkered background if the image is transparent */
             if(gdk_pixbuf_get_has_alpha(pixbuf))
             {
-                for(i = 0; i <= x2/10; i++)
-                {
-                    if(i == x2/10)
-                    {
-                        width = x2-10*i;
-                    }
-                    else
-                    {   
-                        width = 10;
-                    }
-                    for(a = 0; a <= y2/10; a++)
-                    {
-                        if(a%2?i%2:!(i%2))
-                            color.pixel = 0xcccccccc;
-                        else
-                            color.pixel = 0xdddddddd;
-                        gdk_gc_set_foreground(gc, &color);
-                        if(a == y2/10)
-                        {
-                            height = y2-10*a;
-                        }
-                        else
-                        {   
-                            height = 10;
-                        }
-
-                        gdk_draw_rectangle(GDK_DRAWABLE(buffer),
-                                        gc,
-                                        TRUE,
-                                        x1+10*i,
-                                        y1+10*a,
-                                        width,
-                                        height);
-                    }
-                }
+                /* TODO: give these variables correct names */
+                rstto_image_viewer_paint_checkers (GDK_DRAWABLE(buffer), gc, x2, y2, x1, y1);
             }
             gdk_draw_pixbuf(GDK_DRAWABLE(buffer), 
                             NULL, 
@@ -496,6 +465,7 @@ rstto_image_viewer_paint (GtkWidget *widget)
                             y2,
                             GDK_RGB_DITHER_NONE,
                             0,0);
+
             if(viewer->priv->motion.state == RSTTO_PICTURE_VIEWER_MOTION_STATE_BOX_ZOOM)
             {
                 gdk_gc_set_foreground(gc,
@@ -631,6 +601,60 @@ rstto_image_viewer_paint (GtkWidget *widget)
 }
 
 static void
+rstto_image_viewer_paint_checkers (GdkDrawable *drawable, GdkGC *gc, gint width, gint height, gint x_offset, gint y_offset)
+{
+    gint x, y;
+    gint block_width, block_height;
+    GdkColor color;
+
+    /* This is to remind me of a bug in this function, 
+     * the top-left square is colored red, it shouldn't
+     */
+    color.pixel = 0xeeee0000;
+
+    for(x = 0; x <= width/10; x++)
+    {
+        if(x == width/10)
+        {
+            block_width = width-10*x;
+        }
+        else
+        {   
+            block_width = 10;
+        }
+        for(y = 0; y <= height/10; y++)
+        {
+            gdk_gc_set_foreground(gc, &color);
+            if(y == height/10)
+            {
+                block_height = height-10*y;
+            }
+            else
+            {   
+                block_height = 10;
+            }
+
+            if((y%2?x%2:!(x%2))) {
+                color.pixel = 0xcccccccc;
+            }
+            else
+            {
+                color.pixel = 0xdddddddd;
+            }
+
+            gdk_draw_rectangle(GDK_DRAWABLE(drawable),
+                            gc,
+                            TRUE,
+                            x_offset+10*x,
+                            y_offset+10*y,
+                            block_width,
+                            block_height);
+        }
+    }
+    
+}
+
+static void
 rstto_image_viewer_queued_repaint (RsttoImageViewer *viewer, gboolean refresh)
 {
     if (viewer->priv->repaint.idle_id > 0)
@@ -668,7 +692,6 @@ rstto_image_viewer_new (void)
 void
 rstto_image_viewer_set_file (RsttoImageViewer *viewer, GFile *file)
 {
-    g_debug("%s", __FUNCTION__);
 
     /*
      * Check if a file is set, or unset.
@@ -697,12 +720,14 @@ rstto_image_viewer_set_file (RsttoImageViewer *viewer, GFile *file)
 
                 g_object_unref (viewer->priv->file);
                 viewer->priv->file = g_file_dup(file);
+                viewer->priv->scale = -1;
                 rstto_image_viewer_load_image (viewer, viewer->priv->file);
             }
         }
         else
         {
             viewer->priv->file = g_file_dup(file);
+            viewer->priv->scale = -1;
             rstto_image_viewer_load_image (viewer, viewer->priv->file);
         }
     } 
@@ -712,6 +737,12 @@ rstto_image_viewer_set_file (RsttoImageViewer *viewer, GFile *file)
         {
             g_object_unref (viewer->priv->file);
             viewer->priv->file = NULL;
+            if (viewer->priv->pixbuf)
+            {
+                g_object_unref (viewer->priv->pixbuf);
+                viewer->priv->pixbuf = NULL;
+            }
+            rstto_image_viewer_queued_repaint (viewer, TRUE);
         }
     }
 }
@@ -754,7 +785,6 @@ rstto_image_viewer_load_image (RsttoImageViewer *viewer, GFile *file)
 static void
 rstto_image_viewer_transaction_free (RsttoImageViewerTransaction *tr)
 {
-    g_debug("%s", __FUNCTION__);
     /*
      * Check if this transaction is current,
      * if so, remove the reference from the viewer.
@@ -770,6 +800,28 @@ rstto_image_viewer_transaction_free (RsttoImageViewerTransaction *tr)
     g_free (tr);
 }
 
+void
+rstto_image_viewer_set_scale (RsttoImageViewer *viewer, gdouble scale)
+{
+    viewer->priv->scale = scale;
+    if (scale == 0)
+    {
+        viewer->priv->auto_scale = TRUE;
+    }
+    else
+    {
+        viewer->priv->auto_scale = FALSE;
+    }
+
+    rstto_image_viewer_queued_repaint (viewer, TRUE);
+}
+
+gdouble
+rstto_image_viewer_get_scale (RsttoImageViewer *viewer)
+{
+    return viewer->priv->scale;
+}
+
 
 /************************/
 /** CALLBACK FUNCTIONS **/
@@ -807,7 +859,6 @@ cb_rstto_image_viewer_read_file_ready (GObject *source_object, GAsyncResult *res
 static void
 cb_rstto_image_viewer_read_input_stream_ready (GObject *source_object, GAsyncResult *result, gpointer user_data)
 {
-    g_debug("%s", __FUNCTION__);
     GError *error = NULL;
     RsttoImageViewerTransaction *transaction = (RsttoImageViewerTransaction *)user_data;
     gssize read_bytes = g_input_stream_read_finish (G_INPUT_STREAM (source_object), result, &error);
@@ -911,7 +962,6 @@ cb_rstto_image_loader_size_prepared (GdkPixbufLoader *loader, gint width, gint h
 static void
 cb_rstto_image_loader_closed (GdkPixbufLoader *loader, RsttoImageViewerTransaction *transaction)
 {
-    g_debug("%s", __FUNCTION__);
 
     rstto_image_viewer_queued_repaint (transaction->viewer, TRUE);
 }
@@ -960,17 +1010,75 @@ cb_rstto_image_viewer_update_pixbuf (RsttoImageViewer *viewer)
 static gboolean 
 cb_rstto_image_viewer_queued_repaint (RsttoImageViewer *viewer)
 {
-    g_debug("%s", __FUNCTION__);
+    gint width, height;
     g_source_remove (viewer->priv->repaint.idle_id);
     viewer->priv->repaint.idle_id = -1;
     viewer->priv->repaint.refresh = FALSE;
 
     if (viewer->priv->pixbuf)
     {
-    viewer->priv->dst_pixbuf = gdk_pixbuf_scale_simple (viewer->priv->pixbuf,
-                               (GTK_WIDGET(viewer)->allocation.width),
-                               (GTK_WIDGET(viewer)->allocation.height),
-                               GDK_INTERP_BILINEAR);
+        width = gdk_pixbuf_get_width (viewer->priv->pixbuf);
+        height = gdk_pixbuf_get_height (viewer->priv->pixbuf);
+
+        /*
+         * Scale == -1, this means the image is not loaded before, 
+         * and it should be rendered at the best possible quality.
+         * This means:
+         *      - Images smaller then the widget-size: at 100%
+         *      - Images larger then the widget-size, scaled to fit.
+         */
+        if (viewer->priv->scale == -1)
+        {
+            if (width > height)
+            { 
+                viewer->priv->scale = (gdouble)(GTK_WIDGET (viewer)->allocation.width) / (gdouble)width;
+            }
+            else
+            {
+                viewer->priv->scale = (gdouble)(GTK_WIDGET (viewer)->allocation.height) / (gdouble)width;
+            }
+
+            viewer->priv->auto_scale = TRUE;
+            /*
+             * If the scale is greater then 1.0 (meaning the image is smaller then the window)
+             * reset the scale to 1.0, so the image won't be blown-up.
+             */
+            if (viewer->priv->scale > 1.0)
+            {
+                viewer->priv->scale = 1.0;
+                viewer->priv->auto_scale = FALSE;
+            }
+        }
+        else
+        {
+            /*
+             * if auto_scale == true, calculate the scale
+             */
+            if (viewer->priv->auto_scale)
+            {
+                if (width > height)
+                { 
+                    viewer->priv->scale = (gdouble)(GTK_WIDGET (viewer)->allocation.width) / (gdouble)width;
+                }
+                else
+                {
+                    viewer->priv->scale = (gdouble)(GTK_WIDGET (viewer)->allocation.height) / (gdouble)width;
+                }
+            }
+        }
+
+        viewer->priv->dst_pixbuf = gdk_pixbuf_scale_simple (viewer->priv->pixbuf,
+                                   (gint)((gdouble)width*viewer->priv->scale),
+                                   (gint)((gdouble)height*viewer->priv->scale),
+                                   GDK_INTERP_BILINEAR);
+    }
+    else
+    {
+        if (viewer->priv->dst_pixbuf)
+        {
+            g_object_unref (viewer->priv->dst_pixbuf);
+            viewer->priv->dst_pixbuf = NULL;
+        }
     }
     rstto_image_viewer_paint (GTK_WIDGET (viewer));
 
diff --git a/src/image_viewer.h b/src/image_viewer.h
index 9ebdf47..b3ef109 100644
--- a/src/image_viewer.h
+++ b/src/image_viewer.h
@@ -70,6 +70,9 @@ GType      rstto_image_viewer_get_type();
 GtkWidget *rstto_image_viewer_new ();
 void       rstto_image_viewer_set_file (RsttoImageViewer *viewer, GFile *file);
 
+void       rstto_image_viewer_set_scale (RsttoImageViewer *viewer, gdouble scale);
+gdouble    rstto_image_viewer_get_scale (RsttoImageViewer *viewer);
+
 G_END_DECLS
 
 #endif /* __RISTRETTO_IMAGE_VIEWER_H__ */
diff --git a/src/main_window.c b/src/main_window.c
index 83f5aac..a4874ef 100644
--- a/src/main_window.c
+++ b/src/main_window.c
@@ -796,7 +796,6 @@ rstto_main_window_new (RsttoImageList *image_list, gboolean fullscreen)
 static void
 rstto_main_window_image_list_iter_changed (RsttoMainWindow *window)
 {
-    g_debug("%s", __FUNCTION__);
     gchar *file_basename, *title, *status;
     GFile *file = NULL;
     GFileInfo *file_info = NULL;
@@ -863,6 +862,8 @@ 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);
+
 
             menu_item = gtk_image_menu_item_new_with_label (_("Empty"));
             gtk_menu_shell_append (GTK_MENU_SHELL (open_with_window_menu), menu_item);
@@ -1778,7 +1779,7 @@ cb_rstto_main_window_configure_event (GtkWidget *widget, GdkEventConfigure *even
 static void
 cb_rstto_main_window_zoom_fit (GtkWidget *widget, RsttoMainWindow *window)
 {
-    //rstto_picture_viewer_zoom_fit (RSTTO_PICTURE_VIEWER (window->priv->picture_viewer));
+    rstto_image_viewer_set_scale (RSTTO_IMAGE_VIEWER(window->priv->image_viewer), 0);
 }
 
 /**
@@ -1791,7 +1792,7 @@ cb_rstto_main_window_zoom_fit (GtkWidget *widget, RsttoMainWindow *window)
 static void
 cb_rstto_main_window_zoom_100 (GtkWidget *widget, RsttoMainWindow *window)
 {
-    //rstto_picture_viewer_zoom_100 (RSTTO_PICTURE_VIEWER (window->priv->picture_viewer));
+    rstto_image_viewer_set_scale (RSTTO_IMAGE_VIEWER(window->priv->image_viewer), 1);
 }
 
 /**
@@ -1804,7 +1805,8 @@ cb_rstto_main_window_zoom_100 (GtkWidget *widget, RsttoMainWindow *window)
 static void
 cb_rstto_main_window_zoom_in (GtkWidget *widget, RsttoMainWindow *window)
 {
-    //rstto_picture_viewer_zoom_in (RSTTO_PICTURE_VIEWER (window->priv->picture_viewer), ZOOM_FACTOR);
+    gdouble scale = rstto_image_viewer_get_scale (RSTTO_IMAGE_VIEWER(window->priv->image_viewer));
+    rstto_image_viewer_set_scale (RSTTO_IMAGE_VIEWER(window->priv->image_viewer), scale*1.2);
 }
 
 /**
@@ -1817,7 +1819,8 @@ cb_rstto_main_window_zoom_in (GtkWidget *widget, RsttoMainWindow *window)
 static void
 cb_rstto_main_window_zoom_out (GtkWidget *widget, RsttoMainWindow *window)
 {
-    //rstto_picture_viewer_zoom_out (RSTTO_PICTURE_VIEWER (window->priv->picture_viewer), ZOOM_FACTOR);
+    gdouble scale = rstto_image_viewer_get_scale (RSTTO_IMAGE_VIEWER(window->priv->image_viewer));
+    rstto_image_viewer_set_scale (RSTTO_IMAGE_VIEWER(window->priv->image_viewer), scale/1.2);
 }
 
 /**********************/


More information about the Xfce4-commits mailing list