Alpha webclient split interface support
This commit is contained in:
parent
6783d5faa0
commit
b55638b622
5 changed files with 434 additions and 178 deletions
|
|
@ -8,10 +8,11 @@
|
||||||
--- */
|
--- */
|
||||||
|
|
||||||
/* Overall element look */
|
/* Overall element look */
|
||||||
html, body, #clientwrapper { height: 100% }
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
background: #000;
|
background: #000;
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
font-size: .9em;
|
font-size: .9em;
|
||||||
|
|
@ -19,6 +20,12 @@ body {
|
||||||
line-height: 1.6em;
|
line-height: 1.6em;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
@media screen and (max-width: 480px) {
|
||||||
|
body {
|
||||||
|
font-size: .5rem;
|
||||||
|
line-height: .7rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
a:link, a:visited { color: inherit; }
|
a:link, a:visited { color: inherit; }
|
||||||
|
|
@ -74,93 +81,75 @@ div {margin:0px;}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Style specific classes corresponding to formatted, narative text. */
|
/* Style specific classes corresponding to formatted, narative text. */
|
||||||
|
.wrapper {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
/* Container surrounding entire client */
|
/* Container surrounding entire client */
|
||||||
#wrapper {
|
#clientwrapper {
|
||||||
position: relative;
|
height: 100%;
|
||||||
height: 100%
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Main scrolling message area */
|
/* Main scrolling message area */
|
||||||
|
|
||||||
#messagewindow {
|
#messagewindow {
|
||||||
position: absolute;
|
overflow-y: auto;
|
||||||
overflow: auto;
|
overflow-x: hidden;
|
||||||
padding: 1em;
|
overflow-wrap: break-word;
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 70px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Input area containing input field and button */
|
#messagewindow {
|
||||||
#inputform {
|
overflow-y: auto;
|
||||||
position: absolute;
|
overflow-x: hidden;
|
||||||
width: 100%;
|
overflow-wrap: break-word;
|
||||||
padding: 0;
|
|
||||||
bottom: 0;
|
|
||||||
margin: 0;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
border-top: 1px solid #555;
|
|
||||||
}
|
|
||||||
|
|
||||||
#inputcontrol {
|
|
||||||
width: 100%;
|
|
||||||
padding: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Input field */
|
/* Input field */
|
||||||
#inputfield, #inputsend, #inputsizer {
|
#inputfield, #inputsizer {
|
||||||
display: block;
|
height: 100%;
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
height: 50px;
|
|
||||||
background: #000;
|
background: #000;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
padding: 0 .45em;
|
padding: 0 .45rem;
|
||||||
font-size: 1.1em;
|
font-size: 1.1rem;
|
||||||
font-family: 'DejaVu Sans Mono', Consolas, Inconsolata, 'Lucida Console', monospace;
|
font-family: 'DejaVu Sans Mono', Consolas, Inconsolata, 'Lucida Console', monospace;
|
||||||
}
|
|
||||||
|
|
||||||
#inputfield, #inputsizer {
|
|
||||||
float: left;
|
|
||||||
width: 95%;
|
|
||||||
border: 0;
|
|
||||||
resize: none;
|
resize: none;
|
||||||
line-height: normal;
|
}
|
||||||
|
#inputsend {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
#inputcontrol {
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#inputfield:focus {
|
#inputfield:focus {
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#inputsizer {
|
|
||||||
margin-left: -9999px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Input 'send' button */
|
|
||||||
#inputsend {
|
|
||||||
float: right;
|
|
||||||
width: 3%;
|
|
||||||
max-width: 25px;
|
|
||||||
margin-right: 10px;
|
|
||||||
border: 0;
|
|
||||||
background: #555;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prompt area above input field */
|
/* prompt area above input field */
|
||||||
#prompt {
|
.prompt {
|
||||||
margin-top: 10px;
|
max-height: 3rem;
|
||||||
padding: 0 .45em;
|
}
|
||||||
|
|
||||||
|
.splitbutton {
|
||||||
|
position: absolute;
|
||||||
|
right: 1%;
|
||||||
|
top: 1%;
|
||||||
|
z-index: 1;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
font-size: 2rem;
|
||||||
|
color: #a6a6a6;
|
||||||
|
background-color: transparent;
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.splitbutton:hover {
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#optionsbutton {
|
#optionsbutton {
|
||||||
width: 40px;
|
width: 2rem;
|
||||||
font-size: 20px;
|
font-size: 2rem;
|
||||||
color: #a6a6a6;
|
color: #a6a6a6;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border: 0px;
|
border: 0px;
|
||||||
|
|
@ -173,8 +162,8 @@ div {margin:0px;}
|
||||||
|
|
||||||
#toolbar {
|
#toolbar {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: .5rem;
|
||||||
right: 5px;
|
right: .5rem;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,6 +237,48 @@ div {margin:0px;}
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
.gutter.gutter-vertical {
|
||||||
|
cursor: row-resize;
|
||||||
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFAQMAAABo7865AAAABlBMVEVHcEzMzMzyAv2sAAAAAXRSTlMAQObYZgAAABBJREFUeF5jOAMEEAIEEFwAn3kMwcB6I2AAAAAASUVORK5CYII=')
|
||||||
|
}
|
||||||
|
|
||||||
|
.gutter.gutter-horizontal {
|
||||||
|
cursor: col-resize;
|
||||||
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==')
|
||||||
|
}
|
||||||
|
|
||||||
|
.split {
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
border: 1px solid #C0C0C0;
|
||||||
|
box-shadow: inset 0 1px 2px #e4e4e4;
|
||||||
|
background-color: black;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 480px) {
|
||||||
|
.content {
|
||||||
|
padding: .5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.gutter {
|
||||||
|
background-color: grey;
|
||||||
|
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.split.split-horizontal, .gutter.gutter-horizontal {
|
||||||
|
height: 100%;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
/* XTERM256 colors */
|
/* XTERM256 colors */
|
||||||
|
|
||||||
|
|
|
||||||
77
evennia/web/webclient/static/webclient/js/splithandler.js
Normal file
77
evennia/web/webclient/static/webclient/js/splithandler.js
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
// Use split.js to create a basic ui
|
||||||
|
var SplitHandler = (function () {
|
||||||
|
var num_splits = 0;
|
||||||
|
var split_panes = {};
|
||||||
|
|
||||||
|
var set_pane_types = function(splitpane, types) {
|
||||||
|
split_panes[splitpane]['types'] = types;
|
||||||
|
}
|
||||||
|
|
||||||
|
var dynamic_split = function(splitpane, direction, update_method1, update_method2) {
|
||||||
|
var first = ++num_splits;
|
||||||
|
var second = ++num_splits;
|
||||||
|
|
||||||
|
var first_div = $( '<div id="split_'+first +'" class="split split-'+direction+'" />' )
|
||||||
|
var first_sub = $( '<div id="split_'+first +'-sub"/>' )
|
||||||
|
var second_div = $( '<div id="split_'+second+'" class="split split-'+direction+'" />' )
|
||||||
|
var second_sub = $( '<div id="split_'+second+'-sub"/>' )
|
||||||
|
|
||||||
|
// check to see if this pane contains the primary message window.
|
||||||
|
contents = $('#'+splitpane).contents();
|
||||||
|
if( contents ) {
|
||||||
|
// it does, so move it to the first new div (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 split
|
||||||
|
delete( split_panes[splitpane] );
|
||||||
|
|
||||||
|
// now vaporize the current split_N-sub placeholder and create two new panes.
|
||||||
|
$('#'+splitpane).parent().append(first_div);
|
||||||
|
$('#'+splitpane).parent().append(second_div);
|
||||||
|
$('#'+splitpane).remove();
|
||||||
|
|
||||||
|
// And split
|
||||||
|
Split(['#split_'+first,'#split_'+second], {
|
||||||
|
direction: direction,
|
||||||
|
sizes: [50,50],
|
||||||
|
gutterSize: 4,
|
||||||
|
minSize: [50,50],
|
||||||
|
});
|
||||||
|
|
||||||
|
// store our new splits for future splits/uses by the main UI.
|
||||||
|
split_panes['split_'+first +'-sub'] = { 'types': [], 'update_method': update_method1 };
|
||||||
|
split_panes['split_'+second+'-sub'] = { 'types': [], 'update_method': update_method2 };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var init = function(settings) {
|
||||||
|
//change Mustache tags to ruby-style (Django gets mad otherwise)
|
||||||
|
var customTags = [ '<%', '%>' ];
|
||||||
|
Mustache.tags = customTags;
|
||||||
|
|
||||||
|
var input_template = $('#input-template').html();
|
||||||
|
Mustache.parse(input_template);
|
||||||
|
|
||||||
|
Split(['#main','#input'], {
|
||||||
|
direction: 'vertical',
|
||||||
|
sizes: [90,10],
|
||||||
|
gutterSize: 4,
|
||||||
|
minSize: [50,50],
|
||||||
|
});
|
||||||
|
|
||||||
|
var input_render = Mustache.render(input_template);
|
||||||
|
$('[data-role-input]').html(input_render);
|
||||||
|
console.log("SplitHandler initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
init: init,
|
||||||
|
set_pane_types: set_pane_types,
|
||||||
|
dynamic_split: dynamic_split,
|
||||||
|
split_panes: split_panes,
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
@ -17,6 +17,10 @@
|
||||||
|
|
||||||
|
|
||||||
var options = {};
|
var options = {};
|
||||||
|
|
||||||
|
var known_types = new Array();
|
||||||
|
known_types.push('help');
|
||||||
|
|
||||||
//
|
//
|
||||||
// GUI Elements
|
// GUI Elements
|
||||||
//
|
//
|
||||||
|
|
@ -106,6 +110,7 @@ function togglePopup(dialogname, content) {
|
||||||
|
|
||||||
// Grab text from inputline and send to Evennia
|
// Grab text from inputline and send to Evennia
|
||||||
function doSendText() {
|
function doSendText() {
|
||||||
|
console.log("sending text");
|
||||||
if (!Evennia.isConnected()) {
|
if (!Evennia.isConnected()) {
|
||||||
var reconnect = confirm("Not currently connected. Reconnect?");
|
var reconnect = confirm("Not currently connected. Reconnect?");
|
||||||
if (reconnect) {
|
if (reconnect) {
|
||||||
|
|
@ -158,6 +163,10 @@ function onKeydown (event) {
|
||||||
var code = event.which;
|
var code = event.which;
|
||||||
var history_entry = null;
|
var history_entry = null;
|
||||||
var inputfield = $("#inputfield");
|
var inputfield = $("#inputfield");
|
||||||
|
if (code === 9) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
inputfield.focus();
|
inputfield.focus();
|
||||||
|
|
||||||
if (code === 13) { // Enter key sends text
|
if (code === 13) { // Enter key sends text
|
||||||
|
|
@ -205,64 +214,68 @@ function onKeyPress (event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var resizeInputField = function () {
|
var resizeInputField = function () {
|
||||||
var min_height = 50;
|
|
||||||
var max_height = 300;
|
|
||||||
var prev_text_len = 0;
|
|
||||||
|
|
||||||
// Check to see if we should change the height of the input area
|
|
||||||
return function() {
|
return function() {
|
||||||
var inputfield = $("#inputfield");
|
var wrapper = $("#inputform")
|
||||||
var scrollh = inputfield.prop("scrollHeight");
|
var input = $("#inputcontrol")
|
||||||
var clienth = inputfield.prop("clientHeight");
|
var prompt = $("#prompt")
|
||||||
var newh = 0;
|
|
||||||
var curr_text_len = inputfield.val().length;
|
|
||||||
|
|
||||||
if (scrollh > clienth && scrollh <= max_height) {
|
input.height(wrapper.height() - (input.offset().top - wrapper.offset().top));
|
||||||
// Need to make it bigger
|
|
||||||
newh = scrollh;
|
|
||||||
}
|
|
||||||
else if (curr_text_len < prev_text_len) {
|
|
||||||
// There is less text in the field; try to make it smaller
|
|
||||||
// To avoid repaints, we draw the text in an offscreen element and
|
|
||||||
// determine its dimensions.
|
|
||||||
var sizer = $('#inputsizer')
|
|
||||||
.css("width", inputfield.prop("clientWidth"))
|
|
||||||
.text(inputfield.val());
|
|
||||||
newh = sizer.prop("scrollHeight");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newh != 0) {
|
|
||||||
newh = Math.min(newh, max_height);
|
|
||||||
if (clienth != newh) {
|
|
||||||
inputfield.css("height", newh + "px");
|
|
||||||
doWindowResize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prev_text_len = curr_text_len;
|
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
|
|
||||||
// Handle resizing of client
|
// Handle resizing of client
|
||||||
function doWindowResize() {
|
function doWindowResize() {
|
||||||
var formh = $('#inputform').outerHeight(true);
|
resizeInputField();
|
||||||
var message_scrollh = $("#messagewindow").prop("scrollHeight");
|
var resizable = $("[data-update-append]");
|
||||||
$("#messagewindow")
|
var parents = resizable.closest(".split")
|
||||||
.css({"bottom": formh}) // leave space for the input form
|
parents.animate({
|
||||||
.scrollTop(message_scrollh); // keep the output window scrolled to the bottom
|
scrollTop: parents.prop("scrollHeight")
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle text coming from the server
|
// Handle text coming from the server
|
||||||
function onText(args, kwargs) {
|
function onText(args, kwargs) {
|
||||||
// append message to previous ones, then scroll so latest is at
|
var use_default_pane = true;
|
||||||
// the bottom. Send 'cls' kwarg to modify the output class.
|
|
||||||
var renderto = "main";
|
if ( kwargs && 'type' in kwargs ) {
|
||||||
if (kwargs["type"] == "help") {
|
var 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( msgtype == 'help' ) {
|
||||||
if (("helppopup" in options) && (options["helppopup"])) {
|
if (("helppopup" in options) && (options["helppopup"])) {
|
||||||
renderto = "#helpdialog";
|
openPopup("#helpdialog", args[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// fall through to the default output
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// pass this message to each pane that has this msgtype mapped
|
||||||
|
if( SplitHandler ) {
|
||||||
|
for ( var key in SplitHandler.split_panes) {
|
||||||
|
var pane = SplitHandler.split_panes[key];
|
||||||
|
console.log(pane);
|
||||||
|
// is this message type mapped to this pane?
|
||||||
|
if ( (pane['types'].length > 0) && pane['types'].includes(msgtype) ) {
|
||||||
|
// yes, so append/replace this pane's inner div with this message
|
||||||
|
if ( pane['update_method'] == 'replace' ) {
|
||||||
|
$('#'+key).html(args[0])
|
||||||
|
} else {
|
||||||
|
$('#'+key).append(args[0]).animate({ scrollTop: document.getElementById("#"+key).scrollHeight }, 0);
|
||||||
|
}
|
||||||
|
// record sending this message to a pane, no need to update the default div
|
||||||
|
use_default_pane = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderto == "main") {
|
// append message to default pane, then scroll so latest is at the bottom.
|
||||||
|
if(use_default_pane) {
|
||||||
var mwin = $("#messagewindow");
|
var mwin = $("#messagewindow");
|
||||||
var cls = kwargs == null ? 'out' : kwargs['cls'];
|
var cls = kwargs == null ? 'out' : kwargs['cls'];
|
||||||
mwin.append("<div class='" + cls + "'>" + args[0] + "</div>");
|
mwin.append("<div class='" + cls + "'>" + args[0] + "</div>");
|
||||||
|
|
@ -271,8 +284,6 @@ function onText(args, kwargs) {
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
onNewLine(args[0], null);
|
onNewLine(args[0], null);
|
||||||
} else {
|
|
||||||
openPopup(renderto, args[0]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -377,7 +388,10 @@ function onNewLine(text, originator) {
|
||||||
document.title = "(" + unread + ") " + originalTitle;
|
document.title = "(" + unread + ") " + originalTitle;
|
||||||
if ("Notification" in window){
|
if ("Notification" in window){
|
||||||
if (("notification_popup" in options) && (options["notification_popup"])) {
|
if (("notification_popup" in options) && (options["notification_popup"])) {
|
||||||
Notification.requestPermission().then(function(result) {
|
// There is a Promise-based API for this, but it’s not supported
|
||||||
|
// in Safari and some older browsers:
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/Notification/requestPermission#Browser_compatibility
|
||||||
|
Notification.requestPermission(function(result) {
|
||||||
if(result === "granted") {
|
if(result === "granted") {
|
||||||
var title = originalTitle === "" ? "Evennia" : originalTitle;
|
var title = originalTitle === "" ? "Evennia" : originalTitle;
|
||||||
var options = {
|
var options = {
|
||||||
|
|
@ -427,6 +441,81 @@ function doStartDragDialog(event) {
|
||||||
$(document).bind("mouseup", undrag);
|
$(document).bind("mouseup", undrag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function onSplitDialogClose() {
|
||||||
|
var pane = $("input[name=pane]:checked").attr("value");
|
||||||
|
var direction = $("input[name=direction]:checked").attr("value");
|
||||||
|
var flow1 = $("input[name=flow1]:checked").attr("value");
|
||||||
|
var flow2 = $("input[name=flow2]:checked").attr("value");
|
||||||
|
|
||||||
|
SplitHandler.dynamic_split( pane, direction, flow1, flow2 );
|
||||||
|
|
||||||
|
closePopup("#splitdialog");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function onSplitDialog() {
|
||||||
|
var dialog = $("#splitdialogcontent");
|
||||||
|
dialog.empty();
|
||||||
|
|
||||||
|
dialog.append("<h3>Split?</h3>");
|
||||||
|
dialog.append('<input type="radio" name="direction" value="vertical" checked> top/bottom<br />');
|
||||||
|
dialog.append('<input type="radio" name="direction" value="horizontal"> side-by-side<br />');
|
||||||
|
|
||||||
|
dialog.append("<h3>Split Which Pane?</h3>");
|
||||||
|
for ( var pane in SplitHandler.split_panes ) {
|
||||||
|
dialog.append('<input type="radio" name="pane" value="'+ pane +'">'+ pane +'<br />');
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.append("<h3>New First Pane Flow</h3>");
|
||||||
|
dialog.append('<input type="radio" name="flow1" value="append" checked>append<br />');
|
||||||
|
dialog.append('<input type="radio" name="flow1" value="replace">replace<br />');
|
||||||
|
|
||||||
|
dialog.append("<h3>New Second Pane Flow</h3>");
|
||||||
|
dialog.append('<input type="radio" name="flow2" value="append" checked>append<br />');
|
||||||
|
dialog.append('<input type="radio" name="flow2" value="replace">replace<br />');
|
||||||
|
|
||||||
|
dialog.append('<div id="splitclose" class="button">Split It</div>');
|
||||||
|
|
||||||
|
$("#splitclose").bind("click", onSplitDialogClose);
|
||||||
|
|
||||||
|
openPopup("#splitdialog");
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPaneControlDialogClose() {
|
||||||
|
var pane = $("input[name=pane]:checked").attr("value");
|
||||||
|
|
||||||
|
var types = new Array;
|
||||||
|
$('#splitdialogcontent input[type=checkbox]:checked').each(function() {
|
||||||
|
types.push( $(this).attr('value') );
|
||||||
|
});
|
||||||
|
|
||||||
|
SplitHandler.set_pane_types( pane, types );
|
||||||
|
|
||||||
|
closePopup("#splitdialog");
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPaneControlDialog() {
|
||||||
|
var dialog = $("#splitdialogcontent");
|
||||||
|
dialog.empty();
|
||||||
|
|
||||||
|
dialog.append("<h3>Set Which Pane?</h3>");
|
||||||
|
for ( var pane in SplitHandler.split_panes ) {
|
||||||
|
dialog.append('<input type="radio" name="pane" value="'+ pane +'">'+ pane +'<br />');
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.append("<h3>Which content types?</h3>");
|
||||||
|
for ( var type in known_types ) {
|
||||||
|
dialog.append('<input type="checkbox" value="'+ known_types[type] +'">'+ known_types[type] +'<br />');
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.append('<div id="paneclose" class="button">Make It So</div>');
|
||||||
|
|
||||||
|
$("#paneclose").bind("click", onPaneControlDialogClose);
|
||||||
|
|
||||||
|
openPopup("#splitdialog");
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Register Events
|
// Register Events
|
||||||
//
|
//
|
||||||
|
|
@ -434,6 +523,16 @@ function doStartDragDialog(event) {
|
||||||
// Event when client finishes loading
|
// Event when client finishes loading
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
if( SplitHandler ) {
|
||||||
|
SplitHandler.init();
|
||||||
|
SplitHandler.split_panes['main-sub'] = {'types': ['help'], 'update_method': 'replace'};
|
||||||
|
$("#splitbutton").bind("click", onSplitDialog);
|
||||||
|
$("#panebutton").bind("click", onPaneControlDialog);
|
||||||
|
} else {
|
||||||
|
$("#splitbutton").hide();
|
||||||
|
$("#panebutton").hide();
|
||||||
|
}
|
||||||
|
|
||||||
if ("Notification" in window) {
|
if ("Notification" in window) {
|
||||||
Notification.requestPermission();
|
Notification.requestPermission();
|
||||||
}
|
}
|
||||||
|
|
@ -450,7 +549,7 @@ $(document).ready(function() {
|
||||||
|
|
||||||
//$(document).on("visibilitychange", onVisibilityChange);
|
//$(document).on("visibilitychange", onVisibilityChange);
|
||||||
|
|
||||||
$("#inputfield").bind("resize", doWindowResize)
|
$("[data-role-input]").bind("resize", doWindowResize)
|
||||||
.keypress(onKeyPress)
|
.keypress(onKeyPress)
|
||||||
.bind("paste", resizeInputField)
|
.bind("paste", resizeInputField)
|
||||||
.bind("cut", resizeInputField);
|
.bind("cut", resizeInputField);
|
||||||
|
|
@ -503,6 +602,7 @@ $(document).ready(function() {
|
||||||
},
|
},
|
||||||
60000*3
|
60000*3
|
||||||
);
|
);
|
||||||
|
console.log("Completed GUI setup");
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -14,55 +14,16 @@ JQuery available.
|
||||||
<meta name="author" content="Evennia" />
|
<meta name="author" content="Evennia" />
|
||||||
<meta name="generator" content="Evennia" />
|
<meta name="generator" content="Evennia" />
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
|
||||||
|
<!-- Bootstrap CSS -->
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
|
||||||
|
|
||||||
<link rel='stylesheet' type="text/css" media="screen" href={% static "webclient/css/webclient.css" %}>
|
<link rel='stylesheet' type="text/css" media="screen" href={% static "webclient/css/webclient.css" %}>
|
||||||
|
|
||||||
<link rel="icon" type="image/x-icon" href="/static/website/images/evennia_logo.png" />
|
|
||||||
|
|
||||||
<!-- Import JQuery and warn if there is a problem -->
|
|
||||||
{% block jquery_import %}
|
|
||||||
<script src="https://code.jquery.com/jquery-2.1.1.min.js" type="text/javascript" charset="utf-8"></script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
<script type="text/javascript" charset="utf-8">
|
|
||||||
if(!window.jQuery) {
|
|
||||||
document.write("<div class='err'>jQuery library not found or the online version could not be reached. Check so Javascript is not blocked in your browser.</div>");
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Set up Websocket url and load the evennia.js library-->
|
|
||||||
<script language="javascript" type="text/javascript">
|
|
||||||
{% if websocket_enabled %}
|
|
||||||
var wsactive = true;
|
|
||||||
{% else %}
|
|
||||||
var wsactive = false;
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if browser_sessid %}
|
|
||||||
var csessid = "{{browser_sessid}}";
|
|
||||||
{% else %}
|
|
||||||
var csessid = false;
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if websocket_url %}
|
|
||||||
var wsurl = "{{websocket_url}}:{{websocket_port}}";
|
|
||||||
{% else %}
|
|
||||||
var wsurl = "ws://" + this.location.hostname + ":{{websocket_port}}";
|
|
||||||
{% endif %}
|
|
||||||
</script>
|
|
||||||
<script src={% static "webclient/js/evennia.js" %} language="javascript" type="text/javascript" charset="utf-8"/></script>
|
|
||||||
|
|
||||||
<!-- Load gui library -->
|
|
||||||
{% block guilib_import %}
|
|
||||||
<script src={% static "webclient/js/webclient_gui.js" %} language="javascript" type="text/javascript" charset="utf-8"></script>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
<script src="https://cdn.rawgit.com/ejci/favico.js/master/favico-0.3.10.min.js" language="javascript" type="text/javascript" charset="utf-8"></script>
|
<script src="https://cdn.rawgit.com/ejci/favico.js/master/favico-0.3.10.min.js" language="javascript" type="text/javascript" charset="utf-8"></script>
|
||||||
<script type="text/javascript" charset="utf-8">
|
|
||||||
if(!window.Favico) {
|
|
||||||
document.write("<div class='err'>Favico.js library not found or the online version could not be reached. Check so Javascript is not blocked in your browser.</div>");
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
<link rel="icon" type="image/x-icon" href="/static/website/images/evennia_logo.png" />
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -79,17 +40,69 @@ JQuery available.
|
||||||
web browser supporting javascript. <p>
|
web browser supporting javascript. <p>
|
||||||
This error could also be due to not being able to access
|
This error could also be due to not being able to access
|
||||||
the online jQuery javascript library.</p>
|
the online jQuery javascript library.</p>
|
||||||
<!-- This is will only fire if javascript is actually active -->
|
|
||||||
<script language="javascript" type="text/javascript">
|
|
||||||
$('#noscript').remove();
|
|
||||||
</script>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- main client -->
|
<!-- main client -->
|
||||||
<div id=clientwrapper>
|
<div id=clientwrapper class="d-none">
|
||||||
{% block client %}
|
{% block client %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Import JQuery and warn if there is a problem -->
|
||||||
|
{% block jquery_import %}
|
||||||
|
<script src="https://code.jquery.com/jquery-3.2.1.min.js" type="text/javascript" charset="utf-8"></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
<script type="text/javascript" charset="utf-8">
|
||||||
|
if(!window.jQuery) {
|
||||||
|
document.write("<div class='err'>jQuery library not found or the online version could not be reached.</div>");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- This is will only fire if javascript is actually active -->
|
||||||
|
<script language="javascript" type="text/javascript">
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('#noscript').remove();
|
||||||
|
$('#clientwrapper').removeClass('d-none');
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Set up Websocket url and load the evennia.js library-->
|
||||||
|
<script language="javascript" type="text/javascript">
|
||||||
|
{% if websocket_enabled %}
|
||||||
|
var wsactive = true;
|
||||||
|
{% else %}
|
||||||
|
var wsactive = false;
|
||||||
|
{% endif %}
|
||||||
|
{% if browser_sessid %}
|
||||||
|
var csessid = "{{browser_sessid}}";
|
||||||
|
{% else %}
|
||||||
|
var csessid = false;
|
||||||
|
{% endif %}
|
||||||
|
{% if websocket_url %}
|
||||||
|
var wsurl = "{{websocket_url}}";
|
||||||
|
{% else %}
|
||||||
|
var wsurl = "ws://" + this.location.hostname + ":{{websocket_port}}";
|
||||||
|
{% endif %}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script src={% static "webclient/js/evennia.js" %} language="javascript" type="text/javascript" charset="utf-8"/></script>
|
||||||
|
|
||||||
|
<!-- set up splits before loading the GUI -->
|
||||||
|
<script src="https://unpkg.com/split.js/split.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.min.js"></script>
|
||||||
|
<script src={% static "webclient/js/splithandler.js" %} language="javascript"></script>
|
||||||
|
|
||||||
|
<!-- Load gui library -->
|
||||||
|
{% block guilib_import %}
|
||||||
|
<script src={% static "webclient/js/webclient_gui.js" %} language="javascript" type="text/javascript" charset="utf-8"></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
<!-- jQuery first, then Tether, then Bootstrap JS. -->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script>
|
||||||
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>
|
||||||
|
{% block scripts %}
|
||||||
|
{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -8,20 +8,30 @@
|
||||||
|
|
||||||
|
|
||||||
{% block client %}
|
{% block client %}
|
||||||
|
|
||||||
<div id="wrapper">
|
|
||||||
<div id="toolbar">
|
<div id="toolbar">
|
||||||
<button id="optionsbutton" type="button" class="hidden">⚙</button>
|
<button id="optionsbutton" type="button" aria-haspopup="true" aria-owns="#optionsdialog">⚙<span class="sr-only sr-only-focusable">Settings</span></button>
|
||||||
|
<button id="splitbutton" type="button" aria-haspopup="true" aria-owns="#optionsdialog">⇹<span class="sr-only sr-only-focusable">Splits</span></button>
|
||||||
|
<button id="panebutton" type="button" aria-haspopup="true" aria-owns="#optionsdialog">⚙<span class="sr-only sr-only-focusable">Splits</span></button>
|
||||||
</div>
|
</div>
|
||||||
<div id="messagewindow" role="log"></div>
|
|
||||||
<div id="inputform">
|
<!-- The "Main" Content -->
|
||||||
<div id="prompt"></div>
|
<div id="main" class="split split-vertical" data-role-default>
|
||||||
<div id="inputcontrol">
|
<div id="main-sub">
|
||||||
<textarea id="inputfield" type="text"></textarea>
|
<div id="messagewindow"></div>
|
||||||
<input id="inputsend" type="button" value=">"/>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- The "Input" Pane -->
|
||||||
|
<div id="input" class="split split-vertical" data-role-input data-update-append>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Basic UI Components -->
|
||||||
|
<div id="splitdialog" class="dialog">
|
||||||
|
<div class="dialogtitle">Split Pane<span class="dialogclose">×</span></div>
|
||||||
|
<div class="dialogcontentparent">
|
||||||
|
<div id="splitdialogcontent" class="dialogcontent">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="inputsizer"></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="optionsdialog" class="dialog">
|
<div id="optionsdialog" class="dialog">
|
||||||
|
|
@ -47,4 +57,29 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script type="text/html" id="split-template">
|
||||||
|
<div class="split content<%#horizontal%> split-horizontal<%/horizontal%>" id='<%id%>'>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/html" id="output-template">
|
||||||
|
<div id="<%id%>" role="log" data-role-output data-update-append data-tags='[<%#tags%>"<%.%>", <%/tags%>]'></div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/html" id="input-template">
|
||||||
|
<div id="inputform" class="wrapper">
|
||||||
|
<div id="prompt" class="prompt">
|
||||||
|
</div>
|
||||||
|
<div id="inputcontrol" class="input-group">
|
||||||
|
<textarea id="inputfield" type="text" class="form-control"></textarea>
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button class="btn btn-large btn-outline-primary" id="inputsend" type="button" value="">></button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
{% block scripts %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue