/* 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: ColorIntensityBar.js 616 2013-04-22 23:48:38Z geert $ */ "use strict"; SUI.control.ColorIntensityBar = SUI.defineClass( /** @lends SUI.control.ColorIntensityBar.prototype */{ /** @ignore */ baseClass: SUI.Box, /** * @class * SUI.control.ColorIntensityBar is a slider control to make a color * intensity selection for a single RGB color component. The intensity * selection made will be in the range 0-1. * * @augments SUI.Box * * @description * Create a color intensity bar. The bar is always 256 pixels long and * 20 pixels high. * * @constructs * @param see base class * @param {String} arg.color The background color of the control: "r", * "g" or "b". * @param {Function} arg.onChange Listener function that is executed each * time the control's color intensity selection changes. */ initializer: function(arg) { SUI.control.ColorIntensityBar.initializeBase(this, arg); // set the width and height of the bar this.width(this.AXIS_LENGTH); this.height(this.HEIGHT); // the background image and color of the bar this.el().style.backgroundImage = "url(" + SUI.imgDir + "/" + SUI.resource.rgbBar+")"; this.el().style.backgroundColor = arg.color == "r" ? "#FF0000" : (arg.color == "g" ? "#00FF00" : "#0000FF"); // the crosshair extends over the bar's edges, show it this.el().style.overflow = "visible"; // conversion from length to range can be done nicely by substracting // the crosshair width of the length this._axisRange = this.AXIS_LENGTH - this.CROSSHAIR_LINE; // calculate the top offset of the crosshair image w.r.t. the top of // the bar this._ofsCh = (this.CROSSHAIR_LINE - this.CROSSHAIR_WIDTH) / 2 | 0; // create the crosshair, a dragger component this._ch = new SUI.Dragger({ parent: this, width: this.CROSSHAIR_WIDTH, height: this.CROSSHAIR_HEIGHT, top: (this.HEIGHT - this.CROSSHAIR_HEIGHT) / 2 | 0, left: this._ofsCh }); // set the range for dragging ... this._ch.xMin(this._ofsCh); this._ch.xMax( this._ofsCh + this.AXIS_LENGTH - this.CROSSHAIR_LINE); // ... and the direction in which we may draw this._ch.direction(this._ch.HORIZONTAL); // set the crosshair background image ... this._ch.el().style.backgroundImage = "url(" + SUI.imgDir + "/" + SUI.resource.rgbCh + ")"; // ... and an appropriate cursor this._ch.el().style.cursor = "pointer"; // start dragging on the onmousedown of the crosshair var that = this; SUI.browser.addEventListener(this._ch.el(), "mousedown", function(e) { if (!that._startDrag(new SUI.Event(this, e))) { SUI.browser.noPropagation(e); } } ); // set the onChange handler if (arg.onChange) { this.addListener("onChange", arg.onChange); } }, /** * Length of the color axis. */ AXIS_LENGTH: 256, /** * Width of the crosshair line. */ CROSSHAIR_LINE: 1, /** * Height of the bar. */ HEIGHT: 20, /** * Height of the crosshair image. */ CROSSHAIR_WIDTH: 15, /** * Width of the crosshair image. */ CROSSHAIR_HEIGHT: 26, /** * Display RGB control. Set the size and position of the bar and crosshair. */ display: function() { this.setDim(); this._ch.setDim(); }, /** * onChange event handler: is executed when the control's color selection * changes. This happens continuously when the user is dragging the * crosshairs. * @param {String} c The color intensity selected by the control. */ onChange: function(c) { }, /** * Set the value of the control's currently selected color intensity * and redisplay the control. * @param {int} val The new value for the control's currently selected * color intensity (0 <= value <= 1), no value to use this method * as a getter. * @return {int} the value of the control's currently selected color * intentsity, or null if this method is used as a setter. */ value: function(val) { if (val === undefined) { return this._val; } // got here? the method is a setter this._val = val; this._ch.left((this._val * this._axisRange | 0) + this._ofsCh); this.display(); return null; }, // length vs range: fi length: 128 -> range: 0-127 _axisRange: 0, // dragger box for the crosshair _ch: null, // offset of the crosshair w.r.t. the left of the bar _ofsCh: 0, // current intensity setting _val: 0, // While dragging the crosshair change the selected color intensity // setting and call the onChange listener _drag: function() { this._val = (this._ch.left() - this._ofsCh) / this._axisRange; this.callListener("onChange", this._val); }, // On start dragging the crosshair initialize the onDrag handler of // the dragger and start dragging _startDrag: function(e) { var that = this; this._ch.addListener("onDrag", function() { that._drag(); }); this._ch.start(e, this); } });