mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-08 14:11:21 +00:00
GUAC-807: Zoom controls somewhat working.
This commit is contained in:
committed by
Michael Jumper
parent
72c82aea8b
commit
2e8283c94f
@@ -41,11 +41,10 @@ angular.module('home').controller('clientController', ['$scope', '$routeParams',
|
|||||||
var connectionDAO = $injector.get('connectionDAO');
|
var connectionDAO = $injector.get('connectionDAO');
|
||||||
|
|
||||||
// Client settings and state
|
// Client settings and state
|
||||||
$scope.clientParameters = {scale: 1};
|
$scope.clientProperties = {scale: 1};
|
||||||
|
|
||||||
// Hide menu by default
|
// Hide menu by default
|
||||||
$scope.menuShown = false;
|
$scope.menuShown = true;
|
||||||
$scope.menuHasBeenShown = false;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse the type, name, and id out of the url paramteres,
|
* Parse the type, name, and id out of the url paramteres,
|
||||||
@@ -113,9 +112,6 @@ angular.module('home').controller('clientController', ['$scope', '$routeParams',
|
|||||||
// Toggle the menu
|
// Toggle the menu
|
||||||
$scope.safeApply(function() {
|
$scope.safeApply(function() {
|
||||||
$scope.menuShown = !$scope.menuShown;
|
$scope.menuShown = !$scope.menuShown;
|
||||||
|
|
||||||
// The menu has been shown at least once before
|
|
||||||
$scope.menuHasBeenShown = true;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Reset the keys pressed
|
// Reset the keys pressed
|
||||||
@@ -129,4 +125,30 @@ angular.module('home').controller('clientController', ['$scope', '$routeParams',
|
|||||||
delete keysCurrentlyPressed[keysym];
|
delete keysCurrentlyPressed[keysym];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$scope.formattedScale = function formattedScale() {
|
||||||
|
return Math.round($scope.clientProperties.scale * 100);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.zoomIn = function zoomIn() {
|
||||||
|
$scope.clientProperties.scale += 0.1;
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.zoomOut = function zoomOut() {
|
||||||
|
$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;
|
||||||
|
} else {
|
||||||
|
$scope.clientProperties.scale = 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.autoFitDisabled = function() {
|
||||||
|
return $scope.clientProperties.minZoom >= 1;
|
||||||
|
};
|
||||||
|
|
||||||
}]);
|
}]);
|
||||||
|
@@ -31,7 +31,7 @@ angular.module('client').directive('guacClient', [function guacClient() {
|
|||||||
replace: true,
|
replace: true,
|
||||||
scope: {
|
scope: {
|
||||||
// Parameters for controlling client state
|
// Parameters for controlling client state
|
||||||
clientParameters : '=',
|
clientProperties : '=',
|
||||||
|
|
||||||
// Parameters for initially connecting
|
// Parameters for initially connecting
|
||||||
id : '=',
|
id : '=',
|
||||||
@@ -42,6 +42,21 @@ angular.module('client').directive('guacClient', [function guacClient() {
|
|||||||
templateUrl: 'app/client/templates/guacClient.html',
|
templateUrl: 'app/client/templates/guacClient.html',
|
||||||
controller: ['$scope', '$injector', '$element', function guacClientController($scope, $injector, $element) {
|
controller: ['$scope', '$injector', '$element', function guacClientController($scope, $injector, $element) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Safe $apply implementation from Alex Vanston:
|
||||||
|
* https://coderwall.com/p/ngisma
|
||||||
|
*/
|
||||||
|
$scope.safeApply = function(fn) {
|
||||||
|
var phase = this.$root.$$phase;
|
||||||
|
if(phase === '$apply' || phase === '$digest') {
|
||||||
|
if(fn && (typeof(fn) === 'function')) {
|
||||||
|
fn();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$apply(fn);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var $window = $injector.get('$window'),
|
var $window = $injector.get('$window'),
|
||||||
guacAudio = $injector.get('guacAudio'),
|
guacAudio = $injector.get('guacAudio'),
|
||||||
guacVideo = $injector.get('guacVideo'),
|
guacVideo = $injector.get('guacVideo'),
|
||||||
@@ -86,10 +101,6 @@ angular.module('client').directive('guacClient', [function guacClient() {
|
|||||||
"TEXT_INPUT_PADDING" : 128, /* characters */
|
"TEXT_INPUT_PADDING" : 128, /* characters */
|
||||||
"TEXT_INPUT_PADDING_CODEPOINT" : 0x200B,
|
"TEXT_INPUT_PADDING_CODEPOINT" : 0x200B,
|
||||||
|
|
||||||
/* Settings for zoom */
|
|
||||||
"min_zoom" : 1,
|
|
||||||
"max_zoom" : 3,
|
|
||||||
|
|
||||||
/* Current connection parameters */
|
/* Current connection parameters */
|
||||||
|
|
||||||
/* The user defined named for this connection */
|
/* The user defined named for this connection */
|
||||||
@@ -111,6 +122,19 @@ angular.module('client').directive('guacClient', [function guacClient() {
|
|||||||
"clipboard_integration_enabled" : undefined
|
"clipboard_integration_enabled" : undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var CLIENT_PROPERTY_DEFAULTS = {
|
||||||
|
scale: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var propertyName in CLIENT_PROPERTY_DEFAULTS) {
|
||||||
|
if (!(propertyName in $scope.clientProperties))
|
||||||
|
$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
|
* Updates the scale of the attached Guacamole.Client based on current window
|
||||||
* size and "auto-fit" setting.
|
* size and "auto-fit" setting.
|
||||||
@@ -122,23 +146,23 @@ angular.module('client').directive('guacClient', [function guacClient() {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Determine whether display is currently fit to the screen
|
// Determine whether display is currently fit to the screen
|
||||||
var auto_fit = (guac.getDisplay().getScale() === $scope.min_zoom);
|
var auto_fit = (guac.getDisplay().getScale() === $scope.clientProperties.minZoom);
|
||||||
|
|
||||||
// Calculate scale to fit screen
|
// Calculate scale to fit screen
|
||||||
$scope.min_zoom = Math.min(
|
$scope.clientProperties.minZoom = Math.min(
|
||||||
$scope.main.offsetWidth / Math.max(guac.getDisplay().getWidth(), 1),
|
$scope.main.offsetWidth / Math.max(guac.getDisplay().getWidth(), 1),
|
||||||
$scope.main.offsetHeight / Math.max(guac.getDisplay().getHeight(), 1)
|
$scope.main.offsetHeight / Math.max(guac.getDisplay().getHeight(), 1)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Calculate appropriate maximum zoom level
|
// Calculate appropriate maximum zoom level
|
||||||
$scope.max_zoom = Math.max($scope.min_zoom, 3);
|
$scope.clientProperties.maxZoom = Math.max($scope.clientProperties.minZoom, 3);
|
||||||
|
|
||||||
// Clamp zoom level, maintain auto-fit
|
// Clamp zoom level, maintain auto-fit
|
||||||
if (guac.getDisplay().getScale() < $scope.min_zoom || auto_fit)
|
if (guac.getDisplay().getScale() < $scope.clientProperties.minZoom || auto_fit)
|
||||||
$scope.setScale($scope.min_zoom);
|
$scope.clientProperties.scale = $scope.clientProperties.minZoom;
|
||||||
|
|
||||||
else if (guac.getDisplay().getScale() > $scope.max_zoom)
|
else if (guac.getDisplay().getScale() > $scope.clientProperties.maxZoom)
|
||||||
$scope.setScale($scope.max_zoom);
|
$scope.clientProperties.scale = $scope.clientProperties.maxZoom;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -166,7 +190,7 @@ angular.module('client').directive('guacClient', [function guacClient() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
guac.getDisplay().onresize = function() {
|
guac.getDisplay().onresize = function() {
|
||||||
$scope.updateDisplayScale();
|
$scope.safeApply($scope.updateDisplayScale);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -532,45 +556,30 @@ angular.module('client').directive('guacClient', [function guacClient() {
|
|||||||
$scope.guac.connect(connectString);
|
$scope.guac.connect(connectString);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// Adjust scale if modified externally
|
||||||
* Sets the current display scale to the given value, where 1 is 100% (1:1
|
$scope.$watch('clientProperties.scale', function changeScale(scale) {
|
||||||
* pixel ratio). Out-of-range values will be clamped in-range.
|
|
||||||
*
|
|
||||||
* @param {Number} scale The new scale to apply
|
|
||||||
*/
|
|
||||||
$scope.setScale = function setScale(scale) {
|
|
||||||
|
|
||||||
scale = Math.max(scale, $scope.min_zoom);
|
// Fix scale within limits
|
||||||
scale = Math.min(scale, $scope.max_zoom);
|
scale = Math.max(scale, $scope.clientProperties.minZoom);
|
||||||
|
scale = Math.min(scale, $scope.clientProperties.maxZoom);
|
||||||
|
|
||||||
|
// If at minimum zoom level, hide scroll bars
|
||||||
|
if (scale === $scope.clientProperties.minZoom)
|
||||||
|
$scope.main.style.overflow = "hidden";
|
||||||
|
|
||||||
|
// If not at minimum zoom level, show scroll bars
|
||||||
|
else
|
||||||
|
$scope.main.style.overflow = "auto";
|
||||||
|
|
||||||
|
// Apply scale if client attached
|
||||||
if ($scope.attachedClient)
|
if ($scope.attachedClient)
|
||||||
$scope.attachedClient.getDisplay().scale(scale);
|
$scope.attachedClient.getDisplay().scale(scale);
|
||||||
|
|
||||||
return scale;
|
if (scale !== $scope.clientProperties.scale)
|
||||||
};
|
$scope.clientProperties.scale = scale;
|
||||||
|
|
||||||
// Adjust scale if modified externally
|
|
||||||
$scope.$watch('clientParameters.scale', function changeScale(scale) {
|
|
||||||
$scope.setScale(scale);
|
|
||||||
checkScale();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Verify that the scale is within acceptable bounds, and adjust if needed
|
|
||||||
function checkScale() {
|
|
||||||
|
|
||||||
// If at minimum zoom level, auto fit is ON
|
|
||||||
if ($scope.scale === $scope.min_zoom) {
|
|
||||||
$scope.main.style.overflow = "hidden";
|
|
||||||
$scope.autoFitEnabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If at minimum zoom level, auto fit is OFF
|
|
||||||
else {
|
|
||||||
$scope.main.style.overflow = "auto";
|
|
||||||
$scope.autoFitEnabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var show_keyboard_gesture_possible = true;
|
var show_keyboard_gesture_possible = true;
|
||||||
|
|
||||||
// Handle Keyboard events
|
// Handle Keyboard events
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
<!-- Client -->
|
<!-- Client -->
|
||||||
<guac-client
|
<guac-client
|
||||||
client-parameters="clientParameters"
|
client-properties="clientProperties"
|
||||||
type="type"
|
type="type"
|
||||||
id="id"
|
id="id"
|
||||||
connection-name="connectionName"
|
connection-name="connectionName"
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<div id="notificationArea"/>
|
<div id="notificationArea"/>
|
||||||
|
|
||||||
<!-- Menu -->
|
<!-- Menu -->
|
||||||
<div ng-class="{closed: menuHasBeenShown && !menuShown, open: menuShown}" id="menu">
|
<div ng-class="{open: menuShown}" id="menu">
|
||||||
<h2 id="menu-title">Guacamole ${project.version}</h2>
|
<h2 id="menu-title">Guacamole ${project.version}</h2>
|
||||||
|
|
||||||
<h3>{{'client.clipboard' | translate}}</h3>
|
<h3>{{'client.clipboard' | translate}}</h3>
|
||||||
@@ -102,10 +102,10 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div id="zoom-settings">
|
<div id="zoom-settings">
|
||||||
<div ng-click="zoomOut()" id="zoom-out"><img src="images/settings/zoom-out.png" alt="-"/></div>
|
<div ng-click="zoomOut()" id="zoom-out"><img src="images/settings/zoom-out.png" alt="-"/></div>
|
||||||
<div id="zoom-state">{{formattedScale()}}</div>
|
<div id="zoom-state">{{formattedScale()}}%</div>
|
||||||
<div ng-click="zoomIn()" id="zoom-in"><img src="images/settings/zoom-in.png" alt="+"/></div>
|
<div ng-click="zoomIn()" id="zoom-in"><img src="images/settings/zoom-in.png" alt="+"/></div>
|
||||||
</div>
|
</div>
|
||||||
<div><label><input ng-model="autoFitEnabled" ng-change="autoFit(autoFitEnabled)" type="checkbox" id="auto-fit" checked="checked"/> {{'client.autoFit' | translate}}</label></div>
|
<div><label><input ng-model="autoFit" ng-disabled="autoFitDisabled()" type="checkbox" id="auto-fit"/> {{'client.autoFit' | translate}}</label></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user