/**
* @constructor
*/
hui.ui.ColorPicker = function(options) {
this.options = options || {};
this.name = options.name;
this.element = hui.get(options.element);
this.color = null;
this.buttons = [];
this.preview = hui.get.firstByClass(this.element,'hui_colorpicker_preview');
this.pages = hui.get.byClass(this.element,'hui_colorpicker_page');
this.input = hui.get.firstByTag(this.element,'input');
this.wheel1 = this.pages[0];
this.wheel2 = this.pages[1];
this.wheel3 = this.pages[2];
this.swatches = this.pages[3];
hui.ui.extend(this);
if (options.listener) {
this.listen(options.listener);
}
this.addBehavior();
this.buildData();
};
hui.ui.ColorPicker.create = function(options) {
var swatches = '',
c, hex, j;
for (var i = 0; i < 360; i += 30) {
for (j = 0.05; j <= 1; j += 0.15) {
c = hui.Color.hsv2rgb(i, j, 1);
hex = hui.Color.rgb2hex(c);
swatches += '<a style="background: rgb(' + c[0] + ',' + c[1] + ',' + c[2] + ')" rel="' + hex + '"></a>';
}
for (j = 1; j >= 0.20; j -= 0.15) {
c = hui.Color.hsv2rgb(i, 1, j);
hex = hui.Color.rgb2hex(c);
swatches += '<a style="background: rgb(' + c[0] + ',' + c[1] + ',' + c[2] + ')" rel="' + hex + '"></a>';
}
}
for (j = 255; j >= 0; j -= 255 / 12) {
hex = hui.Color.rgb2hex([j, j, j]);
swatches += '<a style="background: rgb('+Math.round(j)+','+Math.round(j)+','+Math.round(j)+')" rel="'+hex+'"></a>';
}
options = options || {};
options.element = hui.build('div',{
'class':'hui_colorpicker',
html :
'<div class="hui_bar hui_bar-window_mini">'+
'<div class="hui_bar_left">'+
'<a class="hui_bar_button hui_bar_button-selected" href="javascript:void(0)" rel="0">'+
'<span class="hui_icon_16" style="'+hui.ui.getIconStyle('colorpicker/wheel_pastels',16)+'"></span>'+
'</a>'+
'<a class="hui_bar_button" href="javascript:void(0)" rel="1">'+
'<span class="hui_icon_16" style="'+hui.ui.getIconStyle('colorpicker/wheel_brightness',16)+'"></span>'+
'</a>'+
'<a class="hui_bar_button" href="javascript:void(0)" rel="2">'+
'<span class="hui_icon_16" style="'+hui.ui.getIconStyle('colorpicker/wheel_saturated',16)+'"></span>'+
'</a>'+
'<a class="hui_bar_button" href="javascript:void(0)" rel="3">'+
'<span class="hui_icon_16" style="'+hui.ui.getIconStyle('colorpicker/swatches',16)+'"></span>'+
'</a>'+
'</div>'+
'<div class="hui_bar_right">'+
'<input class="hui_colorpicker"/>'+
'</div>' +
'</div>'+
'<div class="hui_colorpicker_pages">'+
'<div class="hui_colorpicker_page hui_colorpicker_wheel1"></div>'+
'<div class="hui_colorpicker_page hui_colorpicker_wheel2"></div>'+
'<div class="hui_colorpicker_page hui_colorpicker_wheel3"></div>'+
'<div class="hui_colorpicker_page hui_colorpicker_swatches">'+swatches+'</div>'+
'</div>'+
'<div class="hui_colorpicker_preview"></div>'
});
return new hui.ui.ColorPicker(options);
};
hui.ui.ColorPicker.prototype = {
/** @private */
addBehavior : function() {
var bs = hui.get.byClass(this.element,'hui_bar_button');
for (var i=0; i < bs.length; i++) {
var button = new hui.ui.Bar.Button({element:bs[i]});
button.listen(this);
this.buttons.push(button);
}
hui.listen(this.element,'click',this._click.bind(this));
hui.listen(this.wheel1,'mousemove',this._hoverWheel1.bind(this));
hui.listen(this.wheel1,'click',this._pickColor.bind(this));
hui.listen(this.wheel2,'mousemove',this._hoverWheel2.bind(this));
hui.listen(this.wheel2,'click',this._pickColor.bind(this));
hui.listen(this.wheel3,'mousemove',this._hoverWheel3.bind(this));
hui.listen(this.wheel3,'click',this._pickColor.bind(this));
hui.listen(this.element,'mousedown',function(e) {
hui.stop(e);
});
hui.listen(this.swatches,'mousemove',function(e) {
e = hui.event(e);
this._hoverColor(e.element.getAttribute('rel'));
}.bind(this));
hui.listen(this.swatches,'click',this._pickColor.bind(this));
},
/** @private */
$click : function(button) {
var page = parseInt(button.element.getAttribute('rel')),
i;
for (i = this.pages.length - 1; i >= 0; i--){
this.pages[i].style.display = i==page ? 'block' : 'none';
}
for (i=0; i < this.buttons.length; i++) {
this.buttons[i].setSelected(this.buttons[i]==button);
}
},
_click : function(e) {
e = hui.event(e);
e.stop();
var input = e.findByTag('input');
if (input) {input.focus();}
},
_pickColor : function(e) {
hui.stop(e);
this.fire('colorWasSelected',this.color);
},
_hoverColor : function(color) {
this.preview.style.background = color;
this.color = color;
this.fire('colorWasHovered',this.color);
this.input.value = color;
},
/** @private */
buildData : function() {
var addary = []; //red
addary[0] = new Array(0,1,0); //red green
addary[1] = new Array(-1,0,0); //green
addary[2] = new Array(0,0,1); //green blue
addary[3] = new Array(0,-1,0); //blue
addary[4] = new Array(1,0,0); //red blue
addary[5] = new Array(0,0,-1); //red
addary[6] = new Array(255,1,1);
var clrary = new Array(360);
for(var i = 0; i < 6; i++) {
for(var j = 0; j < 60; j++) {
clrary[60 * i + j] = new Array(3);
for(var k = 0; k < 3; k++) {
clrary[60 * i + j][k] = addary[6][k];
addary[6][k] += (addary[i][k] * 4);
}
}
}
this.colorArray = clrary;
},
_hoverWheel1 : function(e) {
e = hui.event(e);
var pos = hui.position.get(this.wheel1);
var x = 4 * (e.getLeft() - pos.left);
var y = 4 * (e.getTop() - pos.top);
var sx = x - 512;
var sy = y - 512;
var qx = (sx < 0)?0:1;
var qy = (sy < 0)?0:1;
var q = 2 * qy + qx;
var quad = new Array(-180,360,180,0);
var xa = Math.abs(sx);
var ya = Math.abs(sy);
var d = ya * 45 / xa;
if(ya > xa) {
d = 90 - (xa * 45 / ya);
}
var deg = Math.floor(Math.abs(quad[q] - d));
sx = Math.abs(x - 512);
sy = Math.abs(y - 512);
var r = Math.sqrt((sx * sx) + (sy * sy));
var c;
if(x == 512 & y == 512) {
c = "000000";
} else {
var n = 0;
for(var i = 0; i < 3; i++) {
var r2 = this.colorArray[deg][i] * r / 256;
if(r > 256) r2 += Math.floor(r - 256);
if(r2 > 255) r2 = 255;
n = 256 * n + Math.floor(r2);
}
c = n.toString(16);
}
while(c.length < 6) c = "0" + c;
this._hoverColor('#'+c);
},
_hoverWheel2 : function(e) {
var rgb,sat,val;
e = hui.event(e);
var pos = hui.position.get(this.wheel2);
var x = (e.getLeft() - pos.left);
var y = (e.getTop() - pos.top);
if (y > 256) {return;}
var cartx = x - 128;
var carty = 128 - y;
var cartx2 = cartx * cartx;
var carty2 = carty * carty;
var rraw = Math.sqrt(cartx2 + carty2); //raw radius
var rnorm = rraw / 128; //normalized radius
if (rraw === 0) {
sat = 0;
val = 0;
rgb = new Array(0, 0, 0);
} else {
var arad = Math.acos(cartx / rraw); //angle in radians
var aradc = (carty >= 0) ? arad : 2 * Math.PI - arad; //correct below axis
var adeg = 360 * aradc / (2 * Math.PI); //convert to degrees
if (rnorm > 1) { // outside circle
rgb = new Array(255, 255, 255);
sat = 1;
val = 1;
} else if (rnorm >= 0.5) {
sat = 1 - ((rnorm - 0.5) * 2);
val = 1;
rgb = hui.Color.hsv2rgb(adeg, sat, val);
} else {
sat = 1;
val = rnorm * 2;
rgb = hui.Color.hsv2rgb(adeg, sat, val);
}
}
this._hoverColor(hui.Color.rgb2hex(rgb));
},
_hoverWheel3 : function(e) {
var rgb,sat,val;
e = hui.event(e);
var pos = hui.position.get(this.wheel3);
var x = (e.getLeft() - pos.left);
var y = (e.getTop() - pos.top);
if (y > 256) {return;}
var cartx = x - 128;
var carty = 128 - y;
var cartx2 = cartx * cartx;
var carty2 = carty * carty;
var rraw = Math.sqrt(cartx2 + carty2); //raw radius
var rnorm = rraw/128; //normalized radius
if (rraw === 0) {
sat = 0;
val = 0;
rgb = new Array(0,0,0);
} else {
var arad = Math.acos(cartx/rraw); //angle in radians
var aradc = (carty>=0) ? arad : 2*Math.PI - arad; //correct below axis
var adeg = 360 * aradc/(2*Math.PI); //convert to degrees
if (rnorm > 1) { // outside circle
rgb = new Array(255,255,255);
sat = 1;
val = 1;
} else {
sat = rnorm;// - ((rnorm - .5) *2);
val = 1;
rgb = hui.Color.hsv2rgb(adeg,sat,val);
}
}
this._hoverColor(hui.Color.rgb2hex(rgb));
}
};