2 * jQuery Mobile Widget @VERSION
4 * This software is licensed under the MIT licence (as defined by the OSI at
5 * http://www.opensource.org/licenses/mit-license.php)
7 * ***************************************************************************
8 * Copyright (C) 2011 by Intel Corporation Ltd.
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software" ),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 * ***************************************************************************
29 * Authors: Gabriel Schulhof <gabriel.schulhof@intel.com>
32 // Displays three sliders that allow the user to select the
33 // hue, saturation, and value for a color.
35 // To apply, add the attribute data-role="hsvpicker" to a <div>
36 // element inside a page. Alternatively, call hsvpicker()
37 // on an element (see below).
41 // color: String; the initial color can be specified in html using the
42 // data-color="#ff00ff" attribute or when constructed
44 // $( "#myhsvpicker" ).hsvpicker({ color: "#ff00ff" });
45 // where the html might be :
46 // <div id="myhsvpicker"></div>
47 // The color can be changed post-construction like this :
48 // $( "#myhsvpicker" ).hsvpicker( "option", "color", "#ABCDEF" );
53 // colorchanged: Fired when the color is changed.
55 (function ( $, undefined ) {
57 $.widget( "tizen.hsvpicker", $.tizen.colorwidget, {
59 initSelector: ":jqmData(role='hsvpicker')"
64 container: "#hsvpicker",
66 eventSource: "[data-event-source='hue']",
67 selector: "#hsvpicker-hue-selector",
68 hue: "#hsvpicker-hue-hue",
69 valMask: "#hsvpicker-hue-mask-val"
72 gradient: "#hsvpicker-sat-gradient",
73 eventSource: "[data-event-source='sat']",
74 selector: "#hsvpicker-sat-selector",
75 hue: "#hsvpicker-sat-hue",
76 valMask: "#hsvpicker-sat-mask-val"
79 gradient: "#hsvpicker-val-gradient",
80 eventSource: "[data-event-source='val']",
81 selector: "#hsvpicker-val-selector",
82 hue: "#hsvpicker-val-hue"
87 _create: function () {
95 .css( "display", "none" )
96 .after( this._ui.container );
98 this._ui.hue.hue.huegradient();
101 dragging_hsv: [ 0, 0, 0],
102 selectorDraggingOffset: {
109 this._ui.container.find( ".hsvpicker-arrow-btn" )
111 .bind( "vclick", function ( e ) {
112 chan = $( this).attr( "data-" + ( $.mobile.ns || "" ) + "target" );
113 hsvIdx = ( "hue" === chan ) ? 0 :
114 ( "sat" === chan) ? 1 : 2;
115 max = ( 0 == hsvIdx ? 360 : 1 );
118 self.dragging_hsv[hsvIdx] = self.dragging_hsv[hsvIdx] + step * ( "left" === $( this ).attr( "data-" + ( $.mobile.ns || "" ) + "location" ) ? -1 : 1);
119 self.dragging_hsv[hsvIdx] = Math.min( max, Math.max( 0.0, self.dragging_hsv[hsvIdx] ) );
120 self._updateSelectors( self.dragging_hsv );
124 .bind( "vmousemove", function ( event ) {
125 if ( self.dragging != -1 ) {
126 event.stopPropagation();
127 event.preventDefault();
130 .bind( "vmouseup", function ( event ) {
134 this._bindElements( "hue", 0 );
135 this._bindElements( "sat", 1 );
136 this._bindElements( "val", 2 );
139 _bindElements: function ( chan, idx ) {
141 this._ui[chan].selector
142 .bind( "mousedown vmousedown", function ( e ) { self._handleMouseDown( chan, idx, e, true ); } )
143 .bind( "vmousemove touchmove", function ( e ) { self._handleMouseMove( chan, idx, e, true ); } )
144 .bind( "vmouseup", function ( e ) { self.dragging = -1; } );
145 this._ui[chan].eventSource
146 .bind( "mousedown vmousedown", function ( e ) { self._handleMouseDown( chan, idx, e, false ); } )
147 .bind( "vmousemove touchmove", function ( e ) { self._handleMouseMove( chan, idx, e, false ); } )
148 .bind( "vmouseup", function ( e ) { self.dragging = -1; } );
151 _handleMouseDown: function ( chan, idx, e, isSelector ) {
152 var coords = $.mobile.tizen.targetRelativeCoordsFromEvent( e ),
153 widgetStr = ( isSelector ? "selector" : "eventSource" );
155 if ( coords.x >= 0 && coords.x <= this._ui[chan][widgetStr].outerWidth() &&
156 coords.y >= 0 && coords.y <= this._ui[chan][widgetStr].outerHeight() ) {
161 this.selectorDraggingOffset.x = coords.x;
162 this.selectorDraggingOffset.y = coords.y;
165 this._handleMouseMove( chan, idx, e, isSelector, coords );
169 _handleMouseMove: function ( chan, idx, e, isSelector, coords ) {
170 if ( this.dragging === idx ) {
171 coords = ( coords || $.mobile.tizen.targetRelativeCoordsFromEvent( e ) );
173 var factor = ( ( 0 === idx ) ? 360 : 1 ),
174 potential = ( isSelector
175 ? ( ( this.dragging_hsv[idx] / factor) +
176 ( ( coords.x - this.selectorDraggingOffset.x ) / this._ui[chan].eventSource.width() ) )
177 : ( coords.x / this._ui[chan].eventSource.width() ) );
179 this.dragging_hsv[idx] = Math.min( 1.0, Math.max( 0.0, potential ) ) * factor;
182 this.selectorDraggingOffset.x = Math.ceil( this._ui[chan].selector.outerWidth() / 2.0 );
183 this.selectorDraggingOffset.y = Math.ceil( this._ui[chan].selector.outerHeight() / 2.0 );
186 this._updateSelectors( this.dragging_hsv );
192 _updateSelectors: function ( hsv ) {
193 var clrlib = $.tizen.colorwidget.clrlib,
194 clrwidget = $.tizen.colorwidget.prototype,
195 clr = clrlib.HSVToHSL( hsv ),
196 hclr = clrlib.HSVToHSL( [hsv[0], 1.0, 1.0] ),
197 vclr = clrlib.HSVToHSL( [hsv[0], hsv[1], 1.0] );
199 this._ui.hue.selector.css( { left : this._ui.hue.eventSource.width() * hsv[0] / 360} );
200 clrwidget._setElementColor.call( this, this._ui.hue.selector, clr, "background" );
201 if ( $.mobile.browser.ie ) {
202 this._ui.hue.hue.find( "*" ).css( "opacity", hsv[1] );
204 this._ui.hue.hue.css( "opacity", hsv[1] );
207 this._ui.hue.valMask.css( "opacity", 1.0 - hsv[2] );
209 this._ui.sat.selector.css( { left : this._ui.sat.eventSource.width() * hsv[1]} );
210 clrwidget._setElementColor.call( this, this._ui.sat.selector, clr, "background" );
211 clrwidget._setElementColor.call( this, this._ui.sat.hue, hclr, "background" );
212 this._ui.sat.valMask.css( "opacity", 1.0 - hsv[2] );
214 this._ui.val.selector.css( { left : this._ui.val.eventSource.width() * hsv[2]} );
215 clrwidget._setElementColor.call( this, this._ui.val.selector, clr, "background" );
216 clrwidget._setElementColor.call( this, this._ui.val.hue, vclr, "background" );
217 clrwidget._setColor.call( this, clrlib.RGBToHTML( clrlib.HSLToRGB(clr) ) );
220 _setDisabled: function ( value ) {
221 $.tizen.widgetex.prototype._setDisabled.call( this, value );
222 this._ui.container[value ? "addClass" : "removeClass"]( "ui-disabled" );
223 this._ui.hue.hue.huegradient( "option", "disabled", value );
224 $.tizen.colorwidget.prototype._displayDisabledState.call( this, this._ui.container );
227 _setColor: function ( clr ) {
228 if ( $.tizen.colorwidget.prototype._setColor.call( this, clr ) ) {
229 this.dragging_hsv = $.tizen.colorwidget.clrlib.RGBToHSV( $.tizen.colorwidget.clrlib.HTMLToRGB( this.options.color ) );
230 this._updateSelectors( this.dragging_hsv );
235 $( document ).bind( "pagecreate create", function ( e ) {
236 $( $.tizen.hsvpicker.prototype.options.initSelector, e.target )
237 .not( ":jqmData(role='none'), :jqmData(role='nojs')" )