Login Register

dojox.widget.ColorPicker

... i got tired of people saying YUI had a better color picker, and there were a couple of requests in the Widget Wishlist for such a beast, so I've started it. I kind of like it, but hey, I wrote it:

colorPicker.png

some notes on what it needs before I check it in, hoping for a little feedback: (it has lots of bugs atm, this is a first pass)

a) should I mixin Form-widget? I'd like to be able to getValue() from the widget, and fire onChange, but it seems like I'd want to do that internally, and just provide a single 'export' value defined by the used (rgb, hex, or hsv values) ... is that sane? or should I just be dumping the hex and telling people to use dojo.color to convert.

2) I stole dojo.gfx.color.hsv2rgb() from 0.4 ... it was a direct port, but it has bugs. The math hurts my head ... ;) It is currently defined as a private method of the widget (_hsv2rgb(h,s,v)) ... should I pop it out of there. should it go back in dojox.gfx?

c) is there an easy way to populate my RGB and HSV input nodes? (i have all the values, mostly) Would we want to accept inputs on those nodes, and adjust the picker's color (and hue bg) , or just make them read-only, and use the single 'export' input mentioned in [a]? When i say easy, I mean anything but a dojoAttachPoint on each of the six inputs, to be updated on each onChange (it's a lot of floating connections i'd like to avoid personally) ...

4) the only solution I see at the moment to update the preview color onDrag would be to subscribe to dragStart and dragEnd setting and clearing an interval on each topic publish. Is this the best idea? This is because there is no dragMove in dojo.dnd.Mover ...

e) before you say anything, Wildbill, I don't want to put a widgetInTemplate and use a slider. Not until a 2d slider like 0.4 had has been implemented. I should look at the code for that, to help in solving my constrainedMover issue:

6) The two drag handles are dnd.Movers with a constrainedMover. The parent is 150x150px, the handle is 10x10px ... I want the center of the mover to be the constrained bit, so I set t:-5, l:-5, w:155, h:155 ... which works, but wreaks havoc on my x/y positioning -> HSV calculation. (hue is easier, but even with my calculations, I cannot get 255..0 (or 360..0) ... Because of the mover offset I had to hack in, i get 256.5...1.5 (>255 is invalid, and returns black) ... I'm probably just doing the math wrong. (not wanting to hard-code the offset in, and base it on the 'center' of whatever handle node is being used)

Thats all for now. Its a fairly small widget, 201 lines with comments ... Feedback welcome. :)

Regards.

A couple of quick comments.

1. I wouldn't mind seeing it a little bigger; I've had half a mind to pull one that is entirely like the one you'd find in Photoshop, with that kind of arrangement.

2. In the charting code I checked in recently (mostly to do with theming/skinning), there are 2 private functions to convert RGB to HSB--and the HSB is expressed the way you'd see it in Photoshop (360 deg, %, %). You're welcome to use that if you'd like; it's in a separate file:

http://trac.dojotoolkit.org/browser/dojox/trunk/charting/_color.js

If it comes down to it, we can probably create a separate Color project--though I'm starting to wonder if we shouldn't do something like the Dojo Core does with the Dojo Base, and create something to that effect. Just thinking of it now, not feeling too strong about it one way or the other.

3. A slider in this widget doesn't need to conform to the same requirements as Dijit does, so don't feel bad about not using one of the Dijit Sliders :)

4. I would say that input on the various form controls is a must; the overwhelming majority of the time when I'm using the Photoshop picker, I'm using the form controls first and then adjusting later. This is especially useful when you have a base color picked already and are looking for a variant on it (such as a lighter or darker shade of that color).

5. I'd suggest losing the # symbol in the hex representation.

6. I think a getValue and onChanged event would be a great idea; after all, the point of the widget (for the most part) is to find a color, right?

7. While I haven't looked at the DnD code at all yet, knowing Eugene I'd expect that he wrote it for you to hook to onDragEnd. Though in this case, I would think onDragMove would be a very good thing to have.

8. One thing Photoshop does which I find kind of nice is to keep a color chip of the previously selected color as the bottom half of the color chip you have there. Is that something you're doing?

Looking good so far otherwise. If you need any questions answered and I'm around, feel free to ping me.

Quick comments

I don't know the origin of dojo.gfx.color.hsv2rgb(). I suggest to look at newer Tom's code (referenced in his reply).

If you have suggestions, improvents for dojo.dnd --- file an enhancement ticket. Right now I am up to my eyeballs in dojox.gfx, but after that I'll come back to dojo.dnd to implement multiple enhancements. See my current list: http://trac.dojotoolkit.org/query?status=new&status=assigned&status=reop...

IIRC, it was written...

...by Cal Henderson (of Flickr fame), and they were implementations from one of the core CS textbooks. I think there's comments to that effect in the 0.4 code.

My implementations of the HSB code came mostly from there, with leavening from the implementation in MochiKit.

wrt to dndMove

i've changed my mind about onDragMove topic. (i secretly added it in my local copy, and the performance took a big hit) the implementation i came up with of this.timer = setInterval(doit,50); and clearInterval(this.timer) in the functions attached to the topics works just fine, and is easy enough for people to implement should they need something similar ... I did a similar patch a while back, and decided the same then. Must have forgotten publish is more expensive than an interval ...

it was brought to my attention it looks 'frightenly similar' to the YUI ColorPicker. Rest assured, I went to lengths to avoid ANY code copying. I simply looked at the YUI picker in one tab, and styled my template/css to match as closely as possible. I even re-created the simple gradient overlay image, and hue bar. I was so frustrated having not found any HSV/HSB code in dojo core I almost peeked at the color conversion code, then dmachi pointed me to dojo.gfx.colors from 0.4 ... no worries anyone: this is 104% Dojo ... (though i will look into using dojox.charting color code, because the 0.4 implementation had some bugs, and I'm jumping through hoops to convert some values to %'s and some from 0..255 -> 0..360 (and back, ugh!) ... )

any cleanup on my calculations would be greatly appreciated ttrenka ... I'm missing some very important step wrt to my offsets and scaling calculations (the div is 150px, but S + V are 0..100 values. it's rounding, but rounding down in some cases where it shouldn't, and you can only get 99% saturation via draging ... and some other little nitpicks. but all-in-all not a bad little widget. Glad I snuck it in before 0.9final haha .

The formwidget mixin is the top priority as I see it. Would be cool to use number spinners for the inputs, too. Would that wreak havok on a formWidget mixin?