this.draw = new function() { var drawlib = this; this.create_color = function(tuple) { /* convert a tuple of 3 digits (value >= 0, < 255) to a string */ testing.assert(tuple instanceof Array, 'color should be an array'); testing.assert(tuple.length == 3, 'color should have 3 values'); for (var i=0; i < tuple.length; i++) { testing.assert((tuple[i] >= 0 && tuple[i] < 256), 'wrong color value ' + tuple[i]); }; return 'rgb(' + tuple.join(',') + ')'; }; this.Canvas = function(doc) { /* initialize the canvas */ this.doc = doc || document; this.draw = false; this._init(); }; this.Canvas.prototype.attachTo = function(el) { /* attach the canvas (table) to an element (DOM node) in the page */ el.appendChild(this.canvas); }; this.Canvas.prototype.changeColor = function(color) { this.current_color = drawlib.create_color(color); }; this.Canvas.prototype.drawPixel = function(td) { if (!this.draw || td.nodeName.toLowerCase() != 'td') { return; }; td.style.backgroundColor = this.current_color; }; this.Canvas.prototype.buildNew = function(width, height, psize) { this.cleanup(); this.canvas = this._create_canvas(width, height, psize); misclib.addEventHandler(this.canvas, 'mousedown', this.handleMouseDown, this); misclib.addEventHandler(this.doc, 'mouseup', this.handleMouseUp, this); }; this.Canvas.prototype.buildFromPixmap = function(xpm, psize) { /* build from an xpmlib.PixMap object */ this.cleanup(); var table = xpm.render(new xpmlib.TableRenderer(this.doc)); table.className = 'canvas'; var trs = table.getElementsByTagName('tr'); for (var i=0; i < trs.length; i++) { var tds = trs[i].getElementsByTagName('td'); for (var j=0; j < tds.length; j++) { tds[j].style.width = psize + 'px'; tds[j].style.height = psize + 'px'; }; }; misclib.addEventHandler(table, 'mouseover', this.handleMouseOver, this); this.canvas = table; misclib.addEventHandler(this.canvas, 'mousedown', this.handleMouseDown, this); misclib.addEventHandler(this.doc, 'mouseup', this.handleMouseUp, this); }; this.Canvas.prototype.toPixmap = function() { /* generates an xpm.Pixmap object from the current content */ return new xpmlib.PixMap(this.canvas); }; this.Canvas.prototype.cleanup = function() { if (this.canvas) { this.canvas.parentNode.removeChild(this.canvas); }; }; this.Canvas.prototype.handleMouseOver = function(event) { var target = event.target || event.srcElement; this.drawPixel(target); }; this.Canvas.prototype.handleMouseDown = function(event) { this.draw = true; var target = event.target || event.srcElement; this.drawPixel(target); }; this.Canvas.prototype.handleMouseUp = function(event) { this.draw = false; }; this.Canvas.prototype._init = function() { this.background_color = 'rgb(255, 255, 255)'; this.changeColor([0, 0, 0]); }; this.Canvas.prototype._create_canvas = function(width, height, psize) { var c = this.doc.createElement('table'); misclib.addEventHandler(c, 'mouseover', this.handleMouseOver, this); c.className = 'canvas'; c.cellPadding = "0"; c.cellSpacing = "0"; var tb = this.doc.createElement('tbody'); c.appendChild(tb); for (var i=0; i < height; i++) { var tr = this.doc.createElement('tr'); tb.appendChild(tr); for (var j=0; j < width; j++) { var td = this.doc.createElement('td'); tr.appendChild(td); // XXX removed for now, makes that IE doesn't display a // selection when drawing... and seems to work fine in most // browsers //td.appendChild(this.doc.createTextNode('\xa0')); td.style.lineHeight = "1px"; td.style.fontSize = "1px"; td.style.height = psize + "px"; td.style.width = psize + "px"; td.style.backgroundColor = this.background_color; }; }; return c; }; this.SimpleColorPicker = function(canvas, cellwidth, cellheight, doc) { /* simple 216 color color picker */ this._init(canvas, cellwidth, cellheight, doc); }; this.SimpleColorPicker.prototype.attachTo = function(el) { /* attach the colorpicker (div with tables) to an element */ el.appendChild(this.picker); }; this.SimpleColorPicker.prototype._init = function(canvas, cellwidth, cellheight, numrows, doc) { this.canvas = canvas; this.cellwidth = cellwidth || 10; this.cellheight = cellheight || 10; this.numrows = numrows || 2; this.doc = doc || document; this.picker = this._build(); }; this.SimpleColorPicker.prototype._build = function() { var otable = this.doc.createElement('table'); otable.className = 'simple-colorpicker'; otable.cellPadding = '0'; otable.cellSpacing = '0'; var otbody = this.doc.createElement('tbody'); otable.appendChild(otbody); misclib.addEventHandler(otable, 'click', this.handleClick, this); var hexdigits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f']; var currow = null; for (var i=0; i < hexdigits.length; i++) { r = hexdigits[i]; if (i % this.numrows == 0) { currow = this.doc.createElement('tr'); otbody.appendChild(currow); } var container = this.doc.createElement('td'); currow.appendChild(container); var table = this.doc.createElement('table'); table.cellPadding = '0'; table.cellSpacing = '0'; container.appendChild(table); var tbody = this.doc.createElement('tbody'); table.appendChild(tbody); for (var j=0; j < hexdigits.length; j++) { g = hexdigits[j]; var tr = this.doc.createElement('tr'); tbody.appendChild(tr); for (var k=0; k < hexdigits.length; k++) { b = hexdigits[k]; var td = this.doc.createElement('td'); tr.appendChild(td); // this should give us all 'web-safe' colors rc = parseInt('' + r + r, 16); gc = parseInt('' + g + g, 16); bc = parseInt('' + b + b, 16); td.style.backgroundColor = drawlib.create_color( [rc, gc, bc]); td.style.width = this.cellwidth + 'px'; td.style.height = this.cellheight + 'px'; td.setAttribute('r', rc); td.setAttribute('g', gc); td.setAttribute('b', bc); }; }; }; return otable; }; this.SimpleColorPicker.prototype.handleClick = function(event) { var target = event.target || event.srcElement; if (target.nodeName.toLowerCase() != 'td') { return; }; this.canvas.changeColor([parseInt(target.getAttribute('r')), parseInt(target.getAttribute('g')), parseInt(target.getAttribute('b'))]); }; }();