Export 0.1.61
[platform/framework/web/web-ui-fw.git] / src / widgets / hsvpicker / js / jquery.mobile.tizen.hsvpicker.js
1 /*
2  * jQuery Mobile Widget @VERSION
3  *
4  * This software is licensed under the MIT licence (as defined by the OSI at
5  * http://www.opensource.org/licenses/mit-license.php)
6  * 
7  * ***************************************************************************
8  * Copyright (C) 2011 by Intel Corporation Ltd.
9  * 
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:
16  * 
17  * The above copyright notice and this permission notice shall be included in
18  * all copies or substantial portions of the Software.
19  * 
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  * ***************************************************************************
28  *
29  * Authors: Gabriel Schulhof <gabriel.schulhof@intel.com>
30  */
31
32 // Displays three sliders that allow the user to select the
33 // hue, saturation, and value for a color.
34 //
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).
38 //
39 // Options:
40 //
41 //     color: String; the initial color can be specified in html using the
42 //            data-color="#ff00ff" attribute or when constructed
43 //            in javascript, eg
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" );
49 //            Default: "#1a8039"
50 //
51 // Events:
52 //
53 //     colorchanged: Fired when the color is changed.
54
55 (function ( $, undefined ) {
56
57         $.widget( "tizen.hsvpicker", $.tizen.colorwidget, {
58                 options: {
59                         initSelector: ":jqmData(role='hsvpicker')"
60                 },
61
62                 _htmlProto: {
63                         ui: {
64                                 container: "#hsvpicker",
65                                 hue: {
66                                         eventSource: "[data-event-source='hue']",
67                                         selector: "#hsvpicker-hue-selector",
68                                         hue: "#hsvpicker-hue-hue",
69                                         valMask:  "#hsvpicker-hue-mask-val"
70                                 },
71                                 sat: {
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"
77                                 },
78                                 val: {
79                                         gradient: "#hsvpicker-val-gradient",
80                                         eventSource: "[data-event-source='val']",
81                                         selector: "#hsvpicker-val-selector",
82                                         hue: "#hsvpicker-val-hue"
83                                 }
84                         }
85                 },
86
87                 _create: function () {
88                         var self = this,
89                                 chan,
90                                 hsvIdx,
91                                 max,
92                                 step;
93
94                         this.element
95                                 .css( "display", "none" )
96                                 .after( this._ui.container );
97
98                         this._ui.hue.hue.huegradient();
99
100                         $.extend( this, {
101                                 dragging_hsv: [ 0, 0, 0],
102                                 selectorDraggingOffset: {
103                                         x : -1,
104                                         y : -1
105                                 },
106                                 dragging: -1
107                         } );
108
109                         this._ui.container.find( ".hsvpicker-arrow-btn" )
110                                 .buttonMarkup()
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 );
116                                         step = 0.05 * max;
117
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 );
121                                 } );
122
123                         $( document )
124                                 .bind( "vmousemove", function ( event ) {
125                                         if ( self.dragging != -1 ) {
126                                                 event.stopPropagation();
127                                                 event.preventDefault();
128                                         }
129                                 } )
130                                 .bind( "vmouseup", function ( event ) {
131                                         self.dragging = -1;
132                                 } );
133
134                         this._bindElements( "hue", 0 );
135                         this._bindElements( "sat", 1 );
136                         this._bindElements( "val", 2 );
137                 },
138
139                 _bindElements: function ( chan, idx ) {
140                         var self = this;
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; } );
149                 },
150
151                 _handleMouseDown: function ( chan, idx, e, isSelector ) {
152                         var coords = $.mobile.tizen.targetRelativeCoordsFromEvent( e ),
153                                 widgetStr = ( isSelector ? "selector" : "eventSource" );
154
155                         if ( coords.x >= 0 && coords.x <= this._ui[chan][widgetStr].outerWidth() &&
156                                         coords.y >= 0 && coords.y <= this._ui[chan][widgetStr].outerHeight() ) {
157
158                                 this.dragging = idx;
159
160                                 if ( isSelector ) {
161                                         this.selectorDraggingOffset.x = coords.x;
162                                         this.selectorDraggingOffset.y = coords.y;
163                                 }
164
165                                 this._handleMouseMove( chan, idx, e, isSelector, coords );
166                         }
167                 },
168
169                 _handleMouseMove: function ( chan, idx, e, isSelector, coords ) {
170                         if ( this.dragging === idx ) {
171                                 coords = ( coords || $.mobile.tizen.targetRelativeCoordsFromEvent( e ) );
172
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() ) );
178
179                                 this.dragging_hsv[idx] = Math.min( 1.0, Math.max( 0.0, potential ) ) * factor;
180
181                                 if ( !isSelector ) {
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 );
184                                 }
185
186                                 this._updateSelectors( this.dragging_hsv );
187                                 e.stopPropagation();
188                                 e.preventDefault();
189                         }
190                 },
191
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] );
198
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] );
203                         } else {
204                                 this._ui.hue.hue.css( "opacity", hsv[1] );
205                         }
206
207                         this._ui.hue.valMask.css( "opacity", 1.0 - hsv[2] );
208
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] );
213
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) ) );
218                 },
219
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 );
225                 },
226
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 );
231                         }
232                 }
233         } );
234
235         $( document ).bind( "pagecreate create", function ( e ) {
236                 $( $.tizen.hsvpicker.prototype.options.initSelector, e.target )
237                         .not( ":jqmData(role='none'), :jqmData(role='nojs')" )
238                         .hsvpicker();
239         } );
240
241 }( jQuery ) );