+ //
+
+ // showRgb: Boolean
+ // show/update RGB input nodes
+ showRgb: true,
+
+ // showHsv: Boolean
+ // show/update HSV input nodes
+ showHsv: true,
+
+ // showHex: Boolean
+ // show/update Hex value field
+ showHex: true,
+
+ // webSafe: Boolean
+ // deprecated? or just use a toggle to show/hide that node, too?
+ webSafe: true,
+
+ // animatePoint: Boolean
+ // toggle to use slideTo (true) or just place the cursor (false) on click
+ animatePoint: true,
+
+ // slideDuration: Integer
+ // time in ms picker node will slide to next location (non-dragging) when animatePoint=true
+ slideDuration: 250,
+
+ _underlay: dojo.moduleUrl("dojox.widget","ColorPicker/images/underlay.png"),
+ templateString:"
\n\t
\n\t\t\n\t\t\n\t
\n\t
\n\t\t\n\t\t\n\t
\n\t\n\t\n\t
\n\t\t
\n\t\t\t
\n\t\t\t
r
\n\t\t\t
g
\n\t\t\t
b
\n\t\t\t
\n\t\t
\n\t\t
\n\t\t\t
\n\t\t\t
h
°
\n\t\t\t
s
%
\n\t\t\t
v
%
\n\t\t\t
\n\t\t
\n\t\t
\t\n\t\t\thex: \n\t\t
\n\t
\n
\n",
+
+ postCreate: function(){
+ // summary: As quickly as we can, set up ie6 alpha-filter support for our
+ // underlay. we don't do image handles (done in css), just the 'core'
+ // of this widget: the underlay.
+ if(dojo.isIE && dojo.isIE<7){
+ this.colorUnderlay.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this._underlay+"', sizingMethod='scale')";
+ this.colorUnderlay.src = dojo.moduleUrl("dojo","resources/blank.gif").toString();
+ }
+ // hide toggle-able nodes:
+ if (!this.showRgb){ this.rgbNode.style.display = "none"; }
+ if (!this.showHsv){ this.hsvNode.style.display = "none"; }
+ if (!this.showHex){ this.hexNode.style.display = "none"; }
+ if (!this.webSafe){ this.safePreviewNode.style.display = "none"; }
+ },
+
+ startup: function(){
+ // summary: defer all additional calls until we're started, and our
+ // embeded sliders are loaded? (not implemented yet)
+
+ // this._offset = ((dojo.marginBox(this.cursorNode).w)/2);
+ this._offset = 0;
+
+ this._mover = new dojo.dnd.Moveable(this.cursorNode, {
+ mover: dojo.dnd.boxConstrainedMover({ t:0, l:0, w:150, h:150 })
+ });
+ this._hueMover = new dojo.dnd.Moveable(this.hueCursorNode, {
+ mover: dojo.dnd.boxConstrainedMover({ t:0, l:0, w:0, h:150 })
+ });
+
+ // no dnd/move/move published ... use a timer:
+ dojo.subscribe("/dnd/move/stop",dojo.hitch(this,"_clearTimer"));
+ dojo.subscribe("/dnd/move/start",dojo.hitch(this,"_setTimer"));
+
+ // ugly scaling calculator. need a XYslider badly
+ this._sc = (1/dojo.coords(this.colorUnderlay).w);
+ this._hueSc = (255/(dojo.coords(this.hueNode).h+this._offset));
+
+ // initial color
+ this._updateColor();
+
+ },
+
+ _setTimer: function(/* dojo.dnd.Mover */mover){
+ this._timer = setInterval(dojo.hitch(this,"_updateColor"),45);
+ },
+ _clearTimer: function(/* dojo.dnd.Mover */mover){
+ clearInterval(this._timer);
+ this.onChange(this.value);
+ },
+
+ _setHue: function(/* Decimal */h){
+ // summary: sets a natural color background for the
+ // underlay image against closest hue value (full saturation)
+ // h: 0..255
+
+ // this is not a pretty conversion:
+ var hue = dojo.colorFromArray(this._hsv2rgb(h,1,1,{ inputRange: 1 })).toHex();
+ dojo.style(this.colorUnderlay,"backgroundColor",hue);
+ },
+
+ _updateColor: function(){
+ // summary: update the previewNode color, and input values [optional]
+ var h = Math.round((255+(this._offset))-((dojo.style(this.hueCursorNode,"top")+this._offset)*this._hueSc));
+ var s = Math.round((dojo.style(this.cursorNode,"left")*this._sc)*100);
+ var v = Math.round(100-(dojo.style(this.cursorNode,"top")*this._sc)*100);
+
+ // limit hue calculations to only when it changes
+ if(h != this._hue){ this._setHue(h); }
+
+ var rgb = this._hsv2rgb(h,s/100,v/100,{ inputRange: 1 });
+ var hex = (dojo.colorFromArray(rgb).toHex());
+
+ this.previewNode.style.backgroundColor = hex;
+ if(this.webSafe){ this.safePreviewNode.style.backgroundColor = hex; }
+ if(this.showHex){ this.hexCode.value = hex; }
+ if(this.showRgb){
+ this.Rval.value = rgb[0];
+ this.Gval.value = rgb[1];
+ this.Bval.value = rgb[2];
+ }
+ if(this.showHsv){
+ this.Hval.value = Math.round((h*360)/255); // convert to 0..360
+ this.Sval.value = s;
+ this.Vval.value = v;
+ }
+ this.value=hex;
+
+ // anytime we muck with the color, fire onChange?
+ if (!this._timer && !(arguments[1])){
+ this.setValue(this.value);
+ this.onChange(this.value);
+ }
+ },
+
+ _setHuePoint: function(/* Event */evt){
+ // summary: set the hue picker handle on relative y coordinates
+ if(this.animatePoint){
+ dojo.fx.slideTo({
+ node: this.hueCursorNode,
+ duration:this.slideDuration,
+ top: evt.layerY,
+ left: 0,
+ onEnd: dojo.hitch(this,"_updateColor")
+ }).play();
+ }else{
+ dojo.style(this.hueCursorNode,"top",(evt.layerY)+"px");
+ this._updateColor(false);
+ }
+ },
+
+ _setPoint: function(/* Event */evt){
+ // summary: set our picker point based on relative x/y coordinates
+ if(this.animatePoint){
+ dojo.fx.slideTo({
+ node: this.cursorNode,
+ duration:this.slideDuration,
+ top: evt.layerY-this._offset,
+ left: evt.layerX-this._offset,
+ onEnd: dojo.hitch(this,"_updateColor")
+ }).play();
+ }else{
+ dojo.style(this.cursorNode,"left",(evt.layerX-this._offset)+"px");
+ dojo.style(this.cursorNode,"top",(evt.layerY-this._offset)+"px");
+ this._updateColor(false);
+ }
+ },
+
+ // this ported directly from 0.4 dojo.gfx.colors.hsv, with bugs :)
+ // FIXME: use ttrenka's HSB ?
+ _hsv2rgb: function(/* int || Array */h, /* int */s, /* int */v, /* Object? */options){
+ // summary
+ // converts an HSV value set to RGB, ranges depending on optional options object.
+ // patch for options by Matthew Eernisse
+ if (dojo.isArray(h)) {
+ if(s){
+ options = s;
+ }
+ v = h[2] || 0;
+ s = h[1] || 0;
+ h = h[0] || 0;
+ }
+
+ var opt = {
+ inputRange: (options && options.inputRange) ? options.inputRange : [255, 255, 255],
+ outputRange: (options && options.outputRange) ? options.outputRange : 255
+ };
+
+ switch(opt.inputRange[0]) {
+ // 0.0-1.0
+ case 1: h = h * 360; break;
+ // 0-100
+ case 100: h = (h / 100) * 360; break;
+ // 0-360
+ case 360: h = h; break;
+ // 0-255
+ default: h = (h / 255) * 360;
+ }
+ if (h == 360){ h = 0;}
+
+ // no need to alter if inputRange[1] = 1
+ switch(opt.inputRange[1]){
+ case 100: s /= 100; break;
+ case 255: s /= 255;
+ }
+
+ // no need to alter if inputRange[1] = 1
+ switch(opt.inputRange[2]){
+ case 100: v /= 100; break;
+ case 255: v /= 255;
+ }
+
+ var r = null;
+ var g = null;
+ var b = null;
+
+ if (s == 0){
+ // color is on black-and-white center line
+ // achromatic: shades of gray
+ r = v;
+ g = v;
+ b = v;
+ }else{
+ // chromatic color
+ var hTemp = h / 60; // h is now IN [0,6]
+ var i = Math.floor(hTemp); // largest integer <= h
+ var f = hTemp - i; // fractional part of h
+
+ var p = v * (1 - s);
+ var q = v * (1 - (s * f));
+ var t = v * (1 - (s * (1 - f)));
+
+ switch(i){
+ case 0: r = v; g = t; b = p; break;
+ case 1: r = q; g = v; b = p; break;
+ case 2: r = p; g = v; b = t; break;
+ case 3: r = p; g = q; b = v; break;
+ case 4: r = t; g = p; b = v; break;
+ case 5: r = v; g = p; b = q; break;
+ }
+ }
+
+ switch(opt.outputRange){
+ case 1:
+ r = dojo.math.round(r, 2);
+ g = dojo.math.round(g, 2);
+ b = dojo.math.round(b, 2);
+ break;
+ case 100:
+ r = Math.round(r * 100);
+ g = Math.round(g * 100);
+ b = Math.round(b * 100);
+ break;
+ default:
+ r = Math.round(r * 255);
+ g = Math.round(g * 255);
+ b = Math.round(b * 255);
+ }
+ return [r, g, b];
+ }
+});
+
+}
diff --git a/includes/js/dojox/widget/ColorPicker/ColorPicker.css b/includes/js/dojox/widget/ColorPicker/ColorPicker.css
new file mode 100644
index 0000000..3d62bc7
--- /dev/null
+++ b/includes/js/dojox/widget/ColorPicker/ColorPicker.css
@@ -0,0 +1,78 @@
+.dojoxColorPicker {
+ padding:8px;
+ border:1px solid #a0a0a0;
+ background:#ededed;
+ width:300px;
+ height:150px;
+ -moz-border-radius:4pt;
+ -webkit-border-radius:5pt;
+}
+.dojoxColorPickerBox {
+ position:relative;
+ width:150px;
+ height:150px;
+ margin:0; padding:0;
+}
+.dojoxColorPickerUnderlay {
+ position:absolute;
+ top:0; left:0;
+ width:150px;
+ height:150px;
+ z-index:1;
+ border:1px solid #a0a0a0;
+}
+.dojoxHuePickerUnderlay {
+ background:url(images/hue.png) no-repeat top center;
+ position:absolute;
+ top:0; left:0;
+ height:150px;
+ width:20px;
+ z-index:1;
+}
+.dojoxHuePicker { position:relative; top:-150px; left:157px; }
+.dojoxHuePickerPoint {
+ position:absolute;
+ top:0; left:0;
+ width:20px;
+ height:8px;
+ z-index:3;
+ background-color:#666;
+ cursor:pointer;
+ background:url(images/hueHandle.png) no-repeat center center;
+}
+.dojoxColorPickerPoint {
+ position:absolute;
+ width:10px;
+ height:10px;
+ background: url(images/pickerPointer.png) no-repeat center center;
+ border:0;
+ z-index:3;
+ cursor:pointer;
+}
+.dojoxColorPickerPreview {
+ display:block;
+ width:45px;
+ height:45px;
+ border:1px solid #333;
+ background-color:#fff;
+ position:relative;
+ top:-150px;
+ left: 185px;
+}
+.dojoxColorPickerWebSafePreview {
+ display:block;
+ width:25px;
+ height:25px;
+ position:relative;
+ top:-197px;
+ left:240px;
+ border:1px solid #333;
+}
+.dojoxColorPickerOptional {
+ position:relative;
+ top:-170px;
+ left:185px;
+}
+.dojoxColorPickerRgb { position:absolute; top:0; left:0; }
+.dojoxColorPickerHsv { position:absolute; top:0; left:50px; }
+.dojoxColorPickerHex { position:absolute; top:73px; left:2px; }
diff --git a/includes/js/dojox/widget/ColorPicker/ColorPicker.css.commented.css b/includes/js/dojox/widget/ColorPicker/ColorPicker.css.commented.css
new file mode 100644
index 0000000..789a9dd
--- /dev/null
+++ b/includes/js/dojox/widget/ColorPicker/ColorPicker.css.commented.css
@@ -0,0 +1,89 @@
+.dojoxColorPicker {
+ padding:8px;
+ border:1px solid #a0a0a0;
+ background:#ededed;
+ width:300px;
+ height:150px;
+ -moz-border-radius:4pt;
+ -webkit-border-radius:5pt;
+}
+
+
+.dojoxColorPickerBox {
+ position:relative;
+ width:150px;
+ height:150px;
+ margin:0; padding:0;
+}
+
+.dojoxColorPickerUnderlay {
+ position:absolute;
+ top:0; left:0;
+ width:150px;
+ height:150px;
+ z-index:1;
+ border:1px solid #a0a0a0;
+}
+
+.dojoxHuePickerUnderlay {
+ background:url(images/hue.png) no-repeat top center;
+ position:absolute;
+ top:0; left:0;
+ height:150px;
+ width:20px;
+ z-index:1;
+}
+
+.dojoxHuePicker { position:relative; top:-150px; left:157px; }
+
+.dojoxHuePickerPoint {
+ position:absolute;
+ top:0; left:0;
+ width:20px;
+ height:8px;
+ z-index:3;
+ background-color:#666;
+ cursor:pointer;
+ background:url(images/hueHandle.png) no-repeat center center;
+}
+
+
+.dojoxColorPickerPoint {
+ position:absolute;
+ width:10px;
+ height:10px;
+ background: url(images/pickerPointer.png) no-repeat center center;
+ border:0;
+ z-index:3;
+ cursor:pointer;
+}
+
+.dojoxColorPickerPreview {
+ display:block;
+ width:45px;
+ height:45px;
+ border:1px solid #333;
+ background-color:#fff;
+ position:relative;
+ top:-150px;
+ left: 185px;
+}
+.dojoxColorPickerWebSafePreview {
+ display:block;
+ width:25px;
+ height:25px;
+ position:relative;
+ top:-197px;
+ left:240px;
+ border:1px solid #333;
+}
+
+.dojoxColorPickerOptional {
+ position:relative;
+ top:-170px;
+ left:185px;
+}
+
+.dojoxColorPickerRgb { position:absolute; top:0; left:0; }
+.dojoxColorPickerHsv { position:absolute; top:0; left:50px; }
+.dojoxColorPickerHex { position:absolute; top:73px; left:2px; }
diff --git a/includes/js/dojox/widget/ColorPicker/ColorPicker.html b/includes/js/dojox/widget/ColorPicker/ColorPicker.html
new file mode 100644
index 0000000..de317ba
--- /dev/null
+++ b/includes/js/dojox/widget/ColorPicker/ColorPicker.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
r
+
g
+
b
+
+
+
+
+
h
°
+
s
%
+
v
%
+
+
+
+ hex:
+
+
+
diff --git a/includes/js/dojox/widget/ColorPicker/images/hue.png b/includes/js/dojox/widget/ColorPicker/images/hue.png
new file mode 100644
index 0000000..2746235
Binary files /dev/null and b/includes/js/dojox/widget/ColorPicker/images/hue.png differ
diff --git a/includes/js/dojox/widget/ColorPicker/images/hueHandle.png b/includes/js/dojox/widget/ColorPicker/images/hueHandle.png
new file mode 100644
index 0000000..c7b56e8
Binary files /dev/null and b/includes/js/dojox/widget/ColorPicker/images/hueHandle.png differ
diff --git a/includes/js/dojox/widget/ColorPicker/images/pickerPointer.png b/includes/js/dojox/widget/ColorPicker/images/pickerPointer.png
new file mode 100644
index 0000000..28a3c81
Binary files /dev/null and b/includes/js/dojox/widget/ColorPicker/images/pickerPointer.png differ
diff --git a/includes/js/dojox/widget/ColorPicker/images/underlay.png b/includes/js/dojox/widget/ColorPicker/images/underlay.png
new file mode 100644
index 0000000..0f5eb7c
Binary files /dev/null and b/includes/js/dojox/widget/ColorPicker/images/underlay.png differ
diff --git a/includes/js/dojox/widget/FileInput.js b/includes/js/dojox/widget/FileInput.js
new file mode 100644
index 0000000..40cf58c
--- /dev/null
+++ b/includes/js/dojox/widget/FileInput.js
@@ -0,0 +1,75 @@
+if(!dojo._hasResource["dojox.widget.FileInput"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.widget.FileInput"] = true;
+dojo.provide("dojox.widget.FileInput");
+dojo.experimental("dojox.widget.FileInput");
+
+dojo.require("dijit.form._FormWidget");
+dojo.require("dijit._Templated");
+
+dojo.declare("dojox.widget.FileInput",
+ dijit.form._FormWidget,
+ {
+ // summary: A styled input type="file"
+ //
+ // description: A input type="file" form widget, with a button for uploading to be styled via css,
+ // a cancel button to clear selection, and FormWidget mixin to provide standard dijit.form.Form
+ // support (FIXME: maybe not fully implemented)
+
+ // label: String
+ // the title text of the "Browse" button
+ label: "Browse ...",
+
+ // cancelText: String
+ // the title of the "Cancel" button
+ cancelText: "Cancel",
+
+ // name: String
+ // ugh, this should be pulled from this.domNode
+ name: "uploadFile",
+
+ templateString:"
diff --git a/includes/js/dojox/widget/FileInput/FileInputAuto.html b/includes/js/dojox/widget/FileInput/FileInputAuto.html
new file mode 100644
index 0000000..f3c6216
--- /dev/null
+++ b/includes/js/dojox/widget/FileInput/FileInputAuto.html
@@ -0,0 +1,9 @@
+
+
+
+
+
${label}
+
${cancelText}
+
+
+
diff --git a/includes/js/dojox/widget/FileInput/ReceiveFile.php b/includes/js/dojox/widget/FileInput/ReceiveFile.php
new file mode 100644
index 0000000..aca541f
--- /dev/null
+++ b/includes/js/dojox/widget/FileInput/ReceiveFile.php
@@ -0,0 +1,37 @@
+ "success",
+ 'name' => $name,
+ 'request' => $_REQUEST,
+ 'postvars' => $_POST,
+ 'details' => $_FILES,
+ // and some static subarray just to see
+ 'foo' => array('foo'=>"bar")
+ );
+
+}else{
+ $ar = array(
+ 'status' => "failed",
+ 'details' => ""
+ );
+}
+
+// yeah, seems you have to wrap iframeIO stuff in textareas?
+$foo = $json->encode($ar);
+?>
+
diff --git a/includes/js/dojox/widget/FileInputAuto.js b/includes/js/dojox/widget/FileInputAuto.js
new file mode 100644
index 0000000..1035531
--- /dev/null
+++ b/includes/js/dojox/widget/FileInputAuto.js
@@ -0,0 +1,185 @@
+if(!dojo._hasResource["dojox.widget.FileInputAuto"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.widget.FileInputAuto"] = true;
+dojo.provide("dojox.widget.FileInputAuto");
+
+dojo.require("dojox.widget.FileInput");
+dojo.require("dojo.io.iframe");
+
+dojo.declare("dojox.widget.FileInputAuto",
+ dojox.widget.FileInput,
+ {
+ // summary: An extension on dojox.widget.FileInput providing background upload progress
+ //
+ // description: An extended version of FileInput - when the user focuses away from the input
+ // the selected file is posted via dojo.io.iframe to the url. example implementation
+ // comes with PHP solution for handling upload, and returning required data.
+ //
+ // notes: the return data from the io.iframe is used to populate the input element with
+ // data regarding the results. it will be a JSON object, like:
+ //
+ // results = { size: "1024", filename: "file.txt" }
+ //
+ // all the parameters allowed to dojox.widget.FileInput apply
+
+ // url: String
+ // the URL where our background FileUpload will be sent
+ url: "",
+
+ // blurDelay: Integer
+ // time in ms before an un-focused widget will wait before uploading the file to the url="" specified
+ // default: 2 seconds
+ blurDelay: 2000,
+
+ // duration: Integer
+ // The time in ms to use as the generic timing mechanism for the animations
+ // set to 1 or 0 for "immediate respose"
+ duration: 500,
+
+ // uploadMessage: String
+ //
+ // FIXME: i18n somehow?
+ uploadMessage: "Uploading ...",
+
+ _sent: false,
+
+ // small template changes, new attachpoint: overlay
+ templateString:"
\n\t\n\t
\n\t\t\n\t\t
${label}
\n\t\t
${cancelText}
\n\t
\n\t
\n
\n",
+
+ startup: function(){
+ // summary: add our extra blur listeners
+ this._blurListener = dojo.connect(this.fileInput,"onblur",this,"_onBlur");
+ this._focusListener = dojo.connect(this.fileInput,"onfocus",this,"_onFocus");
+ this.inherited("startup",arguments);
+ },
+
+ _onFocus: function(){
+ // summary: clear the upload timer
+ if(this._blurTimer){ clearTimeout(this._blurTimer); }
+ },
+
+ _onBlur: function(){
+ // summary: start the upload timer
+ if(this._blurTimer){ clearTimeout(this._blurTimer); }
+ if(!this._sent){
+ this._blurTimer = setTimeout(dojo.hitch(this,"_sendFile"),this.blurDelay);
+ }
+ },
+
+
+ setMessage: function(/*String*/title){
+ // summary: set the text of the progressbar
+
+ // FIXME: this throws errors in IE?!?!?!? egads.
+ if(!dojo.isIE){ this.overlay.innerHTML = title; }
+ },
+
+ _sendFile: function(/* Event */e){
+ // summary: triggers the chain of events needed to upload a file in the background.
+ if(!this.fileInput.value || this._sent){ return; }
+
+ dojo.style(this.fakeNodeHolder,"display","none");
+ dojo.style(this.overlay,"opacity","0");
+ dojo.style(this.overlay,"display","block");
+
+ this.setMessage(this.uploadMessage);
+
+ dojo.fadeIn({ node: this.overlay, duration:this.duration }).play();
+
+ var _newForm;
+ if(dojo.isIE){
+ // just to reiterate, IE is a steaming pile of code.
+ _newForm = document.createElement('