/* 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());
}
}
});