From 354484251466b4f604186e9e410fac6904aae7b4 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. --- guacamole/src/main/webapp/client.xhtml | 249 +----------- .../src/main/webapp/scripts/interface.js | 366 ++++++++++++++++-- 2 files changed, 332 insertions(+), 283 deletions(-) diff --git a/guacamole/src/main/webapp/client.xhtml b/guacamole/src/main/webapp/client.xhtml index 1a4c0821e..be2250951 100644 --- a/guacamole/src/main/webapp/client.xhtml +++ b/guacamole/src/main/webapp/client.xhtml @@ -72,254 +72,28 @@ - + + + diff --git a/guacamole/src/main/webapp/scripts/interface.js b/guacamole/src/main/webapp/scripts/interface.js index 63cc4264f..c2d5a5d09 100644 --- a/guacamole/src/main/webapp/scripts/interface.js +++ b/guacamole/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() { - }, 30); + 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(); + }; + + // 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); + }; -function showMenu() { - - if (menu_shaded) { - - var step = Math.floor(menu.offsetHeight / 5) + 1; - var offset = -menu.offsetHeight; - menu_shaded = false; - menu.style.visiblity = ""; - - window.clearInterval(shade_interval); - show_interval = window.setInterval(function() { - - offset += step; - - if (offset >= 0) { - offset = 0; - window.clearInterval(show_interval); - } - - menu.style.top = offset + "px"; - - }, 30); + 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; + + // Unknown status code + default: + GuacamoleUI.state.textContent = "Unknown"; + + } + }; + + // Name instruction handler + guac.onname = function(name) { + document.title = name; + }; + + // Error handler + guac.onerror = function(error) { + + // 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