From e33fff473096a4d36d9a7f6746d3665e34dd251f Mon Sep 17 00:00:00 2001 From: James Muehlner Date: Wed, 5 Nov 2014 23:46:21 -0800 Subject: [PATCH] GUAC-807 Fixed scaling/zooming. --- .../client/controllers/clientController.js | 15 +++-- .../app/client/directives/guacClient.js | 58 ++++++++-------- .../app/client/services/clientProperties.js | 66 +++++++++++++++++++ .../webapp/app/client/templates/client.html | 2 +- 4 files changed, 108 insertions(+), 33 deletions(-) create mode 100644 guacamole/src/main/webapp/app/client/services/clientProperties.js diff --git a/guacamole/src/main/webapp/app/client/controllers/clientController.js b/guacamole/src/main/webapp/app/client/controllers/clientController.js index d82d009c1..62e6e74ca 100644 --- a/guacamole/src/main/webapp/app/client/controllers/clientController.js +++ b/guacamole/src/main/webapp/app/client/controllers/clientController.js @@ -39,9 +39,10 @@ angular.module('home').controller('clientController', ['$scope', '$routeParams', // Get DAO for reading connections and groups var connectionGroupDAO = $injector.get('connectionGroupDAO'); var connectionDAO = $injector.get('connectionDAO'); + var ClientProperties = $injector.get('clientProperties'); // Client settings and state - $scope.clientProperties = {scale: 1}; + $scope.clientProperties = new ClientProperties(); // Hide menu by default $scope.menuShown = false; @@ -130,22 +131,26 @@ angular.module('home').controller('clientController', ['$scope', '$routeParams', }; $scope.zoomIn = function zoomIn() { + $scope.autoFit = false; + $scope.clientProperties.autoFit = false; $scope.clientProperties.scale += 0.1; }; $scope.zoomOut = function zoomOut() { + $scope.clientProperties.autoFit = false; $scope.clientProperties.scale -= 0.1; }; $scope.autoFit = true; - $scope.$watch('autoFit', function changeAutoFit(autoFit) { - if(autoFit && $scope.clientProperties.minZoom) { - $scope.clientProperties.scale = $scope.clientProperties.minZoom; + $scope.changeAutoFit = function changeAutoFit() { + if ($scope.autoFit && $scope.clientProperties.minScale) { + $scope.clientProperties.autoFit = true; } else { + $scope.clientProperties.autoFit = false; $scope.clientProperties.scale = 1; } - }); + }; $scope.autoFitDisabled = function() { return $scope.clientProperties.minZoom >= 1; diff --git a/guacamole/src/main/webapp/app/client/directives/guacClient.js b/guacamole/src/main/webapp/app/client/directives/guacClient.js index 085d4a224..2d674ee9a 100644 --- a/guacamole/src/main/webapp/app/client/directives/guacClient.js +++ b/guacamole/src/main/webapp/app/client/directives/guacClient.js @@ -131,39 +131,32 @@ angular.module('client').directive('guacClient', [function guacClient() { $scope.clientProperties[propertyName] = CLIENT_PROPERTY_DEFAULTS[propertyName]; } - // Maximum and minimum zoom levels - $scope.clientProperties.minZoom = 1; - $scope.clientProperties.maxZoom = 3; - /** * Updates the scale of the attached Guacamole.Client based on current window * size and "auto-fit" setting. */ $scope.updateDisplayScale = function() { + $scope.safeApply(function() { + var guac = $scope.attachedClient; + if (!guac) + return; - var guac = $scope.attachedClient; - if (!guac) - return; + // Calculate scale to fit screen + $scope.clientProperties.minScale = Math.min( + $scope.main.offsetWidth / Math.max(guac.getDisplay().getWidth(), 1), + $scope.main.offsetHeight / Math.max(guac.getDisplay().getHeight(), 1) + ); - // Determine whether display is currently fit to the screen - var auto_fit = (guac.getDisplay().getScale() === $scope.clientProperties.minZoom); + // Calculate appropriate maximum zoom level + $scope.clientProperties.maxScale = Math.max($scope.clientProperties.minScale, 3); - // Calculate scale to fit screen - $scope.clientProperties.minZoom = Math.min( - $scope.main.offsetWidth / Math.max(guac.getDisplay().getWidth(), 1), - $scope.main.offsetHeight / Math.max(guac.getDisplay().getHeight(), 1) - ); - - // Calculate appropriate maximum zoom level - $scope.clientProperties.maxZoom = Math.max($scope.clientProperties.minZoom, 3); - - // Clamp zoom level, maintain auto-fit - if (guac.getDisplay().getScale() < $scope.clientProperties.minZoom || auto_fit) - $scope.clientProperties.scale = $scope.clientProperties.minZoom; - - else if (guac.getDisplay().getScale() > $scope.clientProperties.maxZoom) - $scope.clientProperties.scale = $scope.clientProperties.maxZoom; + // Clamp zoom level, maintain auto-fit + if (guac.getDisplay().getScale() < $scope.clientProperties.minScale || $scope.clientProperties.autoFit) + $scope.clientProperties.scale = $scope.clientProperties.minScale; + else if (guac.getDisplay().getScale() > $scope.clientProperties.maxScale) + $scope.clientProperties.scale = $scope.clientProperties.maxScale; + }); }; /** @@ -578,11 +571,11 @@ angular.module('client').directive('guacClient', [function guacClient() { $scope.$watch('clientProperties.scale', function changeScale(scale) { // Fix scale within limits - scale = Math.max(scale, $scope.clientProperties.minZoom); - scale = Math.min(scale, $scope.clientProperties.maxZoom); + scale = Math.max(scale, $scope.clientProperties.minScale); + scale = Math.min(scale, $scope.clientProperties.maxScale); // If at minimum zoom level, hide scroll bars - if (scale === $scope.clientProperties.minZoom) + if (scale === $scope.clientProperties.minScale) $scope.main.style.overflow = "hidden"; // If not at minimum zoom level, show scroll bars @@ -598,6 +591,17 @@ angular.module('client').directive('guacClient', [function guacClient() { }); + // If autofit is set, the scale should be set to the minimum scale, filling the screen + $scope.$watch('clientProperties.autoFit', function changeAutoFit(autoFit) { + if(autoFit) + $scope.clientProperties.scale = $scope.clientProperties.minScale; + }); + + // If the window is resized, attempt to resize client + $window.addEventListener('resize', function onResizeWindow() { + $scope.updateDisplayScale(); + }); + var show_keyboard_gesture_possible = true; // Handle Keyboard events diff --git a/guacamole/src/main/webapp/app/client/services/clientProperties.js b/guacamole/src/main/webapp/app/client/services/clientProperties.js new file mode 100644 index 000000000..c31119860 --- /dev/null +++ b/guacamole/src/main/webapp/app/client/services/clientProperties.js @@ -0,0 +1,66 @@ +/* + * 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 service for generating new guacClient properties objects. + */ +angular.module('client').factory('clientProperties', [function clientProperties() { + + /** + * Object used for interacting with a guacClient directive. + * + * @constructor + */ + return function() { + + /** + * Whether the display should be scaled automatically to fit within the + * available space. + * + * @type Boolean + */ + this.autoFit = true; + + /** + * The current scale. If autoFit is true, the effect of setting this + * value is undefined. + * + * @type Number + */ + this.scale = 1; + + /** + * The minimum scale value. + * + * @type Number + */ + this.minScale = 1; + + /** + * The maximum scale value. + * + * @type Number + */ + this.maxScale = 3; + }; + +}]); \ No newline at end of file diff --git a/guacamole/src/main/webapp/app/client/templates/client.html b/guacamole/src/main/webapp/app/client/templates/client.html index 0ec1fd43a..ff863f429 100644 --- a/guacamole/src/main/webapp/app/client/templates/client.html +++ b/guacamole/src/main/webapp/app/client/templates/client.html @@ -105,7 +105,7 @@
{{formattedScale()}}%
+
-
+