[gimp] widgets: Implement zoom focus in gradient editor



commit ae3c4c3577a0664f6311d3c3f68c0c77452c871c
Author: Povilas Kanapickas <povilas radix lt>
Date:   Wed Apr 6 18:47:16 2022 +0300

    widgets: Implement zoom focus in gradient editor
    
    Zoom focus centers the point that we're zooming into at the location of
    the mouse pointer.
    
    Default zoom focus value is 0.5 which results in previous behavior.

 app/actions/gradient-editor-commands.c |  2 +-
 app/widgets/gimpgradienteditor.c       | 72 ++++++++++++++++++++++++++++------
 app/widgets/gimpgradienteditor.h       |  3 +-
 3 files changed, 64 insertions(+), 13 deletions(-)
---
diff --git a/app/actions/gradient-editor-commands.c b/app/actions/gradient-editor-commands.c
index 01864061a8..cb30c8cda8 100644
--- a/app/actions/gradient-editor-commands.c
+++ b/app/actions/gradient-editor-commands.c
@@ -660,7 +660,7 @@ gradient_editor_zoom_cmd_callback (GimpAction *action,
   GimpGradientEditor *editor    = GIMP_GRADIENT_EDITOR (data);
   GimpZoomType        zoom_type = (GimpZoomType) g_variant_get_int32 (value);
 
-  gimp_gradient_editor_zoom (editor, zoom_type, 1.0);
+  gimp_gradient_editor_zoom (editor, zoom_type, 1.0, 0.5);
 }
 
 
diff --git a/app/widgets/gimpgradienteditor.c b/app/widgets/gimpgradienteditor.c
index e1691bb930..c721dd834e 100644
--- a/app/widgets/gimpgradienteditor.c
+++ b/app/widgets/gimpgradienteditor.c
@@ -187,6 +187,8 @@ static void      view_zoom_gesture_update         (GtkGestureZoom     *gesture,
                                                    GdkEventSequence   *sequence,
                                                    GimpGradientEditor *editor);
 
+static gdouble   view_get_normalized_last_x_pos   (GimpGradientEditor *editor);
+
 /* Gradient control functions */
 
 static gboolean  control_events                   (GtkWidget          *widget,
@@ -226,6 +228,8 @@ static double    control_move                     (GimpGradientEditor  *editor,
                                                    GimpGradientSegment *range_r,
                                                    gdouble              delta);
 
+static gdouble   control_get_normalized_last_x_pos (GimpGradientEditor *editor);
+
 /* Control update/redraw functions */
 
 static void      control_update                   (GimpGradientEditor *editor,
@@ -674,7 +678,8 @@ gimp_gradient_editor_edit_right_color (GimpGradientEditor *editor)
 void
 gimp_gradient_editor_zoom (GimpGradientEditor *editor,
                            GimpZoomType        zoom_type,
-                           gdouble             delta)
+                           gdouble             delta,
+                           gdouble             zoom_focus_x)
 {
   GtkAdjustment *adjustment;
   gdouble        old_value;
@@ -713,7 +718,7 @@ gimp_gradient_editor_zoom (GimpGradientEditor *editor,
       editor->zoom_factor += delta;
 
       page_size = 1.0 / editor->zoom_factor;
-      value     = old_value + (old_page_size - page_size) / 2.0;
+      value     = old_value + (old_page_size - page_size) * zoom_focus_x;
       break;
 
     case GIMP_ZOOM_OUT_MORE:
@@ -724,7 +729,7 @@ gimp_gradient_editor_zoom (GimpGradientEditor *editor,
       editor->zoom_factor -= delta;
 
       page_size = 1.0 / editor->zoom_factor;
-      value     = old_value - (page_size - old_page_size) / 2.0;
+      value     = old_value - (page_size - old_page_size) * zoom_focus_x;
 
       if (value < 0.0)
         value = 0.0;
@@ -752,7 +757,7 @@ gimp_gradient_editor_zoom (GimpGradientEditor *editor,
         editor->zoom_factor = 1;
 
       page_size = 1.0 / editor->zoom_factor;
-      value     = old_value + (old_page_size - page_size) / 2.0;
+      value     = old_value + (old_page_size - page_size) * zoom_focus_x;
 
       if (value < 0.0)
         value = 0.0;
@@ -1210,16 +1215,19 @@ view_events (GtkWidget          *widget,
             switch (sevent->direction)
               {
               case GDK_SCROLL_UP:
-                gimp_gradient_editor_zoom (editor, GIMP_ZOOM_IN, 1.0);
+                gimp_gradient_editor_zoom (editor, GIMP_ZOOM_IN, 1.0,
+                                           view_get_normalized_last_x_pos (editor));
                 break;
 
               case GDK_SCROLL_DOWN:
-                gimp_gradient_editor_zoom (editor, GIMP_ZOOM_OUT, 1.0);
+                gimp_gradient_editor_zoom (editor, GIMP_ZOOM_OUT, 1.0,
+                                           view_get_normalized_last_x_pos (editor));
                 break;
 
               case GDK_SCROLL_SMOOTH:
                 gdk_event_get_scroll_deltas (event, NULL, &delta);
-                gimp_gradient_editor_zoom (editor, GIMP_ZOOM_SMOOTH, delta);
+                gimp_gradient_editor_zoom (editor, GIMP_ZOOM_SMOOTH, delta,
+                                           view_get_normalized_last_x_pos (editor));
                 break;
 
               default:
@@ -1367,7 +1375,26 @@ view_zoom_gesture_update (GtkGestureZoom     *gesture,
   gdouble delta = (current_scale - editor->last_zoom_scale) / editor->last_zoom_scale;
   editor->last_zoom_scale = current_scale;
 
-  gimp_gradient_editor_zoom (editor, GIMP_ZOOM_PINCH, delta);
+  gimp_gradient_editor_zoom (editor, GIMP_ZOOM_PINCH, delta,
+                             view_get_normalized_last_x_pos (editor));
+}
+
+static gdouble
+view_get_normalized_last_x_pos (GimpGradientEditor *editor)
+{
+  GtkAllocation allocation;
+  gdouble       normalized;
+  if (editor->view_last_x < 0)
+    return 0.5;
+
+  gtk_widget_get_allocation (GIMP_DATA_EDITOR (editor)->view, &allocation);
+  normalized = (double) editor->view_last_x / (allocation.width - 1);
+
+  if (normalized < 0)
+    return 0;
+  if (normalized > 1.0)
+    return 1;
+  return normalized;
 }
 
 /***** Gradient control functions *****/
@@ -1427,16 +1454,19 @@ control_events (GtkWidget          *widget,
             switch (sevent->direction)
               {
               case GDK_SCROLL_UP:
-                gimp_gradient_editor_zoom (editor, GIMP_ZOOM_IN, 1.0);
+                gimp_gradient_editor_zoom (editor, GIMP_ZOOM_IN, 1.0,
+                                           control_get_normalized_last_x_pos (editor));
                 break;
 
               case GDK_SCROLL_DOWN:
-                gimp_gradient_editor_zoom (editor, GIMP_ZOOM_OUT, 1.0);
+                gimp_gradient_editor_zoom (editor, GIMP_ZOOM_OUT, 1.0,
+                                           control_get_normalized_last_x_pos (editor));
                 break;
 
               case GDK_SCROLL_SMOOTH:
                 gdk_event_get_scroll_deltas (event, NULL, &delta);
-                gimp_gradient_editor_zoom (editor, GIMP_ZOOM_SMOOTH, delta);
+                gimp_gradient_editor_zoom (editor, GIMP_ZOOM_SMOOTH, delta,
+                                           control_get_normalized_last_x_pos (editor));
                 break;
 
               default:
@@ -2024,6 +2054,26 @@ control_move (GimpGradientEditor  *editor,
 
 /*****/
 
+static gdouble
+control_get_normalized_last_x_pos (GimpGradientEditor *editor)
+{
+  GtkAllocation allocation;
+  gdouble       normalized;
+  if (editor->control_last_x < 0)
+    return 0.5;
+
+  gtk_widget_get_allocation (editor->control, &allocation);
+  normalized = (double) editor->control_last_x / (allocation.width - 1);
+
+  if (normalized < 0)
+    return 0;
+  if (normalized > 1.0)
+    return 1;
+  return normalized;
+}
+
+/*****/
+
 static void
 control_update (GimpGradientEditor *editor,
                 GimpGradient       *gradient,
diff --git a/app/widgets/gimpgradienteditor.h b/app/widgets/gimpgradienteditor.h
index 09dcc50a89..98dfff27f2 100644
--- a/app/widgets/gimpgradienteditor.h
+++ b/app/widgets/gimpgradienteditor.h
@@ -115,7 +115,8 @@ void        gimp_gradient_editor_edit_right_color (GimpGradientEditor   *editor)
 
 void        gimp_gradient_editor_zoom             (GimpGradientEditor   *editor,
                                                    GimpZoomType          zoom_type,
-                                                   gdouble               delta);
+                                                   gdouble               delta,
+                                                   gdouble               zoom_focus_x);
 
 
 #endif  /* __GIMP_GRADIENT_EDITOR_H__ */


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