if(!dojo._hasResource["dojox.sketch.Figure"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. dojo._hasResource["dojox.sketch.Figure"] = true; dojo.provide("dojox.sketch.Figure"); dojo.experimental("dojox.sketch"); dojo.require("dojox.gfx"); dojo.require("dojox.sketch.UndoStack"); (function(){ var ta=dojox.sketch; ta.tools={}; ta.registerTool=function(type, fn){ ta.tools[type]=fn; }; ta.Figure = function(){ var self=this; var annCounter=1; this.shapes=[]; this.image=null; this.imageSrc=null; this.size={ w:0, h:0 }; this.surface=null; this.group=null; this.node=null; this.zoomFactor=1; // multiplier for zooming. this.tools=null; // toolbar reference. this.nextKey=function(){ return annCounter++; }; this.obj={}; // lookup table for shapes. Not keen on this solution. this.initUndoStack(); // what is selected. this.selected=[]; this.hasSelections=function(){ return this.selected.length>0 }; this.isSelected=function(obj){ for(var i=0; i-1){ obj.setMode(ta.Annotation.Modes.View); self.selected.splice(idx,1); } return obj; }; this.clearSelections=function(){ for(var i=0; i-1){ self.selected.splice(idx,1,n); } }; // for the drag and drop handlers. this._c=null; // current shape this._ctr=null; // container measurements this._lp=null; // last position this._action=null; this._prevState=null; this._startPoint=null; // test to record a move. // if an object isn't selected and we're dragging anyways. this._ctool=null; // hard code it. this._start=null; this._end=null; this._absEnd=null; this._cshape=null; this._click=function(e){ if(self._c){ dojo.stopEvent(e); return; } var o=self._fromEvt(e); if(!o){ self.clearSelections(); dojo.stopEvent(e); } else if(!o.setMode){ // skip me. } else self.select(o); }; this._dblclick=function(e){ var o=self._fromEvt(e); if(o){ self.onDblClickShape(o,e); } }; this._keydown=function(e){ var prevent=false; if(e.ctrlKey){ if(e.keyCode==90){ //ctrl+z self.undo(); prevent = true; }else if(e.keyCode==89){ //ctrl+y self.redo(); prevent = true; } } if(e.keyCode==46 || e.keyCode==8){ //delete or backspace self._delete(self.selected); prevent = true; } if(prevent){ dojo.stopEvent(e); } }; // drag handlers. this._md=function(e){ var o=self._fromEvt(e); self._startPoint={ x:e.pageX, y:e.pageY }; var win = dijit.getDocumentWindow(self.node.ownerDocument); // figure out the coordinates within the iframe self._ctr=dojo._abs(self.node); var scroll=dojo.withGlobal(win,dojo._docScroll); self._ctr={x:self._ctr.x-scroll.x, y:self._ctr.y-scroll.y}; var X=e.clientX-self._ctr.x, Y=e.clientY-self._ctr.y; self._lp={ x:X, y:Y }; // capture it separately self._start={ x:X, y:Y }; self._end={ x:X, y:Y }; self._absEnd={ x:X, y:Y }; if(!o){ self.clearSelections(); self._ctool.onMouseDown(e); }else{ if(o.type && o.type()!="Anchor"){ self.select(o); } o.beginEdit(); self._c=o; } }; this._mm=function(e){ if(!self._ctr) return; var x=e.clientX-self._ctr.x; var y=e.clientY-self._ctr.y; var dx=x-self._lp.x; var dy=y-self._lp.y; self._absEnd={x:x, y:y}; if(self._c){ self._c.doChange({dx:Math.round(dx/self.zoomFactor), dy:Math.round(dy/self.zoomFactor)}); self._c.setBinding({dx:Math.round(dx/self.zoomFactor), dy:Math.round(dy/self.zoomFactor)}); self._lp={x:x, y:y}; } else { self._end={x:dx, y:dy}; var rect={ x:Math.min(self._start.x,self._absEnd.x), y:Math.min(self._start.y,self._absEnd.y), width:Math.abs(self._start.x-self._absEnd.x), height:Math.abs(self._start.y-self._absEnd.y) } self._ctool.onMouseMove(e,rect); } }; this._mu=function(e){ if(self._c){ // record the event. self._c.endEdit(); }else{ self._ctool.onMouseUp(e); } // clear the stuff out. self._c=self._ctr=self._lp=self._action=self._prevState=self._startPoint=null; self._cshape=self._start=self._end=self._absEnd=null; }; this._delete=function(arr,noundo){ for(var i=0; i this.group.createRect({ x:0, y:0, width:this.size.w, height:this.size.h }); this.image=this.group.createImage({ width:this.size.w, height:this.size.h, src:this.imageSrc }); }; p.destroy=function(isLoading){ if(!this.node){ return; } if(!isLoading){ if(this.history) this.history.destroy(); if(this._subscribed){ dojo.unsubscribe(this._subscribed); delete this._subscribed; } } dojo.forEach(this._cons,dojo.disconnect); this._cons=[]; this.node.removeChild(this.surface.getEventSource()); this.group=this.surface=null; this.obj={}; this.shapes=[]; }; p.draw=function(){ }; p.zoom=function(pct){ // first get the new dimensions this.zoomFactor=pct/100; var w=this.size.w*this.zoomFactor; var h=this.size.h*this.zoomFactor; this.surface.setDimensions(w, h); // then scale it. this.group.setTransform(dojox.gfx.matrix.scale(this.zoomFactor, this.zoomFactor)); if(dojo.isIE){ this.image.rawNode.style.width=Math.max(w,this.size.w); this.image.rawNode.style.height=Math.max(h,this.size.h); } //this.rect.setShape({width:w,height:h}); }; p.getFit=function(){ // assume fitting the parent node. // var box=dojo.html.getContentBox(this.node.parentNode); //the following should work under IE and FF, not sure about others though var wF=(this.node.parentNode.clientWidth-5)/this.size.w; var hF=(this.node.parentNode.clientHeight-5)/this.size.h; return Math.min(wF, hF)*100; }; p.unzoom=function(){ // restore original size. this.zoomFactor=1; this.surface.setDimensions(this.size.w, this.size.h); this.group.setTransform(); }; // object registry for drag handling. p._add=function(obj){ this.obj[obj._key]=obj; }; p._remove=function(obj){ if(this.obj[obj._key]){ delete this.obj[obj._key]; } }; p._get=function(key){ if(key&&key.indexOf("bounding")>-1) key=key.replace("-boundingBox",""); return this.obj[key]; }; p._fromEvt=function(e){ var key=e.target.id+""; if(key.length==0){ // ancestor tree until you get to the end (meaning this.surface) var p=e.target.parentNode; var node=this.surface.getEventSource(); while(p && p.id.length==0 && p!=node){ p=p.parentNode; } key=p.id; } return this._get(key); }; p.add=function(annotation){ for(var i=0; i-1) this.shapes.splice(idx, 1); return annotation; }; p.get=function(id){ for(var i=0; i' + '' + ''; for(var i=0; i