From e5a1b22c561c3a9861745f771606b647d5802f9e Mon Sep 17 00:00:00 2001
From: Jonathan Wilkes <jon.w.wilkes@gmail.com>
Date: Wed, 21 Oct 2015 22:38:23 -0400
Subject: [PATCH] attempt to fix the "drag" event for [draw], and make it more
 robust. But it still needs to be tested to make sure it interacts properly
 with all the other events.

---
 pd/nw/pd_canvas.js | 50 ++++++++++++++++++++++++++++++++++++++++
 pd/nw/pdgui.js     | 57 ++++++++++++----------------------------------
 2 files changed, 64 insertions(+), 43 deletions(-)

diff --git a/pd/nw/pd_canvas.js b/pd/nw/pd_canvas.js
index f62658b36..dab7638df 100644
--- a/pd/nw/pd_canvas.js
+++ b/pd/nw/pd_canvas.js
@@ -65,6 +65,10 @@ pdgui.gui_post("flub!");
 var canvas_events = (function() {
     var name,
         state,
+        scalar_draggables = {}, // elements of a scalar which have the "drag" event enabled
+        draggable_elem,         // the current scalar element being dragged
+        last_draggable_x,       // last x position for the element we're dragging
+        last_draggable_y,       // last y 
         previous_state = 'none', /* last state, excluding explicit 'none' */
         match_words_state = false,
         last_search_term = '',
@@ -90,6 +94,17 @@ var canvas_events = (function() {
                 // than html5...
                 var b = evt.button + 1;
                 var mod;
+                // See if there are any draggable scalar shapes...
+                if (Object.keys(scalar_draggables)) {
+                    // if so, see if our target is one of them...
+                    if (scalar_draggables[evt.target.id]) {
+                        // then set some state and turn on the drag events
+                        draggable_elem = evt.target;
+                        last_draggable_x = evt.pageX;
+                        last_draggable_y = evt.pageY;
+                        canvas_events.scalar_drag();
+                    }
+                }
                 // For some reason right-click sends a modifier value of "8",
                 // and canvas_doclick in g_editor.c depends on that value to
                 // do the right thing.  So let's hack...
@@ -304,6 +319,19 @@ var canvas_events = (function() {
                 if (evt.keyCode === 13) {
                     events.find_click(evt);
                 }
+            },
+            scalar_draggable_mousemove: function(evt) {
+                var new_x = evt.pageX,
+                    new_y = evt.pageY;
+                var obj = scalar_draggables[draggable_elem.id];
+                pdgui.pdsend(obj.cid, "scalar_event", obj.scalar_sym, 
+                    obj.drawcommand_sym, obj.event_name, new_x - last_draggable_x,
+                    new_y - last_draggable_y);
+                last_draggable_x = new_x;
+                last_draggable_y = new_y;
+            },
+            scalar_draggable_mouseup: function(evt) {
+                canvas_events.normal();
             }
         },
         utils = {
@@ -398,6 +426,15 @@ var canvas_events = (function() {
             state = 'normal';
             set_edit_menu_modals(true);
         },
+        scalar_drag: function() {
+            // This scalar_drag is a prototype for moving more of the editing environment 
+            // directly to the GUI.  At the moment we're leaving the other "normal" 
+            // events live, since behavior like editmode selection still happens from
+            // the Pd engine.
+            //this.none();
+            document.addEventListener("mousemove", events.scalar_draggable_mousemove, false);
+            document.addEventListener("mouseup", events.scalar_draggable_mouseup, false);
+        },
         text: function() {
             this.none();
 
@@ -445,6 +482,19 @@ var canvas_events = (function() {
         },
         match_words: function(state) {
             match_words_state = state;
+        },
+        add_scalar_draggable: function(cid, tag, scalar_sym, drawcommand_sym, event_name) {
+            scalar_draggables[tag] = {
+                cid: cid,
+                scalar_sym: scalar_sym,
+                drawcommand_sym, drawcommand_sym,
+                event_name: event_name
+            };
+        },
+        remove_scalar_draggable: function(id) {
+            if (scalar_draggables[id]) {
+                scalar_draggables[id] = null;
+            }
         }
     }
 }());
diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index 800fe8be6..c8189daba 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -2173,51 +2173,22 @@ 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;
-        }
+// set a drag event for a shape that's part of a scalar.
+// this is a convenience method for the user, so that dragging outside
+// of the bbox of the shape will still register as part of the event.
+// (Attempting to set the event more than once is ignored.)
+function gui_draw_drag_event(cid, tag, scalar_sym, drawcommand_sym,
+    event_name, state) {
+    var win = patchwin[cid].window;
+    if (state === 0) {
+        win.canvas_events.remove_scalar_draggable(tag); 
+    } else {
+        win.canvas_events.add_scalar_draggable(cid, tag, scalar_sym,
+            drawcommand_sym, event_name);
     }
-}());
+}
 
+// Events for scalars-- mouseover, mouseout, etc.
 function gui_draw_event(cid, tag, scalar_sym, drawcommand_sym, event_name,
     state) {
     var item = get_item(cid, tag),
-- 
GitLab