ColorPicker.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. require({cache:{
  2. 'url:dojox/widget/ColorPicker/ColorPicker.html':"<table class=\"dojoxColorPicker\" dojoAttachEvent=\"onkeypress: _handleKey\" cellpadding=\"0\" cellspacing=\"0\">\n\t<tr>\n\t\t<td valign=\"top\" class=\"dojoxColorPickerRightPad\">\n\t\t\t<div class=\"dojoxColorPickerBox\">\n\t\t\t\t<!-- Forcing ABS in style attr due to dojo DND issue with not picking it up form the class. -->\n\t\t\t\t<img role=\"status\" title=\"${saturationPickerTitle}\" alt=\"${saturationPickerTitle}\" class=\"dojoxColorPickerPoint\" src=\"${_pickerPointer}\" tabIndex=\"0\" dojoAttachPoint=\"cursorNode\" style=\"position: absolute; top: 0px; left: 0px;\">\n\t\t\t\t<img role=\"presentation\" alt=\"\" dojoAttachPoint=\"colorUnderlay\" dojoAttachEvent=\"onclick: _setPoint, onmousedown: _stopDrag\" class=\"dojoxColorPickerUnderlay\" src=\"${_underlay}\" ondragstart=\"return false\">\n\t\t\t</div>\n\t\t</td>\n\t\t<td valign=\"top\" class=\"dojoxColorPickerRightPad\">\n\t\t\t<div class=\"dojoxHuePicker\">\n\t\t\t\t<!-- Forcing ABS in style attr due to dojo DND issue with not picking it up form the class. -->\n\t\t\t\t<img role=\"status\" dojoAttachPoint=\"hueCursorNode\" tabIndex=\"0\" class=\"dojoxHuePickerPoint\" title=\"${huePickerTitle}\" alt=\"${huePickerTitle}\" src=\"${_huePickerPointer}\" style=\"position: absolute; top: 0px; left: 0px;\">\n\t\t\t\t<div class=\"dojoxHuePickerUnderlay\" dojoAttachPoint=\"hueNode\">\n\t\t\t\t <img role=\"presentation\" alt=\"\" dojoAttachEvent=\"onclick: _setHuePoint, onmousedown: _stopDrag\" src=\"${_hueUnderlay}\">\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</td>\n\t\t<td valign=\"top\">\n\t\t\t<table cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t<tr>\n\t\t\t\t\t<td valign=\"top\" class=\"dojoxColorPickerPreviewContainer\">\n\t\t\t\t\t\t<table cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td valign=\"top\" class=\"dojoxColorPickerRightPad\">\n\t\t\t\t\t\t\t\t\t<div dojoAttachPoint=\"previewNode\" class=\"dojoxColorPickerPreview\"></div>\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td valign=\"top\">\n\t\t\t\t\t\t\t\t\t<div dojoAttachPoint=\"safePreviewNode\" class=\"dojoxColorPickerWebSafePreview\"></div>\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t</table>\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td valign=\"bottom\">\n\t\t\t\t\t\t<table class=\"dojoxColorPickerOptional\" cellpadding=\"0\" cellspacing=\"0\">\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t<div class=\"dijitInline dojoxColorPickerRgb\" dojoAttachPoint=\"rgbNode\">\n\t\t\t\t\t\t\t\t\t\t<table cellpadding=\"1\" cellspacing=\"1\">\n\t\t\t\t\t\t\t\t\t\t<tr><td><label for=\"${_uId}_r\">${redLabel}</label></td><td><input id=\"${_uId}_r\" dojoAttachPoint=\"Rval\" size=\"1\" dojoAttachEvent=\"onchange: _colorInputChange\"></td></tr>\n\t\t\t\t\t\t\t\t\t\t<tr><td><label for=\"${_uId}_g\">${greenLabel}</label></td><td><input id=\"${_uId}_g\" dojoAttachPoint=\"Gval\" size=\"1\" dojoAttachEvent=\"onchange: _colorInputChange\"></td></tr>\n\t\t\t\t\t\t\t\t\t\t<tr><td><label for=\"${_uId}_b\">${blueLabel}</label></td><td><input id=\"${_uId}_b\" dojoAttachPoint=\"Bval\" size=\"1\" dojoAttachEvent=\"onchange: _colorInputChange\"></td></tr>\n\t\t\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t<div class=\"dijitInline dojoxColorPickerHsv\" dojoAttachPoint=\"hsvNode\">\n\t\t\t\t\t\t\t\t\t\t<table cellpadding=\"1\" cellspacing=\"1\">\n\t\t\t\t\t\t\t\t\t\t<tr><td><label for=\"${_uId}_h\">${hueLabel}</label></td><td><input id=\"${_uId}_h\" dojoAttachPoint=\"Hval\"size=\"1\" dojoAttachEvent=\"onchange: _colorInputChange\"> ${degLabel}</td></tr>\n\t\t\t\t\t\t\t\t\t\t<tr><td><label for=\"${_uId}_s\">${saturationLabel}</label></td><td><input id=\"${_uId}_s\" dojoAttachPoint=\"Sval\" size=\"1\" dojoAttachEvent=\"onchange: _colorInputChange\"> ${percentSign}</td></tr>\n\t\t\t\t\t\t\t\t\t\t<tr><td><label for=\"${_uId}_v\">${valueLabel}</label></td><td><input id=\"${_uId}_v\" dojoAttachPoint=\"Vval\" size=\"1\" dojoAttachEvent=\"onchange: _colorInputChange\"> ${percentSign}</td></tr>\n\t\t\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t\t<div class=\"dojoxColorPickerHex\" dojoAttachPoint=\"hexNode\" aria-live=\"polite\">\t\n\t\t\t\t\t\t\t\t\t\t<label for=\"${_uId}_hex\">&nbsp;${hexLabel}&nbsp;</label><input id=\"${_uId}_hex\" dojoAttachPoint=\"hexCode, focusNode, valueNode\" size=\"6\" class=\"dojoxColorPickerHexCode\" dojoAttachEvent=\"onchange: _colorInputChange\">\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t</table>\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t</table>\n\t\t</td>\n\t</tr>\n</table>\n\n"}});
  3. define("dojox/widget/ColorPicker", [
  4. "dojo/_base/kernel","dojo/_base/declare","dojo/_base/lang","dojo/_base/array",
  5. "dojo/_base/html","dojo/_base/connect","dojo/_base/sniff","dojo/_base/window",
  6. "dojo/_base/event","dojo/dom","dojo/dom-class","dojo/keys","dojo/fx","dojo/dnd/move",
  7. "dijit/registry","dijit/_base/focus","dijit/form/_FormWidget","dijit/typematic",
  8. "dojox/color","dojo/i18n","dojo/i18n!./nls/ColorPicker","dojo/i18n!dojo/cldr/nls/number",
  9. "dojo/text!./ColorPicker/ColorPicker.html"
  10. ], function(kernel,declare,lang,ArrayUtil,html,Hub,has,win,Event,DOM,DOMClass,Keys,fx,move,
  11. registry,FocusManager,FormWidget,Typematic,color,i18n,bundle1,bundle2,template){
  12. kernel.experimental("dojox.widget.ColorPicker");
  13. var webSafeFromHex = function(hex){
  14. // stub, this is planned later:
  15. return hex;
  16. };
  17. /*=====
  18. var FormWidget = dijit.form._FormWidget;
  19. =====*/
  20. // TODO: shouldn't this extend _FormValueWidget?
  21. return declare("dojox.widget.ColorPicker", FormWidget, {
  22. // summary:
  23. // a HSV color picker - similar to Photoshop picker
  24. //
  25. // description:
  26. // Provides an interactive HSV ColorPicker similar to
  27. // PhotoShop's color selction tool. This is an enhanced
  28. // version of the default dijit.ColorPalette, though provides
  29. // no accessibility.
  30. //
  31. // example:
  32. // | var picker = new dojox.widget.ColorPicker({
  33. // | // a couple of example toggles:
  34. // | animatePoint:false,
  35. // | showHsv: false,
  36. // | webSafe: false,
  37. // | showRgb: false
  38. // | });
  39. //
  40. // example:
  41. // | <!-- markup: -->
  42. // | <div dojoType="dojox.widget.ColorPicker"></div>
  43. //
  44. // showRgb: Boolean
  45. // show/update RGB input nodes
  46. showRgb: true,
  47. // showHsv: Boolean
  48. // show/update HSV input nodes
  49. showHsv: true,
  50. // showHex: Boolean
  51. // show/update Hex value field
  52. showHex: true,
  53. // webSafe: Boolean
  54. // deprecated? or just use a toggle to show/hide that node, too?
  55. webSafe: true,
  56. // animatePoint: Boolean
  57. // toggle to use slideTo (true) or just place the cursor (false) on click
  58. animatePoint: true,
  59. // slideDuration: Integer
  60. // time in ms picker node will slide to next location (non-dragging) when animatePoint=true
  61. slideDuration: 250,
  62. // liveUpdate: Boolean
  63. // Set to true to fire onChange in an indeterminate way
  64. liveUpdate: false,
  65. // PICKER_HUE_H: int
  66. // Height of the hue picker, used to calculate positions
  67. PICKER_HUE_H: 150,
  68. // PICKER_SAT_VAL_H: int
  69. // Height of the 2d picker, used to calculate positions
  70. PICKER_SAT_VAL_H: 150,
  71. // PICKER_SAT_VAL_W: int
  72. // Width of the 2d picker, used to calculate positions
  73. PICKER_SAT_VAL_W: 150,
  74. // PICKER_HUE_SELECTOR_H: int
  75. // Height of the hue selector DOM node, used to calc offsets so that selection
  76. // is center of the image node.
  77. PICKER_HUE_SELECTOR_H: 8,
  78. // PICKER_SAT_SELECTOR_H: int
  79. // Height of the saturation selector DOM node, used to calc offsets so that selection
  80. // is center of the image node.
  81. PICKER_SAT_SELECTOR_H: 10,
  82. // PICKER_SAT_SELECTOR_W: int
  83. // Width of the saturation selector DOM node, used to calc offsets so that selection
  84. // is center of the image node.
  85. PICKER_SAT_SELECTOR_W: 10,
  86. // value: String
  87. // Default color for this component. Only hex values are accepted as incoming/returned
  88. // values. Adjust this value with `.attr`, eg: dijit.byId("myPicker").attr("value", "#ededed");
  89. // to cause the points to adjust and the values to reflect the current color.
  90. value: "#ffffff",
  91. _underlay: kernel.moduleUrl("dojox.widget","ColorPicker/images/underlay.png"),
  92. _hueUnderlay: kernel.moduleUrl("dojox.widget","ColorPicker/images/hue.png"),
  93. _pickerPointer: kernel.moduleUrl("dojox.widget","ColorPicker/images/pickerPointer.png"),
  94. _huePickerPointer: kernel.moduleUrl("dojox.widget","ColorPicker/images/hueHandle.png"),
  95. _huePickerPointerAlly: kernel.moduleUrl("dojox.widget","ColorPicker/images/hueHandleA11y.png"),
  96. templateString: template,
  97. postMixInProperties: function(){
  98. if(DOMClass.contains(win.body(), "dijit_a11y")){
  99. // Use the pointer that will show up in high contrast.
  100. this._huePickerPointer = this._huePickerPointerAlly;
  101. }
  102. this._uId = registry.getUniqueId(this.id);
  103. lang.mixin(this, i18n.getLocalization("dojox.widget", "ColorPicker"));
  104. lang.mixin(this, i18n.getLocalization("dojo.cldr", "number"));
  105. this.inherited(arguments);
  106. },
  107. postCreate: function(){
  108. // summary:
  109. // As quickly as we can, set up ie6 alpha-filter support for our
  110. // underlay. we don't do image handles (done in css), just the 'core'
  111. // of this widget: the underlay.
  112. this.inherited(arguments);
  113. if(has("ie") < 7){
  114. this.colorUnderlay.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this._underlay+"', sizingMethod='scale')";
  115. this.colorUnderlay.src = this._blankGif.toString();
  116. }
  117. // hide toggle-able nodes:
  118. if(!this.showRgb){ this.rgbNode.style.visibility = "hidden"; }
  119. if(!this.showHsv){ this.hsvNode.style.visibility = "hidden"; }
  120. if(!this.showHex){ this.hexNode.style.visibility = "hidden"; }
  121. if(!this.webSafe){ this.safePreviewNode.style.visibility = "hidden"; }
  122. },
  123. startup: function(){
  124. if(this._started){
  125. return;
  126. }
  127. this._started = true;
  128. this.set("value", this.value);
  129. this._mover = new move.boxConstrainedMoveable(this.cursorNode, {
  130. box: {
  131. t: -(this.PICKER_SAT_SELECTOR_H/2),
  132. l: -(this.PICKER_SAT_SELECTOR_W/2),
  133. w:this.PICKER_SAT_VAL_W,
  134. h:this.PICKER_SAT_VAL_H
  135. }
  136. });
  137. this._hueMover = new move.boxConstrainedMoveable(this.hueCursorNode, {
  138. box: {
  139. t: -(this.PICKER_HUE_SELECTOR_H/2),
  140. l:0,
  141. w:0,
  142. h:this.PICKER_HUE_H
  143. }
  144. });
  145. this._subs = [];
  146. // no dnd/move/move published ... use a timer:
  147. this._subs.push(Hub.subscribe("/dnd/move/stop", lang.hitch(this, "_clearTimer")));
  148. this._subs.push(Hub.subscribe("/dnd/move/start", lang.hitch(this, "_setTimer")));
  149. // Bind to up, down, left and right arrows on the hue and saturation nodes.
  150. this._keyListeners = [];
  151. this._connects.push(Typematic.addKeyListener(this.hueCursorNode,{
  152. charOrCode: Keys.UP_ARROW,
  153. shiftKey: false,
  154. metaKey: false,
  155. ctrlKey: false,
  156. altKey: false
  157. }, this, lang.hitch(this, this._updateHueCursorNode), 25, 25));
  158. this._connects.push(Typematic.addKeyListener(this.hueCursorNode,{
  159. charOrCode: Keys.DOWN_ARROW,
  160. shiftKey: false,
  161. metaKey: false,
  162. ctrlKey: false,
  163. altKey: false
  164. }, this, lang.hitch(this, this._updateHueCursorNode), 25, 25));
  165. this._connects.push(Typematic.addKeyListener(this.cursorNode,{
  166. charOrCode: Keys.UP_ARROW,
  167. shiftKey: false,
  168. metaKey: false,
  169. ctrlKey: false,
  170. altKey: false
  171. }, this, lang.hitch(this, this._updateCursorNode), 25, 25));
  172. this._connects.push(Typematic.addKeyListener(this.cursorNode,{
  173. charOrCode: Keys.DOWN_ARROW,
  174. shiftKey: false,
  175. metaKey: false,
  176. ctrlKey: false,
  177. altKey: false
  178. }, this, lang.hitch(this, this._updateCursorNode), 25, 25));
  179. this._connects.push(Typematic.addKeyListener(this.cursorNode,{
  180. charOrCode: Keys.LEFT_ARROW,
  181. shiftKey: false,
  182. metaKey: false,
  183. ctrlKey: false,
  184. altKey: false
  185. }, this, lang.hitch(this, this._updateCursorNode), 25, 25));
  186. this._connects.push(Typematic.addKeyListener(this.cursorNode,{
  187. charOrCode: Keys.RIGHT_ARROW,
  188. shiftKey: false,
  189. metaKey: false,
  190. ctrlKey: false,
  191. altKey: false
  192. }, this, lang.hitch(this, this._updateCursorNode), 25, 25));
  193. },
  194. _setValueAttr: function(value){
  195. if(!this._started){ return; }
  196. this.setColor(value, true);
  197. },
  198. setColor: function(/* String */col, force){
  199. // summary: Set a color on a picker. Usually used to set
  200. // initial color as an alternative to passing defaultColor option
  201. // to the constructor.
  202. col = color.fromString(col);
  203. this._updatePickerLocations(col);
  204. this._updateColorInputs(col);
  205. this._updateValue(col, force);
  206. },
  207. _setTimer: function(/* d.dnd.Mover */mover){
  208. if(mover.node != this.cursorNode && mover.node != this.hueCursorNode){ return; }
  209. // FIXME: should I assume this? focus on mouse down so on mouse up
  210. FocusManager.focus(mover.node);
  211. DOM.setSelectable(this.domNode,false);
  212. this._timer = setInterval(lang.hitch(this, "_updateColor"), 45);
  213. },
  214. _clearTimer: function(/* d.dnd.Mover */mover){
  215. if(!this._timer){ return; }
  216. clearInterval(this._timer);
  217. this._timer = null;
  218. this.onChange(this.value);
  219. DOM.setSelectable(this.domNode,true);
  220. },
  221. _setHue: function(/* Decimal */h){
  222. // summary:
  223. // Sets a natural color background for the
  224. // underlay image against closest hue value (full saturation)
  225. // h: 0..360
  226. html.style(this.colorUnderlay, "backgroundColor", color.fromHsv(h,100,100).toHex());
  227. },
  228. _updateHueCursorNode: function(count, node, e){
  229. // summary:
  230. // Function used by the typematic code to handle cursor position and update
  231. // via keyboard.
  232. // count:
  233. // -1 means stop, anything else is just how many times it was called.
  234. // node:
  235. // The node generating the event.
  236. // e:
  237. // The event.
  238. if(count !== -1){
  239. var y = html.style(this.hueCursorNode, "top");
  240. var selCenter = this.PICKER_HUE_SELECTOR_H/2;
  241. // Account for our offset
  242. y += selCenter;
  243. var update = false;
  244. if(e.charOrCode == Keys.UP_ARROW){
  245. if(y > 0){
  246. y -= 1;
  247. update = true;
  248. }
  249. }else if(e.charOrCode == Keys.DOWN_ARROW){
  250. if(y < this.PICKER_HUE_H){
  251. y += 1;
  252. update = true;
  253. }
  254. }
  255. y -= selCenter;
  256. if(update){
  257. html.style(this.hueCursorNode, "top", y + "px");
  258. }
  259. }else{
  260. this._updateColor(true);
  261. }
  262. },
  263. _updateCursorNode: function(count, node, e){
  264. // summary:
  265. // Function used by the typematic code to handle cursor position and update
  266. // via keyboard.
  267. // count:
  268. // -1 means stop, anything else is just how many times it was called.
  269. // node:
  270. // The node generating the event.
  271. // e:
  272. // The event.
  273. var selCenterH = this.PICKER_SAT_SELECTOR_H/2;
  274. var selCenterW = this.PICKER_SAT_SELECTOR_W/2;
  275. if(count !== -1){
  276. var y = html.style(this.cursorNode, "top");
  277. var x = html.style(this.cursorNode, "left");
  278. // Account for our offsets to center
  279. y += selCenterH;
  280. x += selCenterW;
  281. var update = false;
  282. if(e.charOrCode == Keys.UP_ARROW){
  283. if(y > 0){
  284. y -= 1;
  285. update = true;
  286. }
  287. }else if(e.charOrCode == Keys.DOWN_ARROW){
  288. if(y < this.PICKER_SAT_VAL_H){
  289. y += 1;
  290. update = true;
  291. }
  292. }else if(e.charOrCode == Keys.LEFT_ARROW){
  293. if(x > 0){
  294. x -= 1;
  295. update = true;
  296. }
  297. }else if(e.charOrCode == Keys.RIGHT_ARROW){
  298. if(x < this.PICKER_SAT_VAL_W){
  299. x += 1;
  300. update = true;
  301. }
  302. }
  303. if(update){
  304. // Account for our offsets to center
  305. y -= selCenterH;
  306. x -= selCenterW;
  307. html.style(this.cursorNode, "top", y + "px");
  308. html.style(this.cursorNode, "left", x + "px");
  309. }
  310. }else{
  311. this._updateColor(true);
  312. }
  313. },
  314. _updateColor: function(){
  315. // summary: update the previewNode color, and input values [optional]
  316. var hueSelCenter = this.PICKER_HUE_SELECTOR_H/2,
  317. satSelCenterH = this.PICKER_SAT_SELECTOR_H/2,
  318. satSelCenterW = this.PICKER_SAT_SELECTOR_W/2;
  319. var _huetop = html.style(this.hueCursorNode,"top") + hueSelCenter,
  320. _pickertop = html.style(this.cursorNode,"top") + satSelCenterH,
  321. _pickerleft = html.style(this.cursorNode,"left") + satSelCenterW,
  322. h = Math.round(360 - (_huetop / this.PICKER_HUE_H * 360)),
  323. col = color.fromHsv(h, _pickerleft / this.PICKER_SAT_VAL_W * 100, 100 - (_pickertop / this.PICKER_SAT_VAL_H * 100))
  324. ;
  325. this._updateColorInputs(col);
  326. this._updateValue(col, true);
  327. // update hue, not all the pickers
  328. if(h!=this._hue){
  329. this._setHue(h);
  330. }
  331. },
  332. _colorInputChange: function(e){
  333. //summary: updates picker position and inputs
  334. // according to rgb, hex or hsv input changes
  335. var col, hasit = false;
  336. switch(e.target){
  337. //transform to hsv to pixels
  338. case this.hexCode:
  339. col = color.fromString(e.target.value);
  340. hasit = true;
  341. break;
  342. case this.Rval:
  343. case this.Gval:
  344. case this.Bval:
  345. col = color.fromArray([this.Rval.value, this.Gval.value, this.Bval.value]);
  346. hasit = true;
  347. break;
  348. case this.Hval:
  349. case this.Sval:
  350. case this.Vval:
  351. col = color.fromHsv(this.Hval.value, this.Sval.value, this.Vval.value);
  352. hasit = true;
  353. break;
  354. }
  355. if(hasit){
  356. this._updatePickerLocations(col);
  357. this._updateColorInputs(col);
  358. this._updateValue(col, true);
  359. }
  360. },
  361. _updateValue: function(/* dojox.color.Color */col, /* Boolean */fireChange){
  362. // summary: updates the value of the widget
  363. // can cancel reverse onChange by specifying second param
  364. var hex = col.toHex();
  365. this.value = this.valueNode.value = hex;
  366. // anytime we muck with the color, fire onChange?
  367. if(fireChange && (!this._timer || this.liveUpdate)){
  368. this.onChange(hex);
  369. }
  370. },
  371. _updatePickerLocations: function(/* dojox.color.Color */col){
  372. //summary: update handles on the pickers acording to color values
  373. //
  374. var hueSelCenter = this.PICKER_HUE_SELECTOR_H/2,
  375. satSelCenterH = this.PICKER_SAT_SELECTOR_H/2,
  376. satSelCenterW = this.PICKER_SAT_SELECTOR_W/2;
  377. var hsv = col.toHsv(),
  378. ypos = Math.round(this.PICKER_HUE_H - hsv.h / 360 * this.PICKER_HUE_H) - hueSelCenter,
  379. newLeft = Math.round(hsv.s / 100 * this.PICKER_SAT_VAL_W) - satSelCenterW,
  380. newTop = Math.round(this.PICKER_SAT_VAL_H - hsv.v / 100 * this.PICKER_SAT_VAL_H) - satSelCenterH
  381. ;
  382. if(this.animatePoint){
  383. fx.slideTo({
  384. node: this.hueCursorNode,
  385. duration: this.slideDuration,
  386. top: ypos,
  387. left: 0
  388. }).play();
  389. fx.slideTo({
  390. node: this.cursorNode,
  391. duration: this.slideDuration,
  392. top: newTop,
  393. left: newLeft
  394. }).play();
  395. }
  396. else {
  397. html.style(this.hueCursorNode, "top", ypos + "px");
  398. html.style(this.cursorNode, {
  399. left: newLeft + "px",
  400. top: newTop + "px"
  401. });
  402. }
  403. // limit hue calculations to only when it changes
  404. if(hsv.h != this._hue){
  405. this._setHue(hsv.h);
  406. }
  407. },
  408. _updateColorInputs: function(/* dojox.color.Color */col){
  409. //summary: updates color inputs that were changed through other inputs
  410. //or by clicking on the picker
  411. var hex = col.toHex();
  412. if(this.showRgb){
  413. this.Rval.value = col.r;
  414. this.Gval.value = col.g;
  415. this.Bval.value = col.b;
  416. }
  417. if(this.showHsv){
  418. var hsv = col.toHsv();
  419. this.Hval.value = Math.round((hsv.h)); // convert to 0..360
  420. this.Sval.value = Math.round(hsv.s);
  421. this.Vval.value = Math.round(hsv.v);
  422. }
  423. if(this.showHex){
  424. this.hexCode.value = hex;
  425. }
  426. this.previewNode.style.backgroundColor = hex;
  427. if(this.webSafe){
  428. this.safePreviewNode.style.backgroundColor = webSafeFromHex(hex);
  429. }
  430. },
  431. _setHuePoint: function(/* Event */evt){
  432. // summary: set the hue picker handle on relative y coordinates
  433. var selCenter = this.PICKER_HUE_SELECTOR_H/2;
  434. var ypos = evt.layerY - selCenter;
  435. if(this.animatePoint){
  436. fx.slideTo({
  437. node: this.hueCursorNode,
  438. duration:this.slideDuration,
  439. top: ypos,
  440. left: 0,
  441. onEnd: lang.hitch(this, function(){ this._updateColor(true); FocusManager.focus(this.hueCursorNode); })
  442. }).play();
  443. }else{
  444. html.style(this.hueCursorNode, "top", ypos + "px");
  445. this._updateColor(false);
  446. }
  447. },
  448. _setPoint: function(/* Event */evt){
  449. // summary: set our picker point based on relative x/y coordinates
  450. // evt.preventDefault();
  451. var satSelCenterH = this.PICKER_SAT_SELECTOR_H/2;
  452. var satSelCenterW = this.PICKER_SAT_SELECTOR_W/2;
  453. var newTop = evt.layerY - satSelCenterH;
  454. var newLeft = evt.layerX - satSelCenterW;
  455. if(evt){ FocusManager.focus(evt.target); }
  456. if(this.animatePoint){
  457. fx.slideTo({
  458. node: this.cursorNode,
  459. duration: this.slideDuration,
  460. top: newTop,
  461. left: newLeft,
  462. onEnd: lang.hitch(this, function(){ this._updateColor(true); FocusManager.focus(this.cursorNode); })
  463. }).play();
  464. }else{
  465. html.style(this.cursorNode, {
  466. left: newLeft + "px",
  467. top: newTop + "px"
  468. });
  469. this._updateColor(false);
  470. }
  471. },
  472. _handleKey: function(/* Event */e){
  473. // FIXME: not implemented YET
  474. // var keys = d.keys;
  475. },
  476. focus: function(){
  477. // summary:
  478. // Put focus on this widget, only if focus isn't set on it already.
  479. if(!this.focused){
  480. FocusManager.focus(this.focusNode);
  481. }
  482. },
  483. _stopDrag: function(e){
  484. // summary:
  485. // Function to hald the mouse down default
  486. // to disable draggong of images out of the color
  487. // picker.
  488. Event.stop(e);
  489. },
  490. destroy: function(){
  491. // summary:
  492. // Over-ride to clean up subscriptions, etc.
  493. this.inherited(arguments);
  494. ArrayUtil.forEach(this._subs, function(sub){
  495. Hub.unsubscribe(sub);
  496. });
  497. delete this._subs;
  498. }
  499. });
  500. });