")
+ .append( promptfield )
+ .append( inputfield )
+ .appendTo( container.getElement() );
+
+ button.bind("click", function (evnt) {
+ // focus our textarea
+ $( $(evnt.target).siblings(".inputfield")[0] ).focus();
+ // fake a carriage return event
+ var e = $.Event("keydown");
+ e.which = 13;
+ $( $(evnt.target).siblings(".inputfield")[0] ).trigger(e);
+ });
+
+ container.on("tab", onInputCreate);
+ });
+
+ // register the generic "evennia" component
+ myLayout.registerComponent( "evennia", function (container, componentState) {
+ let div = $("");
+ initComponent(div, container, componentState, "all", "newlines");
+ container.on("destroy", calculateUntaggedTypes);
+ });
+ }
+
//
// Public
//
@@ -403,6 +442,42 @@ let goldenlayout = (function () {
}
+ //
+ // Add new HTML message to an existing Div pane, while
+ // honoring the pane's updateMethod and scroll state, etc.
+ //
+ var addMessageToPaneDiv = function (textDiv, message) {
+ let atBottom = false;
+ let updateMethod = textDiv.attr("updateMethod");
+
+ if ( updateMethod === "replace" ) {
+ textDiv.html(message);
+ } else if ( updateMethod === "append" ) {
+ textDiv.append(message);
+ } else { // line feed
+ textDiv.append("
" + message + "
");
+ }
+
+ // Calculate the scrollback state.
+ //
+ // This check helps us avoid scrolling to the bottom when someone is
+ // manually scrolled back, trying to read their backlog.
+ // Auto-scrolling would force them to re-scroll to their previous scroll position.
+ // Which, on fast updating games, destroys the utility of scrolling entirely.
+ //
+ //if( textDiv.scrollTop === (textDiv.scrollHeight - textDiv.offsetHeight) ) {
+ atBottom = true;
+ //}
+
+ // if we are at the bottom of the window already, scroll to display the new content
+ if( atBottom ) {
+ let scrollHeight = textDiv.prop("scrollHeight");
+ let clientHeight = textDiv.prop("clientHeight");
+ textDiv.scrollTop( scrollHeight - clientHeight );
+ }
+ }
+
+
//
// returns an array of pane divs that the given message should be sent to
//
@@ -445,6 +520,49 @@ let goldenlayout = (function () {
}
+ //
+ //
+ var onGotOptions = function (args, kwargs) {
+ // Reset the UI if the JSON layout sent from the server doesn't match the client's current JSON
+ if( ("webclientLayout" in kwargs) && (kwargs["webclientLayout"] !== window.options["webclientLayout"]) ) {
+ var mainsub = document.getElementById("main-sub");
+
+ // rebuild the original HTML stacking
+ var messageDiv = $("#messagewindow").detach();
+ messageDiv.prependTo( mainsub );
+
+ // out with the old
+ myLayout.destroy();
+
+ // in with the new
+ myLayout = new GoldenLayout( JSON.parse( kwargs["webclientLayout"] ), mainsub );
+
+ // re-register our main, input and generic evennia components.
+ registerComponents( myLayout );
+
+ // call all other plugins to give them a chance to registerComponents.
+ for( let plugin in window.plugins ) {
+ if( "onLayoutChange" in window.plugins[plugin] ) {
+ window.plugins[plugin].onLayoutChange();
+ }
+ }
+
+ // finish the setup and actually start GoldenLayout
+ myLayout.init();
+
+ // work out which types are untagged based on our pre-configured layout
+ calculateUntaggedTypes();
+
+ // Set the Event handler for when the client window changes size
+ $(window).bind("resize", scrollAll);
+
+ // Set Save State callback
+ myLayout.on( "stateChanged", onStateChanged );
+
+ return true;
+ }
+ }
+
//
//
var onText = function (args, kwargs) {
@@ -453,11 +571,9 @@ let goldenlayout = (function () {
var msgHandled = false;
divs.forEach( function (div) {
- let updateMethod = div.attr("updateMethod");
let txt = args[0];
-
// yes, so add this text message to the target div
- routeMsg( div, txt, updateMethod );
+ addMessageToPaneDiv( div, txt );
msgHandled = true;
});
@@ -483,14 +599,16 @@ let goldenlayout = (function () {
//
- // required Init me
+ // required Init
var init = function (options) {
// Set up our GoldenLayout instance built off of the default main-sub div
var savedState = localStorage.getItem( "evenniaGoldenLayoutSavedState" );
var mainsub = document.getElementById("main-sub");
if( savedState !== null ) {
- // Overwrite the global-variable configuration with the version from localstorage
+ // Overwrite the global-variable configuration from
+ // webclient/js/plugins/goldenlayout_default_config.js
+ // with the version from localstorage
window.goldenlayout_config = JSON.parse( savedState );
}
@@ -499,56 +617,20 @@ let goldenlayout = (function () {
$("#prompt").remove(); // remove the HTML-defined prompt div
$("#inputcontrol").remove(); // remove the cluttered, HTML-defined input divs
- // register our component and replace the default messagewindow with the Main component
- myLayout.registerComponent( "Main", function (container, componentState) {
- let main = $("#messagewindow").addClass("content");
- initComponent(main, container, componentState, "untagged", "newlines" );
- });
-
- // register our new input component
- myLayout.registerComponent( "input", function (container, componentState) {
- var promptfield = $("");
- var formcontrol = $("");
- var button = $("");
-
- var inputfield = $("
",
- ].join("\n") );
-
- // Add buttons in front of the existing #inputform
- $("#input").prev().replaceWith(buttons);
-
- Split(["#main","#buttons","#input"], {
- sizes: [85,5,10],
- direction: "vertical",
- gutterSize: 4,
- minSize: [150,20,50],
- });
-
- for( var n=0; nDon\'t echo prompts to the main text area',
- ' ',
- '',
- ' ',
- '',
- '',
- ' ',
- '',
- ' ',
- ].join("\n");
-
- // Create a new options Dialog
- plugins['popups'].createDialog( 'optionsdialog', 'Options', content );
- }
-
- //
- // addHelpUI
- var addHelpUI = function () {
- // Create a new Help Dialog
- plugins['popups'].createDialog( 'helpdialog', 'Help', "" );
- }
-
- // addToolbarButton
- var addToolbarButton = function () {
- var optionsbutton = $( [
- '',
- ].join("") );
- $('#toolbar').append( optionsbutton );
- }
-
- //
- // Opens the options dialog
- var doOpenOptions = function () {
- if (!Evennia.isConnected()) {
- alert("You need to be connected.");
- return;
- }
-
- plugins['popups'].togglePopup("#optionsdialog");
- }
-
- //
- // When the user changes a setting from the interface
- var onOptionCheckboxChanged = function () {
- var name = $(this).data("setting");
- var value = this.checked;
-
- var changedoptions = {};
- changedoptions[name] = value;
- Evennia.msg("webclient_options", [], changedoptions);
-
- options[name] = value;
- }
-
- // Public functions
-
- //
- // onKeydown check for 'ESC' key.
- var onKeydown = function (event) {
- var code = event.which;
-
- if (code === 27) { // Escape key
- if ($('#helpdialog').is(':visible')) {
- plugins['popups'].closePopup("#helpdialog");
- return true;
- }
- if ($('#optionsdialog').is(':visible')) {
- plugins['popups'].closePopup("#optionsdialog");
- return true;
- }
- }
- return false;
- }
-
- //
- // Called when options settings are sent from server
- var onGotOptions = function (args, kwargs) {
- options = kwargs;
-
- $.each(kwargs, function(key, value) {
- var elem = $("[data-setting='" + key + "']");
- if (elem.length === 0) {
- console.log("Could not find option: " + key);
- console.log(args);
- console.log(kwargs);
- } else {
- elem.prop('checked', value);
- };
- });
- }
-
- //
- // Called when the user logged in
- var onLoggedIn = function (args, kwargs) {
- $('#optionsbutton').removeClass('hidden');
- Evennia.msg("webclient_options", [], {});
- }
-
- //
- // Display a "prompt" command from the server
- var onPrompt = function (args, kwargs) {
- // also display the prompt in the output window if gagging is disabled
- if (("gagprompt" in options) && (!options["gagprompt"])) {
- plugin_handler.onText(args, kwargs);
- }
-
- // don't claim this Prompt as completed.
- return false;
- }
-
- //
- // Make sure to close any dialogs on connection lost
- var onConnectionClose = function () {
- $('#optionsbutton').addClass('hidden');
- plugins['popups'].closePopup("#optionsdialog");
- plugins['popups'].closePopup("#helpdialog");
- }
-
- //
- // Make sure to close any dialogs on connection lost
- var onText = function (args, kwargs) {
- // is helppopup set? and if so, does this Text have type 'help'?
- if ('helppopup' in options && options['helppopup'] ) {
- if (kwargs && ('type' in kwargs) && (kwargs['type'] == 'help') ) {
- $('#helpdialogcontent').prepend('
'+ args + '
');
- plugins['popups'].togglePopup("#helpdialog");
- return true;
- }
- }
-
- return false;
- }
-
- //
- // Register and init plugin
- var init = function () {
- // Add GUI components
- addOptionsUI();
- addHelpUI();
-
- // Add Options toolbar button.
- addToolbarButton();
-
- // Pressing the settings button
- $("#optionsbutton").bind("click", doOpenOptions);
-
- // Checking a checkbox in the settings dialog
- $("[data-setting]").bind("change", onOptionCheckboxChanged);
-
- console.log('Options Plugin Initialized.');
- }
-
- return {
- init: init,
- onKeydown: onKeydown,
- onLoggedIn: onLoggedIn,
- onGotOptions: onGotOptions,
- onPrompt: onPrompt,
- onConnectionClose: onConnectionClose,
- onText: onText,
- }
-})()
-plugin_handler.add('options', options_plugin);
diff --git a/evennia/web/webclient/static/webclient/js/plugins/options2.js b/evennia/web/webclient/static/webclient/js/plugins/options2.js
index 2e5ff4a410..14063c7c85 100644
--- a/evennia/web/webclient/static/webclient/js/plugins/options2.js
+++ b/evennia/web/webclient/static/webclient/js/plugins/options2.js
@@ -4,7 +4,7 @@
*/
let options2 = (function () {
- var options_container = null ;
+ var optionsContainer = null ;
//
// When the user changes a setting from the interface
@@ -51,35 +51,6 @@ let options2 = (function () {
}
- //
- // Create and register the "options" golden-layout component
- var createOptionsComponent = function () {
- var myLayout = window.plugins["goldenlayout"].getGL();
-
- myLayout.registerComponent( "options", function (container, componentState) {
- var plugins = window.plugins;
- options_container = container.getElement();
-
- // build the buttons
- var div = $("
");
-
- for( let plugin in plugins ) {
- if( "onOptionsUI" in plugins[plugin] ) {
- var card = $("
");
- var body = $("
");
-
- plugins[plugin].onOptionsUI( body );
-
- card.append(body);
- card.appendTo( div );
- }
- }
-
- div.appendTo( options_container );
- });
- }
-
-
// handler for the "Options" button
var onOpenCloseOptions = function () {
var optionsComponent = {
@@ -92,7 +63,7 @@ let options2 = (function () {
// Create a new GoldenLayout tab filled with the optionsComponent above
var myLayout = window.plugins["goldenlayout"].getGL();
- if( ! options_container ) {
+ if( ! optionsContainer ) {
// open new optionsComponent
var main = myLayout.root.getItemsByType("stack")[0].getActiveContentItem();
@@ -102,16 +73,16 @@ let options2 = (function () {
.closeElement
.off("click")
.click( function () {
- options_container = null;
+ optionsContainer = null;
tab.contentItem.remove();
});
- options_container = tab.contentItem;
+ optionsContainer = tab.contentItem;
}
});
main.parent.addChild( optionsComponent );
} else {
- options_container.remove();
- options_container = null;
+ optionsContainer.remove();
+ optionsContainer = null;
}
}
@@ -132,6 +103,34 @@ let options2 = (function () {
});
}
+ //
+ // Create and register the "options" golden-layout component
+ var onLayoutChanged = function () {
+ var myLayout = window.plugins["goldenlayout"].getGL();
+
+ myLayout.registerComponent( "options", function (container, componentState) {
+ var plugins = window.plugins;
+ optionsContainer = container.getElement();
+
+ // build the buttons
+ var div = $("
");
+
+ for( let plugin in plugins ) {
+ if( "onOptionsUI" in plugins[plugin] ) {
+ var card = $("
");
+ var body = $("
");
+
+ plugins[plugin].onOptionsUI( body );
+
+ card.append(body);
+ card.appendTo( div );
+ }
+ }
+
+ div.appendTo( optionsContainer );
+ });
+ }
+
//
// Called when the user logged in
var onLoggedIn = function (args, kwargs) {
@@ -165,7 +164,7 @@ let options2 = (function () {
var postInit = function() {
// Are we using GoldenLayout?
if( window.plugins["goldenlayout"] ) {
- createOptionsComponent();
+ onLayoutChanged();
$("#optionsbutton").bind("click", onOpenCloseOptions);
}
@@ -176,6 +175,7 @@ let options2 = (function () {
init: init,
postInit: postInit,
onGotOptions: onGotOptions,
+ onLayoutChanged: onLayoutChanged,
onLoggedIn: onLoggedIn,
onOptionsUI: onOptionsUI,
onPrompt: onPrompt,