/* Copyright (c) 2011, Geert Bergman (geert@scrivo.nl) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of "Scrivo" nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * $Id: HSVColorPicker.js 616 2013-04-22 23:48:38Z geert $ */ "use strict"; SUI.control.HSVColorPicker = SUI.defineClass( /** @lends SUI.control.HSVColorPicker.prototype */{ /** @ignore */ baseClass: SUI.AnchorLayout, /** * @class * SUI.control.HSVColorPicker is an enhanced version of the * SUI.control.HSVSelector so that the total hue, saturation, value color * selection control is more like the controls that you'll find in image * manipulation programs as the GIMP. Next to the HSV control you'll find * three input boxes where you can set the values for the hue, saturation * and value directly. Also an HTML color code can be entered directly. * Direct feedback of the control's current color selection is provided. * * @augments SUI.AnchorLayout * * @description * Create an HSV color picker control. * * @constructs * @param see base class * @param {Function} arg.onChange Listener function that is executed * each time the control's color selection changes. */ initializer: function(arg) { SUI.control.HSVColorPicker.initializeBase(this, arg); // Set the size of the control this.width(this.WIDTH); this.height(this.HEIGHT); // create a HSV color selection control this._hsv = new SUI.control.HSVSelector({}); // start at the top var top = this.PADDING; // create an input field and label for direct hue entry this._inpHue = new SUI.form.Input({ width: this.INPUT_WIDTH, right: this.PADDING, top: top, anchor: {right: true} }); this._lblHue = new SUI.form.Label({ width: this.LABEL_WIDTH, left: this.LABEL_LEFT, top: top, forBox: this._inpHue, title: SUI.i18n.hsvHue }); // move to next row top += this.ROW_HEIGHT; // create an input field and label for direct saturation entry this._inpSat = new SUI.form.Input({ width: this.INPUT_WIDTH, right: this.PADDING, top: top, anchor: {right: true} }); this._lblSat = new SUI.form.Label({ width: this.LABEL_WIDTH, left: this.LABEL_LEFT, top: top, forBox: this._inpSat, title: SUI.i18n.hsvSaturation }); // move to next row top += this.ROW_HEIGHT; // create an input field and label for direct value entry this._inpVal = new SUI.form.Input({ width: this.INPUT_WIDTH, right: this.PADDING, top: top, anchor: {right: true} }); this._lblVal = new SUI.form.Label({ width: this.LABEL_WIDTH, left: this.LABEL_LEFT, top: top, forBox: this._inpVal, title: SUI.i18n.hsvValue }); // move to next row top += this.ROW_HEIGHT; // create an input box and label for the HTML color code this._inpCode = new SUI.form.Input({ width: this.COLBOX_WIDTH, right: this.PADDING, top: top, anchor: {right: true} }); this._inpCode.el().maxLength = 7; this._inpCode.el().style.textAlign = "right"; this._inpCode.el().style.fontFamily = "mono"; this._lblCode = new SUI.form.Label({ width: this.LABEL_WIDTH, left: this.LABEL_LEFT, top: top, forBox: this._inpCode, title: SUI.i18n.hsvCode }); // move to next row top += this.ROW_HEIGHT; // create a colored box and label to display the color this._boxCol = new SUI.Box({ width: this.COLBOX_WIDTH, height: this.COLBOX_HEIGHT, right: this.PADDING, top: top, anchor: {right: true} }); this._boxCol.border(new SUI.Border(1)); this._boxCol.el().style.borderColor = "black"; this._lblColor = new SUI.form.Label({ width: this.LABEL_WIDTH, left: this.LABEL_LEFT, top: top, title: SUI.i18n.hsvColor }); // set the default value for the input fields this._setInputs(); // set the onChange listener if (arg.onChange) { this.addListener("onChange", arg.onChange); } // add the event handlers of the control this._addEventHandlers(); // now add all components to the control's container box this.add(this._hsv); this.add(this._lblHue); this.add(this._lblSat); this.add(this._lblVal); this.add(this._lblCode); this.add(this._lblColor); this.add(this._inpHue); this.add(this._inpSat); this.add(this._inpVal); this.add(this._inpCode); this.add(this._boxCol); }, /** * The height of the boxes in which the color an HTML color code are shown. */ COLBOX_HEIGHT: 20, /** * The Width of the boxes in which the color an HTML color code are shown. */ COLBOX_WIDTH: 64, /** * The total height of the control. */ HEIGHT: 158, /** * The width of the hue, saturation and value input boxes. */ INPUT_WIDTH: 30, /** * The left position of the labels. */ LABEL_LEFT: 200, /** * The width of the labels. */ LABEL_WIDTH: 100, /** * The padding of the control. */ PADDING: 15, /** * The row height for the rows with hue, saturation, value and color boxes. */ ROW_HEIGHT: 27, /** * The total width of the control. */ WIDTH: 335, /** * Set or get the HTML color code selection of the control. * @param {String} val An HTML color code (#FF7700), or none to get * the current color selection from the control. * @return {String} An HTML color code (#FF7700), if no argument was given * this method act as a getter and value will be returned. */ colorCode: function(val) { if (val == undefined) { return this._hsv.colorCode(); } // got here? the method is a setter // strip the # of the color value and try to convert it to a number ... var v = parseInt(val.substr(1), 16); // ... if that works and the is in the valid range ... if (!isNaN(v) && (v >= 0 && v <= 0xFFFFFF)) { // ... set the hsv control's color selection ... this._hsv.colorCode(val); // ... and hsv input fields this._setInputs(); } else { // ... throw an exception throw "SUI.control.HSVColorPicker: colorCode, invalid color"; } return null; }, /** * onChange event handler: is executed when the control's color selection * changes. * @param {String} c The HTML color code of the color that is currently * selected by the control. */ onChange: function(c) { }, // box for the HTML color code _inpCode: null, // box to display the selected color _boxCol: null, // the HSV control _hsv: null, // a label for the HTML color code box _lblCode: null, // a label for the color display box _lblColor: null, // a label for the hue input box _lblHue: null, // a label for the saturation input box _lblSat: null, // a label for the value input box _lblVal: null, // the hue input box _inpHue: null, // the saturation input box _inpSat: null, // the value input box _inpVal: null, // add the onblur event handlers to the input buttons an the onChange // listener to the HSV control. _addEventHandlers: function() { var that = this; // set hue on the onblur of the hue input field SUI.browser.addEventListener(this._inpHue.el(), "blur", function(e) { if (!that._setHue(that._inpHue.el().value)) { SUI.browser.noPropagation(e); } } ); // set saturation on the onblur of the saturation input field SUI.browser.addEventListener(this._inpSat.el(), "blur", function(e) { if (that._setSaturation(that._inpSat.el().value)) { SUI.browser.noPropagation(e); } } ); // set value on the onblur of the value input field SUI.browser.addEventListener(this._inpVal.el(), "blur", function(e) { if (that._setValue(that._inpVal.el().value)) { SUI.browser.noPropagation(e); } } ); // after entering the color set control's color selection so that // it will reflect the changes SUI.browser.addEventListener(this._inpCode.el(), "blur", function(e) { that.colorCode(this.value); that.callListener("onChange", that._hsv.colorCode()); SUI.browser.noPropagation(e); } ); // set the input fields if the HSV control's color selection changes this._hsv.addListener("onChange", function(c) { that._setInputs(); that.callListener("onChange", that._hsv.colorCode()); } ); }, // set the hue of the control's selected color _setHue: function(val) { // get the hue in degrees ... var v = parseInt(String(val), 10); // ... is it a valid selection? if (!isNaN(v) && (v >= 0 && v <= 360)) { // yes, set the HSV control's hue ... this._hsv.hue(v); // ... set the input fields to HSV control's color selection ... this._setInputs(); // ... and notify listeners that the color selection was changed this.callListener("onChange", this._hsv.colorCode()); } }, // set the input field and color boxes to reflect the color that is // selected by the HSV control _setInputs: function() { var c = this._hsv.colorCode(); // get the hue of the HSV control and set the hue input field this._inpHue.el().value = this._hsv.hue() | 0; // get saturation of HSV ctrl and set sat. input field as percentage this._inpSat.el().value = this._hsv.saturation() * 100 | 0; // get value of HSV ctrl and set value input field as percentage this._inpVal.el().value = this._hsv.value() * 100 | 0; // display the color code in the text box this._inpCode.el().value = c.toUpperCase(); // display the color in the color box this._boxCol.el().style.backgroundColor = c; }, // set the saturation of the control's selected color _setSaturation: function(val) { // get the saturation in degrees ... var v = parseInt(String(val), 10); // ... is it a valid selection? if (!isNaN(v) && (v >= 0 && v <= 100)) { // yes, set the HSV control's saturation ... this._hsv.saturation(v/100); // ... set the input fields to HSV control's color selection ... this._setInputs(); // ... and notify listeners that the color selection was changed this.callListener("onChange", this._hsv.colorCode()); } }, // set the value of the control's selected color _setValue: function(val) { // get the value as percentage ... var v = parseInt(String(val), 10); // ... is it a valid selection? if (!isNaN(v) && (v >= 0 && v <= 100)) { // yes, set the HSV control's value ... this._hsv.value(v/100); // ... set the input fields to HSV control's color selection ... this._setInputs(); // ... and notify listeners that the color selection was changed this.callListener("onChange", this._hsv.colorCode()); } } });