Tizen 2.1 base
[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
90         this.element
91             .css("display", "none")
92             .after(this._ui.container);
93
94         this._ui.hue.hue.huegradient();
95
96         $.extend(this, {
97             dragging_hsv: [ 0, 0, 0],
98             selectorDraggingOffset: {
99                 x : -1,
100                 y : -1
101             },
102             dragging: -1
103         });
104
105         this._ui.container.find(".hsvpicker-arrow-btn")
106             .buttonMarkup()
107             .bind("vclick", function(e) {
108                 var chan = $(this).attr("data-" + ($.mobile.ns || "") + "target"),
109                     hsvIdx = ("hue" === chan) ? 0 :
110                              ("sat" === chan) ? 1 : 2,
111                     max = (0 == hsvIdx ? 360 : 1),
112                     step = 0.05 * max;
113
114                 self.dragging_hsv[hsvIdx] = self.dragging_hsv[hsvIdx] + step * ("left" === $(this).attr("data-" + ($.mobile.ns || "") + "location") ? -1 : 1);
115                 self.dragging_hsv[hsvIdx] = Math.min(max, Math.max(0.0, self.dragging_hsv[hsvIdx]));
116                 self._updateSelectors(self.dragging_hsv);
117             });
118
119         $( document )
120             .bind( "vmousemove", function( event ) {
121                 if ( self.dragging != -1 ) {
122                     event.stopPropagation();
123                     event.preventDefault();
124                 }
125             })
126             .bind( "vmouseup", function( event ) {
127                 self.dragging = -1;
128             });
129
130         this._bindElements("hue", 0);
131         this._bindElements("sat", 1);
132         this._bindElements("val", 2);
133     },
134
135     _bindElements: function(chan, idx) {
136         var self = this;
137         this._ui[chan].selector
138             .bind("mousedown vmousedown", function(e) { self._handleMouseDown(chan, idx, e, true); })
139             .bind("vmousemove touchmove", function(e) { self._handleMouseMove(chan, idx, e, true); })
140             .bind("vmouseup",             function(e) { self.dragging = -1; });
141         this._ui[chan].eventSource
142             .bind("mousedown vmousedown", function(e) { self._handleMouseDown(chan, idx, e, false); })
143             .bind("vmousemove touchmove", function(e) { self._handleMouseMove(chan, idx, e, false); })
144             .bind("vmouseup",             function(e) { self.dragging = -1; });
145     },
146
147     _handleMouseDown: function(chan, idx, e, isSelector) {
148         var coords = $.mobile.tizen.targetRelativeCoordsFromEvent(e),
149             widgetStr = (isSelector ? "selector" : "eventSource");
150
151         if (coords.x >= 0 && coords.x <= this._ui[chan][widgetStr].outerWidth() &&
152             coords.y >= 0 && coords.y <= this._ui[chan][widgetStr].outerHeight()) {
153
154             this.dragging = idx;
155
156             if (isSelector) {
157                 this.selectorDraggingOffset.x = coords.x;
158                 this.selectorDraggingOffset.y = coords.y;
159             }
160
161             this._handleMouseMove(chan, idx, e, isSelector, coords);
162         }
163     },
164
165     _handleMouseMove: function(chan, idx, e, isSelector, coords) {
166         if (this.dragging === idx) {
167             coords = (coords || $.mobile.tizen.targetRelativeCoordsFromEvent(e));
168
169             var factor = ((0 === idx) ? 360 : 1),
170                 potential = (isSelector
171                   ? ((this.dragging_hsv[idx] / factor) +
172                      ((coords.x - this.selectorDraggingOffset.x) / this._ui[chan].eventSource.width()))
173                   : (coords.x / this._ui[chan].eventSource.width()));
174
175             this.dragging_hsv[idx] = Math.min(1.0, Math.max(0.0, potential)) * factor;
176
177             if (!isSelector) {
178                 this.selectorDraggingOffset.x = Math.ceil(this._ui[chan].selector.outerWidth()  / 2.0);
179                 this.selectorDraggingOffset.y = Math.ceil(this._ui[chan].selector.outerHeight() / 2.0);
180             }
181
182             this._updateSelectors(this.dragging_hsv);
183             e.stopPropagation();
184             e.preventDefault();
185         }
186     },
187
188     _updateSelectors: function(hsv) {
189         var clrlib = $.tizen.colorwidget.clrlib,
190             clrwidget = $.tizen.colorwidget.prototype,
191              clr = clrlib.HSVToHSL(hsv),
192             hclr = clrlib.HSVToHSL([hsv[0], 1.0, 1.0]),
193             vclr = clrlib.HSVToHSL([hsv[0], hsv[1], 1.0]);
194
195         this._ui.hue.selector.css({ left : this._ui.hue.eventSource.width() * hsv[0] / 360});
196         clrwidget._setElementColor.call(this, this._ui.hue.selector,  clr, "background");
197         if ($.mobile.browser.ie)
198             this._ui.hue.hue.find("*").css("opacity", hsv[1]);
199         else
200             this._ui.hue.hue.css("opacity", hsv[1]);
201         this._ui.hue.valMask.css("opacity", 1.0 - hsv[2]);
202
203         this._ui.sat.selector.css({ left : this._ui.sat.eventSource.width() * hsv[1]});
204         clrwidget._setElementColor.call(this, this._ui.sat.selector,  clr, "background");
205         clrwidget._setElementColor.call(this, this._ui.sat.hue,      hclr, "background");
206         this._ui.sat.valMask.css("opacity", 1.0 - hsv[2]);
207
208         this._ui.val.selector.css({ left : this._ui.val.eventSource.width() * hsv[2]});
209         clrwidget._setElementColor.call(this, this._ui.val.selector,  clr, "background");
210         clrwidget._setElementColor.call(this, this._ui.val.hue,      vclr, "background");
211         clrwidget._setColor.call(this, clrlib.RGBToHTML(clrlib.HSLToRGB(clr)));
212     },
213
214     _setDisabled: function(value) {
215         $.tizen.widgetex.prototype._setDisabled.call(this, value);
216         this._ui.container[value ? "addClass" : "removeClass"]("ui-disabled");
217         this._ui.hue.hue.huegradient("option", "disabled", value);
218         $.tizen.colorwidget.prototype._displayDisabledState.call(this, this._ui.container);
219     },
220
221     _setColor: function(clr) {
222         if ($.tizen.colorwidget.prototype._setColor.call(this, clr)) {
223             this.dragging_hsv = $.tizen.colorwidget.clrlib.RGBToHSV($.tizen.colorwidget.clrlib.HTMLToRGB(this.options.color));
224             this._updateSelectors(this.dragging_hsv);
225         }
226     }
227 });
228
229 $(document).bind("pagecreate create", function(e) {
230     $($.tizen.hsvpicker.prototype.options.initSelector, e.target)
231         .not(":jqmData(role='none'), :jqmData(role='nojs')")
232         .hsvpicker();
233 });
234
235 })(jQuery);