From fe852079b1aeaafa599adc852090da3dfed82181 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 12 Dec 2011 20:21:04 -0800 Subject: [PATCH] Fixed confusing "Idle" error handling, improved scoping of UI elements and behavior. --- src/main/webapp/client.xhtml | 249 +----------------------- src/main/webapp/scripts/interface.js | 352 ++++++++++++++++++++++++++++++---- 2 files changed, 325 insertions(+), 276 deletions(-) diff --git a/src/main/webapp/client.xhtml b/src/main/webapp/client.xhtml index 1a4c082..be22509 100644 --- a/src/main/webapp/client.xhtml +++ b/src/main/webapp/client.xhtml @@ -72,254 +72,28 @@ - + + + diff --git a/src/main/webapp/scripts/interface.js b/src/main/webapp/scripts/interface.js index 63cc426..c2d5a5d 100644 --- a/src/main/webapp/scripts/interface.js +++ b/src/main/webapp/scripts/interface.js @@ -1,56 +1,340 @@ -var menu_shaded = false; +// UI Definition +var GuacamoleUI = { -var shade_interval = null; -var show_interval = null; + "display": document.getElementById("display"), + "menu" : document.getElementById("menu"), + "logo" : document.getElementById("status-logo"), + "state" : document.getElementById("state"), -function shadeMenu() { + "buttons": { - if (!menu_shaded) { + "showClipboard": document.getElementById("showClipboard"), + "showKeyboard" : document.getElementById("showKeyboard"), + "ctrlAltDelete": document.getElementById("ctrlAltDelete"), + "reconnect" : document.getElementById("reconnect"), + "logout" : document.getElementById("logout") - var step = Math.floor(menu.offsetHeight / 5) + 1; - var offset = 0; - menu_shaded = true; + }, - window.clearInterval(show_interval); - shade_interval = window.setInterval(function() { + "containers": { + "error" : document.getElementById("errorDialog"), + "clipboard": document.getElementById("clipboardDiv"), + "keyboard" : document.getElementById("keyboardContainer") + }, + + "error" : document.getElementById("errorText"), + "clipboard" : document.getElementById("clipboard") - offset -= step; - menu.style.top = offset + "px"; +}; - if (offset <= -menu.offsetHeight) { - window.clearInterval(shade_interval); - menu.style.visiblity = "hidden"; - } +// Constant UI initialization and behavior +(function() { + + var menu_shaded = false; + + var shade_interval = null; + var show_interval = null; + + // Cache error image (might not be available when error occurs) + var guacErrorImage = new Image(); + guacErrorImage.src = "images/noguacamole-logo-24.png"; + + GuacamoleUI.showError = function(error) { + + GuacamoleUI.menu.className = "error"; + GuacamoleUI.display.className += " guac-error"; + + GuacamoleUI.logo.src = guacErrorImage.src; + GuacamoleUI.error.textContent = error; + GuacamoleUI.containers.error.style.visibility = "visible"; + + }; + + GuacamoleUI.shadeMenu = function() { + + if (!menu_shaded) { + + var step = Math.floor(GuacamoleUI.menu.offsetHeight / 5) + 1; + var offset = 0; + menu_shaded = true; + + window.clearInterval(show_interval); + shade_interval = window.setInterval(function() { + + offset -= step; + GuacamoleUI.menu.style.top = offset + "px"; + + if (offset <= -GuacamoleUI.menu.offsetHeight) { + window.clearInterval(shade_interval); + GuacamoleUI.menu.style.visiblity = "hidden"; + } + + }, 30); + } + + }; + + GuacamoleUI.showMenu = function() { + + if (menu_shaded) { + + var step = Math.floor(GuacamoleUI.menu.offsetHeight / 5) + 1; + var offset = -GuacamoleUI.menu.offsetHeight; + menu_shaded = false; + GuacamoleUI.menu.style.visiblity = ""; + + window.clearInterval(shade_interval); + show_interval = window.setInterval(function() { + + offset += step; + + if (offset >= 0) { + offset = 0; + window.clearInterval(show_interval); + } + + GuacamoleUI.menu.style.top = offset + "px"; + + }, 30); + } + + }; + + // Show/Hide clipboard + GuacamoleUI.buttons.showClipboard.onclick = function() { + + var displayed = GuacamoleUI.containers.clipboard.style.display; + if (displayed != "block") { + GuacamoleUI.containers.clipboard.style.display = "block"; + GuacamoleUI.buttons.showClipboard.innerHTML = "Hide Clipboard"; + } + else { + GuacamoleUI.containers.clipboard.style.display = "none"; + GuacamoleUI.buttons.showClipboard.innerHTML = "Show Clipboard"; + GuacamoleUI.clipboard.onchange(); + } + + }; + + // Show/Hide keyboard + GuacamoleUI.buttons.showKeyboard.onclick = function() { + + var displayed = GuacamoleUI.containers.keyboard.style.display; + if (displayed != "block") { + GuacamoleUI.containers.keyboard.style.display = "block"; + GuacamoleUI.buttons.showKeyboard.textContent = "Hide Keyboard"; + } + else { + GuacamoleUI.containers.keyboard.style.display = "none"; + GuacamoleUI.buttons.showKeyboard.textContent = "Show Keyboard"; + } + + }; + + // Logout + GuacamoleUI.buttons.logout.onclick = function() { + window.location.href = "logout"; + }; + + GuacamoleUI.display.onmouseout = function() { + GuacamoleUI.showMenu(); + }; + + GuacamoleUI.display.onmouseover = function() { + GuacamoleUI.shadeMenu(); + }; + + // Reconnect button + GuacamoleUI.buttons.reconnect.onclick = function() { + window.location.reload(); + }; - }, 30); + // On-screen keyboard + GuacamoleUI.keyboard = new Guacamole.OnScreenKeyboard("layouts/en-us-qwerty.xml"); + GuacamoleUI.containers.keyboard.appendChild(GuacamoleUI.keyboard); + +})(); + +// Tie UI events / behavior to a specific Guacamole client +GuacamoleUI.attach = function(guac) { + + // Mouse + var mouse = new Guacamole.Mouse(GuacamoleUI.display); + mouse.onmousedown = mouse.onmouseup = mouse.onmousemove = + function(mouseState) { + + if (mouseState.y <= 5) + GuacamoleUI.showMenu(); + + guac.sendMouseState(mouseState); + }; + + // Keyboard + var keyboard = new Guacamole.Keyboard(document); + + function disableKeyboard() { + keyboard.onkeydown = null; + keyboard.onkeyup = null; + } + + function enableKeyboard() { + keyboard.onkeydown = + function (keysym) { + guac.sendKeyEvent(1, keysym); + }; + + keyboard.onkeyup = + function (keysym) { + guac.sendKeyEvent(0, keysym); + }; } -} + // Enable keyboard by default + enableKeyboard(); + + // Handle client state change + guac.onstatechange = function(clientState) { + switch (clientState) { + + // Idle + case 0: + GuacamoleUI.state.textContent = "Idle." + break; + + // Connecting + case 1: + GuacamoleUI.state.textContent = "Connecting..."; + break; + + // Connected + waiting + case 2: + GuacamoleUI.state.textContent = "Connected, waiting for first update..."; + break; + + // Connected + case 3: + + GuacamoleUI.display.className = + GuacamoleUI.display.className.replace(/guac-loading/, ''); + + GuacamoleUI.menu.className = "connected"; + GuacamoleUI.state.textContent = "Connected."; + GuacamoleUI.shadeMenu(); + break; + + // Disconnecting + case 4: + GuacamoleUI.state.textContent = "Disconnecting..."; + break; + + // Disconnected + case 5: + GuacamoleUI.state.textContent = "Disconnected."; + break; -function showMenu() { + // Unknown status code + default: + GuacamoleUI.state.textContent = "Unknown"; - if (menu_shaded) { + } + }; - var step = Math.floor(menu.offsetHeight / 5) + 1; - var offset = -menu.offsetHeight; - menu_shaded = false; - menu.style.visiblity = ""; + // Name instruction handler + guac.onname = function(name) { + document.title = name; + }; - window.clearInterval(shade_interval); - show_interval = window.setInterval(function() { + // Error handler + guac.onerror = function(error) { - offset += step; + // Disconnect, if connected + guac.disconnect(); + + // Display error message + GuacamoleUI.showError(error); + + // Show error by desaturating display + var layers = guac.getLayers(); + for (var i=0; i= 0) { - offset = 0; - window.clearInterval(show_interval); } - menu.style.top = offset + "px"; + } + + }; - }, 30); - } + // Disconnect on close + window.onunload = function() { + guac.disconnect(); + }; + + // Handle clipboard events + GuacamoleUI.clipboard.onchange = function() { + + var text = GuacamoleUI.clipboard.value; + guac.setClipboard(text); + + }; + + // Ignore keypresses when clipboard is focused + GuacamoleUI.clipboard.onfocus = function() { + disableKeyboard(); + }; + + // Capture keypresses when clipboard is not focused + GuacamoleUI.clipboard.onblur = function() { + enableKeyboard(); + }; + + // Server copy handler + guac.onclipboard = function(data) { + GuacamoleUI.clipboard.value = data; + }; + + GuacamoleUI.keyboard.setKeyPressedHandler( + function(keysym) { + guac.sendKeyEvent(1, keysym); + } + ); + + GuacamoleUI.keyboard.setKeyReleasedHandler( + function(keysym) { + guac.sendKeyEvent(0, keysym); + } + ); + + // Send Ctrl-Alt-Delete + GuacamoleUI.buttons.ctrlAltDelete.onclick = function() { + + var KEYSYM_CTRL = 0xFFE3; + var KEYSYM_ALT = 0xFFE9; + var KEYSYM_DELETE = 0xFFFF; -} + guac.sendKeyEvent(1, KEYSYM_CTRL); + guac.sendKeyEvent(1, KEYSYM_ALT); + guac.sendKeyEvent(1, KEYSYM_DELETE); + guac.sendKeyEvent(0, KEYSYM_DELETE); + guac.sendKeyEvent(0, KEYSYM_ALT); + guac.sendKeyEvent(0, KEYSYM_CTRL); + }; +}; \ No newline at end of file -- 1.7.10.4