From 6f92aa2bbff074cd8ef51357d8603a9c97db5b5f Mon Sep 17 00:00:00 2001
From: Jonathan Wilkes <jon.w.wilkes@gmail.com>
Date: Sun, 16 Jul 2017 14:20:44 -0400
Subject: [PATCH] add rudimentary [mousewheel] reporting (-1 for up, 1 for
 down)

---
 pd/nw/pd_canvas.js | 21 ++++++++++++++++-----
 pd/src/g_editor.c  | 20 ++++++++++++++++++--
 pd/src/x_gui.c     | 16 ++++++++++++----
 3 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/pd/nw/pd_canvas.js b/pd/nw/pd_canvas.js
index 8a02095e6..062179290 100644
--- a/pd/nw/pd_canvas.js
+++ b/pd/nw/pd_canvas.js
@@ -751,13 +751,24 @@ var canvas_events = (function() {
 
     // MouseWheel event for zooming
     document.addEventListener("wheel", function(evt) {
-        if (pdgui.cmd_or_ctrl_key(evt)) {
-            if (evt.deltaY < 0) {
-                nw_window_zoom(name, +1);
-            } else if (evt.deltaY > 0) {
-                nw_window_zoom(name, -1);
+        var d = { deltaX: 0, deltaY: 0, deltaZ: 0 };
+        Object.keys(d).forEach(function(key) {
+            if (evt[key] < 0) {
+                d[key] = -1;
+            } else if (evt[key] > 0) {
+                d[key] = 1;
+            } else {
+                d[key] = 0;
             }
+        });
+        if (pdgui.cmd_or_ctrl_key(evt)) {
+            // scroll up for zoom-in, down for zoom-out
+            nw_window_zoom(name, -d.deltaY);
         }
+        // Send a message on to Pd for the [mousewheel] legacy object
+        // (in the future we can refcount if we want to prevent forwarding
+        // these messages when there's no extant receiver)
+        pdgui.pdsend(name, "mousewheel", d.deltaX, d.deltaY, d.deltaZ);
     });
 
     // The following is commented out because we have to set the
diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c
index 4ff0150d2..71c33cfb0 100644
--- a/pd/src/g_editor.c
+++ b/pd/src/g_editor.c
@@ -3781,6 +3781,20 @@ void canvas_mousedown(t_canvas *x, t_floatarg xpos, t_floatarg ypos,
     canvas_dispatch_mouseclick(1., xpos, ypos, which);
 }
 
+void canvas_mousewheel(t_canvas *x, t_floatarg xpos, t_floatarg ypos,
+    t_floatarg zpos)
+{
+    t_symbol *mousewheelsym = gensym("#mousewheel");
+    if (mousewheelsym->s_thing)
+    {
+        t_atom at[3];
+        SETFLOAT(at, xpos);
+        SETFLOAT(at+1, ypos);
+        SETFLOAT(at+2, zpos);
+        pd_list(mousewheelsym->s_thing, &s_list, 3, at);
+    }
+}
+
 int canvas_isconnected (t_canvas *x, t_text *ob1, int n1,
     t_text *ob2, int n2)
 {
@@ -7580,8 +7594,10 @@ void g_editor_setup(void)
         A_FLOAT, A_FLOAT, A_FLOAT, A_NULL);
     class_addmethod(canvas_class, (t_method)canvas_mouseup_fake,
         gensym("mouseup_fake"), A_NULL);
-    class_addmethod(canvas_class, (t_method)canvas_mousedown_middle, gensym("mouse-2"),
-        A_FLOAT, A_FLOAT, A_FLOAT, A_NULL);
+    class_addmethod(canvas_class, (t_method)canvas_mousedown_middle,
+        gensym("mouse-2"), A_FLOAT, A_FLOAT, A_FLOAT, A_NULL);
+    class_addmethod(canvas_class, (t_method)canvas_mousewheel,
+        gensym("mousewheel"), A_FLOAT, A_FLOAT, A_FLOAT, A_NULL);
     class_addmethod(canvas_class, (t_method)canvas_key, gensym("key"),
         A_GIMME, A_NULL);
     class_addmethod(canvas_class, (t_method)canvas_motion, gensym("motion"),
diff --git a/pd/src/x_gui.c b/pd/src/x_gui.c
index 3386e8bda..5d902a924 100644
--- a/pd/src/x_gui.c
+++ b/pd/src/x_gui.c
@@ -564,19 +564,27 @@ static void mouseclick_free(t_mouseclick *x)
 typedef struct _mousewheel
 {
     t_object x_obj;
+    t_outlet *x_outlet1;
+    t_outlet *x_outlet2;
+    t_outlet *x_outlet3;
 } t_mousewheel;
 
 static void *mousewheel_new( void)
 {
     t_mousewheel *x = (t_mousewheel *)pd_new(mousewheel_class);
-    outlet_new(&x->x_obj, &s_float);
+    x->x_outlet1 = outlet_new(&x->x_obj, &s_float);
+    x->x_outlet2 = outlet_new(&x->x_obj, &s_float);
+    x->x_outlet3 = outlet_new(&x->x_obj, &s_float);
     pd_bind(&x->x_obj.ob_pd, mousewheel_sym);
     return (x);
 }
 
-static void mousewheel_float(t_mousewheel *x, t_floatarg f)
+static void mousewheel_list(t_mousewheel *x, t_symbol *s, int argc,
+    t_atom *argv)
 {
-    outlet_float(x->x_obj.ob_outlet, f);
+    outlet_float(x->x_outlet3, atom_getfloatarg(2, argc, argv));
+    outlet_float(x->x_outlet2, atom_getfloatarg(1, argc, argv));
+    outlet_float(x->x_outlet1, atom_getfloatarg(0, argc, argv));
 }
 
 static void mousewheel_free(t_mousewheel *x)
@@ -601,7 +609,7 @@ static void mouse_setup(void)
     mousewheel_class = class_new(gensym("mousewheel"),
         (t_newmethod)mousewheel_new, (t_method)mousewheel_free,
         sizeof(t_mousewheel), CLASS_NOINLET, 0);
-    class_addfloat(mousewheel_class, mousewheel_float);
+    class_addfloat(mousewheel_class, mousewheel_list);
     mousewheel_sym = gensym("#mousewheel");
 }
 
-- 
GitLab