From 8e48d3ed028e4b12c33d723eb59b734be8f12561 Mon Sep 17 00:00:00 2001 From: Jonathan Wilkes <jon.w.wilkes@gmail.com> Date: Tue, 15 Nov 2016 23:58:32 -0500 Subject: [PATCH] prepare to add key events for sending keypresses from the console window to Pd --- pd/nw/index.js | 10 +++ pd/nw/pd_canvas.js | 178 ++------------------------------------------ pd/nw/pdgui.js | 182 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 197 insertions(+), 173 deletions(-) diff --git a/pd/nw/index.js b/pd/nw/index.js index 9c84762a7..a7502fc06 100644 --- a/pd/nw/index.js +++ b/pd/nw/index.js @@ -242,6 +242,16 @@ function add_events() { // Find bar var find_bar = document.getElementById("console_find_text"); find_bar.placeholder = l("pd_window.find.placeholder"); + // Forward console key events to Pd using the global "pd key" method... + document.addEventListener("keydown", function(evt) { + pdgui.keydown("pd", evt); + }, false); + document.addEventListener("keypress", function(evt) { + pdgui.keypress("pd", evt); + }, false); + document.addEventListener("keyup", function(evt) { + pdgui.keyup("pd", evt); + }, false); find_bar.addEventListener("keydown", function(e) { return console_find_keydown(e); diff --git a/pd/nw/pd_canvas.js b/pd/nw/pd_canvas.js index 2f697bebe..261b0eb43 100644 --- a/pd/nw/pd_canvas.js +++ b/pd/nw/pd_canvas.js @@ -19,15 +19,6 @@ document.getElementById("fileDialog") document.getElementById("fileDialog").setAttribute("accept", Object.keys(pdgui.pd_filetypes).toString()); -var last_keydown = ""; - -// This could probably be in pdgui.js -function add_keymods(key, evt) { - var shift = evt.shiftKey ? "Shift" : ""; - var ctrl = evt.ctrlKey ? "Ctrl" : ""; - return shift + ctrl + key; -} - function close_save_dialog() { document.getElementById("save_before_quit").close(); } @@ -156,14 +147,6 @@ function canvas_find_focus() { canvas_events.search(); } -function cmd_or_ctrl_key(evt) { - if (process.platform === "darwin") { - return evt.metaKey; - } else { - return evt.ctrlKey; - } -} - var canvas_events = (function() { var name, state, @@ -174,7 +157,6 @@ var canvas_events = (function() { previous_state = "none", /* last state, excluding explicit 'none' */ match_words_state = false, last_search_term = "", - keydown_autorepeat = false, svg_view = document.getElementById("patchsvg").viewBox.baseVal, textbox = function () { return document.getElementById("new_object_textentry"); @@ -224,11 +206,11 @@ var canvas_events = (function() { events = { mousemove: function(evt) { //pdgui.post("x: " + evt.pageX + " y: " + evt.pageY + - // " modifier: " + (evt.shiftKey + (cmd_or_ctrl_key(evt) << 1))); + // " modifier: " + (evt.shiftKey + (pdgui.cmd_or_ctrl_key(evt) << 1))); pdgui.pdsend(name, "motion", (evt.pageX + svg_view.x), (evt.pageY + svg_view.y), - (evt.shiftKey + (cmd_or_ctrl_key(evt) << 1)) + (evt.shiftKey + (pdgui.cmd_or_ctrl_key(evt) << 1)) ); evt.stopPropagation(); evt.preventDefault(); @@ -276,7 +258,7 @@ var canvas_events = (function() { // right-click mod = 8; } else { - mod = (evt.shiftKey + (cmd_or_ctrl_key(evt) << 1)); + mod = (evt.shiftKey + (pdgui.cmd_or_ctrl_key(evt) << 1)); } pdgui.pdsend(name, "mouse", (evt.pageX + svg_view.x), @@ -299,163 +281,15 @@ var canvas_events = (function() { evt.preventDefault(); }, keydown: function(evt) { - var key_code = evt.keyCode, - hack = null; // hack for unprintable ascii codes - keydown_autorepeat = evt.repeat; - switch(key_code) { - case 8: - case 9: - case 10: - case 27: - //case 32: - case 127: hack = key_code; break; - case 37: hack = add_keymods("Left", evt); break; - case 38: hack = add_keymods("Up", evt); break; - case 39: hack = add_keymods("Right", evt); break; - case 40: hack = add_keymods("Down", evt); break; - case 33: hack = add_keymods("Prior", evt); break; - case 34: hack = add_keymods("Next", evt); break; - case 35: hack = add_keymods("End", evt); break; - case 36: hack = add_keymods("Home", evt); break; - - // These may be different on Safari... - case 112: hack = add_keymods("F1", evt); break; - case 113: hack = add_keymods("F2", evt); break; - case 114: hack = add_keymods("F3", evt); break; - case 115: hack = add_keymods("F4", evt); break; - case 116: hack = add_keymods("F5", evt); break; - case 117: hack = add_keymods("F6", evt); break; - case 118: hack = add_keymods("F7", evt); break; - case 119: hack = add_keymods("F8", evt); break; - case 120: hack = add_keymods("F9", evt); break; - case 121: hack = add_keymods("F10", evt); break; - case 122: hack = add_keymods("F11", evt); break; - case 123: hack = add_keymods("F12", evt); break; - - // Handle weird behavior for clipboard shortcuts - // Which don't fire a keypress for some odd reason - - case 65: - if (cmd_or_ctrl_key(evt)) { // ctrl-a - // This is handled in the nwjs menu, but we - // add a way to toggle the window menubar - // the following command should be uncommented... - //pdgui.pdsend(name, "selectall"); - hack = 0; // not sure what to report here... - } - break; - case 88: - if (cmd_or_ctrl_key(evt)) { // ctrl-x - // This is handled in the nwjs menubar. If we - // add a way to toggle the menubar it will be - // handled with the "cut" DOM listener, so we - // can probably remove this code... - //pdgui.pdsend(name, "cut"); - hack = 0; // not sure what to report here... - } - break; - case 67: - if (cmd_or_ctrl_key(evt)) { // ctrl-c - // Handled in nwjs menubar (see above) - //pdgui.pdsend(name, "copy"); - hack = 0; // not sure what to report here... - } - break; - case 86: - if (cmd_or_ctrl_key(evt)) { // ctrl-v - // We also use "cut" and "copy" DOM event handlers - // and leave this code in case we need to change - // tactics for some reason. - //pdgui.pdsend(name, "paste"); - hack = 0; // not sure what to report here... - } - break; - case 90: - if (cmd_or_ctrl_key(evt)) { // ctrl-z undo/redo - // We have to catch undo and redo here. - // undo and redo have nw.js menu item shortcuts, - // and those shortcuts don't behave consistently - // across platforms: - // Gnu/Linux: key events for the shortcut do not - // propogate down to the DOM - // OSX: key events for the shortcut _do_ propogate - // down to the DOM - // Windows: not sure... - - // Solution-- let the menu item shortcuts handle - // undo/redo functionality, and do nothing here... - //if (evt.shiftKey) { - // pdgui.pdsend(name, "redo"); - //} else { - // pdgui.pdsend(name, "undo"); - //} - } - break; - - // Need to handle Control key, Alt - - case 16: hack = "Shift"; break; - case 17: hack = "Control"; break; - case 18: hack = "Alt"; break; - - // keycode 188 = comma -- in contrast to / this is - // next to the period on most Latin keyboards, so - // much more convenient to quickly switch dsp off - // and then on again - case 188: - // keycode 55 = 7 key (shifted = '/' on German keyboards) - case 55: - if (cmd_or_ctrl_key(evt)) { - evt.preventDefault(); - pdgui.pdsend("pd dsp 1"); - } - break; - - } - if (hack !== null) { - pdgui.canvas_sendkey(name, 1, evt, hack, keydown_autorepeat); - pdgui.set_keymap(key_code, hack); - } - - //pdgui.post("keydown time: keycode is " + evt.keyCode); - last_keydown = evt.keyCode; - //evt.stopPropagation(); - //evt.preventDefault(); + pdgui.keydown(name, evt); }, keypress: function(evt) { - // For some reasons <ctrl-e> registers a keypress with - // charCode of 5. We filter that out here so it doesn't - // cause trouble when toggling editmode. - // Also, we're capturing <ctrl-or-cmd-Enter> in the "Edit" - // menu item "reselect", so we filter it out here as well. - // (That may change once we find a more flexible way of - // handling keyboard shortcuts - if (evt.charCode !== 5 && - (!cmd_or_ctrl_key(evt) || evt.charCode !== 10)) { - pdgui.canvas_sendkey(name, 1, evt, evt.charCode, - keydown_autorepeat); - pdgui.set_keymap(last_keydown, evt.charCode, - keydown_autorepeat); - } - //pdgui.post("keypress time: charcode is " + evt.charCode); + pdgui.keypress(name, evt); // Don't do things like scrolling on space, arrow keys, etc. - //evt.stopPropagation(); evt.preventDefault(); }, keyup: function(evt) { - var my_char_code = pdgui.get_char_code(evt.keyCode); - // Sometimes we don't have char_code. For example, the - // nw menu doesn't propogate shortcut events, so we don't get - // to map a charcode on keydown/keypress. In those cases we'll - // get null, so we check for that here... - if (my_char_code) { - pdgui.canvas_sendkey(name, 0, evt, my_char_code, evt.repeat); - } - // This can probably be removed - //if (cmd_or_ctrl_key(evt) && - // (evt.keyCode === 13 || evt.keyCode === 10)) { - // pdgui.pdsend(name, "reselect"); - //} + pdgui.keyup(name, evt); evt.stopPropagation(); evt.preventDefault(); }, diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js index 8b6235abc..171241810 100644 --- a/pd/nw/pdgui.js +++ b/pd/nw/pdgui.js @@ -250,6 +250,185 @@ function get_char_code(keycode) { exports.get_char_code = get_char_code; +// This could probably be in pdgui.js +function add_keymods(key, evt) { + var shift = evt.shiftKey ? "Shift" : ""; + var ctrl = evt.ctrlKey ? "Ctrl" : ""; + return shift + ctrl + key; +} + +function cmd_or_ctrl_key(evt) { + if (process.platform === "darwin") { + return evt.metaKey; + } else { + return evt.ctrlKey; + } +} + +exports.cmd_or_ctrl_key = cmd_or_ctrl_key; + +var last_keydown = ""; + +exports.keydown = function(cid, evt) { + var key_code = evt.keyCode, + hack = null, // hack for unprintable ascii codes + cmd_or_ctrl + switch(key_code) { + case 8: + case 9: + case 10: + case 27: + //case 32: + case 127: hack = key_code; break; + case 37: hack = add_keymods("Left", evt); break; + case 38: hack = add_keymods("Up", evt); break; + case 39: hack = add_keymods("Right", evt); break; + case 40: hack = add_keymods("Down", evt); break; + case 33: hack = add_keymods("Prior", evt); break; + case 34: hack = add_keymods("Next", evt); break; + case 35: hack = add_keymods("End", evt); break; + case 36: hack = add_keymods("Home", evt); break; + + // These may be different on Safari... + case 112: hack = add_keymods("F1", evt); break; + case 113: hack = add_keymods("F2", evt); break; + case 114: hack = add_keymods("F3", evt); break; + case 115: hack = add_keymods("F4", evt); break; + case 116: hack = add_keymods("F5", evt); break; + case 117: hack = add_keymods("F6", evt); break; + case 118: hack = add_keymods("F7", evt); break; + case 119: hack = add_keymods("F8", evt); break; + case 120: hack = add_keymods("F9", evt); break; + case 121: hack = add_keymods("F10", evt); break; + case 122: hack = add_keymods("F11", evt); break; + case 123: hack = add_keymods("F12", evt); break; + + // Handle weird behavior for clipboard shortcuts + // Which don't fire a keypress for some odd reason + + case 65: + if (cmd_or_ctrl_key(evt)) { // ctrl-a + // This is handled in the nwjs menu, but we + // add a way to toggle the window menubar + // the following command should be uncommented... + //pdsend(name, "selectall"); + hack = 0; // not sure what to report here... + } + break; + case 88: + if (cmd_or_ctrl_key(evt)) { // ctrl-x + // This is handled in the nwjs menubar. If we + // add a way to toggle the menubar it will be + // handled with the "cut" DOM listener, so we + // can probably remove this code... + //pdsend(name, "cut"); + hack = 0; // not sure what to report here... + } + break; + case 67: + if (cmd_or_ctrl_key(evt)) { // ctrl-c + // Handled in nwjs menubar (see above) + //pdsend(name, "copy"); + hack = 0; // not sure what to report here... + } + break; + case 86: + if (cmd_or_ctrl_key(evt)) { // ctrl-v + // We also use "cut" and "copy" DOM event handlers + // and leave this code in case we need to change + // tactics for some reason. + //pdsend(name, "paste"); + hack = 0; // not sure what to report here... + } + break; + case 90: + if (cmd_or_ctrl_key(evt)) { // ctrl-z undo/redo + // We have to catch undo and redo here. + // undo and redo have nw.js menu item shortcuts, + // and those shortcuts don't behave consistently + // across platforms: + // Gnu/Linux: key events for the shortcut do not + // propogate down to the DOM + // OSX: key events for the shortcut _do_ propogate + // down to the DOM + // Windows: not sure... + + // Solution-- let the menu item shortcuts handle + // undo/redo functionality, and do nothing here... + //if (evt.shiftKey) { + // pdsend(name, "redo"); + //} else { + // pdsend(name, "undo"); + //} + } + break; + + // Need to handle Control key, Alt + + case 16: hack = "Shift"; break; + case 17: hack = "Control"; break; + case 18: hack = "Alt"; break; + + // keycode 188 = comma -- in contrast to / this is + // next to the period on most Latin keyboards, so + // much more convenient to quickly switch dsp off + // and then on again + case 188: + // keycode 55 = 7 key (shifted = '/' on German keyboards) + case 55: + if (cmd_or_ctrl_key(evt)) { + evt.preventDefault(); + pdsend("pd dsp 1"); + } + break; + + } + if (hack !== null) { + canvas_sendkey(cid, 1, evt, hack, evt.repeat); + set_keymap(key_code, hack); + } + + //post("keydown time: keycode is " + evt.keyCode); + last_keydown = evt.keyCode; + //evt.stopPropagation(); + //evt.preventDefault(); +}; + +exports.keypress = function(cid, evt) { + // For some reasons <ctrl-e> registers a keypress with + // charCode of 5. We filter that out here so it doesn't + // cause trouble when toggling editmode. + // Also, we're capturing <ctrl-or-cmd-Enter> in the "Edit" + // menu item "reselect", so we filter it out here as well. + // (That may change once we find a more flexible way of + // handling keyboard shortcuts + if (evt.charCode !== 5 && + (!cmd_or_ctrl_key(evt) || evt.charCode !== 10)) { + canvas_sendkey(cid, 1, evt, evt.charCode, + evt.repeat); + set_keymap(last_keydown, evt.charCode, + evt.repeat); + } + //post("keypress time: charcode is " + evt.charCode); + // Don't do things like scrolling on space, arrow keys, etc. +}; + +exports.keyup = function(cid, evt) { + var my_char_code = get_char_code(evt.keyCode); + // Sometimes we don't have char_code. For example, the + // nw menu doesn't propogate shortcut events, so we don't get + // to map a charcode on keydown/keypress. In those cases we'll + // get null, so we check for that here... + if (my_char_code) { + canvas_sendkey(cid, 0, evt, my_char_code, evt.repeat); + } + // This can probably be removed + //if (cmd_or_ctrl_key(evt) && + // (evt.keyCode === 13 || evt.keyCode === 10)) { + // pdgui.pdsend(name, "reselect"); + //} +}; + // Hard-coded Pd-l2ork font metrics /* var font_fixed_metrics = [ @@ -1014,7 +1193,8 @@ function gui_canvas_cursor(cid, pd_event_type) { patch.style.cursor = c; } -// Not sure why this has the "gui_" prefix. It doesn't get called by Pd +// Note: cid can either be a real canvas id, or the string "pd" for the +// console window function canvas_sendkey(cid, state, evt, char_code, repeat) { var shift = evt.shiftKey ? 1 : 0, repeat_number = repeat ? 1 : 0; -- GitLab