Removed SplitHandler from the docs and plugins folder

This commit is contained in:
ChrisLR 2020-10-03 15:41:37 -04:00
parent c44681ebcf
commit 9bb238c3d4
3 changed files with 2 additions and 512 deletions

View file

@ -69,12 +69,11 @@ The order of the plugins defined in `base.html` is important. All the callbacks
* `oob.js` Defines onSend. Allows the user to test/send Out Of Band json messages to the server.
* `options.js` Defines most callbacks. Provides a popup-based UI to coordinate options settings with the server.
* `options2.js` Defines most callbacks. Provides a goldenlayout-based version of the options/settings tab. Integrates with other plugins via the custom onOptionsUI callback.
* `popups.js` Provides default popups/Dialog UI for other plugins to use.
* `splithandler.js` Defines onText. Provides an older, less-flexible alternative to goldenlayout for multi-window UI to automatically separate out screen real-estate by type of message.
* `popups.js` Provides default popups/Dialog UI for other plugins to use.
# Writing your own Plugins
So, you love the functionality of the webclient, but your game has specific types of text that need to be separated out into their own space, visually. There are two plugins to help with this. The Goldenlayout plugin framework, and the older Splithandler framework.
So, you love the functionality of the webclient, but your game has specific types of text that need to be separated out into their own space, visually. The Goldenlayout plugin framework can help with this.
## GoldenLayout
@ -189,73 +188,3 @@ window.plugin_handler.add("myplugin", myplugin);
You can then add "mycomponent" to an item's componentName in your goldenlayout_default_config.js.
Make sure to stop your server, evennia collectstatic, and restart your server. Then make sure to clear your browser cache before loading the webclient page.
## Older Splithandler
The splithandler.js plugin provides a means to do this, but you don't want to have to force every player to set up their own layout every time they use the client.
Let's create a `mygame/web/static_overrides/webclient/js/plugins/layout.js` plugin!
First up, follow the directions in Customizing the Web Client section above to override the base.html.
Next, add the new plugin to your copy of base.html:
```
<script src={% static "webclient/js/plugins/layout.js" %} language="javascript" type="text/javascript"></script>
```
Remember, plugins are load-order dependent, so make sure the new `<script>` tag comes after the splithandler.js
And finally create the layout.js file and add the minimum skeleton of a plugin to it:
```
// my new plugin
var my_plugin = (function () {
let init = function () {
console.log("myplugin! Hello World!");
}
return {
init: init,
}
})();
plugin_handler.add("myplugin", my_plugin);
```
Now, `evennia stop`, `evennia collectstatic`, and `evennia start` and then load the webclient up in your browser.
Enable developer options and look in the console, and you should see the message 'myplugin! Hello World!'
Since our layout.js plugin is going to use the splithandler, let's enhance this by adding a check to make sure the splithandler.js plugin has been loaded:
change the above init function to:
```
let init = function () {
let splithandler = plugins['splithandler'];
if( splithandler ) {
console.log("MyPlugin initialized");
} else {
alert('MyPlugin requires the splithandler.js plugin. Please contact the game maintainer to correct this');
}
}
```
And finally, the splithandler.js provides provides two functions to cut up the screen real-estate:
`dynamic_split( pane_name_to_cut_apart, direction_of_split, new_pane_name1, new_pane_name2, text_flow_pane1, text_flow_pane2, array_of_split_percentages )`
and
`set_pane_types( pane_to_set, array_of_known_message_types_to_assign)`
In this case, we'll cut it into 3 panes, 1 bigger, two smaller, and assign 'help' messages to the top-right pane:
```
let init = function () {
let splithandler = plugins['splithandler'];
if( splithandler ) {
splithandler.dynamic_split("main","horizontal","left","right","linefeed","linefeed",[50,50]);
splithandler.dynamic_split("right","vertical","help","misc","replace","replace",[50,50]);
splithandler.set_pane_types('help', ['help']);
console.log("MyPlugin initialized");
} else {
alert('MyPlugin requires the splithandler.js plugin. Please contact the game maintainer to correct this');
}
}
```
`evennia stop`, `evennia collectstatic`, and `evennia start` once more, and force-reload your browser page to clear any cached version. You should now have a nicely split layout.

View file

@ -1,438 +0,0 @@
/*
*
* Plugin to use split.js to create a basic windowed ui
*
*/
let splithandler_plugin = (function () {
var num_splits = 0;
var split_panes = {};
var backout_list = [];
var known_types = ['all', 'rest'];
// Exported Functions
//
// function to assign "Text types to catch" to a pane
var set_pane_types = function (splitpane, types) {
split_panes[splitpane]['types'] = types;
}
//
// Add buttons to the Evennia webcilent toolbar
function addToolbarButtons () {
var toolbar = $('#toolbar');
toolbar.append( $('<button id="splitbutton" type="button">&#x21f9;</button>') );
toolbar.append( $('<button id="panebutton" type="button">&#x2699;</button>') );
toolbar.append( $('<button id="undobutton" type="button">&#x21B6;</button>') );
$('#undobutton').hide();
}
function addSplitDialog () {
plugins['popups'].createDialog('splitdialog', 'Split Pane', '');
}
function addPaneDialog () {
plugins['popups'].createDialog('panedialog', 'Assign Pane Options', '');
}
//
// Handle resizing the InputField after a client resize event so that the splits dont get too big.
function resizeInputField () {
var wrapper = $("#inputform")
var input = $("#inputcontrol")
var prompt = $("#prompt")
input.height( wrapper.height() - (input.offset().top - wrapper.offset().top) );
}
//
// Handle resizing of client
function doWindowResize() {
var resizable = $("[data-update-append]");
var parents = resizable.closest(".split");
resizeInputField();
parents.animate({
scrollTop: parents.prop("scrollHeight")
}, 0);
}
//
// create a new UI split
var dynamic_split = function (splitpane, direction, pane_name1, pane_name2, update_method1, update_method2, sizes) {
// find the sub-div of the pane we are being asked to split
splitpanesub = splitpane + '-sub';
// create the new div stack to replace the sub-div with.
var first_div = $( '<div id="'+pane_name1+'" class="split split-'+direction+'" />' )
var first_sub = $( '<div id="'+pane_name1+'-sub" class="split-sub" />' )
var second_div = $( '<div id="'+pane_name2+'" class="split split-'+direction+'" />' )
var second_sub = $( '<div id="'+pane_name2+'-sub" class="split-sub" />' )
// check to see if this sub-pane contains anything
contents = $('#'+splitpanesub).contents();
if( contents ) {
// it does, so move it to the first new div-sub (TODO -- selectable between first/second?)
contents.appendTo(first_sub);
}
first_div.append( first_sub );
second_div.append( second_sub );
// update the split_panes array to remove this pane name, but store it for the backout stack
var backout_settings = split_panes[splitpane];
delete( split_panes[splitpane] );
// now vaporize the current split_N-sub placeholder and create two new panes.
$('#'+splitpane).append(first_div);
$('#'+splitpane).append(second_div);
$('#'+splitpane+'-sub').remove();
// And split
Split(['#'+pane_name1,'#'+pane_name2], {
direction: direction,
sizes: sizes,
gutterSize: 4,
minSize: [50,50],
});
// store our new split sub-divs for future splits/uses by the main UI.
split_panes[pane_name1] = { 'types': [], 'update_method': update_method1 };
split_panes[pane_name2] = { 'types': [], 'update_method': update_method2 };
// add our new split to the backout stack
backout_list.push( {'pane1': pane_name1, 'pane2': pane_name2, 'undo': backout_settings} );
$('#undobutton').show();
}
//
// Reverse the last UI split
var undo_split = function () {
// pop off the last split pair
var back = backout_list.pop();
if( !back ) {
return;
}
if( backout_list.length === 0 ) {
$('#undobutton').hide();
}
// Collect all the divs/subs in play
var pane1 = back['pane1'];
var pane2 = back['pane2'];
var pane1_sub = $('#'+pane1+'-sub');
var pane2_sub = $('#'+pane2+'-sub');
var pane1_parent = $('#'+pane1).parent();
var pane2_parent = $('#'+pane2).parent();
if( pane1_parent.attr('id') != pane2_parent.attr('id') ) {
// sanity check failed...somebody did something weird...bail out
console.log( pane1 );
console.log( pane2 );
console.log( pane1_parent );
console.log( pane2_parent );
return;
}
// create a new sub-pane in the panes parent
var parent_sub = $( '<div id="'+pane1_parent.attr('id')+'-sub" class="split-sub" />' )
// check to see if the special #messagewindow is in either of our sub-panes.
var msgwindow = pane1_sub.find('#messagewindow')
if( !msgwindow ) {
//didn't find it in pane 1, try pane 2
msgwindow = pane2_sub.find('#messagewindow')
}
if( msgwindow ) {
// It is, so collect all contents into it instead of our parent_sub div
// then move it to parent sub div, this allows future #messagewindow divs to flow properly
msgwindow.append( pane1_sub.contents() );
msgwindow.append( pane2_sub.contents() );
parent_sub.append( msgwindow );
} else {
//didn't find it, so move the contents of the two panes' sub-panes into the new sub-pane
parent_sub.append( pane1_sub.contents() );
parent_sub.append( pane2_sub.contents() );
}
// clear the parent
pane1_parent.empty();
// add the new sub-pane back to the parent div
pane1_parent.append(parent_sub);
// pull the sub-div's from split_panes
delete split_panes[pane1];
delete split_panes[pane2];
// add our parent pane back into the split_panes list for future splitting
split_panes[pane1_parent.attr('id')] = back['undo'];
}
//
// UI elements
//
//
// Draw "Split Controls" Dialog
var onSplitDialog = function () {
var dialog = $("#splitdialogcontent");
dialog.empty();
var selection = '<select name="pane">';
for ( var pane in split_panes ) {
selection = selection + '<option value="' + pane + '">' + pane + '</option>';
}
selection = "Pane to split: " + selection + "</select> ";
dialog.append(selection);
dialog.append('<input type="radio" name="direction" value="vertical" checked>top/bottom </>');
dialog.append('<input type="radio" name="direction" value="horizontal">side-by-side <hr />');
dialog.append('Pane 1: <input type="text" name="new_pane1" value="" />');
dialog.append('<input type="radio" name="flow1" value="linefeed" checked>newlines </>');
dialog.append('<input type="radio" name="flow1" value="replace">replace </>');
dialog.append('<input type="radio" name="flow1" value="append">append <hr />');
dialog.append('Pane 2: <input type="text" name="new_pane2" value="" />');
dialog.append('<input type="radio" name="flow2" value="linefeed" checked>newlines </>');
dialog.append('<input type="radio" name="flow2" value="replace">replace </>');
dialog.append('<input type="radio" name="flow2" value="append">append <hr />');
dialog.append('<div id="splitclose" class="btn btn-large btn-outline-primary float-right">Split</div>');
$("#splitclose").bind("click", onSplitDialogClose);
plugins['popups'].togglePopup("#splitdialog");
}
//
// Close "Split Controls" Dialog
var onSplitDialogClose = function () {
var pane = $("select[name=pane]").val();
var direction = $("input[name=direction]:checked").attr("value");
var new_pane1 = $("input[name=new_pane1]").val();
var new_pane2 = $("input[name=new_pane2]").val();
var flow1 = $("input[name=flow1]:checked").attr("value");
var flow2 = $("input[name=flow2]:checked").attr("value");
if( new_pane1 == "" ) {
new_pane1 = 'pane_'+num_splits;
num_splits++;
}
if( new_pane2 == "" ) {
new_pane2 = 'pane_'+num_splits;
num_splits++;
}
if( document.getElementById(new_pane1) ) {
alert('An element: "' + new_pane1 + '" already exists');
return;
}
if( document.getElementById(new_pane2) ) {
alert('An element: "' + new_pane2 + '" already exists');
return;
}
dynamic_split( pane, direction, new_pane1, new_pane2, flow1, flow2, [50,50] );
plugins['popups'].closePopup("#splitdialog");
}
//
// Draw "Pane Controls" dialog
var onPaneControlDialog = function () {
var dialog = $("#panedialogcontent");
dialog.empty();
var selection = '<select name="assign-pane">';
for ( var pane in split_panes ) {
selection = selection + '<option value="' + pane + '">' + pane + '</option>';
}
selection = "Assign to pane: " + selection + "</select> <hr />";
dialog.append(selection);
var multiple = '<select multiple name="assign-type">';
for ( var type in known_types ) {
multiple = multiple + '<option value="' + known_types[type] + '">' + known_types[type] + '</option>';
}
multiple = "Content types: " + multiple + "</select> <hr />";
dialog.append(multiple);
dialog.append('<div id="paneclose" class="btn btn-large btn-outline-primary float-right">Assign</div>');
$("#paneclose").bind("click", onPaneControlDialogClose);
plugins['popups'].togglePopup("#panedialog");
}
//
// Close "Pane Controls" dialog
var onPaneControlDialogClose = function () {
var pane = $("select[name=assign-pane]").val();
var types = $("select[name=assign-type]").val();
// var types = new Array;
// $('#splitdialogcontent input[type=checkbox]:checked').each(function() {
// types.push( $(this).attr('value') );
// });
set_pane_types( pane, types );
plugins['popups'].closePopup("#panedialog");
}
//
// helper function sending text to a pane
var txtToPane = function (panekey, txt) {
var pane = split_panes[panekey];
var text_div = $('#' + panekey + '-sub');
if ( pane['update_method'] == 'replace' ) {
text_div.html(txt)
} else if ( pane['update_method'] == 'append' ) {
text_div.append(txt);
var scrollHeight = text_div.parent().prop("scrollHeight");
text_div.parent().animate({ scrollTop: scrollHeight }, 0);
} else { // line feed
text_div.append("<div class='out'>" + txt + "</div>");
var scrollHeight = text_div.parent().prop("scrollHeight");
text_div.parent().animate({ scrollTop: scrollHeight }, 0);
}
}
//
// plugin functions
//
//
// Accept plugin onText events
var onText = function (args, kwargs) {
// If the message is not itself tagged, we'll assume it
// should go into any panes with 'all' or 'rest' set
var msgtype = "rest";
if ( kwargs && 'type' in kwargs ) {
msgtype = kwargs['type'];
if ( ! known_types.includes(msgtype) ) {
// this is a new output type that can be mapped to panes
console.log('detected new output type: ' + msgtype)
known_types.push(msgtype);
}
}
var target_panes = [];
var rest_panes = [];
for (var key in split_panes) {
var pane = split_panes[key];
// is this message type mapped to this pane (or does the pane has an 'all' type)?
if (pane['types'].length > 0) {
if (pane['types'].includes(msgtype) || pane['types'].includes('all')) {
target_panes.push(key);
} else if (pane['types'].includes('rest')) {
// store rest-panes in case we have no explicit to send to
rest_panes.push(key);
}
} else {
// unassigned panes are assumed to be rest-panes too
rest_panes.push(key);
}
}
var ntargets = target_panes.length;
var nrests = rest_panes.length;
if (ntargets > 0) {
// we have explicit target panes to send to
for (var i=0; i<ntargets; i++) {
txtToPane(target_panes[i], args[0]);
}
return true;
} else if (nrests > 0) {
// no targets, send remainder to rest-panes/unassigned
for (var i=0; i<nrests; i++) {
txtToPane(rest_panes[i], args[0]);
}
return true;
}
// unhandled message
return false;
}
//
// onKeydown check for 'ESC' key.
var onKeydown = function (event) {
var code = event.which;
if (code === 27) { // Escape key
if ($('#splitdialog').is(':visible')) {
plugins['popups'].closePopup("#splitdialog");
return true;
}
if ($('#panedialog').is(':visible')) {
plugins['popups'].closePopup("#panedialog");
return true;
}
}
// capture all keys while one of our "modal" dialogs is open
if ($('#splitdialogcontent').is(':visible') || $('#panedialogcontent').is(':visible')) {
return true;
}
return false;
}
//
// Required plugin "init" function
var init = function(settings) {
known_types.push('help');
Split(['#main','#input'], {
direction: 'vertical',
sizes: [90,10],
gutterSize: 4,
minSize: [50,50],
});
split_panes['main'] = { 'types': [], 'update_method': 'linefeed' };
// Create our UI
addToolbarButtons();
addSplitDialog();
addPaneDialog();
// Register our utility button events
$("#splitbutton").bind("click", onSplitDialog);
$("#panebutton").bind("click", onPaneControlDialog);
$("#undobutton").bind("click", undo_split);
// Event when client window changes
$(window).bind("resize", doWindowResize);
$("[data-role-input]").bind("resize", doWindowResize)
.bind("paste", resizeInputField)
.bind("cut", resizeInputField);
// Event when any key is pressed
$(document).keyup(resizeInputField);
console.log("Splithandler Plugin Initialized.");
}
return {
init: init,
onText: onText,
dynamic_split: dynamic_split,
undo_split: undo_split,
set_pane_types: set_pane_types,
onKeydown: onKeydown,
}
})()
plugin_handler.add('splithandler', splithandler_plugin);

View file

@ -64,7 +64,6 @@ JQuery available.
<!-- set up splits before loading the GUI -->
<!--
<script src="https://unpkg.com/split.js@1.5.9/dist/split.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.min.js"></script>
-->
<script type="text/javascript" src="https://golden-layout.com/files/latest/js/goldenlayout.min.js"></script>