mirror of
https://github.com/evennia/evennia.git
synced 2026-03-23 08:16:30 +01:00
Initial work for webclient Options UI extensions
This commit is contained in:
parent
3c08447f59
commit
04e89bba37
9 changed files with 409 additions and 1 deletions
|
|
@ -88,6 +88,10 @@ div {margin:0px;}
|
|||
height: 100%;
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
/* Container surrounding entire client */
|
||||
#clientwrapper {
|
||||
height: 100%;
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
79
evennia/web/webclient/static/webclient/js/plugins/font.js
Normal file
79
evennia/web/webclient/static/webclient/js/plugins/font.js
Normal 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);
|
||||
68
evennia/web/webclient/static/webclient/js/plugins/iframe.js
Normal file
68
evennia/web/webclient/static/webclient/js/plugins/iframe.js
Normal 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);
|
||||
|
|
@ -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);
|
||||
103
evennia/web/webclient/static/webclient/js/plugins/options2.js
Normal file
103
evennia/web/webclient/static/webclient/js/plugins/options2.js
Normal 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">⚙</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);
|
||||
|
|
@ -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>
|
||||
-->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue