diff --git a/guacamole/pom.xml b/guacamole/pom.xml
index 7a686065c..8f90f2715 100644
--- a/guacamole/pom.xml
+++ b/guacamole/pom.xml
@@ -501,6 +501,13 @@
1.0.10
+
+
+ org.webjars.npm
+ simonwep__pickr
+ 1.2.6
+
+
diff --git a/guacamole/src/licenses/LICENSE b/guacamole/src/licenses/LICENSE
index 1e228d2e5..7c696e57f 100644
--- a/guacamole/src/licenses/LICENSE
+++ b/guacamole/src/licenses/LICENSE
@@ -688,6 +688,37 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+Pickr (https://simonwep.github.io/pickr/)
+-----------------------------------------
+
+ Version: 1.2.6
+ From: 'Simon Reinisch' (https://github.com/Simonwep/)
+ License(s):
+ MIT (bundled/pickr-1.2.6/LICENSE)
+
+MIT License
+
+Copyright (c) 2019 Simon Reinisch
+
+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.
+
+
Simple Logging Facade for Java (http://slf4j.org/)
--------------------------------------------------
diff --git a/guacamole/src/licenses/bundled/pickr-1.2.6/LICENSE b/guacamole/src/licenses/bundled/pickr-1.2.6/LICENSE
new file mode 100644
index 000000000..e02b384f9
--- /dev/null
+++ b/guacamole/src/licenses/bundled/pickr-1.2.6/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Simon Reinisch
+
+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.
diff --git a/guacamole/src/main/webapp/app/form/controllers/terminalColorSchemeFieldController.js b/guacamole/src/main/webapp/app/form/controllers/terminalColorSchemeFieldController.js
index d3f23e535..d999cc6b5 100644
--- a/guacamole/src/main/webapp/app/form/controllers/terminalColorSchemeFieldController.js
+++ b/guacamole/src/main/webapp/app/form/controllers/terminalColorSchemeFieldController.js
@@ -47,6 +47,14 @@ angular.module('form').controller('terminalColorSchemeFieldController', ['$scope
*/
$scope.customColorScheme = new ColorScheme();
+ /**
+ * The array of colors to include within the color picker as pre-defined
+ * options for convenience.
+ *
+ * @type String[]
+ */
+ $scope.defaultPalette = new ColorScheme().colors;
+
/**
* The string value which is assigned to selectedColorScheme if a custom
* color scheme is selected.
diff --git a/guacamole/src/main/webapp/app/form/directives/guacInputColor.js b/guacamole/src/main/webapp/app/form/directives/guacInputColor.js
new file mode 100644
index 000000000..e5cd3bfd5
--- /dev/null
+++ b/guacamole/src/main/webapp/app/form/directives/guacInputColor.js
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * A directive which implements a color input field, leveraging the "Pickr"
+ * color picker.
+ */
+angular.module('form').directive('guacInputColor', [function guacInputColor() {
+
+ var config = {
+ restrict: 'E',
+ replace: true,
+ templateUrl: 'app/form/templates/guacInputColor.html',
+ };
+
+ config.scope = {
+
+ /**
+ * The current selected color value, in standard 6-digit hexadecimal
+ * RGB notation. When the user selects a different color using this
+ * directive, this value will updated accordingly.
+ *
+ * @type String
+ */
+ model: '=',
+
+ /**
+ * An optional array of colors to include within the color picker as a
+ * convenient selection of pre-defined colors. The colors within the
+ * array must be in standard 6-digit hexadecimal RGB notation.
+ *
+ * @type String[]
+ */
+ palette: '='
+
+ };
+
+ config.controller = ['$scope', '$element', '$injector',
+ function guacInputColorController($scope, $element, $injector) {
+
+ // Required services
+ var $q = $injector.get('$q');
+ var $translate = $injector.get('$translate');
+
+ // Init color picker after required translation strings are available
+ $q.all({
+ 'save' : $translate('APP.ACTION_SAVE'),
+ 'cancel' : $translate('APP.ACTION_CANCEL')
+ }).then(function stringsRetrieved(strings) {
+
+ /**
+ * An instance of the "Pickr" color picker, bound to the underlying
+ * element of this directive.
+ *
+ * @type Pickr
+ */
+ var pickr = Pickr.create({
+
+ // Bind color picker to the underlying element of this directive
+ el : $element[0],
+
+ // Wrap color picker dialog in Guacamole-specific class for
+ // sake of additional styling
+ appClass : 'guac-input-color-picker',
+
+ // Display color details as hex
+ defaultRepresentation : 'HEX',
+
+ // Use "monolith" theme, as a nice balance between "nano" (does
+ // not work in Internet Explorer) and "classic" (too big)
+ theme : 'monolith',
+
+ // Leverage the container element as the button which shows the
+ // picker, relying on our own styling for that button
+ useAsButton : true,
+ appendToBody : true,
+
+ // Do not include opacity controls
+ lockOpacity : true,
+
+ // Include a selection of palette entries for convenience and
+ // reference
+ swatches : $scope.palette || [],
+
+ components: {
+
+ // Include hue and color preview controls
+ preview : true,
+ hue : true,
+
+ // Display only a text color input field and the save and
+ // cancel buttons (no clear button)
+ interaction: {
+ input : true,
+ save : true,
+ cancel : true
+ }
+
+ },
+
+ // Use translation strings for buttons
+ strings : strings
+
+ });
+
+ // Hide color picker after user clicks "cancel"
+ pickr.on('cancel', function colorChangeCanceled() {
+ pickr.hide();
+ });
+
+ // Keep model in sync with changes to the color picker
+ pickr.on('save', function colorChanged(color) {
+ $scope.$evalAsync(function updateModel() {
+ $scope.model = color.toHEXA().toString();
+ });
+ });
+
+ // Keep color picker in sync with changes to the model
+ pickr.on('init', function pickrReady(color) {
+ $scope.$watch('model', function modelChanged(model) {
+ pickr.setColor(model);
+ });
+ });
+
+ }, angular.noop);
+
+ }];
+
+ return config;
+
+}]);
diff --git a/guacamole/src/main/webapp/app/form/styles/terminal-color-scheme-field.css b/guacamole/src/main/webapp/app/form/styles/terminal-color-scheme-field.css
index fc16501c3..e3b393d35 100644
--- a/guacamole/src/main/webapp/app/form/styles/terminal-color-scheme-field.css
+++ b/guacamole/src/main/webapp/app/form/styles/terminal-color-scheme-field.css
@@ -41,8 +41,6 @@
width: 100%;
margin: 0;
padding: 0;
- display: flex;
- flex-wrap: wrap;
}
.form-field .terminal-color-scheme-field .custom-color-scheme .palette-group {
@@ -51,8 +49,26 @@
flex: 1;
}
-.form-field .terminal-color-scheme-field .custom-color-scheme input[type="color"] {
+.form-field .terminal-color-scheme-field .custom-color-scheme .guac-input-color {
display: block;
margin: 2px;
flex: 1;
-}
\ No newline at end of file
+ width: 1.5em;
+ height: 1.5em;
+ min-width: 1.25em;
+ border-radius: 0.15em;
+}
+
+/* Increase width of color picker to allow two even rows of eight color
+ * swatches */
+.guac-input-color-picker[data-theme="monolith"] {
+ width: 16.25em;
+}
+
+/* Remove Guacamole-specific styles inherited from the generic button rules */
+.guac-input-color-picker[data-theme="monolith"] button {
+ min-width: 0;
+ padding: 0;
+ margin: 0;
+ box-shadow: none;
+}
diff --git a/guacamole/src/main/webapp/app/form/templates/guacInputColor.html b/guacamole/src/main/webapp/app/form/templates/guacInputColor.html
new file mode 100644
index 000000000..de6f15e56
--- /dev/null
+++ b/guacamole/src/main/webapp/app/form/templates/guacInputColor.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/guacamole/src/main/webapp/app/form/templates/terminalColorSchemeField.html b/guacamole/src/main/webapp/app/form/templates/terminalColorSchemeField.html
index 491270fdd..5a2db3a91 100644
--- a/guacamole/src/main/webapp/app/form/templates/terminalColorSchemeField.html
+++ b/guacamole/src/main/webapp/app/form/templates/terminalColorSchemeField.html
@@ -11,13 +11,17 @@