summaryrefslogtreecommitdiff
path: root/js/dojo-1.6/dojox/sketch/Figure.xd.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo-1.6/dojox/sketch/Figure.xd.js')
-rw-r--r--js/dojo-1.6/dojox/sketch/Figure.xd.js543
1 files changed, 543 insertions, 0 deletions
diff --git a/js/dojo-1.6/dojox/sketch/Figure.xd.js b/js/dojo-1.6/dojox/sketch/Figure.xd.js
new file mode 100644
index 0000000..10046e6
--- /dev/null
+++ b/js/dojo-1.6/dojox/sketch/Figure.xd.js
@@ -0,0 +1,543 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+dojo._xdResourceLoaded(function(dojo, dijit, dojox){
+return {depends: [["provide", "dojox.sketch.Figure"],
+["require", "dojox.gfx"],
+["require", "dojox.sketch.UndoStack"]],
+defineResource: function(dojo, dijit, dojox){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(mixin){
+ var self=this;
+ this.annCounter=1;
+
+ this.shapes=[];
+ this.image=null;
+ this.imageSrc=null;
+ this.size={ w:0, h:0 };
+ this.surface=null;
+ this.group=null;
+ //node should have tabindex set, otherwise keyboard action does not work
+ this.node=null;
+
+ this.zoomFactor=1; // multiplier for zooming.
+
+ this.tools=null; // toolbar reference.
+
+ this.obj={}; // lookup table for shapes. Not keen on this solution.
+
+ dojo.mixin(this,mixin);
+
+ // what is selected.
+ this.selected=[];
+ this.hasSelections=function(){ return this.selected.length>0 };
+ this.isSelected=function(obj){
+ for(var i=0; i<self.selected.length; i++){
+ if(self.selected[i]==obj){ return true; }
+ }
+ return false;
+ };
+ this.select=function(obj){
+ // TODO: deal with multiple vs. single selections.
+ if(!self.isSelected(obj)){
+ // force single select
+ self.clearSelections();
+ self.selected=[ obj ];
+ }
+ // force a bbox update, regardless
+ obj.setMode(ta.Annotation.Modes.View);
+ obj.setMode(ta.Annotation.Modes.Edit);
+ };
+ this.deselect=function(obj){
+ var idx=-1;
+ for(var i=0; i<self.selected.length; i++){
+ if(self.selected[i]==obj){
+ idx=i;
+ break;
+ }
+ }
+ if(idx>-1){
+ obj.setMode(ta.Annotation.Modes.View);
+ self.selected.splice(idx,1);
+ }
+ return obj;
+ };
+ this.clearSelections=function(){
+ for(var i=0; i<self.selected.length; i++){
+ self.selected[i].setMode(ta.Annotation.Modes.View);
+ }
+ self.selected=[];
+ };
+ this.replaceSelection=function(n, o){
+ if(!self.isSelected(o)){
+ self.select(n);
+ return;
+ }
+ var idx=-1;
+ for(var i=0; i<self.selected.length; i++){
+ if(self.selected[i]==o){
+ idx=i;
+ break;
+ }
+ }
+ if(idx>-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._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 || e.keyCode===122){ //ctrl+z
+ self.undo();
+ prevent = true;
+ }
+ else if(e.keyCode===89 || e.keyCode===121){ //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){
+ //in IE, when clicking into the drawing canvas, the node does not get focused,
+ //do it manually here to force it, otherwise the keydown event listener is
+ //never triggered in IE.
+ if(dojox.gfx.renderer=='vml'){
+ self.node.focus();
+ }
+ var o=self._fromEvt(e);
+ self._startPoint={ x:e.pageX, y:e.pageY };
+
+ self._ctr=dojo.position(self.node);
+ // figure out the coordinates taking scroll into account
+ var scroll={x:self.node.scrollLeft,y:self.node.scrollTop};
+ //var win = dojo.window.get(self.node.ownerDocument);
+ //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"){
+ if(!self.isSelected(o)){
+ self.select(o);
+ self._sameShapeSelected=false;
+ }else{
+ self._sameShapeSelected=true;
+ }
+ }
+ 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:dx, dy:dy});
+ self._c.setBinding({dx:dx/self.zoomFactor, dy: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)
+ }
+ if(rect.width && rect.height){
+ 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.initUndoStack();
+ };
+
+ var p=ta.Figure.prototype;
+ p.initUndoStack=function(){
+ this.history=new ta.UndoStack(this);
+ };
+ p.setTool=function(/*dojox.sketch._Plugin*/t){
+ this._ctool=t;
+ };
+ //gridSize: int
+ // if it is greater than 0, all new shapes placed on the drawing will have coordinates
+ // snapped to the gridSize. For example, if gridSize is set to 10, all coordinates
+ // (only including coordinates which specifies the x/y position of shape are affected
+ // by this parameter) will be dividable by 10
+ p.gridSize=0;
+ p._calCol=function(v){
+ return this.gridSize?(Math.round(v/this.gridSize)*this.gridSize):v;
+ };
+ p._delete=function(arr,noundo){
+ for(var i=0; i<arr.length; i++){
+ //var before=arr[i].serialize();
+ arr[i].setMode(ta.Annotation.Modes.View);
+ arr[i].destroy(noundo);
+ this.remove(arr[i]);
+ this._remove(arr[i]);
+ if(!noundo){
+ arr[i].onRemove();
+ }
+ }
+ arr.splice(0,arr.length);
+ };
+ p.onDblClickShape=function(shape,e){
+ if(shape['onDblClick']){
+ shape.onDblClick(e);
+ }
+ };
+
+ p.onCreateShape=function(shape){};
+ p.onBeforeCreateShape=function(shape){};
+ p.initialize=function(node){
+ this.node=node;
+ this.surface=dojox.gfx.createSurface(node, this.size.w, this.size.h);
+ //this.backgroundRect=this.surface.createRect({ x:0, y:0, width:this.size.w, height:this.size.h })
+ // .setFill("white");
+ this.group=this.surface.createGroup();
+
+ this._cons=[];
+ var es=this.surface.getEventSource();
+ this._cons.push(
+ // kill any dragging events.
+ // for FF
+ dojo.connect(es, "ondraggesture", dojo.stopEvent),
+ dojo.connect(es, "ondragenter", dojo.stopEvent),
+ dojo.connect(es, "ondragover", dojo.stopEvent),
+ dojo.connect(es, "ondragexit", dojo.stopEvent),
+ dojo.connect(es, "ondragstart", dojo.stopEvent),
+ // for IE
+ dojo.connect(es, "onselectstart", dojo.stopEvent),
+ // hook up the drag system.
+ dojo.connect(es, 'onmousedown', this._md),
+ dojo.connect(es, 'onmousemove', this._mm),
+ dojo.connect(es, 'onmouseup', this._mu),
+ // misc hooks
+ dojo.connect(es, 'onclick', this, 'onClick'),
+ dojo.connect(es, 'ondblclick', this._dblclick),
+ dojo.connect(node, 'onkeydown', this._keydown));
+
+ this.image=this.group.createImage({ width:this.imageSize.w, height:this.imageSize.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=[];
+
+ //TODO: how to destroy a surface properly?
+ dojo.empty(this.node);
+
+ //this.node.removeChild(this.surface.getEventSource());
+ this.group=this.surface=null;
+ this.obj={};
+ this.shapes=[];
+ };
+ p.nextKey=function(){ return "annotation-"+this.annCounter++; };
+ 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));
+
+ for(var i=0; i<this.shapes.length; i++){
+ this.shapes[i].zoom(this.zoomFactor);
+ }
+ };
+ 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.offsetWidth-5)/this.size.w;
+ var hF=(this.node.parentNode.offsetHeight-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","");
+ }else if(key&&key.indexOf("-labelShape")>-1){
+ key=key.replace("-labelShape","");
+ }
+ return this.obj[key];
+ };
+ p._keyFromEvt=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 key;
+ };
+ p._fromEvt=function(e){
+ return this._get(this._keyFromEvt(e));
+ };
+
+ p.add=function(annotation){
+ for(var i=0; i<this.shapes.length; i++){
+ if(this.shapes[i]==annotation){ return true; }
+ }
+ this.shapes.push(annotation);
+ return true;
+ };
+ p.remove=function(annotation){
+ var idx=-1;
+ for(var i=0; i<this.shapes.length; i++){
+ if(this.shapes[i]==annotation){
+ idx=i;
+ break;
+ }
+ }
+ if(idx>-1){ this.shapes.splice(idx, 1); }
+ return annotation;
+ };
+ p.getAnnotator=function(id){
+ for(var i=0; i<this.shapes.length; i++){
+ if(this.shapes[i].id==id) {
+ return this.shapes[i];
+ }
+ }
+ return null;
+ };
+
+ p.convert=function(ann, t){
+ // convert an existing annotation to a different kind of annotation
+ var ctor=t+"Annotation";
+ if(!ta[ctor]){ return; }
+ var type=ann.type(), id=ann.id, label=ann.label, mode=ann.mode, tokenId=ann.tokenId;
+ var start, end, control, transform;
+ switch(type){
+ case "Preexisting":
+ case "Lead":{
+ transform={dx:ann.transform.dx, dy:ann.transform.dy };
+ start={x:ann.start.x, y:ann.start.y};
+ end={x:ann.end.x, y:ann.end.y };
+ var cx=end.x-((end.x-start.x)/2);
+ var cy=end.y-((end.y-start.y)/2);
+ control={x:cx, y:cy};
+ break;
+ }
+ case "SingleArrow":
+ case "DoubleArrow":{
+ transform={dx:ann.transform.dx, dy:ann.transform.dy };
+ start={x:ann.start.x, y:ann.start.y};
+ end={x:ann.end.x, y:ann.end.y };
+ control={x:ann.control.x, y:ann.control.y};
+ break;
+ }
+ case "Underline":{
+ transform={dx:ann.transform.dx, dy:ann.transform.dy };
+ start={x:ann.start.x, y:ann.start.y};
+ control={x:start.x+50, y:start.y+50 };
+ end={x:start.x+100, y:start.y+100 };
+ break;
+ }
+ case "Brace":{ }
+ }
+ var n=new ta[ctor](this, id);
+
+ if(n.type()=="Underline"){
+ // special handling, since we never move the start point.
+ n.transform={dx:transform.dx+start.x, dy:transform.dy+start.y };
+ } else {
+ if(n.transform){ n.transform=transform; }
+ if(n.start){ n.start=start; }
+ }
+ if(n.end){ n.end=end; }
+ if(n.control){ n.control=control; }
+ n.label=label;
+ n.token=dojo.lang.shallowCopy(ann.token);
+ n.initialize();
+
+ this.replaceSelection(n, ann);
+ this._remove(ann);
+ this.remove(ann);
+ ann.destroy();
+
+ // this should do all the things we need it to do for getting it registered.
+ n.setMode(mode);
+ };
+ p.setValue=function(text){
+ var obj=dojox.xml.DomParser.parse(text);
+ var node=this.node;
+ this.load(obj,node);
+ //this.zoom(this.zoomFactor*100); //zoom to orignal scale
+ };
+ p.load=function(obj, n){
+ // create from pseudo-DOM
+ if(this.surface){ this.destroy(true); }
+ var node=obj.documentElement; // should be either the document or the docElement
+ this.size={
+ w:parseFloat(node.getAttribute('width'),10),
+ h:parseFloat(node.getAttribute('height'),10)
+ };
+ var g=node.childrenByName("g")[0];
+ var img=g.childrenByName("image")[0];
+ this.imageSize={
+ w:parseFloat(img.getAttribute('width'),10),
+ h:parseFloat(img.getAttribute('height'),10)
+ };
+ this.imageSrc=img.getAttribute("xlink:href");
+ this.initialize(n);
+
+ // now let's do the annotations.
+ var ann=g.childrenByName("g");
+ for(var i=0; i<ann.length; i++){ this._loadAnnotation(ann[i]); }
+ if(this._loadDeferred){
+ this._loadDeferred.callback(this);
+ this._loadDeferred=null;
+ }
+ this.onLoad();
+ };
+ p.onLoad=function(){};
+ p.onClick=function(){};
+ p._loadAnnotation=function(obj){
+ var ctor=obj.getAttribute('dojoxsketch:type')+"Annotation";
+ if(ta[ctor]){
+ var a=new ta[ctor](this, obj.id);
+ a.initialize(obj);
+ this.nextKey();
+ a.setMode(ta.Annotation.Modes.View);
+ this._add(a);
+ return a;
+ }
+ return null;
+ };
+
+ p.onUndo=function(){};
+ p.onBeforeUndo=function(){};
+ p.onRedo=function(){};
+ p.onBeforeRedo=function(){};
+ p.undo=function(){
+ if(this.history){
+ this.onBeforeUndo();
+ this.history.undo();
+ this.onUndo();
+ }
+ };
+ p.redo=function(){
+ if(this.history){
+ this.onBeforeRedo();
+ this.history.redo();
+ this.onRedo();
+ }
+ };
+ p.serialize=function(){
+ var s='<svg xmlns="http://www.w3.org/2000/svg" '
+ + 'xmlns:xlink="http://www.w3.org/1999/xlink" '
+ + 'xmlns:dojoxsketch="http://dojotoolkit.org/dojox/sketch" '
+ + 'width="' + this.size.w + '" height="' + this.size.h + '">'
+ + '<g>'
+ + '<image xlink:href="' + this.imageSrc + '" x="0" y="0" width="'
+ + this.size.w + '" height="' + this.size.h + '" />';
+ for(var i=0; i<this.shapes.length; i++){ s+= this.shapes[i].serialize(); }
+ s += '</g></svg>';
+ return s;
+ };
+ p.getValue=p.serialize;
+})();
+
+}
+
+}};});