mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
Merge pull request #77 from glyptodon/mobile-issues
GUAC-1044: Fix appearance of menu.
This commit is contained in:
@@ -154,25 +154,49 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
|
|||||||
callback: RECONNECT_ACTION.callback,
|
callback: RECONNECT_ACTION.callback,
|
||||||
remaining: 15
|
remaining: 15
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hide menu by default
|
|
||||||
$scope.menuShown = false;
|
|
||||||
|
|
||||||
// Use physical keyboard by default
|
/**
|
||||||
$scope.inputMethod = 'none';
|
* Menu-specific properties.
|
||||||
|
*/
|
||||||
|
$scope.menu = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the menu is currently shown.
|
||||||
|
*
|
||||||
|
* @type Boolean
|
||||||
|
*/
|
||||||
|
shown : false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the Guacamole display should be scaled to fit the browser
|
||||||
|
* window.
|
||||||
|
*
|
||||||
|
* @type Boolean
|
||||||
|
*/
|
||||||
|
autoFit : true,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The currently selected input method. This may be either "none",
|
||||||
|
* "osk", or "text".
|
||||||
|
*
|
||||||
|
* @type String
|
||||||
|
*/
|
||||||
|
inputMethod : 'none',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current scroll state of the menu.
|
||||||
|
*
|
||||||
|
* @type ScrollState
|
||||||
|
*/
|
||||||
|
scrollState : new ScrollState()
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
// Convenience method for closing the menu
|
// Convenience method for closing the menu
|
||||||
$scope.closeMenu = function closeMenu() {
|
$scope.closeMenu = function closeMenu() {
|
||||||
$scope.menuShown = false;
|
$scope.menu.shown = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* The current scroll state of the menu.
|
|
||||||
*
|
|
||||||
* @type ScrollState
|
|
||||||
*/
|
|
||||||
$scope.menuScrollState = new ScrollState();
|
|
||||||
|
|
||||||
// Update the model when clipboard data received from client
|
// Update the model when clipboard data received from client
|
||||||
$scope.$on('guacClientClipboard', function clientClipboardListener(event, client, mimetype, clipboardData) {
|
$scope.$on('guacClientClipboard', function clientClipboardListener(event, client, mimetype, clipboardData) {
|
||||||
$scope.clipboardData = clipboardData;
|
$scope.clipboardData = clipboardData;
|
||||||
@@ -206,12 +230,12 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
|
|||||||
// Hide menu if swipe gesture is detected
|
// Hide menu if swipe gesture is detected
|
||||||
if (Math.abs(currentY - startY) < MENU_DRAG_VERTICAL_TOLERANCE
|
if (Math.abs(currentY - startY) < MENU_DRAG_VERTICAL_TOLERANCE
|
||||||
&& startX - currentX >= MENU_DRAG_DELTA)
|
&& startX - currentX >= MENU_DRAG_DELTA)
|
||||||
$scope.menuShown = false;
|
$scope.menu.shown = false;
|
||||||
|
|
||||||
// Scroll menu by default
|
// Scroll menu by default
|
||||||
else {
|
else {
|
||||||
$scope.menuScrollState.left -= deltaX;
|
$scope.menu.scrollState.left -= deltaX;
|
||||||
$scope.menuScrollState.top -= deltaY;
|
$scope.menu.scrollState.top -= deltaY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -226,7 +250,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
|
|||||||
|
|
||||||
if (Math.abs(currentY - startY) < MENU_DRAG_VERTICAL_TOLERANCE
|
if (Math.abs(currentY - startY) < MENU_DRAG_VERTICAL_TOLERANCE
|
||||||
&& currentX - startX >= MENU_DRAG_DELTA)
|
&& currentX - startX >= MENU_DRAG_DELTA)
|
||||||
$scope.menuShown = true;
|
$scope.menu.shown = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,7 +318,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
|
|||||||
currentScale = Math.min(currentScale, $scope.client.clientProperties.maxScale);
|
currentScale = Math.min(currentScale, $scope.client.clientProperties.maxScale);
|
||||||
|
|
||||||
// Update scale based on pinch distance
|
// Update scale based on pinch distance
|
||||||
$scope.autoFit = false;
|
$scope.menu.autoFit = false;
|
||||||
$scope.client.clientProperties.autoFit = false;
|
$scope.client.clientProperties.autoFit = false;
|
||||||
$scope.client.clientProperties.scale = currentScale;
|
$scope.client.clientProperties.scale = currentScale;
|
||||||
|
|
||||||
@@ -307,7 +331,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Show/hide UI elements depending on input method
|
// Show/hide UI elements depending on input method
|
||||||
$scope.$watch('inputMethod', function setInputMethod(inputMethod) {
|
$scope.$watch('menu.inputMethod', function setInputMethod(inputMethod) {
|
||||||
|
|
||||||
// Show input methods only if selected
|
// Show input methods only if selected
|
||||||
$scope.showOSK = (inputMethod === 'osk');
|
$scope.showOSK = (inputMethod === 'osk');
|
||||||
@@ -315,7 +339,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.$watch('menuShown', function menuVisibilityChanged(menuShown, menuShownPreviousState) {
|
$scope.$watch('menu.shown', function menuVisibilityChanged(menuShown, menuShownPreviousState) {
|
||||||
|
|
||||||
// Send clipboard data if menu is hidden
|
// Send clipboard data if menu is hidden
|
||||||
if (!menuShown && menuShownPreviousState)
|
if (!menuShown && menuShownPreviousState)
|
||||||
@@ -351,7 +375,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
|
|||||||
|
|
||||||
// Toggle the menu
|
// Toggle the menu
|
||||||
$scope.$apply(function() {
|
$scope.$apply(function() {
|
||||||
$scope.menuShown = !$scope.menuShown;
|
$scope.menu.shown = !$scope.menu.shown;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -372,8 +396,8 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
|
|||||||
|
|
||||||
// Show menu and scroll file transfer into view
|
// Show menu and scroll file transfer into view
|
||||||
if (count > oldCount) {
|
if (count > oldCount) {
|
||||||
$scope.menuShown = true;
|
$scope.menu.shown = true;
|
||||||
$scope.fileTransferMarker.scrollIntoView();
|
$scope.menu.fileTransferMarker.scrollIntoView();
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -460,7 +484,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.zoomIn = function zoomIn() {
|
$scope.zoomIn = function zoomIn() {
|
||||||
$scope.autoFit = false;
|
$scope.menu.autoFit = false;
|
||||||
$scope.client.clientProperties.autoFit = false;
|
$scope.client.clientProperties.autoFit = false;
|
||||||
$scope.client.clientProperties.scale += 0.1;
|
$scope.client.clientProperties.scale += 0.1;
|
||||||
};
|
};
|
||||||
@@ -470,12 +494,11 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
|
|||||||
$scope.client.clientProperties.scale -= 0.1;
|
$scope.client.clientProperties.scale -= 0.1;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.autoFit = true;
|
|
||||||
|
|
||||||
$scope.changeAutoFit = function changeAutoFit() {
|
$scope.changeAutoFit = function changeAutoFit() {
|
||||||
if ($scope.autoFit && $scope.client.clientProperties.minScale) {
|
if ($scope.menu.autoFit && $scope.client.clientProperties.minScale) {
|
||||||
$scope.client.clientProperties.autoFit = true;
|
$scope.client.clientProperties.autoFit = true;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
$scope.client.clientProperties.autoFit = false;
|
$scope.client.clientProperties.autoFit = false;
|
||||||
$scope.client.clientProperties.scale = 1;
|
$scope.client.clientProperties.scale = 1;
|
||||||
}
|
}
|
||||||
@@ -495,7 +518,7 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams
|
|||||||
$scope.client.client.disconnect();
|
$scope.client.client.disconnect();
|
||||||
|
|
||||||
// Hide menu
|
// Hide menu
|
||||||
$scope.menuShown = false;
|
$scope.menu.shown = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -30,6 +30,11 @@ angular.module('client').factory('guacAudio', [function guacAudio() {
|
|||||||
*/
|
*/
|
||||||
return new (function() {
|
return new (function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of codecs to test.
|
||||||
|
*
|
||||||
|
* @type String[]
|
||||||
|
*/
|
||||||
var codecs = [
|
var codecs = [
|
||||||
'audio/ogg; codecs="vorbis"',
|
'audio/ogg; codecs="vorbis"',
|
||||||
'audio/mp4; codecs="mp4a.40.5"',
|
'audio/mp4; codecs="mp4a.40.5"',
|
||||||
@@ -38,41 +43,70 @@ angular.module('client').factory('guacAudio', [function guacAudio() {
|
|||||||
'audio/wav; codecs=1'
|
'audio/wav; codecs=1'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of all codecs that are reported as "probably" supported.
|
||||||
|
*
|
||||||
|
* @type String[]
|
||||||
|
*/
|
||||||
var probably_supported = [];
|
var probably_supported = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of all codecs that are reported as "maybe" supported.
|
||||||
|
*
|
||||||
|
* @type String[]
|
||||||
|
*/
|
||||||
var maybe_supported = [];
|
var maybe_supported = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal audio element for the sake of testing codec support. If
|
||||||
|
* audio is explicitly not supported by the browser, this will instead
|
||||||
|
* be null.
|
||||||
|
*
|
||||||
|
* @type Audio
|
||||||
|
*/
|
||||||
|
var audio = null;
|
||||||
|
|
||||||
|
// Attempt to create audio element
|
||||||
|
try {
|
||||||
|
audio = new Audio();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
// If creation fails, allow audio to remain null
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array of all supported audio mimetypes, ordered by liklihood of
|
* Array of all supported audio mimetypes, ordered by liklihood of
|
||||||
* working.
|
* working.
|
||||||
*/
|
*/
|
||||||
this.supported = [];
|
this.supported = [];
|
||||||
|
|
||||||
// Build array of supported audio formats
|
// Build array of supported audio formats (if audio supported at all)
|
||||||
codecs.forEach(function(mimetype) {
|
if (audio) {
|
||||||
|
codecs.forEach(function(mimetype) {
|
||||||
|
|
||||||
var audio = new Audio();
|
var support_level = audio.canPlayType(mimetype);
|
||||||
var support_level = audio.canPlayType(mimetype);
|
|
||||||
|
|
||||||
// Trim semicolon and trailer
|
// Trim semicolon and trailer
|
||||||
var semicolon = mimetype.indexOf(";");
|
var semicolon = mimetype.indexOf(";");
|
||||||
if (semicolon != -1)
|
if (semicolon !== -1)
|
||||||
mimetype = mimetype.substring(0, semicolon);
|
mimetype = mimetype.substring(0, semicolon);
|
||||||
|
|
||||||
// Partition by probably/maybe
|
// Partition by probably/maybe
|
||||||
if (support_level == "probably")
|
if (support_level === "probably")
|
||||||
probably_supported.push(mimetype);
|
probably_supported.push(mimetype);
|
||||||
else if (support_level == "maybe")
|
else if (support_level === "maybe")
|
||||||
maybe_supported.push(mimetype);
|
maybe_supported.push(mimetype);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add probably supported types first
|
// Add probably supported types first
|
||||||
Array.prototype.push.apply(
|
Array.prototype.push.apply(
|
||||||
this.supported, probably_supported);
|
this.supported, probably_supported);
|
||||||
|
|
||||||
// Prioritize "maybe" supported types second
|
// Prioritize "maybe" supported types second
|
||||||
Array.prototype.push.apply(
|
Array.prototype.push.apply(
|
||||||
this.supported, maybe_supported);
|
this.supported, maybe_supported);
|
||||||
|
}
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@@ -21,10 +21,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#menu {
|
#menu {
|
||||||
overflow: auto;
|
overflow: hidden;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
height: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
width: 480px;
|
width: 480px;
|
||||||
background: #EEE;
|
background: #EEE;
|
||||||
@@ -37,6 +37,43 @@
|
|||||||
transition: left 0.125s, opacity 0.125s;
|
transition: left 0.125s, opacity 0.125s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.menu-content {
|
||||||
|
overflow: hidden;
|
||||||
|
display: table;
|
||||||
|
table-layout: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-header {
|
||||||
|
display: table-row;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-header h2 {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-body {
|
||||||
|
display: table-row;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-body-content {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-body-scroll-region {
|
||||||
|
overflow: auto;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
#menu h3 {
|
#menu h3 {
|
||||||
margin: 1em;
|
margin: 1em;
|
||||||
}
|
}
|
||||||
|
@@ -20,8 +20,9 @@
|
|||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- Client view -->
|
|
||||||
<guac-viewport>
|
<guac-viewport>
|
||||||
|
|
||||||
|
<!-- Client view -->
|
||||||
<div class="client-view">
|
<div class="client-view">
|
||||||
|
|
||||||
<!-- Central portion of view -->
|
<!-- Central portion of view -->
|
||||||
@@ -42,97 +43,110 @@
|
|||||||
|
|
||||||
<!-- On-screen keyboard -->
|
<!-- On-screen keyboard -->
|
||||||
<div class="keyboard-container" ng-show="showOSK">
|
<div class="keyboard-container" ng-show="showOSK">
|
||||||
<guac-osk layout="'CLIENT.URL_OSK_LAYOUT' | translate"/>
|
<guac-osk layout="'CLIENT.URL_OSK_LAYOUT' | translate"></guac-osk>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Menu -->
|
||||||
|
<div ng-class="{open: menu.shown}" id="menu">
|
||||||
|
<div class="menu-content">
|
||||||
|
|
||||||
|
<!-- Stationary header -->
|
||||||
|
<div class="menu-header">
|
||||||
|
<div class="logout-panel">
|
||||||
|
<a class="home button" href="#/">{{'CLIENT.ACTION_NAVIGATE_HOME' | translate}}</a>
|
||||||
|
<a class="disconnect danger button" ng-click="disconnect()">{{'CLIENT.ACTION_DISCONNECT' | translate}}</a>
|
||||||
|
</div>
|
||||||
|
<h2>{{client.name}}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Scrollable body -->
|
||||||
|
<div class="menu-body">
|
||||||
|
<div class="menu-body-content">
|
||||||
|
<div class="menu-body-scroll-region" guac-touch-drag="menuDrag" guac-scroll="menu.scrollState">
|
||||||
|
|
||||||
|
<!-- Clipboard -->
|
||||||
|
<h3>{{'CLIENT.SECTION_HEADER_CLIPBOARD' | translate}}</h3>
|
||||||
|
<div class="content" id="clipboard-settings">
|
||||||
|
<p class="description">{{'CLIENT.HELP_CLIPBOARD' | translate}}</p>
|
||||||
|
<textarea ng-model="client.clipboardData" rows="10" cols="40" id="clipboard"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- File transfers -->
|
||||||
|
<h3 guac-marker="menu.fileTransferMarker">{{'CLIENT.SECTION_HEADER_FILE_TRANSFERS' | translate}}</h3>
|
||||||
|
<div class="content" id="file-transfers">
|
||||||
|
<guac-file-transfer-manager client="client"></guac-file-transfer-manager>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Input method -->
|
||||||
|
<h3>{{'CLIENT.SECTION_HEADER_INPUT_METHOD' | translate}}</h3>
|
||||||
|
<div class="content" id="keyboard-settings">
|
||||||
|
|
||||||
|
<!-- No IME -->
|
||||||
|
<div class="choice">
|
||||||
|
<label><input id="ime-none" name="input-method" ng-change="closeMenu()" ng-model="menu.inputMethod" type="radio" value="none"/> {{'CLIENT.NAME_INPUT_METHOD_NONE' | translate}}</label>
|
||||||
|
<p class="caption"><label for="ime-none">{{'CLIENT.HELP_INPUT_METHOD_NONE' | translate}}</label></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Text input -->
|
||||||
|
<div class="choice">
|
||||||
|
<div class="figure"><label for="ime-text"><img src="images/settings/tablet-keys.png" alt=""/></label></div>
|
||||||
|
<label><input id="ime-text" name="input-method" ng-change="closeMenu()" ng-model="menu.inputMethod" type="radio" value="text"/> {{'CLIENT.NAME_INPUT_METHOD_TEXT' | translate}}</label>
|
||||||
|
<p class="caption"><label for="ime-text">{{'CLIENT.HELP_INPUT_METHOD_TEXT' | translate}} </label></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Guac OSK -->
|
||||||
|
<div class="choice">
|
||||||
|
<label><input id="ime-osk" name="input-method" ng-change="closeMenu()" ng-model="menu.inputMethod" type="radio" value="osk"/> {{'CLIENT.NAME_INPUT_METHOD_OSK' | translate}}</label>
|
||||||
|
<p class="caption"><label for="ime-osk">{{'CLIENT.HELP_INPUT_METHOD_OSK' | translate}}</label></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Mouse mode -->
|
||||||
|
<h3>{{'CLIENT.SECTION_HEADER_MOUSE_MODE' | translate}}</h3>
|
||||||
|
<div class="content" id="mouse-settings">
|
||||||
|
<p class="description">{{'CLIENT.HELP_MOUSE_MODE' | translate}}</p>
|
||||||
|
|
||||||
|
<!-- Touchscreen -->
|
||||||
|
<div class="choice">
|
||||||
|
<input name="mouse-mode" ng-change="closeMenu()" ng-model="client.clientProperties.emulateAbsoluteMouse" type="radio" ng-value="true" checked="checked" id="absolute"/>
|
||||||
|
<div class="figure">
|
||||||
|
<label for="absolute"><img src="images/settings/touchscreen.png" alt="{{'CLIENT.NAME_MOUSE_MODE_ABSOLUTE' | translate}}"/></label>
|
||||||
|
<p class="caption"><label for="absolute">{{'CLIENT.HELP_MOUSE_MODE_ABSOLUTE' | translate}}</label></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Touchpad -->
|
||||||
|
<div class="choice">
|
||||||
|
<input name="mouse-mode" ng-change="closeMenu()" ng-model="client.clientProperties.emulateAbsoluteMouse" type="radio" ng-value="false" id="relative"/>
|
||||||
|
<div class="figure">
|
||||||
|
<label for="relative"><img src="images/settings/touchpad.png" alt="{{'CLIENT.NAME_MOUSE_MODE_RELATIVE' | translate}}"/></label>
|
||||||
|
<p class="caption"><label for="relative">{{'CLIENT.HELP_MOUSE_MODE_RELATIVE' | translate}}</label></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Display options -->
|
||||||
|
<h3>{{'CLIENT.SECTION_HEADER_DISPLAY' | translate}}</h3>
|
||||||
|
<div class="content">
|
||||||
|
<div id="zoom-settings">
|
||||||
|
<div ng-click="zoomOut()" id="zoom-out"><img src="images/settings/zoom-out.png" alt="-"/></div>
|
||||||
|
<div id="zoom-state">{{formattedScale()}}%</div>
|
||||||
|
<div ng-click="zoomIn()" id="zoom-in"><img src="images/settings/zoom-in.png" alt="+"/></div>
|
||||||
|
</div>
|
||||||
|
<div><label><input ng-model="menu.autoFit" ng-change="changeAutoFit()" ng-disabled="autoFitDisabled()" type="checkbox" id="auto-fit"/> {{'CLIENT.TEXT_ZOOM_AUTO_FIT' | translate}}</label></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</guac-viewport>
|
</guac-viewport>
|
||||||
|
|
||||||
<!-- Menu -->
|
|
||||||
<div ng-class="{open: menuShown}" id="menu" guac-touch-drag="menuDrag" guac-scroll="menuScrollState">
|
|
||||||
|
|
||||||
<div class="logout-panel">
|
|
||||||
<a class="home button" href="#/">{{'CLIENT.ACTION_NAVIGATE_HOME' | translate}}</a>
|
|
||||||
<a class="disconnect danger button" ng-click="disconnect()">{{'CLIENT.ACTION_DISCONNECT' | translate}}</a>
|
|
||||||
</div>
|
|
||||||
<h2>{{client.name}}</h2>
|
|
||||||
|
|
||||||
<!-- Clipboard -->
|
|
||||||
<h3>{{'CLIENT.SECTION_HEADER_CLIPBOARD' | translate}}</h3>
|
|
||||||
<div class="content" id="clipboard-settings">
|
|
||||||
<p class="description">{{'CLIENT.HELP_CLIPBOARD' | translate}}</p>
|
|
||||||
<textarea ng-model="client.clipboardData" rows="10" cols="40" id="clipboard"></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- File transfers -->
|
|
||||||
<h3 guac-marker="fileTransferMarker">{{'CLIENT.SECTION_HEADER_FILE_TRANSFERS' | translate}}</h3>
|
|
||||||
<div class="content" id="file-transfers">
|
|
||||||
<guac-file-transfer-manager client="client"></guac-file-transfer-manager>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Input method -->
|
|
||||||
<h3>{{'CLIENT.SECTION_HEADER_INPUT_METHOD' | translate}}</h3>
|
|
||||||
<div class="content" id="keyboard-settings">
|
|
||||||
|
|
||||||
<!-- No IME -->
|
|
||||||
<div class="choice">
|
|
||||||
<label><input id="ime-none" name="input-method" ng-change="closeMenu()" ng-model="inputMethod" type="radio" value="none"/> {{'CLIENT.NAME_INPUT_METHOD_NONE' | translate}}</label>
|
|
||||||
<p class="caption"><label for="ime-none">{{'CLIENT.HELP_INPUT_METHOD_NONE' | translate}}</label></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Text input -->
|
|
||||||
<div class="choice">
|
|
||||||
<div class="figure"><label for="ime-text"><img src="images/settings/tablet-keys.png" alt=""/></label></div>
|
|
||||||
<label><input id="ime-text" name="input-method" ng-change="closeMenu()" ng-model="inputMethod" type="radio" value="text"/> {{'CLIENT.NAME_INPUT_METHOD_TEXT' | translate}}</label>
|
|
||||||
<p class="caption"><label for="ime-text">{{'CLIENT.HELP_INPUT_METHOD_TEXT' | translate}} </label></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Guac OSK -->
|
|
||||||
<div class="choice">
|
|
||||||
<label><input id="ime-osk" name="input-method" ng-change="closeMenu()" ng-model="inputMethod" type="radio" value="osk"/> {{'CLIENT.NAME_INPUT_METHOD_OSK' | translate}}</label>
|
|
||||||
<p class="caption"><label for="ime-osk">{{'CLIENT.HELP_INPUT_METHOD_OSK' | translate}}</label></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Mouse mode -->
|
|
||||||
<h3>{{'CLIENT.SECTION_HEADER_MOUSE_MODE' | translate}}</h3>
|
|
||||||
<div class="content" id="mouse-settings">
|
|
||||||
<p class="description">{{'CLIENT.HELP_MOUSE_MODE' | translate}}</p>
|
|
||||||
|
|
||||||
<!-- Touchscreen -->
|
|
||||||
<div class="choice">
|
|
||||||
<input name="mouse-mode" ng-change="closeMenu()" ng-model="client.clientProperties.emulateAbsoluteMouse" type="radio" ng-value="true" checked="checked" id="absolute"/>
|
|
||||||
<div class="figure">
|
|
||||||
<label for="absolute"><img src="images/settings/touchscreen.png" alt="{{'CLIENT.NAME_MOUSE_MODE_ABSOLUTE' | translate}}"/></label>
|
|
||||||
<p class="caption"><label for="absolute">{{'CLIENT.HELP_MOUSE_MODE_ABSOLUTE' | translate}}</label></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Touchpad -->
|
|
||||||
<div class="choice">
|
|
||||||
<input name="mouse-mode" ng-change="closeMenu()" ng-model="client.clientProperties.emulateAbsoluteMouse" type="radio" ng-value="false" id="relative"/>
|
|
||||||
<div class="figure">
|
|
||||||
<label for="relative"><img src="images/settings/touchpad.png" alt="{{'CLIENT.NAME_MOUSE_MODE_RELATIVE' | translate}}"/></label>
|
|
||||||
<p class="caption"><label for="relative">{{'CLIENT.HELP_MOUSE_MODE_RELATIVE' | translate}}</label></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Display options -->
|
|
||||||
<h3>{{'CLIENT.SECTION_HEADER_DISPLAY' | translate}}</h3>
|
|
||||||
<div class="content">
|
|
||||||
<div id="zoom-settings">
|
|
||||||
<div ng-click="zoomOut()" id="zoom-out"><img src="images/settings/zoom-out.png" alt="-"/></div>
|
|
||||||
<div id="zoom-state">{{formattedScale()}}%</div>
|
|
||||||
<div ng-click="zoomIn()" id="zoom-in"><img src="images/settings/zoom-in.png" alt="+"/></div>
|
|
||||||
</div>
|
|
||||||
<div><label><input ng-model="autoFit" ng-change="changeAutoFit()" ng-disabled="autoFitDisabled()" type="checkbox" id="auto-fit"/> {{'CLIENT.TEXT_ZOOM_AUTO_FIT' | translate}}</label></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
Reference in New Issue
Block a user