# HG changeset patch
# User Paul Clarke
# Date 1691908884 18000
#      Sun Aug 13 01:41:24 2023 -0500
# Branch feature2
# Node ID bdfff88a26242b875379cbcbdc1ba2c1610c8125
# Parent  1adf957e37ac2d89abcd8a98241330b4b40f0469
Allow the user to scroll to zoom in rotate and pan modes.

* __set_default_mouse_modes__.m: Add a member 'ScrollZoom' to the
  __rotate_mode__  and __pan_mode__ attributes.

* __add_default_menu__.m: Add a menu option to toggle ScrollZoom on and off.

* Canvas.cc (Canvas::canvasWheelEvent): when ScrollZoom is on, zoom as
  if we are in zoom mode.

diff -r 1adf957e37ac -r bdfff88a2624 libgui/graphics/Canvas.cc
--- a/libgui/graphics/Canvas.cc	Thu Aug 10 17:36:41 2023 -0400
+++ b/libgui/graphics/Canvas.cc	Sun Aug 13 01:41:24 2023 -0500
@@ -335,6 +335,17 @@
   return zm.contents ("Motion").string_value ();
 }
 
+static bool
+rotate_enabled (const graphics_object figObj)
+{
+  octave_value ov_rm
+    = Utils::properties<figure> (figObj).get___rotate_mode__ ();
+
+  octave_scalar_map rm = ov_rm.scalar_map_value ();
+
+  return rm.contents ("Enable").string_value () == "on";
+}
+
 void
 Canvas::select_object (graphics_object obj, QMouseEvent *event,
                        graphics_object& currentObj, graphics_object& axesObj,
@@ -950,16 +961,7 @@
 
               if (zoom_enabled (figObj))
                 {
-#if defined (HAVE_QWHEELEVENT_ANGLEDELTA)
-                  if (event->angleDelta().y () > 0)
-#else
-                    if (event->delta () > 0)
-#endif
-                      newMouseMode = ZoomInMode;
-                    else
-                      newMouseMode = ZoomOutMode;
-
-                  mode = zoom_mode (figObj);
+                  newMouseMode = ZoomInMode;
                 }
               else if (pan_enabled (figObj))
                 {
@@ -967,47 +969,63 @@
 
                   mode = pan_mode (figObj);
                 }
+              else if (rotate_enabled (figObj))
+                {
+                  newMouseMode = RotateMode;
+                }
             }
 
           bool redrawFigure = true;
+          bool doZoom = false;
 
           switch (newMouseMode)
             {
             case ZoomInMode:
             case ZoomOutMode:
               {
-                axes::properties& ap = Utils::properties<axes> (axesObj);
-
-                // Control how fast to zoom when using scroll wheel.
-                double wheel_zoom_speed = ap.get_mousewheelzoom ();
-
-                // Determine if we're zooming in or out.
-                double factor = (newMouseMode == ZoomInMode
-                                 ? 1 / (1.0 - wheel_zoom_speed)
-                                 : 1.0 - wheel_zoom_speed);
-
-                // FIXME: should we zoom about point for 2D plots?
-
-                ap.zoom (mode, factor);
+                doZoom = true;
               }
               break;
 
             case PanMode:
               {
-                axes::properties& ap = Utils::properties<axes> (axesObj);
+                figure::properties& fp = Utils::properties<figure> (figObj);
+                octave_value ov_pm = fp.get___pan_mode__ ();
+                octave_scalar_map pm = ov_pm.scalar_map_value ();
 
+                if (pm.contents ("ScrollZoom").string_value () == "on")
+                  {
+                    doZoom = true;
+                  } 
+                else 
+                  {
+                    axes::properties& ap = Utils::properties<axes> (axesObj);
+    
 #if defined (HAVE_QWHEELEVENT_ANGLEDELTA)
-                double factor = (event->angleDelta().y () > 0 ? 0.1 : -0.1);
+                    double factor = (event->angleDelta().y () > 0 ? 0.1 : -0.1);
 #else
-                double factor = (event->delta () > 0 ? 0.1 : -0.1);
+                    double factor = (event->delta () > 0 ? 0.1 : -0.1);
 #endif
+    
+                    if (event->modifiers () == Qt::NoModifier
+                        && mode != "horizontal")
+                      ap.pan ("vertical", factor);
+                    else if (event->modifiers () == Qt::ShiftModifier
+                             && mode != "vertical")
+                      ap.pan ("horizontal", factor);
+                  }
+                }
+                break;
+            case RotateMode:
+              {
+                figure::properties& fp = Utils::properties<figure> (figObj);
+                octave_value ov_rm = fp.get___rotate_mode__ ();
+                octave_scalar_map rm = ov_rm.scalar_map_value ();
 
-                if (event->modifiers () == Qt::NoModifier
-                    && mode != "horizontal")
-                  ap.pan ("vertical", factor);
-                else if (event->modifiers () == Qt::ShiftModifier
-                         && mode != "vertical")
-                  ap.pan ("horizontal", factor);
+                if (rm.contents ("ScrollZoom").string_value () == "on")
+                  {
+                    doZoom = true;
+                  } 
               }
               break;
 
@@ -1015,7 +1033,28 @@
               redrawFigure = false;
               break;
             }
+          if (doZoom) 
+            {
+              axes::properties& ap = Utils::properties<axes> (axesObj);
 
+              // Control how fast to zoom when using scroll wheel.
+              double wheel_zoom_speed = ap.get_mousewheelzoom ();
+
+              // Determine if we're zooming in or out.
+              double factor;
+#if defined (HAVE_QWHEELEVENT_ANGLEDELTA)
+              if (event->angleDelta().y () > 0)
+#else
+              if (event->delta () > 0)
+#endif
+                  factor = 1 / (1.0 - wheel_zoom_speed);
+              else
+                  factor = 1.0 - wheel_zoom_speed;
+
+                // Always zoom both directions on scroll.
+                // FIXME: should we zoom about point for 2D plots?
+                ap.zoom ("both", factor);
+            }
           if (redrawFigure)
             redraw (false);
         }
diff -r 1adf957e37ac -r bdfff88a2624 scripts/plot/util/private/__add_default_menu__.m
--- a/scripts/plot/util/private/__add_default_menu__.m	Thu Aug 10 17:36:41 2023 -0400
+++ b/scripts/plot/util/private/__add_default_menu__.m	Sun Aug 13 01:41:24 2023 -0500
@@ -104,6 +104,8 @@
                   "menuselectedfcn", @guimode_cb);
     uimenu (hui2, "label", "Disable mousezoom", "tag", "zoom_off", ...
                   "menuselectedfcn", @guimode_cb);
+    uimenu (hui2, "label", "Toggle scroll to zoom in all modes", "tag", "toggle_scroll_zoom", ...
+                  "menuselectedfcn", @guimode_cb);
     hmenu(3) = hui;
 
     ## Default toolbar
@@ -276,9 +278,11 @@
 
   set (hf, "__pan_mode__", struct ("Enable", "off",
                                    "Motion", "both",
+                                   "ScrollZoom", "on",
                                    "FigureHandle", hf),
            "__rotate_mode__", struct ("Enable", "off",
                                       "RotateStyle", "box",
+                                      "ScrollZoom", "on",
                                       "FigureHandle", hf),
            "__zoom_mode__", struct ("Enable", "off",
                                     "Motion", "both",
@@ -307,6 +311,18 @@
       arrayfun (@(h) set (h, "mousewheelzoom", 0.05), hax);
     case "zoom_off"
       arrayfun (@(h) set (h, "mousewheelzoom", 0.0), hax);
+    case "toggle_scroll_zoom"
+      rm = get(fig, "__rotate_mode__");
+      pm = get(fig, "__pan_mode__");
+      if strcmp(rm.ScrollZoom, "on")
+        new = "off";
+      else
+        new = "on";
+      endif
+      rm.ScrollZoom = new;
+      pm.ScrollZoom = new;
+      set(fig, "__rotate_mode__", rm);
+      set(fig, "__pan_mode__", pm);
   endswitch
 
 endfunction
diff -r 1adf957e37ac -r bdfff88a2624 scripts/plot/util/private/__set_default_mouse_modes__.m
--- a/scripts/plot/util/private/__set_default_mouse_modes__.m	Thu Aug 10 17:36:41 2023 -0400
+++ b/scripts/plot/util/private/__set_default_mouse_modes__.m	Sun Aug 13 01:41:24 2023 -0500
@@ -33,9 +33,11 @@
 
   set (fig, "__pan_mode__", struct ("Enable", "off",
                                     "Motion", "both",
+                                    "ScrollZoom", "on",
                                     "FigureHandle", fig),
             "__rotate_mode__", struct ("Enable", "off",
                                        "RotateStyle", "box",
+                                       "ScrollZoom", "on",
                                        "FigureHandle", fig),
             "__zoom_mode__", struct ("Enable", "off",
                                      "Motion", "both",
