Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2150 mathias 1
if(!dojo._hasResource["dojox.widget.ColorPicker"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2
dojo._hasResource["dojox.widget.ColorPicker"] = true;
3
dojo.provide("dojox.widget.ColorPicker");
4
dojo.experimental("dojox.widget.ColorPicker"); // level: prototype
5
 
6
dojo.require("dijit.form._FormWidget");
7
dojo.require("dojo.dnd.move");
8
dojo.require("dojo.fx");
9
 
10
dojo.declare("dojox.widget.ColorPicker",
11
	dijit.form._FormWidget,
12
	{
13
	// summary: a HSV color picker - like PhotoShop
14
	//
15
	// description:
16
	//	provides an interactive HSV ColorPicker similar to
17
	//	PhotoShop's color selction tool. Will eventually
18
	//	mixin FormWidget and be used as a suplement or a
19
	//	'more interactive' replacement for ColorPalette
20
	//
21
	// example:
22
	//
23
	//	code:
24
	//	var picker = new dojox.widget.ColorPicker({
25
	//		// a couple of example toggles:
26
	//		animatePoint:false,
27
	//		showHsv: false,
28
	//		webSafe: false,
29
	//		showRgb: false
30
	//	});
31
	//
32
	//	markup:
33
	//	<div dojoType="dojox.widget.ColorPicker"></div>
34
	//
35
 
36
	// showRgb: Boolean
37
	//	show/update RGB input nodes
38
	showRgb: true,
39
 
40
	// showHsv: Boolean
41
	//	show/update HSV input nodes
42
	showHsv: true,
43
 
44
	// showHex: Boolean
45
	//	show/update Hex value field
46
	showHex: true,
47
 
48
	// webSafe: Boolean
49
	//	deprecated? or just use a toggle to show/hide that node, too?
50
	webSafe: true,
51
 
52
	// animatePoint: Boolean
53
	//	toggle to use slideTo (true) or just place the cursor (false) on click
54
	animatePoint: true,
55
 
56
	// slideDuration: Integer
57
	//	time in ms picker node will slide to next location (non-dragging) when animatePoint=true
58
	slideDuration: 250,
59
 
60
	_underlay: dojo.moduleUrl("dojox.widget","ColorPicker/images/underlay.png"),
61
	templateString:"<div class=\"dojoxColorPicker\">\n\t<div class=\"dojoxColorPickerBox\">\n\t\t<div dojoAttachPoint=\"cursorNode\" class=\"dojoxColorPickerPoint\"></div>\n\t\t<img dojoAttachPoint=\"colorUnderlay\" dojoAttachEvent=\"onclick: _setPoint\" class=\"dojoxColorPickerUnderlay\" src=\"${_underlay}\">\n\t</div>\n\t<div class=\"dojoxHuePicker\">\n\t\t<div dojoAttachPoint=\"hueCursorNode\" class=\"dojoxHuePickerPoint\"></div>\n\t\t<div dojoAttachPoint=\"hueNode\" class=\"dojoxHuePickerUnderlay\" dojoAttachEvent=\"onclick: _setHuePoint\"></div>\n\t</div>\n\t<div dojoAttachPoint=\"previewNode\" class=\"dojoxColorPickerPreview\"></div>\n\t<div dojoAttachPoint=\"safePreviewNode\" class=\"dojoxColorPickerWebSafePreview\"></div>\n\t<div class=\"dojoxColorPickerOptional\">\n\t\t<div class=\"dijitInline dojoxColorPickerRgb\" dojoAttachPoint=\"rgbNode\">\n\t\t\t<table>\n\t\t\t<tr><td>r</td><td><input dojoAttachPoint=\"Rval\" size=\"1\"></td></tr>\n\t\t\t<tr><td>g</td><td><input dojoAttachPoint=\"Gval\" size=\"1\"></td></tr>\n\t\t\t<tr><td>b</td><td><input dojoAttachPoint=\"Bval\" size=\"1\"></td></tr>\n\t\t\t</table>\n\t\t</div>\n\t\t<div class=\"dijitInline dojoxColorPickerHsv\" dojoAttachPoint=\"hsvNode\">\n\t\t\t<table>\n\t\t\t<tr><td>h</td><td><input dojoAttachPoint=\"Hval\"size=\"1\"> &deg;</td></tr>\n\t\t\t<tr><td>s</td><td><input dojoAttachPoint=\"Sval\" size=\"1\"> %</td></tr>\n\t\t\t<tr><td>v</td><td><input dojoAttachPoint=\"Vval\" size=\"1\"> %</td></tr>\n\t\t\t</table>\n\t\t</div>\n\t\t<div class=\"dojoxColorPickerHex\" dojoAttachPoint=\"hexNode\">\t\n\t\t\thex: <input dojoAttachPoint=\"hexCode, focusNode\" size=\"6\" class=\"dojoxColorPickerHexCode\">\n\t\t</div>\n\t</div>\n</div>\n",
62
 
63
	postCreate: function(){
64
		// summary: As quickly as we can, set up ie6 alpha-filter support for our
65
		// 	underlay.  we don't do image handles (done in css), just the 'core'
66
		//	of this widget: the underlay.
67
		if(dojo.isIE && dojo.isIE<7){
68
			this.colorUnderlay.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this._underlay+"', sizingMethod='scale')";
69
			this.colorUnderlay.src = dojo.moduleUrl("dojox.widget","FisheyeList/blank.gif").toString();
70
		}
71
		// hide toggle-able nodes:
72
		if (!this.showRgb){ this.rgbNode.style.display = "none"; }
73
		if (!this.showHsv){ this.hsvNode.style.display = "none"; }
74
		if (!this.showHex){ this.hexNode.style.display = "none"; }
75
		if (!this.webSafe){ this.safePreviewNode.style.display = "none"; }
76
	},
77
 
78
	startup: function(){
79
		// summary: defer all additional calls until we're started, and our
80
		// embeded sliders are loaded? (not implemented yet)
81
 
82
		// this._offset = ((dojo.marginBox(this.cursorNode).w)/2);
83
		this._offset = 0;
84
 
85
		this._mover = new dojo.dnd.Moveable(this.cursorNode, {
86
			mover: dojo.dnd.boxConstrainedMover({ t:0, l:0, w:150, h:150 })
87
		});
88
		this._hueMover = new dojo.dnd.Moveable(this.hueCursorNode, {
89
			mover: dojo.dnd.boxConstrainedMover({ t:0, l:0, w:0, h:150 })
90
		});
91
 
92
		// no dnd/move/move published ... use a timer:
93
		dojo.subscribe("/dnd/move/stop",dojo.hitch(this,"_clearTimer"));
94
		dojo.subscribe("/dnd/move/start",dojo.hitch(this,"_setTimer"));
95
 
96
		// ugly scaling calculator.  need a XYslider badly
97
		this._sc = (1/dojo.coords(this.colorUnderlay).w);
98
		this._hueSc = (255/(dojo.coords(this.hueNode).h+this._offset));
99
 
100
		// initial color
101
		this._updateColor();
102
 
103
	},
104
 
105
	_setTimer: function(/* dojo.dnd.Mover */mover){
106
		this._timer = setInterval(dojo.hitch(this,"_updateColor"),45);
107
	},
108
	_clearTimer: function(/* dojo.dnd.Mover */mover){
109
		clearInterval(this._timer);
110
		this.onChange(this.value);
111
	},
112
 
113
	_setHue: function(/* Decimal */h){
114
		// summary: sets a natural color background for the
115
		// 	underlay image against closest hue value (full saturation)
116
		// h: 0..255
117
 
118
		// this is not a pretty conversion:
119
		var hue = dojo.colorFromArray(this._hsv2rgb(h,1,1,{ inputRange: 1 })).toHex();
120
		dojo.style(this.colorUnderlay,"backgroundColor",hue);
121
	},
122
 
123
	_updateColor: function(){
124
		// summary: update the previewNode color, and input values [optional]
125
		var h = Math.round((255+(this._offset))-((dojo.style(this.hueCursorNode,"top")+this._offset)*this._hueSc));
126
		var s = Math.round((dojo.style(this.cursorNode,"left")*this._sc)*100);
127
		var v = Math.round(100-(dojo.style(this.cursorNode,"top")*this._sc)*100);
128
 
129
		// limit hue calculations to only when it changes
130
		if(h != this._hue){ this._setHue(h); }
131
 
132
		var rgb = this._hsv2rgb(h,s/100,v/100,{ inputRange: 1 });
133
		var hex = (dojo.colorFromArray(rgb).toHex());
134
 
135
		this.previewNode.style.backgroundColor = hex;
136
		if(this.webSafe){ this.safePreviewNode.style.backgroundColor = hex; }
137
		if(this.showHex){ this.hexCode.value = hex; }
138
		if(this.showRgb){
139
			this.Rval.value = rgb[0];
140
			this.Gval.value = rgb[1];
141
			this.Bval.value = rgb[2];
142
		}
143
		if(this.showHsv){
144
			this.Hval.value = Math.round((h*360)/255); // convert to 0..360
145
			this.Sval.value = s;
146
			this.Vval.value = v;
147
		}
148
		this.value=hex;
149
 
150
		// anytime we muck with the color, fire onChange?
151
		if (!this._timer && !(arguments[1])){
152
			this.setValue(this.value);
153
			this.onChange(this.value);
154
		}
155
	},
156
 
157
	_setHuePoint: function(/* Event */evt){
158
		// summary: set the hue picker handle on relative y coordinates
159
		if(this.animatePoint){
160
			dojo.fx.slideTo({
161
				node: this.hueCursorNode,
162
				duration:this.slideDuration,
163
				top: evt.layerY,
164
				left: 0,
165
				onEnd: dojo.hitch(this,"_updateColor")
166
			}).play();
167
		}else{
168
			dojo.style(this.hueCursorNode,"top",(evt.layerY)+"px");
169
			this._updateColor(false);
170
		}
171
	},
172
 
173
	_setPoint: function(/* Event */evt){
174
		// summary: set our picker point based on relative x/y coordinates
175
		if(this.animatePoint){
176
			dojo.fx.slideTo({
177
				node: this.cursorNode,
178
				duration:this.slideDuration,
179
				top: evt.layerY-this._offset,
180
				left: evt.layerX-this._offset,
181
				onEnd: dojo.hitch(this,"_updateColor")
182
			}).play();
183
		}else{
184
			dojo.style(this.cursorNode,"left",(evt.layerX-this._offset)+"px");
185
			dojo.style(this.cursorNode,"top",(evt.layerY-this._offset)+"px");
186
			this._updateColor(false);
187
		}
188
	},
189
 
190
	// this ported directly from 0.4 dojo.gfx.colors.hsv, with bugs :)
191
	// FIXME: use ttrenka's HSB ?
192
	_hsv2rgb: function(/* int || Array */h, /* int */s, /* int */v, /* Object? */options){
193
		//	summary
194
		//	converts an HSV value set to RGB, ranges depending on optional options object.
195
		//	patch for options by Matthew Eernisse
196
		if (dojo.isArray(h)) {
197
			if(s){
198
				options = s;
199
			}
200
			v = h[2] || 0;
201
			s = h[1] || 0;
202
			h = h[0] || 0;
203
		}
204
 
205
		var opt = {
206
			inputRange:  (options && options.inputRange)  ? options.inputRange : [255, 255, 255],
207
			outputRange: (options && options.outputRange) ? options.outputRange : 255
208
		};
209
 
210
	    switch(opt.inputRange[0]) {
211
			// 0.0-1.0
212
			case 1: h = h * 360; break;
213
			// 0-100
214
			case 100: h = (h / 100) * 360; break;
215
			// 0-360
216
			case 360: h = h; break;
217
			// 0-255
218
			default: h = (h / 255) * 360;
219
		}
220
		if (h == 360){ h = 0;}
221
 
222
		//	no need to alter if inputRange[1] = 1
223
		switch(opt.inputRange[1]){
224
			case 100: s /= 100; break;
225
			case 255: s /= 255;
226
		}
227
 
228
		//	no need to alter if inputRange[1] = 1
229
		switch(opt.inputRange[2]){
230
			case 100: v /= 100; break;
231
			case 255: v /= 255;
232
		}
233
 
234
		var r = null;
235
		var g = null;
236
		var b = null;
237
 
238
		if (s == 0){
239
			// color is on black-and-white center line
240
			// achromatic: shades of gray
241
			r = v;
242
			g = v;
243
			b = v;
244
		}else{
245
			// chromatic color
246
			var hTemp = h / 60;		// h is now IN [0,6]
247
			var i = Math.floor(hTemp);	// largest integer <= h
248
			var f = hTemp - i;		// fractional part of h
249
 
250
			var p = v * (1 - s);
251
			var q = v * (1 - (s * f));
252
			var t = v * (1 - (s * (1 - f)));
253
 
254
			switch(i){
255
				case 0: r = v; g = t; b = p; break;
256
				case 1: r = q; g = v; b = p; break;
257
				case 2: r = p; g = v; b = t; break;
258
				case 3: r = p; g = q; b = v; break;
259
				case 4: r = t; g = p; b = v; break;
260
				case 5: r = v; g = p; b = q; break;
261
			}
262
		}
263
 
264
		switch(opt.outputRange){
265
			case 1:
266
				r = dojo.math.round(r, 2);
267
				g = dojo.math.round(g, 2);
268
				b = dojo.math.round(b, 2);
269
				break;
270
			case 100:
271
				r = Math.round(r * 100);
272
				g = Math.round(g * 100);
273
				b = Math.round(b * 100);
274
				break;
275
			default:
276
				r = Math.round(r * 255);
277
				g = Math.round(g * 255);
278
				b = Math.round(b * 255);
279
		}
280
		return [r, g, b];
281
	}
282
});
283
 
284
}