From de24eef9b82194396f4e329adbbab0976d2684a8 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 18 Dec 2014 04:27:19 -0800 Subject: [PATCH 1/2] GUAC-809: Implement guacOsk directive. --- .../webapp/app/client/styles/keyboard.css | 115 --------------- .../main/webapp/app/osk/directives/guacOsk.js | 114 +++++++++++++++ .../src/main/webapp/app/osk/oskModule.js | 26 ++++ .../src/main/webapp/app/osk/styles/osk.css | 136 ++++++++++++++++++ .../webapp/app/osk/templates/guacOsk.html | 24 ++++ 5 files changed, 300 insertions(+), 115 deletions(-) create mode 100644 guacamole/src/main/webapp/app/osk/directives/guacOsk.js create mode 100644 guacamole/src/main/webapp/app/osk/oskModule.js create mode 100644 guacamole/src/main/webapp/app/osk/styles/osk.css create mode 100644 guacamole/src/main/webapp/app/osk/templates/guacOsk.html diff --git a/guacamole/src/main/webapp/app/client/styles/keyboard.css b/guacamole/src/main/webapp/app/client/styles/keyboard.css index f10472ec9..49508d3c9 100644 --- a/guacamole/src/main/webapp/app/client/styles/keyboard.css +++ b/guacamole/src/main/webapp/app/client/styles/keyboard.css @@ -36,118 +36,3 @@ z-index: 1; } - -.guac-keyboard { - display: inline-block; - width: 100%; - - margin: 0; - padding: 0; - cursor: default; - - text-align: left; - vertical-align: middle; -} - -.guac-keyboard .guac-keyboard-key-container { - display: inline-block; -} - -.guac-keyboard .guac-keyboard-key { - background: #444; - border: 1px outset #888; - -moz-border-radius: 0.1em; - -webkit-border-radius: 0.1em; - -khtml-border-radius: 0.1em; - border-radius: 0.1em; -} - -.guac-keyboard .guac-keyboard-cap { - color: white; - font-family: sans-serif; - font-size: 50%; - font-weight: lighter; - text-align: center; - white-space: pre; -} - -.guac-keyboard .guac-keyboard-key:hover { - cursor: pointer; -} - -.guac-keyboard .guac-keyboard-key.highlight { - background: #666; - border-color: #666; -} - -.guac-keyboard.guac-keyboard-modifier-shift .guac-keyboard-key.shift, -.guac-keyboard.guac-keyboard-modifier-numsym .guac-keyboard-key.numsym { - background: #882; - border-color: #DD4; -} - -.guac-keyboard.guac-keyboard-modifier-control .guac-keyboard-key.control, -.guac-keyboard.guac-keyboard-modifier-numsym .guac-keyboard-key.numsym { - background: #882; - border-color: #DD4; -} - -.guac-keyboard.guac-keyboard-modifier-alt .guac-keyboard-key.alt, -.guac-keyboard.guac-keyboard-modifier-numsym .guac-keyboard-key.numsym { - background: #882; - border-color: #DD4; -} - -.guac-keyboard.guac-keyboard-modifier-super .guac-keyboard-key.super, -.guac-keyboard.guac-keyboard-modifier-numsym .guac-keyboard-key.numsym { - background: #882; - border-color: #DD4; -} - -.guac-keyboard .guac-keyboard-key.guac-keyboard-pressed { - background: #822; - border-color: #D44; - border-style: inset; -} - -.guac-keyboard .guac-keyboard-row { - line-height: 0; -} - -.guac-keyboard .guac-keyboard-column { - display: inline-block; - text-align: center; - vertical-align: top; -} - -.guac-keyboard .guac-keyboard-gap { - display: inline-block; -} - -/* Hide keycaps requiring modifiers which are NOT currently active. */ -.guac-keyboard:not(.guac-keyboard-modifier-caps) -.guac-keyboard-cap.guac-keyboard-requires-caps, - -.guac-keyboard:not(.guac-keyboard-modifier-numsym) -.guac-keyboard-cap.guac-keyboard-requires-numsym, - -.guac-keyboard:not(.guac-keyboard-modifier-shift) -.guac-keyboard-cap.guac-keyboard-requires-shift, - -/* Hide keycaps NOT requiring modifiers which ARE currently active, where that - modifier is used to determine which cap is displayed for the current key. */ -.guac-keyboard.guac-keyboard-modifier-shift -.guac-keyboard-key.guac-keyboard-uses-shift -.guac-keyboard-cap:not(.guac-keyboard-requires-shift), - -.guac-keyboard.guac-keyboard-modifier-numsym -.guac-keyboard-key.guac-keyboard-uses-numsym -.guac-keyboard-cap:not(.guac-keyboard-requires-numsym), - -.guac-keyboard.guac-keyboard-modifier-caps -.guac-keyboard-key.guac-keyboard-uses-caps -.guac-keyboard-cap:not(.guac-keyboard-requires-caps) { - - display: none; - -} diff --git a/guacamole/src/main/webapp/app/osk/directives/guacOsk.js b/guacamole/src/main/webapp/app/osk/directives/guacOsk.js new file mode 100644 index 000000000..6b7cf529c --- /dev/null +++ b/guacamole/src/main/webapp/app/osk/directives/guacOsk.js @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2014 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * A directive which displays the Guacamole on-screen keyboard. + */ +angular.module('osk').directive('guacOsk', [function guacOsk() { + + return { + restrict: 'E', + replace: true, + scope: { + + /** + * The URL for the Guacamole on-screen keyboard layout to use. + * + * @type String + */ + layout : '=' + + }, + + templateUrl: 'app/osk/templates/guacOsk.html', + controller: ['$scope', '$rootScope', '$window', '$element', + function guacOsk($scope, $rootScope, $window, $element) { + + /** + * The current on-screen keyboard, if any. + * + * @type Guacamole.OnScreenKeyboard + */ + var keyboard = null; + + /** + * The main containing element for the entire directive. + * + * @type Element + */ + var main = $element[0]; + + /** + * Event listener which resizes the current keyboard, if any, such + * that it fits within available space. + */ + var resizeListener = function resizeListener() { + + // Resize keyboard, if defined + if (keyboard) + keyboard.resize(main.offsetWidth); + + }; + + // Set layout whenever URL changes + $scope.$watch("layout", function setLayout(layout) { + + // Remove current keyboard + keyboard = null; + main.innerHTML = ""; + + // Load new keyboard + if (layout) { + + // Add OSK element + keyboard = new Guacamole.OnScreenKeyboard(layout); + main.appendChild(keyboard.getElement()); + + // Init size + keyboard.resize(main.offsetWidth); + + // Broadcast keydown for each key pressed + keyboard.onkeydown = function(keysym) { + $rootScope.$broadcast('guacKeydown', keysym); + }; + + // Broadcast keydown for each key released + keyboard.onkeyup = function(keysym) { + $rootScope.$broadcast('guacKeyup', keysym); + }; + + // Resize keyboard whenever window changes size + $window.addEventListener('resize', resizeListener); + + } + + }); // end layout scope watch + + // Clean up event listeners upon destroy + $scope.$on('$destroy', function destroyKeyboard() { + $window.removeEventListener('resize', resizeListener); + }); + + }] + + }; +}]); diff --git a/guacamole/src/main/webapp/app/osk/oskModule.js b/guacamole/src/main/webapp/app/osk/oskModule.js new file mode 100644 index 000000000..36cc8ea69 --- /dev/null +++ b/guacamole/src/main/webapp/app/osk/oskModule.js @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2014 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * Module for displaying the Guacamole on-screen keyboard. + */ +angular.module('osk', []); diff --git a/guacamole/src/main/webapp/app/osk/styles/osk.css b/guacamole/src/main/webapp/app/osk/styles/osk.css new file mode 100644 index 000000000..ae5d26bf9 --- /dev/null +++ b/guacamole/src/main/webapp/app/osk/styles/osk.css @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2014 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +.guac-keyboard { + display: inline-block; + width: 100%; + + margin: 0; + padding: 0; + cursor: default; + + text-align: left; + vertical-align: middle; +} + +.guac-keyboard .guac-keyboard-key-container { + display: inline-block; +} + +.guac-keyboard .guac-keyboard-key { + background: #444; + border: 1px outset #888; + -moz-border-radius: 0.1em; + -webkit-border-radius: 0.1em; + -khtml-border-radius: 0.1em; + border-radius: 0.1em; +} + +.guac-keyboard .guac-keyboard-cap { + color: white; + font-family: sans-serif; + font-size: 50%; + font-weight: lighter; + text-align: center; + white-space: pre; +} + +.guac-keyboard .guac-keyboard-key:hover { + cursor: pointer; +} + +.guac-keyboard .guac-keyboard-key.highlight { + background: #666; + border-color: #666; +} + +.guac-keyboard.guac-keyboard-modifier-shift .guac-keyboard-key.shift, +.guac-keyboard.guac-keyboard-modifier-numsym .guac-keyboard-key.numsym { + background: #882; + border-color: #DD4; +} + +.guac-keyboard.guac-keyboard-modifier-control .guac-keyboard-key.control, +.guac-keyboard.guac-keyboard-modifier-numsym .guac-keyboard-key.numsym { + background: #882; + border-color: #DD4; +} + +.guac-keyboard.guac-keyboard-modifier-alt .guac-keyboard-key.alt, +.guac-keyboard.guac-keyboard-modifier-numsym .guac-keyboard-key.numsym { + background: #882; + border-color: #DD4; +} + +.guac-keyboard.guac-keyboard-modifier-super .guac-keyboard-key.super, +.guac-keyboard.guac-keyboard-modifier-numsym .guac-keyboard-key.numsym { + background: #882; + border-color: #DD4; +} + +.guac-keyboard .guac-keyboard-key.guac-keyboard-pressed { + background: #822; + border-color: #D44; + border-style: inset; +} + +.guac-keyboard .guac-keyboard-row { + line-height: 0; +} + +.guac-keyboard .guac-keyboard-column { + display: inline-block; + text-align: center; + vertical-align: top; +} + +.guac-keyboard .guac-keyboard-gap { + display: inline-block; +} + +/* Hide keycaps requiring modifiers which are NOT currently active. */ +.guac-keyboard:not(.guac-keyboard-modifier-caps) +.guac-keyboard-cap.guac-keyboard-requires-caps, + +.guac-keyboard:not(.guac-keyboard-modifier-numsym) +.guac-keyboard-cap.guac-keyboard-requires-numsym, + +.guac-keyboard:not(.guac-keyboard-modifier-shift) +.guac-keyboard-cap.guac-keyboard-requires-shift, + +/* Hide keycaps NOT requiring modifiers which ARE currently active, where that + modifier is used to determine which cap is displayed for the current key. */ +.guac-keyboard.guac-keyboard-modifier-shift +.guac-keyboard-key.guac-keyboard-uses-shift +.guac-keyboard-cap:not(.guac-keyboard-requires-shift), + +.guac-keyboard.guac-keyboard-modifier-numsym +.guac-keyboard-key.guac-keyboard-uses-numsym +.guac-keyboard-cap:not(.guac-keyboard-requires-numsym), + +.guac-keyboard.guac-keyboard-modifier-caps +.guac-keyboard-key.guac-keyboard-uses-caps +.guac-keyboard-cap:not(.guac-keyboard-requires-caps) { + + display: none; + +} diff --git a/guacamole/src/main/webapp/app/osk/templates/guacOsk.html b/guacamole/src/main/webapp/app/osk/templates/guacOsk.html new file mode 100644 index 000000000..42a73462c --- /dev/null +++ b/guacamole/src/main/webapp/app/osk/templates/guacOsk.html @@ -0,0 +1,24 @@ +
+ + +
From 1e39ff756963b8c717e04701081e01f98d235106 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 18 Dec 2014 05:01:51 -0800 Subject: [PATCH 2/2] GUAC-809: Show OSK if selected within menu. --- .../src/main/webapp/app/client/clientModule.js | 2 +- .../app/client/controllers/clientController.js | 13 ++++++++++++- .../src/main/webapp/app/client/styles/keyboard.css | 5 +++++ .../main/webapp/app/client/templates/client.html | 11 ++++++++--- guacamole/src/main/webapp/translations/en_US.json | 1 + 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/guacamole/src/main/webapp/app/client/clientModule.js b/guacamole/src/main/webapp/app/client/clientModule.js index c27957115..944189dd4 100644 --- a/guacamole/src/main/webapp/app/client/clientModule.js +++ b/guacamole/src/main/webapp/app/client/clientModule.js @@ -23,4 +23,4 @@ /** * The module for code used to connect to a connection or balancing group. */ -angular.module('client', ['auth', 'history', 'rest']); +angular.module('client', ['auth', 'history', 'osk', 'rest']); diff --git a/guacamole/src/main/webapp/app/client/controllers/clientController.js b/guacamole/src/main/webapp/app/client/controllers/clientController.js index 5e134f64d..ec2690ee6 100644 --- a/guacamole/src/main/webapp/app/client/controllers/clientController.js +++ b/guacamole/src/main/webapp/app/client/controllers/clientController.js @@ -145,7 +145,10 @@ angular.module('home').controller('clientController', ['$scope', '$routeParams', // Hide menu by default $scope.menuShown = false; - + + // Use physical keyboard by default + $scope.inputMethod = 'none'; + // Convenience method for closing the menu $scope.closeMenu = function closeMenu() { $scope.menuShown = false; @@ -198,6 +201,14 @@ angular.module('home').controller('clientController', ['$scope', '$routeParams', return true; } + // Show/hide UI elements depending on input method + $scope.$watch('inputMethod', function setInputMethod(inputMethod) { + + // Show on-screen keyboard only if selected + $scope.showOSK = (inputMethod === 'osk'); + + }); + $scope.$watch('menuShown', function setKeyboardEnabled(menuShown, menuShownPreviousState) { // Send clipboard data if menu is hidden diff --git a/guacamole/src/main/webapp/app/client/styles/keyboard.css b/guacamole/src/main/webapp/app/client/styles/keyboard.css index 49508d3c9..270153a4d 100644 --- a/guacamole/src/main/webapp/app/client/styles/keyboard.css +++ b/guacamole/src/main/webapp/app/client/styles/keyboard.css @@ -34,5 +34,10 @@ background: #222; opacity: 0.85; + visibility: hidden; z-index: 1; } + +.keyboard-container.shown { + visibility: visible; +} diff --git a/guacamole/src/main/webapp/app/client/templates/client.html b/guacamole/src/main/webapp/app/client/templates/client.html index 4402a0bbc..460e71641 100644 --- a/guacamole/src/main/webapp/app/client/templates/client.html +++ b/guacamole/src/main/webapp/app/client/templates/client.html @@ -48,20 +48,20 @@
- +

- +

- +

@@ -103,6 +103,11 @@ + +
+ +
+
diff --git a/guacamole/src/main/webapp/translations/en_US.json b/guacamole/src/main/webapp/translations/en_US.json index fd7f20e06..16d282093 100644 --- a/guacamole/src/main/webapp/translations/en_US.json +++ b/guacamole/src/main/webapp/translations/en_US.json @@ -206,6 +206,7 @@ } }, "client": { + "oskLayout" : "layouts/en-us-qwerty.xml", "ctrl" : "Ctrl", "alt" : "Alt", "esc" : "Esc",