From dc2c2cd9210e0f8235b2e74e30d95f306187025f Mon Sep 17 00:00:00 2001
From: Jonathan Wilkes <jon.w.wilkes@gmail.com>
Date: Sun, 20 Sep 2015 01:02:32 -0400
Subject: [PATCH] more work on the "drag" event for [draw]

---
 pd/nw/pdgui.js      | 46 ++++++++++++++++++++++++++++++++++++++++++++-
 pd/src/g_canvas.c   |  6 +++++-
 pd/src/g_template.c | 32 ++++++++++++++++++++++++++-----
 3 files changed, 77 insertions(+), 7 deletions(-)

diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index a05f8bd51..d27f6a269 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -2170,13 +2170,57 @@ function gui_draw_coords(cid, tag, shape, points) {
     }
 }
 
+var gui_draw_drag_event = (function() {
+    var last_mousedown,
+        last_mouseup,
+        last_mousemove;
+    return function gui_draw_drag_event(cid, tag, scalar_sym,
+        drawcommand_sym, event_name, state) {
+        var last_x,
+            last_y,
+            item = get_item(cid, tag),
+            doc = patchwin[cid].window.document,
+            mousemove = function(e) {
+                var new_x = e.pageX,
+                    new_y = e.pageY;
+                pdsend(cid, "scalar_event", scalar_sym, drawcommand_sym,
+                    event_name, new_x - last_x, new_y - last_y);
+                last_x = new_x;
+                last_y = new_y;
+            },
+            mousedown = function(e) {
+                if (e.target === item) {
+                    last_x = e.pageX;
+                    last_y = e.pageY;
+                    doc.addEventListener("mousemove", mousemove, false);
+                }
+            },
+            mouseup = function(e) {
+                doc.removeEventListener("mousemove", mousemove, false);
+            }
+        ;
+        // Go ahead and remove any event listeners
+        doc.removeEventListener("mousedown", last_mousedown, false);
+        doc.removeEventListener("mouseup", last_mouseup, false);
+        doc.removeEventListener("mousemove", last_mousemove, false);
+
+        // Set mousedown and mouseup events to create our "drag" event
+        if (state === 1) {
+            doc.addEventListener("mousedown", mousedown, false);
+            doc.addEventListener("mouseup", mouseup, false);
+            last_mousemove = mousemove;
+            last_mouseup = mouseup;
+            last_mousedown = mousedown;
+        }
+    }
+}());
+
 function gui_draw_event(cid, tag, scalar_sym, drawcommand_sym, event_name,
     state) {
     var item = get_item(cid, tag),
         event_type = "on" + event_name; 
     if (state === 1) {
         item[event_type] = function(e) {
-//            gui_post("Entered! Tag is " + tag);
             pdsend(cid, "scalar_event", scalar_sym, drawcommand_sym, event_name,
                 e.pageX, e.pageY);
         };
diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c
index d5b93ffd0..d881b906c 100644
--- a/pd/src/g_canvas.c
+++ b/pd/src/g_canvas.c
@@ -733,7 +733,11 @@ void draw_notify(t_canvas *x, t_symbol *s, int argc, t_atom *argv);
 
 void canvas_scalar_event(t_canvas *x, t_symbol *s, int argc, t_atom *argv)
 {
-    draw_notify(x, s, argc, argv);
+    /* These events only get sent when we're not in edit mode.  Once
+       we get editmode status sync'd in the GUI we can just prevent
+       sending any messages when in edit mode. */
+    if (!x->gl_edit)
+        draw_notify(x, s, argc, argv);
 }
 
 extern void canvas_check_nlet_highlights(t_canvas *x);
diff --git a/pd/src/g_template.c b/pd/src/g_template.c
index aec7ed311..0ecb62ea5 100644
--- a/pd/src/g_template.c
+++ b/pd/src/g_template.c
@@ -1095,7 +1095,8 @@ typedef struct _svg_event
                e_mouseup,
                e_mouseover,
                e_mousemove,
-               e_mouseout;
+               e_mouseout,
+               e_drag; /* not in the svg spec, but should have been */
 } t_svg_event;
 
 /* svg attributes */
@@ -1366,6 +1367,8 @@ void *svg_new(t_pd *parent, t_symbol *s, int argc, t_atom *argv)
     x->x_events.e_mousemove.a_flag = 0;
     fielddesc_setfloat_const(&x->x_events.e_mouseout.a_attr, 0);
     x->x_events.e_mouseout.a_flag = 0;
+    fielddesc_setfloat_const(&x->x_events.e_drag.a_attr, 0);
+    x->x_events.e_drag.a_flag = 0;
 
     char buf[50];
     // Here we bind the parent object to the addy for
@@ -1710,6 +1713,13 @@ void svg_sendupdate(t_svg *x, t_canvas *c, t_symbol *s,
             (int)fielddesc_getcoord(
                 &x->x_events.e_mousedown.a_attr, template, data, 1));
     }
+    else if (s == gensym("drag"))
+    {
+        gui_vmess("gui_draw_drag_event", "xsxxsi",
+            glist_getcanvas(c), tag, sc, x, "drag",
+            (int)fielddesc_getcoord(
+                &x->x_events.e_drag.a_attr, template, data, 1));
+    }
     else if (s == gensym("vis"))
     {
         gui_vmess("gui_draw_configure", "xsss",
@@ -1980,16 +1990,21 @@ void svg_register_events(t_gobj *z, t_canvas *c, t_scalar *sc,
             glist_getcanvas(c), tagbuf, sc, svg, "mousemove",
             (int)fielddesc_getcoord(&svg->x_events.e_mousemove.a_attr, template,
             data, 1));
-    if (svg->x_events.e_mousemove.a_flag)
+    if (svg->x_events.e_mousedown.a_flag)
         gui_vmess("gui_draw_event", "xsxxsi",
-            glist_getcanvas(c), tagbuf, sc, svg, "mousemove",
-            (int)fielddesc_getcoord(&svg->x_events.e_mousemove.a_attr, template,
+            glist_getcanvas(c), tagbuf, sc, svg, "mousedown",
+            (int)fielddesc_getcoord(&svg->x_events.e_mousedown.a_attr, template,
             data, 1));
     if (svg->x_events.e_mouseup.a_flag)
         gui_vmess("gui_draw_event", "xsxxsi",
             glist_getcanvas(c), tagbuf, sc, svg, "mouseup",
             (int)fielddesc_getcoord(&svg->x_events.e_mouseup.a_attr, template,
             data, 1));
+    if (svg->x_events.e_drag.a_flag)
+        gui_vmess("gui_draw_drag_event", "xsxxsi",
+            glist_getcanvas(c), tagbuf, sc, svg, "drag",
+            (int)fielddesc_getcoord(&svg->x_events.e_drag.a_attr, template,
+            data, 1));
 }
 
 void svg_setattr(t_svg *x, t_symbol *s, t_int argc, t_atom *argv)
@@ -2255,6 +2270,11 @@ void svg_event(t_svg *x, t_symbol *s, int argc, t_atom *argv)
             fielddesc_setfloatarg(&x->x_events.e_mouseout.a_attr, argc, argv);
             x->x_events.e_mouseout.a_flag = 1;
         }
+        else if (s == gensym("drag"))
+        {
+            fielddesc_setfloatarg(&x->x_events.e_drag.a_attr, argc, argv);
+            x->x_events.e_drag.a_flag = 1;
+        }
         svg_update(x, s);
     }
 }
@@ -4316,7 +4336,9 @@ static void draw_setup(void)
         gensym("cy"), A_GIMME, 0);
     class_addmethod(svg_class, (t_method)svg_data,
         gensym("data"), A_GIMME, 0);
-    class_addmethod(svg_class, (t_method)svg_drag,
+//    class_addmethod(svg_class, (t_method)svg_drag,
+//        gensym("drag"), A_GIMME, 0);
+    class_addmethod(svg_class, (t_method)svg_event,
         gensym("drag"), A_GIMME, 0);
     class_addmethod(svg_class, (t_method)svg_fill,
         gensym("fill"), A_GIMME, 0);
-- 
GitLab