[gimp] app: Implement zooming via mouse wheel on GimpContainerTreeView



commit 15ddae315cf2dd4d6de2b62ac421822afeeee99d
Author: Povilas Kanapickas <povilas radix lt>
Date:   Tue Mar 22 02:40:12 2022 +0200

    app: Implement zooming via mouse wheel on GimpContainerTreeView

 app/core/gimp-utils.c                       | 43 ++++++++++++++++++++++
 app/core/gimp-utils.h                       |  3 ++
 app/widgets/gimpcontainertreeview-private.h |  2 ++
 app/widgets/gimpcontainertreeview.c         | 56 +++++++++++++++++++++++++++++
 4 files changed, 104 insertions(+)
---
diff --git a/app/core/gimp-utils.c b/app/core/gimp-utils.c
index ba6c2ee1a7..c307d4fd10 100644
--- a/app/core/gimp-utils.c
+++ b/app/core/gimp-utils.c
@@ -1281,6 +1281,49 @@ gimp_create_image_from_buffer (Gimp        *gimp,
   return image;
 }
 
+gint
+gimp_view_size_get_larger (gint view_size)
+{
+  if (view_size < GIMP_VIEW_SIZE_TINY)
+    return GIMP_VIEW_SIZE_TINY;
+  if (view_size < GIMP_VIEW_SIZE_EXTRA_SMALL)
+    return GIMP_VIEW_SIZE_EXTRA_SMALL;
+  if (view_size < GIMP_VIEW_SIZE_SMALL)
+    return GIMP_VIEW_SIZE_SMALL;
+  if (view_size < GIMP_VIEW_SIZE_MEDIUM)
+    return GIMP_VIEW_SIZE_MEDIUM;
+  if (view_size < GIMP_VIEW_SIZE_LARGE)
+    return GIMP_VIEW_SIZE_LARGE;
+  if (view_size < GIMP_VIEW_SIZE_EXTRA_LARGE)
+    return GIMP_VIEW_SIZE_EXTRA_LARGE;
+  if (view_size < GIMP_VIEW_SIZE_HUGE)
+    return GIMP_VIEW_SIZE_HUGE;
+  if (view_size < GIMP_VIEW_SIZE_ENORMOUS)
+    return GIMP_VIEW_SIZE_ENORMOUS;
+  return GIMP_VIEW_SIZE_GIGANTIC;
+}
+
+gint
+gimp_view_size_get_smaller (gint view_size)
+{
+  if (view_size > GIMP_VIEW_SIZE_GIGANTIC)
+    return GIMP_VIEW_SIZE_GIGANTIC;
+  if (view_size > GIMP_VIEW_SIZE_ENORMOUS)
+    return GIMP_VIEW_SIZE_ENORMOUS;
+  if (view_size > GIMP_VIEW_SIZE_HUGE)
+    return GIMP_VIEW_SIZE_HUGE;
+  if (view_size > GIMP_VIEW_SIZE_EXTRA_LARGE)
+    return GIMP_VIEW_SIZE_EXTRA_LARGE;
+  if (view_size > GIMP_VIEW_SIZE_LARGE)
+    return GIMP_VIEW_SIZE_LARGE;
+  if (view_size > GIMP_VIEW_SIZE_MEDIUM)
+    return GIMP_VIEW_SIZE_MEDIUM;
+  if (view_size > GIMP_VIEW_SIZE_SMALL)
+    return GIMP_VIEW_SIZE_SMALL;
+  if (view_size > GIMP_VIEW_SIZE_EXTRA_SMALL)
+    return GIMP_VIEW_SIZE_EXTRA_SMALL;
+  return GIMP_VIEW_SIZE_TINY;
+}
 
 /* Private functions */
 
diff --git a/app/core/gimp-utils.h b/app/core/gimp-utils.h
index ccc8906b48..b6aa871d5b 100644
--- a/app/core/gimp-utils.h
+++ b/app/core/gimp-utils.h
@@ -123,6 +123,9 @@ GimpImage  * gimp_create_image_from_buffer         (Gimp              *gimp,
                                                     GeglBuffer        *buffer,
                                                     const gchar       *image_name);
 
+gint         gimp_view_size_get_larger             (gint view_size);
+gint         gimp_view_size_get_smaller            (gint view_size);
+
 #ifdef G_OS_WIN32
 
 gboolean     gimp_win32_have_wintab                (void);
diff --git a/app/widgets/gimpcontainertreeview-private.h b/app/widgets/gimpcontainertreeview-private.h
index d3b7f158a8..54f4ee73fc 100644
--- a/app/widgets/gimpcontainertreeview-private.h
+++ b/app/widgets/gimpcontainertreeview-private.h
@@ -43,6 +43,8 @@ struct _GimpContainerTreeViewPrivate
   GdkScrollDirection  scroll_dir;
 
   gboolean            dnd_drop_to_empty;
+
+  gdouble             zoom_accumulated_scroll_delta;
 };
 
 
diff --git a/app/widgets/gimpcontainertreeview.c b/app/widgets/gimpcontainertreeview.c
index 99a2b3b262..10c3e0c44c 100644
--- a/app/widgets/gimpcontainertreeview.c
+++ b/app/widgets/gimpcontainertreeview.c
@@ -33,6 +33,7 @@
 #include "core/gimpcontainer.h"
 #include "core/gimpcontext.h"
 #include "core/gimpviewable.h"
+#include "core/gimp-utils.h"
 
 #include "gimpcellrendererbutton.h"
 #include "gimpcellrendererviewable.h"
@@ -116,6 +117,9 @@ static void          gimp_container_tree_view_selection_changed (GtkTreeSelectio
 static gboolean      gimp_container_tree_view_button            (GtkWidget                   *widget,
                                                                  GdkEventButton              *bevent,
                                                                  GimpContainerTreeView       *tree_view);
+static gboolean      gimp_container_tree_view_scroll            (GtkWidget                   *widget,
+                                                                 GdkEventScroll              *event,
+                                                                 GimpContainerTreeView       *tree_view);
 static gboolean      gimp_container_tree_view_tooltip           (GtkWidget                   *widget,
                                                                  gint                         x,
                                                                  gint                         y,
@@ -346,6 +350,9 @@ gimp_container_tree_view_constructed (GObject *object)
   g_signal_connect (tree_view->view, "drag-data-received",
                     G_CALLBACK (gimp_container_tree_view_drag_data_received),
                     tree_view);
+  g_signal_connect (tree_view->view, "scroll-event",
+                    G_CALLBACK (gimp_container_tree_view_scroll),
+                    tree_view);
 
   /* connect_after so external code can connect to "query-tooltip" too
    * and override the default tip
@@ -1604,6 +1611,55 @@ gimp_container_tree_view_button (GtkWidget             *widget,
     }
 }
 
+/* We want to zoom on each 1/4 scroll events to roughly match zooming
+ * behavior  of the main canvas. Each step of GIMP_VIEW_SIZE_* is
+ * approximately  of sqrt(2) = 1.4 relative change. The main canvas
+ * on the other hand has zoom step equal to ZOOM_MIN_STEP=1.1
+ * (see gimp_zoom_model_zoom_step).
+ */
+#define SCROLL_ZOOM_STEP_SIZE 0.25
+
+static gboolean
+gimp_container_tree_view_scroll (GtkWidget             *widget,
+                                 GdkEventScroll        *event,
+                                 GimpContainerTreeView *tree_view)
+{
+  GimpContainerView *view;
+  gint               view_border_width;
+  gint               view_size;
+
+  if ((event->state & GDK_CONTROL_MASK) == 0)
+    return FALSE;
+
+  if (event->direction == GDK_SCROLL_UP)
+    tree_view->priv->zoom_accumulated_scroll_delta -= SCROLL_ZOOM_STEP_SIZE;
+  else if (event->direction == GDK_SCROLL_DOWN)
+    tree_view->priv->zoom_accumulated_scroll_delta += SCROLL_ZOOM_STEP_SIZE;
+  else if (event->direction == GDK_SCROLL_SMOOTH)
+    tree_view->priv->zoom_accumulated_scroll_delta += event->delta_y * SCROLL_ZOOM_STEP_SIZE;
+  else
+    return FALSE;
+
+  view      = GIMP_CONTAINER_VIEW (tree_view);
+  view_size = gimp_container_view_get_view_size (view, &view_border_width);
+
+  if (tree_view->priv->zoom_accumulated_scroll_delta > 1)
+    {
+      tree_view->priv->zoom_accumulated_scroll_delta -= 1;
+      view_size = gimp_view_size_get_smaller (view_size);
+    }
+  else if (tree_view->priv->zoom_accumulated_scroll_delta < -1)
+    {
+      tree_view->priv->zoom_accumulated_scroll_delta += 1;
+      view_size = gimp_view_size_get_larger (view_size);
+    }
+  else
+    return TRUE;
+
+  gimp_container_view_set_view_size (view, view_size, view_border_width);
+  return TRUE;
+}
+
 static gboolean
 gimp_container_tree_view_tooltip (GtkWidget             *widget,
                                   gint                   x,


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