Addl fix #521: zoom increment is not multiplicative
authorColin Clark <colin.clark@cclark.uk>
Wed, 22 Sep 2021 12:36:09 +0000 (13:36 +0100)
committerColin Clark <colin.clark@cclark.uk>
Wed, 22 Sep 2021 12:36:09 +0000 (13:36 +0100)
https://github.com/BestImageViewer/geeqie/issues/521

Include user option on Preferences/Image to select geometric or
arithmetic zoom mode.

doc/docbook/GuideOptionsImage.xml
src/options.c
src/options.h
src/pixbuf-renderer.c
src/preferences.c
src/rcfile.c
src/typedefs.h

index 446e312..9f2a028 100644 (file)
           <guilabel>Zoom increment</guilabel>\r
         </term>\r
         <listitem>\r
           <guilabel>Zoom increment</guilabel>\r
         </term>\r
         <listitem>\r
-          <para>Adjusts the step size when zooming in or out on an image. This value corresponds to the percentage of the original image.</para>\r
+          <para>Adjusts the step size when zooming in or out on an image.</para>\r
+        </listitem>\r
+      </varlistentry>\r
+      <varlistentry>\r
+        <term>\r
+          <guilabel>Zoom style</guilabel>\r
+        </term>\r
+        <listitem>\r
+          <para>Selects whether the zoom step size is applied as a geometric (n * step) or arithmetic (n + step) factor.</para>\r
         </listitem>\r
       </varlistentry>\r
     </variablelist>\r
         </listitem>\r
       </varlistentry>\r
     </variablelist>\r
index c51df5b..875a65b 100644 (file)
@@ -123,6 +123,7 @@ ConfOptions *init_options(ConfOptions *options)
        options->image.zoom_mode = ZOOM_RESET_NONE;
        options->image.zoom_quality = GDK_INTERP_BILINEAR;
        options->image.zoom_to_fit_allow_expand = FALSE;
        options->image.zoom_mode = ZOOM_RESET_NONE;
        options->image.zoom_quality = GDK_INTERP_BILINEAR;
        options->image.zoom_to_fit_allow_expand = FALSE;
+       options->image.zoom_style = ZOOM_GEOMETRIC;
        options->image.tile_size = 128;
 
        options->image_overlay.template_string = NULL;
        options->image.tile_size = 128;
 
        options->image_overlay.template_string = NULL;
index 31b34e7..668cf52 100644 (file)
@@ -155,6 +155,7 @@ struct _ConfOptions
                gboolean zoom_to_fit_allow_expand;
                guint zoom_quality;
                gint zoom_increment;    /**< 100 is 1.0, 5 is 0.05, 200 is 2.0, etc. */
                gboolean zoom_to_fit_allow_expand;
                guint zoom_quality;
                gint zoom_increment;    /**< 100 is 1.0, 5 is 0.05, 200 is 2.0, etc. */
+               ZoomStyle zoom_style;
                gboolean use_clutter_renderer;
 
                gboolean use_custom_border_color_in_fullscreen;
                gboolean use_clutter_renderer;
 
                gboolean use_custom_border_color_in_fullscreen;
index 3653b41..54a943f 100644 (file)
@@ -1259,40 +1259,68 @@ static void pr_zoom_adjust_real(PixbufRenderer *pr, gdouble increment,
                        }
                }
 
                        }
                }
 
-       if (increment < 0.0)
+       if (options->image.zoom_style == ZOOM_GEOMETRIC)
                {
                {
-               if (zoom >= 1.0)
+               if (increment < 0.0)
                        {
                        {
-                       if (zoom / -(increment - 1.0) < 1.0)
+                       if (zoom >= 1.0)
                                {
                                {
-                               zoom = 1.0 / (zoom / (increment - 1.0));
+                               if (zoom / -(increment - 1.0) < 1.0)
+                                       {
+                                       zoom = 1.0 / (zoom / (increment - 1.0));
+                                       }
+                               else
+                                       {
+                                       zoom = zoom / -(increment - 1.0) ;
+                                       }
                                }
                        else
                                {
                                }
                        else
                                {
-                               zoom = zoom / -(increment - 1.0) ;
+                               zoom = zoom * -(increment - 1.0);
                                }
                        }
                else
                        {
                                }
                        }
                else
                        {
-                       zoom = zoom * -(increment - 1.0);
+                       if (zoom <= -1.0 )
+                               {
+                               if (zoom / (increment + 1.0) > -1.0)
+                                       {
+                                       zoom = -(1.0 / (zoom / (increment + 1.0)));
+                                       }
+                               else
+                                       {
+                                       zoom = zoom / (increment + 1.0) ;
+                                       }
+                               }
+                       else
+                               {
+                               zoom = zoom * (increment + 1.0);
+                               }
                        }
                }
        else
                {
                        }
                }
        else
                {
-               if (zoom <= -1.0 )
+               if (increment < 0.0)
                        {
                        {
-                       if (zoom / (increment + 1.0) > -1.0)
+                       if (zoom >= 1.0 && zoom + increment < 1.0)
                                {
                                {
-                               zoom = -(1.0 / (zoom / (increment + 1.0)));
+                               zoom = zoom + increment - 2.0;
                                }
                        else
                                {
                                }
                        else
                                {
-                               zoom = zoom / (increment + 1.0) ;
+                               zoom = zoom + increment;
                                }
                        }
                else
                        {
                                }
                        }
                else
                        {
-                       zoom = zoom * (increment + 1.0);
+                       if (zoom <= -1.0 && zoom + increment > -1.0)
+                               {
+                               zoom = zoom + increment + 2.0;
+                               }
+                       else
+                               {
+                               zoom = zoom + increment;
+                               }
                        }
                }
 
                        }
                }
 
index 6ce4eb2..8c6804f 100644 (file)
@@ -341,6 +341,8 @@ static void config_window_apply(void)
 
        options->image.zoom_increment = c_options->image.zoom_increment;
 
 
        options->image.zoom_increment = c_options->image.zoom_increment;
 
+       options->image.zoom_style = c_options->image.zoom_style;
+
        options->image.enable_read_ahead = c_options->image.enable_read_ahead;
 
 
        options->image.enable_read_ahead = c_options->image.enable_read_ahead;
 
 
@@ -715,6 +717,47 @@ static void add_clipboard_selection_menu(GtkWidget *table, gint column, gint row
        gtk_widget_show(combo);
 }
 
        gtk_widget_show(combo);
 }
 
+static void zoom_style_selection_menu_cb(GtkWidget *combo, gpointer data)
+{
+       gint *option = data;
+
+       switch (gtk_combo_box_get_active(GTK_COMBO_BOX(combo)))
+               {
+               case 0:
+                       *option = ZOOM_GEOMETRIC;
+                       break;
+               case 1:
+                       *option = ZOOM_ARITHMETIC;
+                       break;
+               default:
+                       *option = ZOOM_GEOMETRIC;
+               }
+}
+
+static void add_zoom_style_selection_menu(GtkWidget *table, gint column, gint row, const gchar *text, ZoomStyle option, ZoomStyle *option_c)
+{
+       GtkWidget *combo;
+       gint current = 0;
+
+       *option_c = option;
+
+       pref_table_label(table, column, row, text, 0.0);
+
+       combo = gtk_combo_box_text_new();
+
+       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Geometric"));
+       if (option == ZOOM_GEOMETRIC) current = 0;
+       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Arithmetic"));
+       if (option == ZOOM_ARITHMETIC) current = 1;
+
+       gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current);
+
+       g_signal_connect(G_OBJECT(combo), "changed", G_CALLBACK(zoom_style_selection_menu_cb), option_c);
+
+       gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1, GTK_SHRINK, 0, 0, 0);
+       gtk_widget_show(combo);
+}
+
 typedef struct _UseableMouseItems UseableMouseItems;
 struct _UseableMouseItems
 {
 typedef struct _UseableMouseItems UseableMouseItems;
 struct _UseableMouseItems
 {
@@ -2244,6 +2287,10 @@ static void config_tab_image(GtkWidget *notebook)
                             G_CALLBACK(zoom_increment_cb), NULL);
        gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
 
                             G_CALLBACK(zoom_increment_cb), NULL);
        gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spin), GTK_UPDATE_ALWAYS);
 
+       c_options->image.zoom_style = options->image.zoom_style;
+       table = pref_table_new(group, 2, 1, FALSE, FALSE);
+       add_zoom_style_selection_menu(table, 0, 0, _("Zoom style:"), options->image.zoom_style, &c_options->image.zoom_style);
+
        group = pref_group_new(vbox, FALSE, _("Fit image to window"), GTK_ORIENTATION_VERTICAL);
 
        hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
        group = pref_group_new(vbox, FALSE, _("Fit image to window"), GTK_ORIENTATION_VERTICAL);
 
        hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);
index 1a71400..e546b1b 100644 (file)
@@ -383,6 +383,7 @@ static void write_global_attributes(GString *outstr, gint indent)
        WRITE_NL(); WRITE_BOOL(*options, image.zoom_to_fit_allow_expand);
        WRITE_NL(); WRITE_UINT(*options, image.zoom_quality);
        WRITE_NL(); WRITE_INT(*options, image.zoom_increment);
        WRITE_NL(); WRITE_BOOL(*options, image.zoom_to_fit_allow_expand);
        WRITE_NL(); WRITE_UINT(*options, image.zoom_quality);
        WRITE_NL(); WRITE_INT(*options, image.zoom_increment);
+       WRITE_NL(); WRITE_UINT(*options, image.zoom_style);
        WRITE_NL(); WRITE_BOOL(*options, image.fit_window_to_image);
        WRITE_NL(); WRITE_BOOL(*options, image.limit_window_size);
        WRITE_NL(); WRITE_INT(*options, image.max_window_size);
        WRITE_NL(); WRITE_BOOL(*options, image.fit_window_to_image);
        WRITE_NL(); WRITE_BOOL(*options, image.limit_window_size);
        WRITE_NL(); WRITE_INT(*options, image.max_window_size);
@@ -864,6 +865,7 @@ static gboolean load_global_params(const gchar **attribute_names, const gchar **
 
                /* Image options */
                if (READ_UINT_CLAMP(*options, image.zoom_mode, 0, ZOOM_RESET_NONE)) continue;
 
                /* Image options */
                if (READ_UINT_CLAMP(*options, image.zoom_mode, 0, ZOOM_RESET_NONE)) continue;
+               if (READ_UINT_CLAMP(*options, image.zoom_style, 0, ZOOM_ARITHMETIC)) continue;
                if (READ_BOOL(*options, image.zoom_2pass)) continue;
                if (READ_BOOL(*options, image.zoom_to_fit_allow_expand)) continue;
                if (READ_BOOL(*options, image.fit_window_to_image)) continue;
                if (READ_BOOL(*options, image.zoom_2pass)) continue;
                if (READ_BOOL(*options, image.zoom_to_fit_allow_expand)) continue;
                if (READ_BOOL(*options, image.fit_window_to_image)) continue;
index c7387a2..2d9901b 100644 (file)
@@ -28,6 +28,11 @@ typedef enum {
        ZOOM_RESET_NONE         = 2
 } ZoomMode;
 
        ZOOM_RESET_NONE         = 2
 } ZoomMode;
 
+typedef enum {
+       ZOOM_GEOMETRIC  = 0,
+       ZOOM_ARITHMETIC = 1
+} ZoomStyle;
+
 typedef enum {
        CLIPBOARD_PRIMARY       = 0,
        CLIPBOARD_CLIPBOARD = 1,
 typedef enum {
        CLIPBOARD_PRIMARY       = 0,
        CLIPBOARD_CLIPBOARD = 1,