From b012c546a2fc1108ab463a4d38cd59e175b0ddb0 Mon Sep 17 00:00:00 2001 From: Brenden Tuck Date: Thu, 31 Jan 2019 22:01:17 -0500 Subject: [PATCH] Add a dual_input plugin --- .../static/webclient/js/plugins/default_in.js | 7 +- .../static/webclient/js/plugins/dual_input.js | 72 ++++++++++ .../static/webclient/js/plugins/history.js | 135 +++++++++++------- .../webclient/templates/webclient/base.html | 4 +- 4 files changed, 164 insertions(+), 54 deletions(-) create mode 100644 evennia/web/webclient/static/webclient/js/plugins/dual_input.js diff --git a/evennia/web/webclient/static/webclient/js/plugins/default_in.js b/evennia/web/webclient/static/webclient/js/plugins/default_in.js index 02fd401706..d6779c8cfb 100644 --- a/evennia/web/webclient/static/webclient/js/plugins/default_in.js +++ b/evennia/web/webclient/static/webclient/js/plugins/default_in.js @@ -8,9 +8,10 @@ let defaultin_plugin = (function () { // // handle the default key triggering onSend() var onKeydown = function (event) { - $("#inputfield").focus(); - if ( (event.which === 13) && (!event.shiftKey) ) { // Enter Key without shift - var inputfield = $("#inputfield"); + var inputfield = $("#inputfield"); + + // Enter Key without shift + if ( inputfield.is(":focus") && (event.which === 13) && (!event.shiftKey) ) { var outtext = inputfield.val(); var lines = outtext.trim().replace(/[\r]+/,"\n").replace(/[\n]+/, "\n").split("\n"); for (var i = 0; i < lines.length; i++) { diff --git a/evennia/web/webclient/static/webclient/js/plugins/dual_input.js b/evennia/web/webclient/static/webclient/js/plugins/dual_input.js new file mode 100644 index 0000000000..5ecce79e82 --- /dev/null +++ b/evennia/web/webclient/static/webclient/js/plugins/dual_input.js @@ -0,0 +1,72 @@ +/* + * + * Dual Input Pane Plugin (Requires splithandler plugin) + * + * This adds a second input window for games that really benefit from having two separate, + * high-complexity commands being created at the same time. + * + * Note: Incompatible with hotbuttons plugin because both Split() the same location + * Split.js doesn't seem to support adding multiple splits at the same level. + */ +plugin_handler.add('dual_input', (function () { + // + // onKeydown check if the second inputfield is focused. + // If so, send the input on '' key. + var onKeydown = function () { + let inputfield = $("#inputfield2"); + if ( inputfield.is(":focus") ) { + if( (event.which === 13) && (!event.shiftKey) ) { + var outtext = inputfield.val(); + var lines = outtext.trim().replace(/[\r\n]+/,"\n").split("\n"); + + for (var i = 0; i < lines.length; i++) { + plugin_handler.onSend( lines[i].trim() ); + } + + inputfield.val(''); + event.preventDefault(); + return true; + } + } + return false; + } + + // + // Initialize me + var init = function() { + // Add buttons to the UI + var input2 = $( [ + '
', + ' ', + '
', + ].join("\n") ); + + // Add second inputform between the existing #main and #inputform, + // replacing the previous gutter div added by the splithandler plugin + $('#input').prev().replaceWith(input2); + + Split(['#main','#input2','#input'], { + sizes: [80,10,10], + direction: 'vertical', + gutterSize: 4, + minSize: [150,50,50], + }); + + $('#inputfield2').css({ + "display": "inline", + "height": "100%", + "width": "100%", + "background-color": "black", + "color": "white", + "padding": "0 .45rem", + "font-size": "1.1rem", + "font-family": "'DejaVu Sans Mono', Consolas, Inconsolata, 'Lucida Console', monospace" + }); + console.log("Dual Input Plugin Initialized."); + } + + return { + init: init, + onKeydown: onKeydown, + } +})()); diff --git a/evennia/web/webclient/static/webclient/js/plugins/history.js b/evennia/web/webclient/static/webclient/js/plugins/history.js index 60b1a2b163..7860547440 100644 --- a/evennia/web/webclient/static/webclient/js/plugins/history.js +++ b/evennia/web/webclient/static/webclient/js/plugins/history.js @@ -6,50 +6,72 @@ let history_plugin = (function () { // Manage history for input line - var history_max = 21; - var history = new Array(); - var history_pos = 0; - - history[0] = ''; // the very latest input is empty for new entry. + var history_max = 20; + var history = {}; + var history_pos = {}; // - // move back in the history - var back = function () { - // step backwards in history stack - history_pos = Math.min(++history_pos, history.length - 1); - return history[history.length - 1 - history_pos]; + // Add a new textarea to track history for. + var track_history_for_id = function(id) { + if( ! history.hasOwnProperty( id ) ) { + history[id] = new Array; + history_pos[id] = -1; + } else { + console.log('IGNORED -- already tracking history for that DOM element!'); + } } // - // move forward in the history - var fwd = function () { - // step forwards in history stack - history_pos = Math.max(--history_pos, 0); - return history[history.length - 1 - history_pos]; + // Return whichever inputfield (if any) is focused, out of the set we are tracking + var get_focused_input = function () { + let inputfield = $( document.activeElement ); + + // is the focused element one of the ones we are tracking history for? + if( history.hasOwnProperty( inputfield.attr('id') ) ) { + return inputfield; + } + return null; + } + + // + // move back from the history (to newer elements) + var back = function (id) { + // step back in history queue, to the most recently stored entry. + if( history_pos[id] >= 0 ) { + history_pos[id]--; + + // if we've stepped "before" the first element of our queue, return new, empty string + if( history_pos[id] == -1 ) { + return ''; + } + } + + return history[id][ history_pos[id] ]; + } + + // + // move forward into the history (to older elements) + var fwd = function (id) { + // step forward in history queue, restricted by bounds checking + if( history_pos[id] < Math.min( history[id].length - 1, history_max - 1 ) ) { + history_pos[id]++; + } + return history[id][ history_pos[id] ]; } // // add a new history line - var add = function (input) { + var add = function (id, input) { // add a new entry to history, don't repeat latest - if (input && input != history[history.length-2]) { - if (history.length >= history_max) { - history.shift(); // kill oldest entry + if (input && input != history[id][0]) { + // make sure to trim the history queue length to 'history_max' + if (history[id].length + 1 >= history_max) { + history[id].pop(); // remove oldest entry from queue } - history[history.length-1] = input; - history[history.length] = ''; + history[id].unshift(input); // add newest entry to beginning of queue } - // reset the position to the last history entry - history_pos = 0; - } - - // - // Add input to the scratch line - var scratch = function (input) { - // Put the input into the last history entry (which is normally empty) - // without making the array larger as with add. - // Allows for in-progress editing to be saved. - history[history.length-1] = input; + // reset the position to the beginning of the queue + history_pos[id] = -1; } // Public @@ -57,39 +79,52 @@ let history_plugin = (function () { // // Handle up arrow and down arrow events. var onKeydown = function(event) { - var code = event.which; - var history_entry = null; - var inputfield = $("#inputfield"); + var keycode = event.which; - if (code === 38) { // Arrow up - history_entry = back(); - } - else if (code === 40) { // Arrow down - history_entry = fwd(); - } + // Is one of the two input fields focused? + let inputfield = get_focused_input(); + if( inputfield != null ) { + let id = inputfield.attr('id') + let history_entry = null; // check the keycode for up/down arrows + if (keycode === 40) { // Arrow down + history_entry = back(id); + } + else if (keycode === 38) { // Arrow up + history_entry = fwd(id); + } - if (history_entry !== null) { - // Performing a history navigation - // replace the text in the input and move the cursor to the end of the new value - inputfield.val(''); - inputfield.blur().focus().val(history_entry); - event.preventDefault(); - return true; + if (history_entry !== null) { + // Performing a history navigation + // replace the text in the input and move the cursor to the end of the new value + inputfield.blur().focus().val(history_entry); + event.preventDefault(); + return true; + } } - return false; } // // Listen for onSend lines to add to history var onSend = function (line) { - add(line); + let inputfield = get_focused_input(); + if( inputfield != null ) { + add(inputfield.attr('id'), line); + } return null; // we are not returning an altered input line } // // Init function var init = function () { + track_history_for_id('inputfield'); // The default inputfield + + // check to see if the dual_input plugin is enabled. + if( !(typeof plugins['dual_input'] === "undefined") ) { + console.log('configuring history tracking for dual_input plugin'); + track_history_for_id('inputfield2'); + } + console.log('History Plugin Initialized.'); } diff --git a/evennia/web/webclient/templates/webclient/base.html b/evennia/web/webclient/templates/webclient/base.html index 0cc4302af4..143f7df926 100644 --- a/evennia/web/webclient/templates/webclient/base.html +++ b/evennia/web/webclient/templates/webclient/base.html @@ -72,8 +72,10 @@ JQuery available. - + + +