dojox/sketch/Figure.js

  • Provides:

    • dojox.sketch.Figure
  • Requires:

    • dojox.gfx in common
    • dojox.sketch.UndoStack in common
  • dojox.sketch.tools

    • type
      Object
    • summary
  • e.target.parentNode.gridSize

    • summary
  • e.target.parentNode.getValue

    • summary
  • dojox.sketch.registerTool

    • type
      Function
    • parameters:
      • type: (typeof )
      • fn: (typeof )
    • source: [view]
       ta.registerTool=function(type, fn){ ta.tools[type]=fn;
    • summary
  • dojox.sketch.Figure

    • type
      Function
    • parameters:
      • mixin: (typeof )
    • source: [view]
        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    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    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[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    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();
    • summary
  • dojox.sketch.Figure.annCounter

    • summary
  • dojox.sketch.Figure.shapes

    • summary
  • dojox.sketch.Figure.image

    • summary
  • dojox.sketch.Figure.imageSrc

    • summary
  • dojox.sketch.Figure.size

    • summary
  • dojox.sketch.Figure.surface

    • summary
  • dojox.sketch.Figure.group

    • summary
  • dojox.sketch.Figure.node

    • summary
  • dojox.sketch.Figure.zoomFactor

    • summary
  • dojox.sketch.Figure.tools

    • summary
  • dojox.sketch.Figure.obj

    • summary
  • dojox.sketch.Figure.selected

    • summary
  • dojox.sketch.Figure._c

    • summary
  • dojox.sketch.Figure._ctr

    • summary
  • dojox.sketch.Figure._lp

    • summary
  • dojox.sketch.Figure._action

    • summary
  • dojox.sketch.Figure._prevState

    • summary
  • dojox.sketch.Figure._startPoint

    • summary
  • dojox.sketch.Figure._ctool

    • summary
  • dojox.sketch.Figure._start

    • summary
  • dojox.sketch.Figure._end

    • summary
  • dojox.sketch.Figure._absEnd

    • summary
  • dojox.sketch.Figure._cshape

    • summary
  • dojox.sketch.Figure.hasSelections

    • type
      Function
    • source: [view]
        this.hasSelections=function(){ return this.selected.length>0
    • summary
  • dojox.sketch.Figure.isSelected

    • type
      Function
    • parameters:
      • obj: (typeof )
    • source: [view]
         for(var i=0; i    if(self.selected[i]==obj){ return true; }
         }
         return false;
    • summary
  • dojox.sketch.Figure.select

    • type
      Function
    • parameters:
      • obj: (typeof )
    • source: [view]
      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    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);
    • summary
  • dojox.sketch.Figure.deselect

    • type
      Function
    • parameters:
      • obj: (typeof )
    • source: [view]
         var idx=-1;
         for(var i=0; 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;
    • summary
  • dojox.sketch.Figure.clearSelections

    • type
      Function
    • source: [view]
         for(var i=0; i    self.selected[i].setMode(ta.Annotation.Modes.View);
         }
         self.selected=[];
    • summary
  • dojox.sketch.Figure.replaceSelection

    • type
      Function
    • parameters:
      • n: (typeof )
      • o: (typeof )
    • source: [view]
         if(!self.isSelected(o)){
          self.select(n);
          return;
         }
         var idx=-1;
         for(var i=0; i    if(self.selected[i]==o){
           idx=i;
           break;
          }
         }
         if(idx>-1){
          self.selected.splice(idx,1,n);
         }
    • summary
  • dojox.sketch.Figure._dblclick

    • type
      Function
    • parameters:
      • e: (typeof )
    • source: [view]
         var o=self._fromEvt(e);
         if(o){
          self.onDblClickShape(o,e);
         }
    • summary
  • dojox.sketch.Figure._keydown

    • type
      Function
    • parameters:
      • e: (typeof )
    • source: [view]
         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);
         }
    • summary
  • dojox.sketch.Figure._md

    • type
      Function
    • parameters:
      • e: (typeof )
    • source: [view]
      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    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    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[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    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;
         }
    • summary
  • dojox.sketch.Figure._mm

    • type
      Function
    • parameters:
      • e: (typeof )
    • source: [view]
         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);
          }
         }
    • summary
  • dojox.sketch.Figure._mu

    • type
      Function
    • parameters:
      • e: (typeof )
    • source: [view]
         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;
    • summary
  • e.target.parentNode.initUndoStack

    • type
      Function
    • source: [view]
        this.history=new ta.UndoStack(this);
    • summary
  • e.target.parentNode.initUndoStack.history

    • summary
  • e.target.parentNode.setTool

    • type
      Function
    • parameters:
      • t: (typeof dojox.sketch._Plugin)
    • source: [view]
        this._ctool=t;
    • summary
  • e.target.parentNode.setTool._ctool

    • summary
  • e.target.parentNode._calCol

    • type
      Function
    • parameters:
      • v: (typeof )
    • source: [view]
      return this.gridSize?(Math.round(v/this.gridSize)*this.gridSize):v;
    • summary
  • e.target.parentNode._delete

    • type
      Function
    • parameters:
      • arr: (typeof )
      • noundo: (typeof )
    • source: [view]
        for(var i=0; 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);
    • summary
  • e.target.parentNode.onDblClickShape

    • type
      Function
    • parameters:
      • shape: (typeof )
      • e: (typeof )
    • source: [view]
        if(shape['onDblClick']){
         shape.onDblClick(e);
        }
    • summary
  • e.target.parentNode.onCreateShape

    • type
      Function
    • parameters:
      • shape: (typeof )
    • source: [view]
      }
    • summary
  • e.target.parentNode.onBeforeCreateShape

    • type
      Function
    • parameters:
      • shape: (typeof )
    • source: [view]
      }
    • summary
  • e.target.parentNode.initialize

    • type
      Function
    • parameters:
      • node: (typeof )
    • source: [view]
        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 });
    • summary
  • e.target.parentNode.initialize.node

    • summary
  • e.target.parentNode.initialize.surface

    • summary
  • e.target.parentNode.initialize.group

    • summary
  • e.target.parentNode.initialize._cons

    • summary
  • e.target.parentNode.initialize.image

    • summary
  • e.target.parentNode.destroy

    • type
      Function
    • parameters:
      • isLoading: (typeof )
    • source: [view]
        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=[];
    • summary
  • e.target.parentNode.destroy._cons

    • summary
  • e.target.parentNode.destroy.group

    • summary
  • e.target.parentNode.destroy.obj

    • summary
  • e.target.parentNode.destroy.shapes

    • summary
  • e.target.parentNode.nextKey

    • type
      Function
    • source: [view]
       p.nextKey=function(){ return "annotation-"+this.annCounter++;
    • summary
  • e.target.parentNode.draw

    • type
      Function
    • source: [view]
      }
    • summary
  • e.target.parentNode.zoom

    • type
      Function
    • parameters:
      • pct: (typeof )
    • source: [view]
      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    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    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[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    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   //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[i].zoom(this.zoomFactor);
        }
    • summary
  • e.target.parentNode.zoom.zoomFactor

    • summary
  • e.target.parentNode.getFit

    • type
      Function
    • source: [view]
      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    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    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[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    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   //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[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;
    • summary
  • e.target.parentNode.unzoom

    • type
      Function
    • source: [view]
      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    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    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[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    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   //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[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();
    • summary
  • e.target.parentNode.unzoom.zoomFactor

    • summary
  • e.target.parentNode._add

    • type
      Function
    • parameters:
      • obj: (typeof )
    • source: [view]
       p._add=function(obj){ this.obj[obj._key]=obj;
    • summary
  • e.target.parentNode._remove

    • type
      Function
    • parameters:
      • obj: (typeof )
    • source: [view]
        if(this.obj[obj._key]){
         delete this.obj[obj._key];
        }
    • summary
  • e.target.parentNode._get

    • type
      Function
    • parameters:
      • key: (typeof )
    • source: [view]
        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];
    • summary
  • e.target.parentNode._keyFromEvt

    • type
      Function
    • parameters:
      • e: (typeof )
    • source: [view]
        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;
    • summary
  • e.target.parentNode._fromEvt

    • type
      Function
    • parameters:
      • e: (typeof )
    • source: [view]
        return this._get(this._keyFromEvt(e));
    • summary
  • e.target.parentNode.add

    • type
      Function
    • parameters:
      • annotation: (typeof )
    • source: [view]
        for(var i=0; i   if(this.shapes[i]==annotation){ return true; }
        }
        this.shapes.push(annotation);
        return true;
    • summary
  • e.target.parentNode.remove

    • type
      Function
    • parameters:
      • annotation: (typeof )
    • source: [view]
        var idx=-1;
        for(var i=0; i   if(this.shapes[i]==annotation){
          idx=i;
          break;
         }
        }
        if(idx>-1){ this.shapes.splice(idx, 1); }
        return annotation;
    • summary
  • e.target.parentNode.getAnnotator

    • type
      Function
    • parameters:
      • id: (typeof )
    • source: [view]
        for(var i=0; i   if(this.shapes[i].id==id) {
          return this.shapes[i];
         }
        }
        return null;
    • summary
  • e.target.parentNode.convert

    • type
      Function
    • parameters:
      • ann: (typeof )
      • t: (typeof )
    • source: [view]
      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    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    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[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    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   //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[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   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   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   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);
    • summary
  • e.target.parentNode.setValue

    • type
      Function
    • parameters:
      • text: (typeof )
    • source: [view]
        var obj=dojox.xml.DomParser.parse(text);
        var node=this.node;
        this.load(obj,node);
        //this.zoom(this.zoomFactor*100); //zoom to orignal scale
    • summary
  • e.target.parentNode.load

    • type
      Function
    • parameters:
      • obj: (typeof )
      • n: (typeof )
    • source: [view]
      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    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    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[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    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   //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[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   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   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   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  if(this._loadDeferred){
         this._loadDeferred.callback(this);
         this._loadDeferred=null;
        }
        this.onLoad();
    • summary
  • e.target.parentNode.load.size

    • summary
  • e.target.parentNode.load.imageSize

    • summary
  • e.target.parentNode.load.imageSrc

    • summary
  • e.target.parentNode.load._loadDeferred

    • summary
  • e.target.parentNode.onLoad

    • type
      Function
    • source: [view]
      }
    • summary
  • e.target.parentNode.onClick

    • type
      Function
    • source: [view]
      }
    • summary
  • e.target.parentNode._loadAnnotation

    • type
      Function
    • parameters:
      • obj: (typeof )
    • source: [view]
        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;
    • summary
  • e.target.parentNode.onUndo

    • type
      Function
    • source: [view]
      }
    • summary
  • e.target.parentNode.onBeforeUndo

    • type
      Function
    • source: [view]
      }
    • summary
  • e.target.parentNode.onRedo

    • type
      Function
    • source: [view]
      }
    • summary
  • e.target.parentNode.onBeforeRedo

    • type
      Function
    • source: [view]
      }
    • summary
  • e.target.parentNode.undo

    • type
      Function
    • source: [view]
        if(this.history){
         this.onBeforeUndo();
         this.history.undo();
         this.onUndo();
        }
    • summary
  • e.target.parentNode.redo

    • type
      Function
    • source: [view]
        if(this.history){
         this.onBeforeRedo();
         this.history.redo();
         this.onRedo();
        }
    • summary
  • e.target.parentNode.serialize

    • type
      Function
    • source: [view]
        var s='   + 'xmlns:xlink="http://www.w3.org/1999/xlink" '
         + 'xmlns:dojoxsketch="http://dojotoolkit.org/dojox/sketch" '
         + 'width="' + this.size.w + '" height="' + this.size.h + '">'
         + ''
         + '';
        for(var i=0; i  s += '
      ';
        return s;
    • summary
  • dojox.sketch

    • type
      Object
    • summary
  • dojox

    • type
      Object
    • summary