Initial work for webclient Options UI extensions

This commit is contained in:
Brenden Tuck 2019-12-29 10:06:22 -05:00
parent 3c08447f59
commit 04e89bba37
9 changed files with 409 additions and 1 deletions

View file

@ -88,6 +88,10 @@ div {margin:0px;}
height: 100%;
}
.card {
background-color: #333;
}
/* Container surrounding entire client */
#clientwrapper {
height: 100%;

View file

@ -0,0 +1,6 @@
@font-face {
font-family: 'DejaVu Sans Mono';
src: url('/static/webclient/fonts/DejaVuSansMono-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}

View file

@ -0,0 +1,25 @@
/*
*
* Evennia Webclient help plugin
*
*/
let clienthelp_plugin = (function () {
//
//
//
var onOptionsUI = function (parentdiv) {
var help_text = $( [
"<h3>Welcome to Evennia.</h3>",
"<div>This client supports a bunch of features, including<div>",
"<div>drag-and-drop window placement, multiple input windows, and per-window message routing.</div>",
"<div>To get the full details, go to: <a href='http://evennia.com'>Evennia.com</a></div><br>",
].join(""));
parentdiv.append(help_text);
}
return {
init: function () {},
onOptionsUI: onOptionsUI,
}
})();
window.plugin_handler.add("clienthelp", clienthelp_plugin);

View file

@ -0,0 +1,79 @@
/*
*
* Evennia Webclient default "send-text-on-enter-key" IO plugin
*
*/
let font_plugin = (function () {
const font_urls = {
'B612 Mono': 'https://fonts.googleapis.com/css?family=B612+Mono&display=swap',
'Consolas': 'https://fonts.googleapis.com/css?family=Consolas&display=swap',
'DejaVu Sans Mono': '/static/webclient/fonts/DejaVuSansMono.css',
'Fira Mono': 'https://fonts.googleapis.com/css?family=Fira+Mono&display=swap',
'Inconsolata': 'https://fonts.googleapis.com/css?family=Inconsolata&display=swap',
'Monospace': '',
'Roboto Mono': 'https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap',
'Source Code Pro': 'https://fonts.googleapis.com/css?family=Source+Code+Pro&display=swap',
'Ubuntu Mono': 'https://fonts.googleapis.com/css?family=Ubuntu+Mono&display=swap',
};
//
//
//
var onOptionsUI = function (parentdiv) {
var fontselect = $('<select>');
var sizeselect = $('<select>');
var fonts = Object.keys(font_urls);
for (var x = 0; x < fonts.length; x++) {
var option = $('<option value="'+fonts[x]+'">'+fonts[x]+'</option>');
fontselect.append(option);
}
for (var x = 4; x < 21; x++) {
var val = (x/10.0);
var option = $('<option value="'+val+'">'+x+'</option>');
sizeselect.append(option);
}
fontselect.val('DejaVu Sans Mono'); // default value
sizeselect.val('9'); // default value
// font-family change callback
fontselect.on('change', function () {
$(document.body).css('font-family', $(this).val());
});
// font size change callback
sizeselect.on('change', function () {
$(document.body).css('font-size', $(this).val()+"em");
});
// add the font selection dialog control to our parentdiv
parentdiv.append('<h3>Font Selection:</h3>');
parentdiv.append(fontselect);
parentdiv.append(sizeselect);
}
//
// Font plugin init function (adds the urls for the webfonts to the page)
//
var init = function () {
var head = $(document.head);
var fonts = Object.keys(font_urls);
for (var x = 0; x < fonts.length; x++) {
if ( fonts[x] != "Monospace" ) {
var url = font_urls[ fonts[x] ];
var link = $('<link href="'+url+'" rel="stylesheet">');
head.append( link );
}
}
}
return {
init: init,
onOptionsUI: onOptionsUI,
}
})();
window.plugin_handler.add("font", font_plugin);

View file

@ -0,0 +1,68 @@
/*
* IFrame plugin
* REQUIRES: goldenlayout.js
*/
let iframe = (function () {
var url = window.location.origin;
//
// Create iframe component
var createIframeComponent = function () {
var myLayout = window.plugins["goldenlayout"].getGL();
myLayout.registerComponent( "iframe", function (container, componentState) {
// build the iframe
var div = $('<iframe src="' + url + '">');
div.css("width", "100%");
div.css("height", "inherit");
div.appendTo( container.getElement() );
});
}
// handler for the "iframe" button
var onOpenIframe = function () {
var iframeComponent = {
title: url,
type: "component",
componentName: "iframe",
componentState: {
},
};
// Create a new GoldenLayout tab filled with the iframeComponent above
var myLayout = window.plugins["goldenlayout"].getGL();
var main = myLayout.root.getItemsByType("stack")[0].getActiveContentItem();
main.parent.addChild( iframeComponent );
}
// Public
var onOptionsUI = function (parentdiv) {
var iframebutton = $('<input type="button" value="open new iframe" />');
iframebutton.on('click', onOpenIframe);
parentdiv.append( '<h3>Browser iFrame:</h3>' );
parentdiv.append( iframebutton );
}
//
//
var postInit = function() {
// Are we using GoldenLayout?
if( window.plugins["goldenlayout"] ) {
createIframeComponent();
$("#iframebutton").bind("click", onOpenIframe);
}
console.log('IFrame plugin Loaded');
}
return {
init: function () {},
postInit: postInit,
onOptionsUI: onOptionsUI,
}
})();
window.plugin_handler.add("iframe", iframe);

View file

@ -0,0 +1,116 @@
/*
* Spawns plugin
* REQUIRES: goldenlayout.js
*/
let spawns = (function () {
var ignoreDefaultKeydown = false;
var spawnmap = {}; // Mapping of regex/tag-pair
var onAlterRegex = function (evnt) {
var regex = $(evnt.target);
var siblings = regex.siblings();
spawnmap[regex.val()] = siblings.val();
localStorage.setItem( "evenniaMessageRoutingSavedState", JSON.stringify(spawnmap) );
}
var onAlterTag = function (evnt) {
var tag = $(evnt.target);
var siblings = tag.siblings();
spawnmap[siblings.val()] = tag.val();
window.plugins["goldenlayout"].addKnownType( tag.val() );
localStorage.setItem( "evenniaMessageRoutingSavedState", JSON.stringify(spawnmap) );
}
var onFocusIn = function (evnt) {
ignoreDefaultKeydown = true;
}
var onFocusOut = function (evnt) {
ignoreDefaultKeydown = false;
}
var onNewRegexRow = function (formdiv, regexstring, tagstring) {
var div = $('<div>');
var regex = $('<input class="regex" type=text value="'+regexstring+'"/>');
var tag = $('<input class="tag" type=text value="'+tagstring+'"/>');
regex.on('change', onAlterRegex );
regex.on('focusin', onFocusIn );
regex.on('focusout', onFocusOut );
tag.on('change', onAlterTag );
tag.on('focusin', onFocusIn );
tag.on('focusout', onFocusOut );
div.append(regex);
div.append(tag);
formdiv.append(div);
}
// Public
//
// onOptionsUI -- create an expandable/deletable row of regex/tag mapping pairs
//
// If there isn't a window with that tag mapped already, open a new one
//
var onOptionsUI = function (parentdiv) {
var div = $('<div>');
var button= $('<input type="button" value="New Regex/Tag Pair" />');
button.on('click', function () { onNewRegexRow(div, '', ''); });
div.append(button);
for( regex in spawnmap ) {
onNewRegexRow(div, regex, spawnmap[regex] );
}
parentdiv.append('<h3>Message Routing:</h3>');
parentdiv.append(div);
}
//
// onText -- catch Text before it is routed by the goldenlayout router
// then test our list of regexes on the given text to see if it matches.
// If it does, rewrite the Text Type to be our tag value instead.
//
var onText = function (args, kwargs) {
var txt = args[0];
for( regex in spawnmap ) {
if ( txt.match(regex) != null ) {
kwargs['type'] = spawnmap[regex];
}
}
}
//
// OnKeydown -- if the Options window is open, capture focus
//
var onKeydown = function(evnt) {
return ignoreDefaultKeydown;
}
//
// init
//
var init = function () {
var ls_spawnmap = localStorage.getItem( "evenniaMessageRoutingSavedState" );
if( ls_spawnmap ) {
spawnmap = JSON.parse(ls_spawnmap);
for( regex in spawnmap ) {
window.plugins["goldenlayout"].addKnownType( spawnmap[regex] );
}
}
console.log('Client-Side Message Routing plugin initialized');
}
return {
init: init,
onOptionsUI: onOptionsUI,
onText: onText,
onKeydown: onKeydown,
}
})();
window.plugin_handler.add("spawns", spawns);

View file

@ -0,0 +1,103 @@
/*
* Options 2.0
* REQUIRES: goldenlayout.js
*/
let options2 = (function () {
var onGagPrompt = function () { console.log('gagprompt') }
var onNotifyPopup = function () { console.log('notifypopup') }
var onNotifySound = function () { console.log('notifysound') }
var onOptionsUI = function (parentdiv) {
var gagprompt = $('<label><input type="checkbox" data-setting="gagprompt" value="value">Don\'t echo prompts to the main text area</label>');
var notifypopup = $('<label><input type="checkbox" data-setting="notification_popup" value="value">Popup notification</label>');
var notifysound = $('<label><input type="checkbox" data-setting="notification_sound" value="value">Play a sound</label>');
gagprompt.on("change", onGagPrompt);
notifypopup.on("change", onNotifyPopup);
notifysound.on("change", onNotifySound);
parentdiv.append(gagprompt);
parentdiv.append(notifypopup);
parentdiv.append(notifysound);
}
//
// 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;
// build the buttons
var div = $("<div class='accordion' style='overflow-y:scroll; height:inherit;'>");
for( let plugin in plugins ) {
if( 'onOptionsUI' in plugins[plugin] ) {
var card = $("<div class='card'>");
var body = $("<div>");
plugins[plugin].onOptionsUI( body );
card.append(body);
card.appendTo( div );
}
}
div.appendTo( container.getElement() );
});
}
// handler for the "Options" button
var onOpenOptions = function () {
var optionsComponent = {
title: "Options",
type: "component",
componentName: "options",
componentState: {
},
};
// Create a new GoldenLayout tab filled with the optionsComponent above
var myLayout = window.plugins["goldenlayout"].getGL();
var main = myLayout.root.getItemsByType("stack")[0].getActiveContentItem();
main.parent.addChild( optionsComponent );
}
// Public
//
// Handle the Webclient_Options event
var onGotOptions = function(args, kwargs) {
// Pressing the settings button
}
var init = function() {
var optionsbutton = $('<button id="optionsbutton">&#x2699;</button>');
$('#toolbar').append( optionsbutton );
// Pressing the settings button
}
//
//
var postInit = function() {
// Are we using GoldenLayout?
if( window.plugins["goldenlayout"] ) {
createOptionsComponent();
$("#optionsbutton").bind("click", onOpenOptions);
}
console.log('Options2 Loaded');
}
return {
init: init,
postInit: postInit,
onGotOptions: onGotOptions,
onOptionsUI: onOptionsUI,
}
})();
window.plugin_handler.add("options2", options2);

View file

@ -76,9 +76,16 @@ JQuery available.
{% block guilib_import %}
<script src={% static "webclient/js/webclient_gui.js" %} language="javascript" type="text/javascript" charset="utf-8"></script>
<script src={% static "webclient/js/plugins/goldenlayout_default_config.js" %} type="text/javascript"></script>
<script src={% static "webclient/js/plugins/clienthelp.js" %} language="javascript" type="text/javascript" charset="utf-8"></script>
<script src={% static "webclient/js/plugins/popups.js" %} language="javascript" type="text/javascript"></script>
<script src={% static "webclient/js/plugins/options.js" %} language="javascript" type="text/javascript"></script>
<!--
<script src={% static "webclient/js/plugins/options.js" %} language="javascript" type="text/javascript"></script>
-->
<script src={% static "webclient/js/plugins/options2.js" %} language="javascript" type="text/javascript"></script>
<script src={% static "webclient/js/plugins/iframe.js" %} language="javascript" type="text/javascript"></script>
<script src={% static "webclient/js/plugins/message_routing.js" %} language="javascript" type="text/javascript"></script>
<script src={% static "webclient/js/plugins/history.js" %} language="javascript" type="text/javascript"></script>
<script src={% static "webclient/js/plugins/font.js" %} language="javascript" type="text/javascript" charset="utf-8"></script>
<!--
<script src={% static "webclient/js/plugins/splithandler.js" %} language="javascript" type="text/javascript"></script>
-->