summaryrefslogtreecommitdiff
path: root/js/dojo-1.6/dojox/drawing/manager
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo-1.6/dojox/drawing/manager')
-rw-r--r--js/dojo-1.6/dojox/drawing/manager/Anchors.js475
-rw-r--r--js/dojo-1.6/dojox/drawing/manager/Anchors.xd.js479
-rw-r--r--js/dojo-1.6/dojox/drawing/manager/Canvas.js172
-rw-r--r--js/dojo-1.6/dojox/drawing/manager/Canvas.xd.js176
-rw-r--r--js/dojo-1.6/dojox/drawing/manager/Mouse.js529
-rw-r--r--js/dojo-1.6/dojox/drawing/manager/Mouse.xd.js533
-rw-r--r--js/dojo-1.6/dojox/drawing/manager/Stencil.js651
-rw-r--r--js/dojo-1.6/dojox/drawing/manager/Stencil.xd.js655
-rw-r--r--js/dojo-1.6/dojox/drawing/manager/StencilUI.js76
-rw-r--r--js/dojo-1.6/dojox/drawing/manager/StencilUI.xd.js80
-rw-r--r--js/dojo-1.6/dojox/drawing/manager/Undo.js68
-rw-r--r--js/dojo-1.6/dojox/drawing/manager/Undo.xd.js72
-rw-r--r--js/dojo-1.6/dojox/drawing/manager/_registry.js42
-rw-r--r--js/dojo-1.6/dojox/drawing/manager/_registry.xd.js46
-rw-r--r--js/dojo-1.6/dojox/drawing/manager/keys.js275
-rw-r--r--js/dojo-1.6/dojox/drawing/manager/keys.xd.js279
16 files changed, 4608 insertions, 0 deletions
diff --git a/js/dojo-1.6/dojox/drawing/manager/Anchors.js b/js/dojo-1.6/dojox/drawing/manager/Anchors.js
new file mode 100644
index 0000000..a5677ed
--- /dev/null
+++ b/js/dojo-1.6/dojox/drawing/manager/Anchors.js
@@ -0,0 +1,475 @@
+/*
+ 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
+*/
+
+
+if(!dojo._hasResource["dojox.drawing.manager.Anchors"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.drawing.manager.Anchors"] = true;
+dojo.provide("dojox.drawing.manager.Anchors");
+
+dojox.drawing.manager.Anchors = dojox.drawing.util.oo.declare(
+ // summary:
+ // Creates and manages the anchor points that are attached to
+ // (usually) the corners of a Stencil.
+ // description:
+ // Used internally, but there are some things that should be known:
+ // Anchors attach to a Stencil's 'points' (See stencil.points)
+ // To not display an anchor on a certain point, add noAnchor:true
+ // to the point.
+
+ function(/* dojox.__stencilArgs */options){
+ // arguments: See stencil._Base
+ this.mouse = options.mouse;
+ this.undo = options.undo;
+ this.util = options.util;
+ this.drawing = options.drawing;
+ this.items = {};
+ },
+ {
+ onAddAnchor: function(/*Anchor*/anchor){
+ // summary:
+ // Event fires when anchor is created
+ },
+
+
+ onReset: function(/*Stencil*/stencil){
+ // summary:
+ // Event fires when an anchor's reset method is called
+ //
+ // a desperate hack in order to get the anchor point to reset.
+ // FIXME: Is this still used? I think its item.deselect();item.select();
+ var st = this.util.byId("drawing").stencils;
+ st.onDeselect(stencil);
+ st.onSelect(stencil);
+ },
+
+ onRenderStencil: function(){
+ // summary:
+ // Event fires when an anchor calls a Stencil's render method
+ //
+ for(var nm in this.items){
+ dojo.forEach(this.items[nm].anchors, function(a){
+ a.shape.moveToFront();
+ });
+ }
+ },
+
+ onTransformPoint: function(/*Anchor*/anchor){
+ // summary:
+ // Event fired on anchor drag
+ //
+ // If anchors are a "group", it's corresponding anchor
+ // is set. All anchors then moved to front.
+ var anchors = this.items[anchor.stencil.id].anchors;
+ var item = this.items[anchor.stencil.id].item;
+ var pts = [];
+ dojo.forEach(anchors, function(a, i){
+
+
+ if(anchor.id == a.id || anchor.stencil.anchorType!="group"){
+ // nothing
+ }else{
+ if(anchor.org.y == a.org.y){
+ a.setPoint({
+ dx: 0,
+ dy: anchor.shape.getTransform().dy - a.shape.getTransform().dy
+ });
+ }else if(anchor.org.x == a.org.x){
+ a.setPoint({
+ dx: anchor.shape.getTransform().dx - a.shape.getTransform().dx,
+ dy: 0
+ });
+ }
+ a.shape.moveToFront();
+ }
+
+ var mx = a.shape.getTransform();
+ pts.push({x:mx.dx + a.org.x, y:mx.dy+ a.org.y});
+
+ if(a.point.t){
+ pts[pts.length-1].t = a.point.t;
+ }
+
+ }, this);
+ item.setPoints(pts);
+ item.onTransform(anchor);
+ this.onRenderStencil();
+ },
+
+ onAnchorUp: function(/*Anchor*/anchor){
+ // summary:
+ // Event fired on anchor mouseup
+ },
+
+ onAnchorDown: function(/*Anchor*/anchor){
+ // summary:
+ // Event fired on anchor mousedown
+ },
+
+ onAnchorDrag: function(/*Anchor*/anchor){
+ // summary:
+ // Event fired when anchor is moved
+ },
+
+ onChangeStyle: function(/*Object*/stencil){
+ // summary:
+ // if the Stencil changes color while were's selected
+ // this moves the anchors to the back. Fix it.
+
+ for(var nm in this.items){
+ dojo.forEach(this.items[nm].anchors, function(a){
+ a.shape.moveToFront();
+ });
+ }
+ },
+
+ add: function(/*Stencil*/item){
+ // summary:
+ // Creates anchor points on a Stencil, based on the
+ // Stencil's points.
+ //
+ this.items[item.id] = {
+ item:item,
+ anchors:[]
+ };
+ if(item.anchorType=="none"){ return; }
+ var pts = item.points;
+ dojo.forEach(pts, function(p, i){
+ if(p.noAnchor){ return; }
+ if(i==0 || i == item.points.length-1){
+ console.log("ITEM TYPE:", item.type, item.shortType);
+ }
+ var a = new dojox.drawing.manager.Anchor({stencil:item, point:p, pointIdx:i, mouse:this.mouse, util:this.util});
+ this.items[item.id]._cons = [
+ dojo.connect(a, "onRenderStencil", this, "onRenderStencil"),
+ dojo.connect(a, "reset", this, "onReset"),
+ dojo.connect(a, "onAnchorUp", this, "onAnchorUp"),
+ dojo.connect(a, "onAnchorDown", this, "onAnchorDown"),
+ dojo.connect(a, "onAnchorDrag", this, "onAnchorDrag"),
+ dojo.connect(a, "onTransformPoint", this, "onTransformPoint"),
+ // FIXME: this will fire for each anchor. yech.
+ dojo.connect(item, "onChangeStyle", this, "onChangeStyle")
+ ];
+
+ this.items[item.id].anchors.push(a);
+ this.onAddAnchor(a);
+ }, this);
+
+ if(item.shortType=="path"){
+ // check if we have a double-point of a closed-curve-path
+ var f = pts[0], l = pts[pts.length-1], a = this.items[item.id].anchors;
+ if(f.x ==l.x && f.y==l.y){
+ console.warn("LINK ANVHROS", a[0], a[a.length-1]);
+ a[0].linkedAnchor = a[a.length-1];
+ a[a.length-1].linkedAnchor = a[0];
+ }
+ }
+
+ if(item.anchorType=="group"){
+ dojo.forEach(this.items[item.id].anchors, function(anchor){
+ dojo.forEach(this.items[item.id].anchors, function(a){
+ if(anchor.id != a.id){
+ if(anchor.org.y == a.org.y){
+ anchor.x_anchor = a;
+ }else if(anchor.org.x == a.org.x){
+ anchor.y_anchor = a;
+ }
+ }
+ },this);
+ },this);
+
+ }
+ },
+
+ remove: function(/*Stencil*/item){
+ // summary:
+ // Destroys the anchor points for a Stencil.
+ //
+ if(!this.items[item.id]){
+ return;
+ }
+ dojo.forEach(this.items[item.id].anchors, function(a){
+ a.destroy();
+ });
+ dojo.forEach(this.items[item.id]._cons, dojo.disconnect, dojo);
+ this.items[item.id].anchors = null;
+ delete this.items[item.id];
+ }
+ }
+);
+
+dojox.drawing.manager.Anchor = dojox.drawing.util.oo.declare(
+ // summary:
+ // An anchor point that is attached to (usually) one of the
+ // corners of a Stencil.
+ // Used internally.
+ function(/* Object */options){
+ // summary:
+ // constructor.
+ // arguments:
+ // dojox.__stencilArgs plus some additional
+ // data, like which point this is (pointIdx)
+ //
+ this.defaults = dojox.drawing.defaults.copy();
+ this.mouse = options.mouse;
+ this.point = options.point;
+ this.pointIdx = options.pointIdx;
+ this.util = options.util;
+ this.id = options.id || this.util.uid("anchor");
+ this.org = dojo.mixin({}, this.point);
+ this.stencil = options.stencil;
+ if(this.stencil.anchorPositionCheck){
+ this.anchorPositionCheck = dojo.hitch(this.stencil, this.stencil.anchorPositionCheck);
+ }
+ if(this.stencil.anchorConstrain){
+ this.anchorConstrain = dojo.hitch(this.stencil, this.stencil.anchorConstrain);
+ }
+ this._zCon = dojo.connect(this.mouse, "setZoom", this, "render");
+ this.render();
+ this.connectMouse();
+ },
+ {
+ y_anchor:null,
+ x_anchor:null,
+ render: function(){
+ // summary:
+ // Creates the anchor point. Unlike most render methods
+ // in Drawing, this is only called once.
+ //
+ this.shape && this.shape.removeShape();
+ var d = this.defaults.anchors,
+ z = this.mouse.zoom,
+ b = d.width * z,
+ s = d.size * z,
+ p = s/2,
+ line = {
+ width:b,
+ style:d.style,
+ color:d.color,
+ cap:d.cap
+ };
+
+
+ var _r = {
+ x: this.point.x-p,
+ y: this.point.y-p,
+ width: s,
+ height: s
+ };
+ this.shape = this.stencil.container.createRect(_r)
+ .setStroke(line)
+ .setFill(d.fill);
+
+ this.shape.setTransform({dx:0, dy:0});
+ this.util.attr(this, "drawingType", "anchor");
+ this.util.attr(this, "id", this.id);
+ },
+ onRenderStencil: function(/*Anchor*/anchor){
+ // summary:
+ // Event fires when an anchor calls a Stencil's render method
+ },
+ onTransformPoint: function(/*Anchor*/anchor){
+ // summary:
+ // Event fires when an anchor changes the points of a Stencil
+ },
+ onAnchorDown: function(/*Mouse.EventObject*/obj){
+ // summary:
+ // Event fires for mousedown on anchor
+ this.selected = obj.id == this.id;
+ },
+ onAnchorUp: function(/*Mouse.EventObject*/obj){
+ // summary:
+ // Event fires for mouseup on anchor
+ this.selected = false;
+ this.stencil.onTransformEnd(this);
+ },
+
+ onAnchorDrag: function(/*Mouse.EventObject*/obj){
+ // summary:
+ // Event fires for on dragging of an anchor
+ if(this.selected){
+ // mx is the original transform from when the anchor
+ // was created. It does not change
+ var mx = this.shape.getTransform();
+
+ var pmx = this.shape.getParent().getParent().getTransform();
+
+ var marginZero = this.defaults.anchors.marginZero;
+
+ var orgx = pmx.dx + this.org.x,
+ orgy = pmx.dy + this.org.y,
+ x = obj.x - orgx,
+ y = obj.y - orgy,
+ s = this.defaults.anchors.minSize;
+
+ var conL, conR, conT, conB;
+
+ var chk = this.anchorPositionCheck(x, y, this);
+ if(chk.x<0){
+ console.warn("X<0 Shift");
+ while(this.anchorPositionCheck(x, y, this).x<0){
+ this.shape.getParent().getParent().applyTransform({dx:2, dy:0});
+ }
+ }
+ if(chk.y<0){
+ console.warn("Y<0 Shift");
+ while(this.anchorPositionCheck(x, y, this).y<0){
+ this.shape.getParent().getParent().applyTransform({dx:0, dy:2});
+ }
+ }
+
+ if(this.y_anchor){
+ // prevent y overlap of opposite anchor
+ if(this.org.y > this.y_anchor.org.y){
+ // bottom anchor
+
+ conT = this.y_anchor.point.y + s - this.org.y;
+ conB = Infinity;
+
+ if(y < conT){
+ // overlapping other anchor
+ y = conT;
+ }
+
+
+ }else{
+ // top anchor
+
+ conT = -orgy + marginZero;
+ conB = this.y_anchor.point.y - s - this.org.y;
+
+ if(y < conT){
+ // less than zero
+ y = conT;
+ }else if(y > conB){
+ // overlapping other anchor
+ y = conB;
+ }
+ }
+ }else{
+ // Lines - check for zero
+ conT = -orgy + marginZero;
+ if(y < conT){
+ // less than zero
+ y = conT;
+ }
+ }
+
+
+
+
+ if(this.x_anchor){
+ // prevent x overlap of opposite anchor
+
+ if(this.org.x>this.x_anchor.org.x){
+ // right anchor
+
+ conL = this.x_anchor.point.x + s - this.org.x;
+ conR = Infinity;
+
+ if(x < conL){
+ // overlapping other anchor
+ x = conL;
+ }
+
+ }else{
+ // left anchor
+
+ conL = -orgx + marginZero;
+ conR = this.x_anchor.point.x - s - this.org.x;
+
+ if(x < conL){
+ x = conL;
+ }else if(x > conR){
+ // overlapping other anchor
+ x = conR;
+ }
+ }
+ }else{
+ // Lines check for zero
+ conL = -orgx + marginZero;
+ if(x < conL){
+ x = conL;
+ }
+ }
+ //Constrains anchor point, returns null if not overwritten by stencil
+ var constrained = this.anchorConstrain(x, y);
+ if(constrained != null){
+ x=constrained.x;
+ y=constrained.y;
+ }
+
+ this.shape.setTransform({
+ dx:x,
+ dy:y
+ });
+ if(this.linkedAnchor){
+ // first and last points of a closed-curve-path
+ this.linkedAnchor.shape.setTransform({
+ dx:x,
+ dy:y
+ });
+ }
+ this.onTransformPoint(this);
+ }
+ },
+
+ anchorConstrain: function(/* Number */x,/* Number */ y){
+ // summary:
+ // To be over written by tool!
+ // Add an anchorConstrain method to the tool
+ // and it will automatically overwrite this stub.
+ // Should return a constrained x & y value.
+ return null;
+ },
+
+ anchorPositionCheck: function(/* Number */x,/* Number */ y, /* Anchor */anchor){
+ // summary:
+ // To be over written by tool!
+ // Add a anchorPositionCheck method to the tool
+ // and it will automatically overwrite this stub.
+ // Should return x and y coords. Success is both
+ // being greater than zero, fail is if one or both
+ // are less than zero.
+ return {x:1, y:1};
+ },
+
+ setPoint: function(mx){
+ // summary:
+ // Internal. Sets the Stencil's point
+ this.shape.applyTransform(mx);
+ },
+
+ connectMouse: function(){
+ // summary:
+ // Internal. Connects anchor to manager.mouse
+ this._mouseHandle = this.mouse.register(this);
+ },
+
+ disconnectMouse: function(){
+ // summary:
+ // Internal. Disconnects anchor to manager.mouse
+ this.mouse.unregister(this._mouseHandle);
+ },
+
+ reset: function(stencil){
+ // summary:
+ // Called (usually) from a Stencil when that Stencil
+ // needed to make modifications to the position of the
+ // point. Basically used when teh anchor causes a
+ // less than zero condition.
+ },
+
+ destroy: function(){
+ // summary:
+ // Destroys anchor.
+ dojo.disconnect(this._zCon);
+ this.disconnectMouse();
+ this.shape.removeShape();
+ }
+ }
+);
+
+}
diff --git a/js/dojo-1.6/dojox/drawing/manager/Anchors.xd.js b/js/dojo-1.6/dojox/drawing/manager/Anchors.xd.js
new file mode 100644
index 0000000..0756184
--- /dev/null
+++ b/js/dojo-1.6/dojox/drawing/manager/Anchors.xd.js
@@ -0,0 +1,479 @@
+/*
+ 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.drawing.manager.Anchors"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.drawing.manager.Anchors"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.drawing.manager.Anchors"] = true;
+dojo.provide("dojox.drawing.manager.Anchors");
+
+dojox.drawing.manager.Anchors = dojox.drawing.util.oo.declare(
+ // summary:
+ // Creates and manages the anchor points that are attached to
+ // (usually) the corners of a Stencil.
+ // description:
+ // Used internally, but there are some things that should be known:
+ // Anchors attach to a Stencil's 'points' (See stencil.points)
+ // To not display an anchor on a certain point, add noAnchor:true
+ // to the point.
+
+ function(/* dojox.__stencilArgs */options){
+ // arguments: See stencil._Base
+ this.mouse = options.mouse;
+ this.undo = options.undo;
+ this.util = options.util;
+ this.drawing = options.drawing;
+ this.items = {};
+ },
+ {
+ onAddAnchor: function(/*Anchor*/anchor){
+ // summary:
+ // Event fires when anchor is created
+ },
+
+
+ onReset: function(/*Stencil*/stencil){
+ // summary:
+ // Event fires when an anchor's reset method is called
+ //
+ // a desperate hack in order to get the anchor point to reset.
+ // FIXME: Is this still used? I think its item.deselect();item.select();
+ var st = this.util.byId("drawing").stencils;
+ st.onDeselect(stencil);
+ st.onSelect(stencil);
+ },
+
+ onRenderStencil: function(){
+ // summary:
+ // Event fires when an anchor calls a Stencil's render method
+ //
+ for(var nm in this.items){
+ dojo.forEach(this.items[nm].anchors, function(a){
+ a.shape.moveToFront();
+ });
+ }
+ },
+
+ onTransformPoint: function(/*Anchor*/anchor){
+ // summary:
+ // Event fired on anchor drag
+ //
+ // If anchors are a "group", it's corresponding anchor
+ // is set. All anchors then moved to front.
+ var anchors = this.items[anchor.stencil.id].anchors;
+ var item = this.items[anchor.stencil.id].item;
+ var pts = [];
+ dojo.forEach(anchors, function(a, i){
+
+
+ if(anchor.id == a.id || anchor.stencil.anchorType!="group"){
+ // nothing
+ }else{
+ if(anchor.org.y == a.org.y){
+ a.setPoint({
+ dx: 0,
+ dy: anchor.shape.getTransform().dy - a.shape.getTransform().dy
+ });
+ }else if(anchor.org.x == a.org.x){
+ a.setPoint({
+ dx: anchor.shape.getTransform().dx - a.shape.getTransform().dx,
+ dy: 0
+ });
+ }
+ a.shape.moveToFront();
+ }
+
+ var mx = a.shape.getTransform();
+ pts.push({x:mx.dx + a.org.x, y:mx.dy+ a.org.y});
+
+ if(a.point.t){
+ pts[pts.length-1].t = a.point.t;
+ }
+
+ }, this);
+ item.setPoints(pts);
+ item.onTransform(anchor);
+ this.onRenderStencil();
+ },
+
+ onAnchorUp: function(/*Anchor*/anchor){
+ // summary:
+ // Event fired on anchor mouseup
+ },
+
+ onAnchorDown: function(/*Anchor*/anchor){
+ // summary:
+ // Event fired on anchor mousedown
+ },
+
+ onAnchorDrag: function(/*Anchor*/anchor){
+ // summary:
+ // Event fired when anchor is moved
+ },
+
+ onChangeStyle: function(/*Object*/stencil){
+ // summary:
+ // if the Stencil changes color while were's selected
+ // this moves the anchors to the back. Fix it.
+
+ for(var nm in this.items){
+ dojo.forEach(this.items[nm].anchors, function(a){
+ a.shape.moveToFront();
+ });
+ }
+ },
+
+ add: function(/*Stencil*/item){
+ // summary:
+ // Creates anchor points on a Stencil, based on the
+ // Stencil's points.
+ //
+ this.items[item.id] = {
+ item:item,
+ anchors:[]
+ };
+ if(item.anchorType=="none"){ return; }
+ var pts = item.points;
+ dojo.forEach(pts, function(p, i){
+ if(p.noAnchor){ return; }
+ if(i==0 || i == item.points.length-1){
+ console.log("ITEM TYPE:", item.type, item.shortType);
+ }
+ var a = new dojox.drawing.manager.Anchor({stencil:item, point:p, pointIdx:i, mouse:this.mouse, util:this.util});
+ this.items[item.id]._cons = [
+ dojo.connect(a, "onRenderStencil", this, "onRenderStencil"),
+ dojo.connect(a, "reset", this, "onReset"),
+ dojo.connect(a, "onAnchorUp", this, "onAnchorUp"),
+ dojo.connect(a, "onAnchorDown", this, "onAnchorDown"),
+ dojo.connect(a, "onAnchorDrag", this, "onAnchorDrag"),
+ dojo.connect(a, "onTransformPoint", this, "onTransformPoint"),
+ // FIXME: this will fire for each anchor. yech.
+ dojo.connect(item, "onChangeStyle", this, "onChangeStyle")
+ ];
+
+ this.items[item.id].anchors.push(a);
+ this.onAddAnchor(a);
+ }, this);
+
+ if(item.shortType=="path"){
+ // check if we have a double-point of a closed-curve-path
+ var f = pts[0], l = pts[pts.length-1], a = this.items[item.id].anchors;
+ if(f.x ==l.x && f.y==l.y){
+ console.warn("LINK ANVHROS", a[0], a[a.length-1]);
+ a[0].linkedAnchor = a[a.length-1];
+ a[a.length-1].linkedAnchor = a[0];
+ }
+ }
+
+ if(item.anchorType=="group"){
+ dojo.forEach(this.items[item.id].anchors, function(anchor){
+ dojo.forEach(this.items[item.id].anchors, function(a){
+ if(anchor.id != a.id){
+ if(anchor.org.y == a.org.y){
+ anchor.x_anchor = a;
+ }else if(anchor.org.x == a.org.x){
+ anchor.y_anchor = a;
+ }
+ }
+ },this);
+ },this);
+
+ }
+ },
+
+ remove: function(/*Stencil*/item){
+ // summary:
+ // Destroys the anchor points for a Stencil.
+ //
+ if(!this.items[item.id]){
+ return;
+ }
+ dojo.forEach(this.items[item.id].anchors, function(a){
+ a.destroy();
+ });
+ dojo.forEach(this.items[item.id]._cons, dojo.disconnect, dojo);
+ this.items[item.id].anchors = null;
+ delete this.items[item.id];
+ }
+ }
+);
+
+dojox.drawing.manager.Anchor = dojox.drawing.util.oo.declare(
+ // summary:
+ // An anchor point that is attached to (usually) one of the
+ // corners of a Stencil.
+ // Used internally.
+ function(/* Object */options){
+ // summary:
+ // constructor.
+ // arguments:
+ // dojox.__stencilArgs plus some additional
+ // data, like which point this is (pointIdx)
+ //
+ this.defaults = dojox.drawing.defaults.copy();
+ this.mouse = options.mouse;
+ this.point = options.point;
+ this.pointIdx = options.pointIdx;
+ this.util = options.util;
+ this.id = options.id || this.util.uid("anchor");
+ this.org = dojo.mixin({}, this.point);
+ this.stencil = options.stencil;
+ if(this.stencil.anchorPositionCheck){
+ this.anchorPositionCheck = dojo.hitch(this.stencil, this.stencil.anchorPositionCheck);
+ }
+ if(this.stencil.anchorConstrain){
+ this.anchorConstrain = dojo.hitch(this.stencil, this.stencil.anchorConstrain);
+ }
+ this._zCon = dojo.connect(this.mouse, "setZoom", this, "render");
+ this.render();
+ this.connectMouse();
+ },
+ {
+ y_anchor:null,
+ x_anchor:null,
+ render: function(){
+ // summary:
+ // Creates the anchor point. Unlike most render methods
+ // in Drawing, this is only called once.
+ //
+ this.shape && this.shape.removeShape();
+ var d = this.defaults.anchors,
+ z = this.mouse.zoom,
+ b = d.width * z,
+ s = d.size * z,
+ p = s/2,
+ line = {
+ width:b,
+ style:d.style,
+ color:d.color,
+ cap:d.cap
+ };
+
+
+ var _r = {
+ x: this.point.x-p,
+ y: this.point.y-p,
+ width: s,
+ height: s
+ };
+ this.shape = this.stencil.container.createRect(_r)
+ .setStroke(line)
+ .setFill(d.fill);
+
+ this.shape.setTransform({dx:0, dy:0});
+ this.util.attr(this, "drawingType", "anchor");
+ this.util.attr(this, "id", this.id);
+ },
+ onRenderStencil: function(/*Anchor*/anchor){
+ // summary:
+ // Event fires when an anchor calls a Stencil's render method
+ },
+ onTransformPoint: function(/*Anchor*/anchor){
+ // summary:
+ // Event fires when an anchor changes the points of a Stencil
+ },
+ onAnchorDown: function(/*Mouse.EventObject*/obj){
+ // summary:
+ // Event fires for mousedown on anchor
+ this.selected = obj.id == this.id;
+ },
+ onAnchorUp: function(/*Mouse.EventObject*/obj){
+ // summary:
+ // Event fires for mouseup on anchor
+ this.selected = false;
+ this.stencil.onTransformEnd(this);
+ },
+
+ onAnchorDrag: function(/*Mouse.EventObject*/obj){
+ // summary:
+ // Event fires for on dragging of an anchor
+ if(this.selected){
+ // mx is the original transform from when the anchor
+ // was created. It does not change
+ var mx = this.shape.getTransform();
+
+ var pmx = this.shape.getParent().getParent().getTransform();
+
+ var marginZero = this.defaults.anchors.marginZero;
+
+ var orgx = pmx.dx + this.org.x,
+ orgy = pmx.dy + this.org.y,
+ x = obj.x - orgx,
+ y = obj.y - orgy,
+ s = this.defaults.anchors.minSize;
+
+ var conL, conR, conT, conB;
+
+ var chk = this.anchorPositionCheck(x, y, this);
+ if(chk.x<0){
+ console.warn("X<0 Shift");
+ while(this.anchorPositionCheck(x, y, this).x<0){
+ this.shape.getParent().getParent().applyTransform({dx:2, dy:0});
+ }
+ }
+ if(chk.y<0){
+ console.warn("Y<0 Shift");
+ while(this.anchorPositionCheck(x, y, this).y<0){
+ this.shape.getParent().getParent().applyTransform({dx:0, dy:2});
+ }
+ }
+
+ if(this.y_anchor){
+ // prevent y overlap of opposite anchor
+ if(this.org.y > this.y_anchor.org.y){
+ // bottom anchor
+
+ conT = this.y_anchor.point.y + s - this.org.y;
+ conB = Infinity;
+
+ if(y < conT){
+ // overlapping other anchor
+ y = conT;
+ }
+
+
+ }else{
+ // top anchor
+
+ conT = -orgy + marginZero;
+ conB = this.y_anchor.point.y - s - this.org.y;
+
+ if(y < conT){
+ // less than zero
+ y = conT;
+ }else if(y > conB){
+ // overlapping other anchor
+ y = conB;
+ }
+ }
+ }else{
+ // Lines - check for zero
+ conT = -orgy + marginZero;
+ if(y < conT){
+ // less than zero
+ y = conT;
+ }
+ }
+
+
+
+
+ if(this.x_anchor){
+ // prevent x overlap of opposite anchor
+
+ if(this.org.x>this.x_anchor.org.x){
+ // right anchor
+
+ conL = this.x_anchor.point.x + s - this.org.x;
+ conR = Infinity;
+
+ if(x < conL){
+ // overlapping other anchor
+ x = conL;
+ }
+
+ }else{
+ // left anchor
+
+ conL = -orgx + marginZero;
+ conR = this.x_anchor.point.x - s - this.org.x;
+
+ if(x < conL){
+ x = conL;
+ }else if(x > conR){
+ // overlapping other anchor
+ x = conR;
+ }
+ }
+ }else{
+ // Lines check for zero
+ conL = -orgx + marginZero;
+ if(x < conL){
+ x = conL;
+ }
+ }
+ //Constrains anchor point, returns null if not overwritten by stencil
+ var constrained = this.anchorConstrain(x, y);
+ if(constrained != null){
+ x=constrained.x;
+ y=constrained.y;
+ }
+
+ this.shape.setTransform({
+ dx:x,
+ dy:y
+ });
+ if(this.linkedAnchor){
+ // first and last points of a closed-curve-path
+ this.linkedAnchor.shape.setTransform({
+ dx:x,
+ dy:y
+ });
+ }
+ this.onTransformPoint(this);
+ }
+ },
+
+ anchorConstrain: function(/* Number */x,/* Number */ y){
+ // summary:
+ // To be over written by tool!
+ // Add an anchorConstrain method to the tool
+ // and it will automatically overwrite this stub.
+ // Should return a constrained x & y value.
+ return null;
+ },
+
+ anchorPositionCheck: function(/* Number */x,/* Number */ y, /* Anchor */anchor){
+ // summary:
+ // To be over written by tool!
+ // Add a anchorPositionCheck method to the tool
+ // and it will automatically overwrite this stub.
+ // Should return x and y coords. Success is both
+ // being greater than zero, fail is if one or both
+ // are less than zero.
+ return {x:1, y:1};
+ },
+
+ setPoint: function(mx){
+ // summary:
+ // Internal. Sets the Stencil's point
+ this.shape.applyTransform(mx);
+ },
+
+ connectMouse: function(){
+ // summary:
+ // Internal. Connects anchor to manager.mouse
+ this._mouseHandle = this.mouse.register(this);
+ },
+
+ disconnectMouse: function(){
+ // summary:
+ // Internal. Disconnects anchor to manager.mouse
+ this.mouse.unregister(this._mouseHandle);
+ },
+
+ reset: function(stencil){
+ // summary:
+ // Called (usually) from a Stencil when that Stencil
+ // needed to make modifications to the position of the
+ // point. Basically used when teh anchor causes a
+ // less than zero condition.
+ },
+
+ destroy: function(){
+ // summary:
+ // Destroys anchor.
+ dojo.disconnect(this._zCon);
+ this.disconnectMouse();
+ this.shape.removeShape();
+ }
+ }
+);
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/drawing/manager/Canvas.js b/js/dojo-1.6/dojox/drawing/manager/Canvas.js
new file mode 100644
index 0000000..6c5e17a
--- /dev/null
+++ b/js/dojo-1.6/dojox/drawing/manager/Canvas.js
@@ -0,0 +1,172 @@
+/*
+ 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
+*/
+
+
+if(!dojo._hasResource["dojox.drawing.manager.Canvas"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.drawing.manager.Canvas"] = true;
+dojo.provide("dojox.drawing.manager.Canvas");
+
+(function(){
+
+ dojox.drawing.manager.Canvas = dojox.drawing.util.oo.declare(
+ // summary:
+ // Creates a dojox.gfx.surface to be used for Drawing. Note that
+ // The 'surface' that Drawing uses is actually a dojox.gfx.group.
+ // This allows for more versatility.
+ //
+ // Called internally from a dojox.Drawing.
+ //
+ // Note: Surface creation is asynchrous. Connect to
+ // onSurfaceReady in Drawing.
+ //
+ function(/*Object*/options){
+ dojo.mixin(this, options);
+
+ var dim = dojo.contentBox(this.srcRefNode);
+ this.height = this.parentHeight = dim.h;
+ this.width = this.parentWidth = dim.w;
+ this.domNode = dojo.create("div", {id:"canvasNode"}, this.srcRefNode);
+ dojo.style(this.domNode, {
+ width:this.width,
+ height:"auto"
+ });
+
+ dojo.setSelectable(this.domNode, false);
+
+ this.id = this.id || this.util.uid("surface");
+
+ console.info("create canvas");
+ this.gfxSurface = dojox.gfx.createSurface(this.domNode, this.width, this.height);
+ this.gfxSurface.whenLoaded(this, function(){
+ setTimeout(dojo.hitch(this, function(){
+ this.surfaceReady = true;
+ if(dojo.isIE){
+ //this.gfxSurface.rawNode.parentNode.id = this.id;
+ }else if(dojox.gfx.renderer == "silverlight"){
+ this.id = this.domNode.firstChild.id
+ }else{
+ //this.gfxSurface.rawNode.id = this.id;
+ }
+
+ this.underlay = this.gfxSurface.createGroup();
+ this.surface = this.gfxSurface.createGroup();
+ this.overlay = this.gfxSurface.createGroup();
+ this.surface.setTransform({dx:0, dy:0,xx:1,yy:1});
+
+ this.gfxSurface.getDimensions = dojo.hitch(this.gfxSurface, "getDimensions");
+ if(options.callback){
+ options.callback(this.domNode);
+ }
+ }),500);
+ });
+ this._mouseHandle = this.mouse.register(this);
+ },
+ {
+ // zoom: [readonly] Number
+ // The amount the canvas is zoomed
+ zoom:1,
+
+ useScrollbars: true,
+ baseClass:"drawingCanvas",
+
+ resize: function(width, height){
+ // summary:
+ // Method used to change size of canvas. Potentially
+ // called from a container like ContentPane. May be
+ // called directly.
+ //
+ this.parentWidth = width;
+ this.parentHeight = height;
+ this.setDimensions(width, height);
+ },
+
+ setDimensions: function(width, height, scrollx, scrolly){
+ // summary:
+ // Internal. Changes canvas size and sets scroll position.
+ // Do not call this, use resize().
+ //
+ // changing the size of the surface and setting scroll
+ // if items are off screen
+ var sw = this.getScrollWidth(); //+ 10;
+ this.width = Math.max(width, this.parentWidth);
+ this.height = Math.max(height, this.parentHeight);
+
+ if(this.height>this.parentHeight){
+ this.width -= sw;
+ }
+ if(this.width>this.parentWidth){
+ this.height -= sw;
+ }
+
+ this.mouse.resize(this.width,this.height);
+ this.gfxSurface.setDimensions(this.width, this.height);
+
+
+ this.domNode.parentNode.scrollTop = scrolly || 0;
+ this.domNode.parentNode.scrollLeft = scrollx || 0;
+
+
+ if(this.useScrollbars){
+ //console.info("Set Canvas Scroll", (this.height > this.parentHeight), this.height, this.parentHeight)
+ dojo.style(this.domNode.parentNode, {
+ overflowY: this.height > this.parentHeight ? "scroll" : "hidden",
+ overflowX: this.width > this.parentWidth ? "scroll" : "hidden"
+ });
+ }else{
+ dojo.style(this.domNode.parentNode, {
+ overflowY: "hidden",
+ overflowX: "hidden"
+ });
+ }
+ },
+
+
+ setZoom: function(zoom){
+ // summary:
+ // Internal. Zooms canvas in and out.
+ this.zoom = zoom;
+ this.surface.setTransform({xx:zoom, yy:zoom});
+ this.setDimensions(this.width*zoom, this.height*zoom)
+ },
+
+ onScroll: function(){
+ // summary:
+ // Event fires on scroll.NOT IMPLEMENTED
+ },
+
+ getScrollOffset: function(){
+ // summary:
+ // Get the scroll position of the canvas
+ return {
+ top:this.domNode.parentNode.scrollTop,
+ left:this.domNode.parentNode.scrollLeft
+ }; // Object
+ },
+
+ getScrollWidth: function(){
+ // summary:
+ // Special method used to detect the width (and height)
+ // of the browser scrollbars. Becomes memoized.
+ //
+ var p = dojo.create('div');
+ p.innerHTML = '<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:0;left:-1000px;"><div style="height:100px;"></div>';
+ var div = p.firstChild;
+ dojo.body().appendChild(div);
+ var noscroll = dojo.contentBox(div).h;
+ dojo.style(div, "overflow", "scroll");
+ var scrollWidth = noscroll - dojo.contentBox(div).h;
+ dojo.destroy(div);
+ this.getScrollWidth = function(){
+ return scrollWidth;
+ };
+ return scrollWidth; // Object
+ }
+ }
+ );
+
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/drawing/manager/Canvas.xd.js b/js/dojo-1.6/dojox/drawing/manager/Canvas.xd.js
new file mode 100644
index 0000000..32e0168
--- /dev/null
+++ b/js/dojo-1.6/dojox/drawing/manager/Canvas.xd.js
@@ -0,0 +1,176 @@
+/*
+ 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.drawing.manager.Canvas"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.drawing.manager.Canvas"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.drawing.manager.Canvas"] = true;
+dojo.provide("dojox.drawing.manager.Canvas");
+
+(function(){
+
+ dojox.drawing.manager.Canvas = dojox.drawing.util.oo.declare(
+ // summary:
+ // Creates a dojox.gfx.surface to be used for Drawing. Note that
+ // The 'surface' that Drawing uses is actually a dojox.gfx.group.
+ // This allows for more versatility.
+ //
+ // Called internally from a dojox.Drawing.
+ //
+ // Note: Surface creation is asynchrous. Connect to
+ // onSurfaceReady in Drawing.
+ //
+ function(/*Object*/options){
+ dojo.mixin(this, options);
+
+ var dim = dojo.contentBox(this.srcRefNode);
+ this.height = this.parentHeight = dim.h;
+ this.width = this.parentWidth = dim.w;
+ this.domNode = dojo.create("div", {id:"canvasNode"}, this.srcRefNode);
+ dojo.style(this.domNode, {
+ width:this.width,
+ height:"auto"
+ });
+
+ dojo.setSelectable(this.domNode, false);
+
+ this.id = this.id || this.util.uid("surface");
+
+ console.info("create canvas");
+ this.gfxSurface = dojox.gfx.createSurface(this.domNode, this.width, this.height);
+ this.gfxSurface.whenLoaded(this, function(){
+ setTimeout(dojo.hitch(this, function(){
+ this.surfaceReady = true;
+ if(dojo.isIE){
+ //this.gfxSurface.rawNode.parentNode.id = this.id;
+ }else if(dojox.gfx.renderer == "silverlight"){
+ this.id = this.domNode.firstChild.id
+ }else{
+ //this.gfxSurface.rawNode.id = this.id;
+ }
+
+ this.underlay = this.gfxSurface.createGroup();
+ this.surface = this.gfxSurface.createGroup();
+ this.overlay = this.gfxSurface.createGroup();
+ this.surface.setTransform({dx:0, dy:0,xx:1,yy:1});
+
+ this.gfxSurface.getDimensions = dojo.hitch(this.gfxSurface, "getDimensions");
+ if(options.callback){
+ options.callback(this.domNode);
+ }
+ }),500);
+ });
+ this._mouseHandle = this.mouse.register(this);
+ },
+ {
+ // zoom: [readonly] Number
+ // The amount the canvas is zoomed
+ zoom:1,
+
+ useScrollbars: true,
+ baseClass:"drawingCanvas",
+
+ resize: function(width, height){
+ // summary:
+ // Method used to change size of canvas. Potentially
+ // called from a container like ContentPane. May be
+ // called directly.
+ //
+ this.parentWidth = width;
+ this.parentHeight = height;
+ this.setDimensions(width, height);
+ },
+
+ setDimensions: function(width, height, scrollx, scrolly){
+ // summary:
+ // Internal. Changes canvas size and sets scroll position.
+ // Do not call this, use resize().
+ //
+ // changing the size of the surface and setting scroll
+ // if items are off screen
+ var sw = this.getScrollWidth(); //+ 10;
+ this.width = Math.max(width, this.parentWidth);
+ this.height = Math.max(height, this.parentHeight);
+
+ if(this.height>this.parentHeight){
+ this.width -= sw;
+ }
+ if(this.width>this.parentWidth){
+ this.height -= sw;
+ }
+
+ this.mouse.resize(this.width,this.height);
+ this.gfxSurface.setDimensions(this.width, this.height);
+
+
+ this.domNode.parentNode.scrollTop = scrolly || 0;
+ this.domNode.parentNode.scrollLeft = scrollx || 0;
+
+
+ if(this.useScrollbars){
+ //console.info("Set Canvas Scroll", (this.height > this.parentHeight), this.height, this.parentHeight)
+ dojo.style(this.domNode.parentNode, {
+ overflowY: this.height > this.parentHeight ? "scroll" : "hidden",
+ overflowX: this.width > this.parentWidth ? "scroll" : "hidden"
+ });
+ }else{
+ dojo.style(this.domNode.parentNode, {
+ overflowY: "hidden",
+ overflowX: "hidden"
+ });
+ }
+ },
+
+
+ setZoom: function(zoom){
+ // summary:
+ // Internal. Zooms canvas in and out.
+ this.zoom = zoom;
+ this.surface.setTransform({xx:zoom, yy:zoom});
+ this.setDimensions(this.width*zoom, this.height*zoom)
+ },
+
+ onScroll: function(){
+ // summary:
+ // Event fires on scroll.NOT IMPLEMENTED
+ },
+
+ getScrollOffset: function(){
+ // summary:
+ // Get the scroll position of the canvas
+ return {
+ top:this.domNode.parentNode.scrollTop,
+ left:this.domNode.parentNode.scrollLeft
+ }; // Object
+ },
+
+ getScrollWidth: function(){
+ // summary:
+ // Special method used to detect the width (and height)
+ // of the browser scrollbars. Becomes memoized.
+ //
+ var p = dojo.create('div');
+ p.innerHTML = '<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:0;left:-1000px;"><div style="height:100px;"></div>';
+ var div = p.firstChild;
+ dojo.body().appendChild(div);
+ var noscroll = dojo.contentBox(div).h;
+ dojo.style(div, "overflow", "scroll");
+ var scrollWidth = noscroll - dojo.contentBox(div).h;
+ dojo.destroy(div);
+ this.getScrollWidth = function(){
+ return scrollWidth;
+ };
+ return scrollWidth; // Object
+ }
+ }
+ );
+
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/drawing/manager/Mouse.js b/js/dojo-1.6/dojox/drawing/manager/Mouse.js
new file mode 100644
index 0000000..530af07
--- /dev/null
+++ b/js/dojo-1.6/dojox/drawing/manager/Mouse.js
@@ -0,0 +1,529 @@
+/*
+ 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
+*/
+
+
+if(!dojo._hasResource["dojox.drawing.manager.Mouse"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.drawing.manager.Mouse"] = true;
+dojo.provide("dojox.drawing.manager.Mouse");
+
+dojox.drawing.manager.Mouse = dojox.drawing.util.oo.declare(
+ // summary:
+ // Master object (instance) that tracks mouse
+ // events. A new instance is created for each
+ // Drawing object.
+ // description:
+ // You could connect to any method or event in this
+ // class, but it is designed to have the object
+ // 'registered'. All objects with the current event
+ // will be called directly.
+ //
+ // Custom events are used often. In addition to
+ // standard events onDown, onUp, onDrag, etc, if
+ // a certain object is clicked upon (or dragged, etc),
+ // that object's drawingType will create the custom event,
+ // such as onAnchorDown, or onStencilDown.
+ //
+ function(/* Object */options){
+ this.util = options.util;
+ this.keys = options.keys;
+ this.id = options.id || this.util.uid("mouse");
+ this.currentNodeId = "";
+ this.registered = {};
+ },
+
+ {
+ // doublClickSpeed: Number
+ // Milliseconds between clicks to
+ // register as for onDoubleClick
+ doublClickSpeed:400,
+
+
+ // rightClickMenu: boolean
+ // If true, right clicks bubble up so that context menus
+ // can be attached to them or the default can be shown.
+ // Otherwise right click is interpreted the same as a left click.
+ rightClickMenu: false,
+
+ // private properties
+
+ _lastx:0,
+ _lasty:0,
+ __reg:0,
+ _downOnCanvas:false,
+
+/*=====
+CustomEventMethod: function(){
+ // summary:
+ // The custom event method that an Object that has
+ // registered with manager.Mouse can receive.
+ // Can contain any or all of the following methods
+ // and they will be called as mouse events. All events
+ // will be sent a EventObject event object.
+ // NOTE:
+ // Events happen anywhere in the document unless
+ // otherwise noted.
+ //
+ // onMove
+ // Fires on mousemove when mouse is up
+ // onDown
+ // Fires on mousedown *on the canvas*
+ // onDrag
+ // Fires on mousemove when mouse is down
+ // onUp
+ // Fires on mouseup, anywhere in the document
+ // onStencilDown
+ // Fired on mousedown on a Stencil
+ // onStencilDrag
+ // Fired when mouse moves and mose is down on a Stencil
+ // onStencilUp
+ // Fired on mouseup off of a Stencil
+ // on[Custom]Up|Down|Move
+ // Custom events can bet set and fired by setting a
+ // different drawingType on a Stencil, or by calling
+ // setEventMode(customEventName)
+},
+EventObject: function(){
+ // summary:
+ // The custom event object that is sent to registered objects
+ // and their respective methods.
+ // NOTE: Most event objects are the same with the exception
+ // of the onDown events, which have fewer.
+ //
+ // All event properties included onDown:
+ //
+ // id: String
+ // Id of the focused object
+ // pageX: Number
+ // The X coordinate of the mouse from the left side of
+ // the document.
+ // pageY: Number
+ // The Y coordinate of the mouse from the top of
+ // the document.
+ // x: Number
+ // The X coordinate of the mouse from the left side
+ // of the canvas
+ // y: Number
+ // The Y coordinate of the mouse from the top
+ // of the canvas
+ //
+ // These event properties are *not* in onDown:
+ //
+ // last: Object
+ // The x and y coordinates of the last mousemove
+ // relative to the canvas
+ // move: Object
+ // The x and y amounts the mouse moved since the last event
+ // orgX: Number
+ // The left side of the canvas from the side of the document
+ // orgY: Number
+ // The top of the canvas from the top of the document
+ // scroll: Object
+ // The 'top' and 'left' scroll amounts of the canvas.
+ // start: Object
+ // The x and y coordinates of the mousedown event
+ // withinCanvas: Boolean
+ // Whether the event happened within the Canvas or not
+
+},
+=====*/
+
+ init: function(/* HTMLNode*/node){
+ // summary:
+ // Internal. Initializes mouse.
+ //
+ this.container = node;
+ this.setCanvas();
+ var c;
+ var _isDown = false;
+ dojo.connect(this.container, "rightclick", this, function(evt){
+ console.warn("RIGHTCLICK")
+ });
+
+ dojo.connect(document.body, "mousedown", this, function(evt){
+ //evt.preventDefault();
+ //dojo.stopEvent(evt);
+ });
+
+ dojo.connect(this.container, "mousedown", this, function(evt){
+ this.down(evt);
+ _isDown = true;
+ c = dojo.connect(document, "mousemove", this, "drag");
+ });
+ dojo.connect(document, "mouseup", this, function(evt){
+ dojo.disconnect(c);
+ _isDown = false;
+ this.up(evt);
+ });
+ dojo.connect(document, "mousemove", this, function(evt){
+ if(!_isDown){
+ this.move(evt);
+ }
+ });
+ dojo.connect(this.keys, "onEsc", this, function(evt){
+ this._dragged = false;
+ });
+ },
+
+ setCanvas: function(){
+ // summary:
+ // Internal. Sets canvas position
+ var pos = dojo.coords(this.container.parentNode);
+ this.origin = dojo.clone(pos);
+ },
+
+ scrollOffset: function(){
+ // summary:
+ // Gets scroll offset of canvas
+ return {
+ top:this.container.parentNode.scrollTop,
+ left:this.container.parentNode.scrollLeft
+ }; // Object
+ },
+
+ resize: function(width,height){
+ if(this.origin){
+ this.origin.w=width;
+ this.origin.h=height;
+ }
+ },
+
+ register: function(/* Object*/scope){
+ // summary:
+ // All objects (Stencils) should register here if they
+ // use mouse events. When registering, the object will
+ // be called if it has that method.
+ // argument:
+ // The object to be called
+ // Returns: handle
+ // Keep the handle to be used for disconnection.
+ // See: CustomEventMethod and EventObject
+ //
+ var handle = scope.id || "reg_"+(this.__reg++);
+ if(!this.registered[handle]){ this.registered[handle] = scope; }
+ return handle; // String
+ },
+ unregister: function(handle){
+ // summary:
+ // Disconnects object. Mouse events are no longer
+ // called for it.
+ if(!this.registered[handle]){ return; }
+ delete this.registered[handle];
+ },
+
+ _broadcastEvent:function(strEvt, obj){
+ // summary:
+ // Fire events to all registered objects.
+ //
+ //console.log("mouse.broadcast:", strEvt, obj)
+ for(var nm in this.registered){
+ if(this.registered[nm][strEvt]) this.registered[nm][strEvt](obj);
+ }
+ },
+
+ onDown: function(obj){
+ // summary:
+ // Create on[xx]Down event and send to broadcaster.
+ // Could be connected to.
+ //console.info("onDown:", this.eventName("down"))
+ this._broadcastEvent(this.eventName("down"), obj);
+ },
+
+ onDrag: function(obj){
+ // summary:
+ // Create on[xx]Drag event and send to broadcaster.
+ // Could be connected to.
+ //
+ var nm = this.eventName("drag");
+ if(this._selected && nm == "onDrag"){
+ nm = "onStencilDrag"
+ }
+ this._broadcastEvent(nm, obj);
+ },
+
+ onMove: function(obj){
+ // summary:
+ // Create onMove event and send to broadcaster.
+ // Could be connected to.
+ // Note: onMove never uses a custom event
+ // Note: onMove is currently not enabled in the app.
+ //
+ this._broadcastEvent("onMove", obj);
+ },
+
+ overName: function(obj,evt){
+ var nm = obj.id.split(".");
+ evt = evt.charAt(0).toUpperCase() + evt.substring(1);
+ if(nm[0] == "dojox" && (dojox.drawing.defaults.clickable || !dojox.drawing.defaults.clickMode)){
+ return "onStencil"+evt;
+ }else{
+ return "on"+evt;
+ }
+
+ },
+
+ onOver: function(obj){
+ // summary:
+ //
+ this._broadcastEvent(this.overName(obj,"over"), obj);
+ },
+
+ onOut: function(obj){
+ // summary:
+ //
+ this._broadcastEvent(this.overName(obj,"out"), obj);
+ },
+
+ onUp: function(obj){
+ // summary:
+ // Create on[xx]Up event and send to broadcaster.
+ // Could be connected to.
+ //
+ // blocking first click-off (deselect), largely for TextBlock
+ // TODO: should have param to make this optional?
+ var nm = this.eventName("up");
+
+ if(nm == "onStencilUp"){
+ this._selected = true;
+ }else if(this._selected && nm == "onUp"){ //////////////////////////////////////////
+ nm = "onStencilUp";
+ this._selected = false;
+ }
+
+ console.info("Up Event:", this.id, nm, "id:", obj.id);
+ this._broadcastEvent(nm, obj);
+
+ // Silverlight double-click handled in Silverlight class
+ if(dojox.gfx.renderer == "silverlight"){ return; }
+
+ // Check Double Click
+ // If a double click is detected, the onDoubleClick event fires,
+ // but does not replace the normal event. They both fire.
+ this._clickTime = new Date().getTime();
+ if(this._lastClickTime){
+ if(this._clickTime-this._lastClickTime<this.doublClickSpeed){
+ var dnm = this.eventName("doubleClick");
+ console.warn("DOUBLE CLICK", dnm, obj);
+ this._broadcastEvent(dnm, obj);
+ }else{
+ //console.log(" slow:", this._clickTime-this._lastClickTime)
+ }
+ }
+ this._lastClickTime = this._clickTime;
+
+ },
+
+ zoom: 1,
+ setZoom: function(zoom){
+ // summary:
+ // Internal. Sets the mouse zoom percentage to
+ // that of the canvas
+ this.zoom = 1/zoom;
+ },
+
+ setEventMode: function(mode){
+ // summary:
+ // Sets the mouse mode s that custom events can be called.
+ // Also can 'disable' events by using a bogus mode:
+ // | mouse.setEventMode("DISABLED")
+ // (unless any object subscribes to this event,
+ // it is effectively disabled)
+ //
+ this.mode = mode ? "on" + mode.charAt(0).toUpperCase() + mode.substring(1) : "";
+ },
+
+ eventName: function(name){
+ // summary:
+ // Internal. Determine the event name
+ //
+ name = name.charAt(0).toUpperCase() + name.substring(1);
+ if(this.mode){
+ if(this.mode == "onPathEdit"){
+ return "on"+name;
+ }
+ if(this.mode == "onUI"){
+ //return "on"+name;
+ }
+ return this.mode + name;
+ }else{
+ //Allow a mode where stencils aren't clickable
+ if(!dojox.drawing.defaults.clickable && dojox.drawing.defaults.clickMode){return "on"+name;}
+ var dt = !this.drawingType || this.drawingType=="surface" || this.drawingType=="canvas" ? "" : this.drawingType;
+ var t = !dt ? "" : dt.charAt(0).toUpperCase() + dt.substring(1);
+ return "on"+t+name;
+ }
+ },
+
+ up: function(evt){
+ // summary:
+ // Internal. Create onUp event
+ //
+ this.onUp(this.create(evt));
+ },
+
+ down: function(evt){
+ // summary:
+ // Internal. Create onDown event
+ //
+ this._downOnCanvas = true;
+ var sc = this.scrollOffset();
+ var dim = this._getXY(evt);
+ this._lastpagex = dim.x;
+ this._lastpagey = dim.y;
+ var o = this.origin;
+ var x = dim.x - o.x + sc.left;
+ var y = dim.y - o.y + sc.top;
+
+ var withinCanvas = x>=0 && y>=0 && x<=o.w && y<=o.h;
+ x*= this.zoom;
+ y*= this.zoom;
+
+ o.startx = x;
+ o.starty = y;
+ this._lastx = x;
+ this._lasty = y;
+
+ this.drawingType = this.util.attr(evt, "drawingType") || "";
+ var id = this._getId(evt);
+ //console.log("DOWN:", this.id, id, withinCanvas);
+ //console.log("this.drawingType:", this.drawingType);
+
+ if(this.rightClickMenu && (evt.button == dojo.mouseButtons.RIGHT) && this.id == "mse"){
+ // Allow event to bubble for right click, for menus
+ }else{
+ evt.preventDefault();
+ dojo.stopEvent(evt);
+ }
+ this.onDown({
+ mid:this.id,
+ x:x,
+ y:y,
+ pageX:dim.x,
+ pageY:dim.y,
+ withinCanvas:withinCanvas,
+ id:id
+ });
+
+ },
+ over: function(obj){
+ // summary:
+ // Internal.
+ //
+ this.onOver(obj);
+ },
+ out: function(obj){
+ // summary:
+ // Internal.
+ //
+ this.onOut(obj);
+ },
+ move: function(evt){
+ // summary:
+ // Internal.
+ //
+ var obj = this.create(evt);
+ if(this.id=="MUI"){
+ //console.log("obj.id:", obj.id, "was:", this.currentNodeId)
+ }
+ if(obj.id != this.currentNodeId){
+ // TODO: I wonder if an ID is good enough
+ // that would avoid the mixin
+ var outObj = {};
+ for(var nm in obj){
+ outObj[nm] = obj[nm];
+ }
+ outObj.id = this.currentNodeId;
+ this.currentNodeId && this.out(outObj);
+ obj.id && this.over(obj);
+ this.currentNodeId = obj.id;
+ }
+ this.onMove(obj);
+ },
+ drag: function(evt){
+ // summary:
+ // Internal. Create onDrag event
+ this.onDrag(this.create(evt, true));
+ },
+ create: function(evt, squelchErrors){
+ // summary:
+ // Internal. Create EventObject
+ //
+ var sc = this.scrollOffset();
+ var dim = this._getXY(evt);
+
+ var pagex = dim.x;
+ var pagey = dim.y;
+
+ var o = this.origin;
+ var x = dim.x - o.x + sc.left;
+ var y = dim.y - o.y + sc.top;
+
+ var withinCanvas = x>=0 && y>=0 && x<=o.w && y<=o.h;
+ x*= this.zoom;
+ y*= this.zoom;
+
+ var id = withinCanvas ? this._getId(evt, squelchErrors) : "";
+ var ret = {
+ mid:this.id,
+ x:x,
+ y:y,
+ pageX:dim.x,
+ pageY:dim.y,
+ page:{
+ x:dim.x,
+ y:dim.y
+ },
+ orgX:o.x,
+ orgY:o.y,
+ last:{
+ x: this._lastx,
+ y: this._lasty
+ },
+ start:{
+ x: this.origin.startx, //+ sc.left,
+ y: this.origin.starty //+ sc.top
+ },
+ move:{
+ x:pagex - this._lastpagex,
+ y:pagey - this._lastpagey
+ },
+ scroll:sc,
+ id:id,
+ withinCanvas:withinCanvas
+ };
+
+ //console.warn("MSE LAST:", x-this._lastx, y-this._lasty)
+ this._lastx = x;
+ this._lasty = y;
+ this._lastpagex = pagex;
+ this._lastpagey = pagey;
+ dojo.stopEvent(evt);
+ return ret; //Object
+ },
+ _getId: function(evt, squelchErrors){
+ // summary:
+ // Internal. Gets ID of focused node.
+ return this.util.attr(evt, "id", null, squelchErrors); // String
+ },
+ _getXY: function(evt){
+ // summary:
+ // Internal. Gets mouse coords to page.
+ return {x:evt.pageX, y:evt.pageY}; // Object
+ },
+
+ setCursor: function(cursor,/* HTMLNode*/node){
+ // summary:
+ // Sets the cursor for a given node. If no
+ // node is specified the containing node is used.
+ if(!node){
+ dojo.style(this.container, "cursor", cursor);
+ }else{
+ dojo.style(node, "cursor", cursor);
+ }
+ }
+ }
+);
+
+}
diff --git a/js/dojo-1.6/dojox/drawing/manager/Mouse.xd.js b/js/dojo-1.6/dojox/drawing/manager/Mouse.xd.js
new file mode 100644
index 0000000..379df33
--- /dev/null
+++ b/js/dojo-1.6/dojox/drawing/manager/Mouse.xd.js
@@ -0,0 +1,533 @@
+/*
+ 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.drawing.manager.Mouse"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.drawing.manager.Mouse"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.drawing.manager.Mouse"] = true;
+dojo.provide("dojox.drawing.manager.Mouse");
+
+dojox.drawing.manager.Mouse = dojox.drawing.util.oo.declare(
+ // summary:
+ // Master object (instance) that tracks mouse
+ // events. A new instance is created for each
+ // Drawing object.
+ // description:
+ // You could connect to any method or event in this
+ // class, but it is designed to have the object
+ // 'registered'. All objects with the current event
+ // will be called directly.
+ //
+ // Custom events are used often. In addition to
+ // standard events onDown, onUp, onDrag, etc, if
+ // a certain object is clicked upon (or dragged, etc),
+ // that object's drawingType will create the custom event,
+ // such as onAnchorDown, or onStencilDown.
+ //
+ function(/* Object */options){
+ this.util = options.util;
+ this.keys = options.keys;
+ this.id = options.id || this.util.uid("mouse");
+ this.currentNodeId = "";
+ this.registered = {};
+ },
+
+ {
+ // doublClickSpeed: Number
+ // Milliseconds between clicks to
+ // register as for onDoubleClick
+ doublClickSpeed:400,
+
+
+ // rightClickMenu: boolean
+ // If true, right clicks bubble up so that context menus
+ // can be attached to them or the default can be shown.
+ // Otherwise right click is interpreted the same as a left click.
+ rightClickMenu: false,
+
+ // private properties
+
+ _lastx:0,
+ _lasty:0,
+ __reg:0,
+ _downOnCanvas:false,
+
+/*=====
+CustomEventMethod: function(){
+ // summary:
+ // The custom event method that an Object that has
+ // registered with manager.Mouse can receive.
+ // Can contain any or all of the following methods
+ // and they will be called as mouse events. All events
+ // will be sent a EventObject event object.
+ // NOTE:
+ // Events happen anywhere in the document unless
+ // otherwise noted.
+ //
+ // onMove
+ // Fires on mousemove when mouse is up
+ // onDown
+ // Fires on mousedown *on the canvas*
+ // onDrag
+ // Fires on mousemove when mouse is down
+ // onUp
+ // Fires on mouseup, anywhere in the document
+ // onStencilDown
+ // Fired on mousedown on a Stencil
+ // onStencilDrag
+ // Fired when mouse moves and mose is down on a Stencil
+ // onStencilUp
+ // Fired on mouseup off of a Stencil
+ // on[Custom]Up|Down|Move
+ // Custom events can bet set and fired by setting a
+ // different drawingType on a Stencil, or by calling
+ // setEventMode(customEventName)
+},
+EventObject: function(){
+ // summary:
+ // The custom event object that is sent to registered objects
+ // and their respective methods.
+ // NOTE: Most event objects are the same with the exception
+ // of the onDown events, which have fewer.
+ //
+ // All event properties included onDown:
+ //
+ // id: String
+ // Id of the focused object
+ // pageX: Number
+ // The X coordinate of the mouse from the left side of
+ // the document.
+ // pageY: Number
+ // The Y coordinate of the mouse from the top of
+ // the document.
+ // x: Number
+ // The X coordinate of the mouse from the left side
+ // of the canvas
+ // y: Number
+ // The Y coordinate of the mouse from the top
+ // of the canvas
+ //
+ // These event properties are *not* in onDown:
+ //
+ // last: Object
+ // The x and y coordinates of the last mousemove
+ // relative to the canvas
+ // move: Object
+ // The x and y amounts the mouse moved since the last event
+ // orgX: Number
+ // The left side of the canvas from the side of the document
+ // orgY: Number
+ // The top of the canvas from the top of the document
+ // scroll: Object
+ // The 'top' and 'left' scroll amounts of the canvas.
+ // start: Object
+ // The x and y coordinates of the mousedown event
+ // withinCanvas: Boolean
+ // Whether the event happened within the Canvas or not
+
+},
+=====*/
+
+ init: function(/* HTMLNode*/node){
+ // summary:
+ // Internal. Initializes mouse.
+ //
+ this.container = node;
+ this.setCanvas();
+ var c;
+ var _isDown = false;
+ dojo.connect(this.container, "rightclick", this, function(evt){
+ console.warn("RIGHTCLICK")
+ });
+
+ dojo.connect(document.body, "mousedown", this, function(evt){
+ //evt.preventDefault();
+ //dojo.stopEvent(evt);
+ });
+
+ dojo.connect(this.container, "mousedown", this, function(evt){
+ this.down(evt);
+ _isDown = true;
+ c = dojo.connect(document, "mousemove", this, "drag");
+ });
+ dojo.connect(document, "mouseup", this, function(evt){
+ dojo.disconnect(c);
+ _isDown = false;
+ this.up(evt);
+ });
+ dojo.connect(document, "mousemove", this, function(evt){
+ if(!_isDown){
+ this.move(evt);
+ }
+ });
+ dojo.connect(this.keys, "onEsc", this, function(evt){
+ this._dragged = false;
+ });
+ },
+
+ setCanvas: function(){
+ // summary:
+ // Internal. Sets canvas position
+ var pos = dojo.coords(this.container.parentNode);
+ this.origin = dojo.clone(pos);
+ },
+
+ scrollOffset: function(){
+ // summary:
+ // Gets scroll offset of canvas
+ return {
+ top:this.container.parentNode.scrollTop,
+ left:this.container.parentNode.scrollLeft
+ }; // Object
+ },
+
+ resize: function(width,height){
+ if(this.origin){
+ this.origin.w=width;
+ this.origin.h=height;
+ }
+ },
+
+ register: function(/* Object*/scope){
+ // summary:
+ // All objects (Stencils) should register here if they
+ // use mouse events. When registering, the object will
+ // be called if it has that method.
+ // argument:
+ // The object to be called
+ // Returns: handle
+ // Keep the handle to be used for disconnection.
+ // See: CustomEventMethod and EventObject
+ //
+ var handle = scope.id || "reg_"+(this.__reg++);
+ if(!this.registered[handle]){ this.registered[handle] = scope; }
+ return handle; // String
+ },
+ unregister: function(handle){
+ // summary:
+ // Disconnects object. Mouse events are no longer
+ // called for it.
+ if(!this.registered[handle]){ return; }
+ delete this.registered[handle];
+ },
+
+ _broadcastEvent:function(strEvt, obj){
+ // summary:
+ // Fire events to all registered objects.
+ //
+ //console.log("mouse.broadcast:", strEvt, obj)
+ for(var nm in this.registered){
+ if(this.registered[nm][strEvt]) this.registered[nm][strEvt](obj);
+ }
+ },
+
+ onDown: function(obj){
+ // summary:
+ // Create on[xx]Down event and send to broadcaster.
+ // Could be connected to.
+ //console.info("onDown:", this.eventName("down"))
+ this._broadcastEvent(this.eventName("down"), obj);
+ },
+
+ onDrag: function(obj){
+ // summary:
+ // Create on[xx]Drag event and send to broadcaster.
+ // Could be connected to.
+ //
+ var nm = this.eventName("drag");
+ if(this._selected && nm == "onDrag"){
+ nm = "onStencilDrag"
+ }
+ this._broadcastEvent(nm, obj);
+ },
+
+ onMove: function(obj){
+ // summary:
+ // Create onMove event and send to broadcaster.
+ // Could be connected to.
+ // Note: onMove never uses a custom event
+ // Note: onMove is currently not enabled in the app.
+ //
+ this._broadcastEvent("onMove", obj);
+ },
+
+ overName: function(obj,evt){
+ var nm = obj.id.split(".");
+ evt = evt.charAt(0).toUpperCase() + evt.substring(1);
+ if(nm[0] == "dojox" && (dojox.drawing.defaults.clickable || !dojox.drawing.defaults.clickMode)){
+ return "onStencil"+evt;
+ }else{
+ return "on"+evt;
+ }
+
+ },
+
+ onOver: function(obj){
+ // summary:
+ //
+ this._broadcastEvent(this.overName(obj,"over"), obj);
+ },
+
+ onOut: function(obj){
+ // summary:
+ //
+ this._broadcastEvent(this.overName(obj,"out"), obj);
+ },
+
+ onUp: function(obj){
+ // summary:
+ // Create on[xx]Up event and send to broadcaster.
+ // Could be connected to.
+ //
+ // blocking first click-off (deselect), largely for TextBlock
+ // TODO: should have param to make this optional?
+ var nm = this.eventName("up");
+
+ if(nm == "onStencilUp"){
+ this._selected = true;
+ }else if(this._selected && nm == "onUp"){ //////////////////////////////////////////
+ nm = "onStencilUp";
+ this._selected = false;
+ }
+
+ console.info("Up Event:", this.id, nm, "id:", obj.id);
+ this._broadcastEvent(nm, obj);
+
+ // Silverlight double-click handled in Silverlight class
+ if(dojox.gfx.renderer == "silverlight"){ return; }
+
+ // Check Double Click
+ // If a double click is detected, the onDoubleClick event fires,
+ // but does not replace the normal event. They both fire.
+ this._clickTime = new Date().getTime();
+ if(this._lastClickTime){
+ if(this._clickTime-this._lastClickTime<this.doublClickSpeed){
+ var dnm = this.eventName("doubleClick");
+ console.warn("DOUBLE CLICK", dnm, obj);
+ this._broadcastEvent(dnm, obj);
+ }else{
+ //console.log(" slow:", this._clickTime-this._lastClickTime)
+ }
+ }
+ this._lastClickTime = this._clickTime;
+
+ },
+
+ zoom: 1,
+ setZoom: function(zoom){
+ // summary:
+ // Internal. Sets the mouse zoom percentage to
+ // that of the canvas
+ this.zoom = 1/zoom;
+ },
+
+ setEventMode: function(mode){
+ // summary:
+ // Sets the mouse mode s that custom events can be called.
+ // Also can 'disable' events by using a bogus mode:
+ // | mouse.setEventMode("DISABLED")
+ // (unless any object subscribes to this event,
+ // it is effectively disabled)
+ //
+ this.mode = mode ? "on" + mode.charAt(0).toUpperCase() + mode.substring(1) : "";
+ },
+
+ eventName: function(name){
+ // summary:
+ // Internal. Determine the event name
+ //
+ name = name.charAt(0).toUpperCase() + name.substring(1);
+ if(this.mode){
+ if(this.mode == "onPathEdit"){
+ return "on"+name;
+ }
+ if(this.mode == "onUI"){
+ //return "on"+name;
+ }
+ return this.mode + name;
+ }else{
+ //Allow a mode where stencils aren't clickable
+ if(!dojox.drawing.defaults.clickable && dojox.drawing.defaults.clickMode){return "on"+name;}
+ var dt = !this.drawingType || this.drawingType=="surface" || this.drawingType=="canvas" ? "" : this.drawingType;
+ var t = !dt ? "" : dt.charAt(0).toUpperCase() + dt.substring(1);
+ return "on"+t+name;
+ }
+ },
+
+ up: function(evt){
+ // summary:
+ // Internal. Create onUp event
+ //
+ this.onUp(this.create(evt));
+ },
+
+ down: function(evt){
+ // summary:
+ // Internal. Create onDown event
+ //
+ this._downOnCanvas = true;
+ var sc = this.scrollOffset();
+ var dim = this._getXY(evt);
+ this._lastpagex = dim.x;
+ this._lastpagey = dim.y;
+ var o = this.origin;
+ var x = dim.x - o.x + sc.left;
+ var y = dim.y - o.y + sc.top;
+
+ var withinCanvas = x>=0 && y>=0 && x<=o.w && y<=o.h;
+ x*= this.zoom;
+ y*= this.zoom;
+
+ o.startx = x;
+ o.starty = y;
+ this._lastx = x;
+ this._lasty = y;
+
+ this.drawingType = this.util.attr(evt, "drawingType") || "";
+ var id = this._getId(evt);
+ //console.log("DOWN:", this.id, id, withinCanvas);
+ //console.log("this.drawingType:", this.drawingType);
+
+ if(this.rightClickMenu && (evt.button == dojo.mouseButtons.RIGHT) && this.id == "mse"){
+ // Allow event to bubble for right click, for menus
+ }else{
+ evt.preventDefault();
+ dojo.stopEvent(evt);
+ }
+ this.onDown({
+ mid:this.id,
+ x:x,
+ y:y,
+ pageX:dim.x,
+ pageY:dim.y,
+ withinCanvas:withinCanvas,
+ id:id
+ });
+
+ },
+ over: function(obj){
+ // summary:
+ // Internal.
+ //
+ this.onOver(obj);
+ },
+ out: function(obj){
+ // summary:
+ // Internal.
+ //
+ this.onOut(obj);
+ },
+ move: function(evt){
+ // summary:
+ // Internal.
+ //
+ var obj = this.create(evt);
+ if(this.id=="MUI"){
+ //console.log("obj.id:", obj.id, "was:", this.currentNodeId)
+ }
+ if(obj.id != this.currentNodeId){
+ // TODO: I wonder if an ID is good enough
+ // that would avoid the mixin
+ var outObj = {};
+ for(var nm in obj){
+ outObj[nm] = obj[nm];
+ }
+ outObj.id = this.currentNodeId;
+ this.currentNodeId && this.out(outObj);
+ obj.id && this.over(obj);
+ this.currentNodeId = obj.id;
+ }
+ this.onMove(obj);
+ },
+ drag: function(evt){
+ // summary:
+ // Internal. Create onDrag event
+ this.onDrag(this.create(evt, true));
+ },
+ create: function(evt, squelchErrors){
+ // summary:
+ // Internal. Create EventObject
+ //
+ var sc = this.scrollOffset();
+ var dim = this._getXY(evt);
+
+ var pagex = dim.x;
+ var pagey = dim.y;
+
+ var o = this.origin;
+ var x = dim.x - o.x + sc.left;
+ var y = dim.y - o.y + sc.top;
+
+ var withinCanvas = x>=0 && y>=0 && x<=o.w && y<=o.h;
+ x*= this.zoom;
+ y*= this.zoom;
+
+ var id = withinCanvas ? this._getId(evt, squelchErrors) : "";
+ var ret = {
+ mid:this.id,
+ x:x,
+ y:y,
+ pageX:dim.x,
+ pageY:dim.y,
+ page:{
+ x:dim.x,
+ y:dim.y
+ },
+ orgX:o.x,
+ orgY:o.y,
+ last:{
+ x: this._lastx,
+ y: this._lasty
+ },
+ start:{
+ x: this.origin.startx, //+ sc.left,
+ y: this.origin.starty //+ sc.top
+ },
+ move:{
+ x:pagex - this._lastpagex,
+ y:pagey - this._lastpagey
+ },
+ scroll:sc,
+ id:id,
+ withinCanvas:withinCanvas
+ };
+
+ //console.warn("MSE LAST:", x-this._lastx, y-this._lasty)
+ this._lastx = x;
+ this._lasty = y;
+ this._lastpagex = pagex;
+ this._lastpagey = pagey;
+ dojo.stopEvent(evt);
+ return ret; //Object
+ },
+ _getId: function(evt, squelchErrors){
+ // summary:
+ // Internal. Gets ID of focused node.
+ return this.util.attr(evt, "id", null, squelchErrors); // String
+ },
+ _getXY: function(evt){
+ // summary:
+ // Internal. Gets mouse coords to page.
+ return {x:evt.pageX, y:evt.pageY}; // Object
+ },
+
+ setCursor: function(cursor,/* HTMLNode*/node){
+ // summary:
+ // Sets the cursor for a given node. If no
+ // node is specified the containing node is used.
+ if(!node){
+ dojo.style(this.container, "cursor", cursor);
+ }else{
+ dojo.style(node, "cursor", cursor);
+ }
+ }
+ }
+);
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/drawing/manager/Stencil.js b/js/dojo-1.6/dojox/drawing/manager/Stencil.js
new file mode 100644
index 0000000..3ee6d74
--- /dev/null
+++ b/js/dojo-1.6/dojox/drawing/manager/Stencil.js
@@ -0,0 +1,651 @@
+/*
+ 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
+*/
+
+
+if(!dojo._hasResource["dojox.drawing.manager.Stencil"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.drawing.manager.Stencil"] = true;
+dojo.provide("dojox.drawing.manager.Stencil");
+
+(function(){
+ var surface, surfaceNode;
+ dojox.drawing.manager.Stencil = dojox.drawing.util.oo.declare(
+ // summary:
+ // The main class for tracking Stencils that are cretaed, added,
+ // selected, or deleted. Also handles selections, multiple
+ // selections, adding and removing from selections, and dragging
+ // selections. It's this class that triggers the anchors to
+ // appear on a Stencil and whther there are anchor on a multiple
+ // select or not (currently not)
+ //
+ function(options){
+ //
+ // TODO: mixin props
+ //
+ surface = options.surface;
+ this.canvas = options.canvas;
+
+ this.defaults = dojox.drawing.defaults.copy();
+ this.undo = options.undo;
+ this.mouse = options.mouse;
+ this.keys = options.keys;
+ this.anchors = options.anchors;
+ this.stencils = {};
+ this.selectedStencils = {};
+ this._mouseHandle = this.mouse.register(this);
+
+ dojo.connect(this.keys, "onArrow", this, "onArrow");
+ dojo.connect(this.keys, "onEsc", this, "deselect");
+ dojo.connect(this.keys, "onDelete", this, "onDelete");
+
+ },
+ {
+ _dragBegun: false,
+ _wasDragged:false,
+ _secondClick:false,
+ _isBusy:false,
+
+ setRecentStencil: function(stencil){
+ // summary:
+ // Keeps track of the most recent stencil interacted
+ // with, whether created or selected.
+ this.recent = stencil;
+ },
+
+ getRecentStencil: function(){
+ // summary:
+ // Returns the stencil most recently interacted
+ // with whether it's last created or last selected
+ return this.recent;
+ },
+
+ register: function(/*Object*/stencil){
+ // summary:
+ // Key method for adding Stencils. Stencils
+ // can be added to the canvas without adding
+ // them to this, but they won't have selection
+ // or drag ability.
+ //
+ console.log("Selection.register ::::::", stencil.id);
+ if(stencil.isText && !stencil.editMode && stencil.deleteEmptyCreate && !stencil.getText()){
+ // created empty text field
+ // defaults say to delete
+ console.warn("EMPTY CREATE DELETE", stencil);
+ stencil.destroy();
+ return false;
+ }
+
+ this.stencils[stencil.id] = stencil;
+ this.setRecentStencil(stencil);
+
+ if(stencil.execText){
+ if(stencil._text && !stencil.editMode){
+ console.log("select text");
+ this.selectItem(stencil);
+ }
+ stencil.connect("execText", this, function(){
+ if(stencil.isText && stencil.deleteEmptyModify && !stencil.getText()){
+ console.warn("EMPTY MOD DELETE", stencil);
+ // text deleted
+ // defaults say to delete
+ this.deleteItem(stencil);
+ }else if(stencil.selectOnExec){
+ this.selectItem(stencil);
+ }
+ });
+ }
+
+ stencil.connect("deselect", this, function(){
+ if(!this._isBusy && this.isSelected(stencil)){
+ // called from within stencil. do action.
+ this.deselectItem(stencil);
+ }
+ });
+
+ stencil.connect("select", this, function(){
+ if(!this._isBusy && !this.isSelected(stencil)){
+ // called from within stencil. do action.
+ this.selectItem(stencil);
+ }
+ });
+
+ return stencil;
+ },
+ unregister: function(/*Object*/stencil){
+ // summary:
+ // Method for removing Stencils from the manager.
+ // This doesn't delete them, only removes them from
+ // the list.
+ //
+ console.log("Selection.unregister ::::::", stencil.id, "sel:", stencil.selected);
+ if(stencil){
+ stencil.selected && this.onDeselect(stencil);
+ delete this.stencils[stencil.id];
+ }
+ },
+
+ onArrow: function(/*Key Event*/evt){
+ // summary:
+ // Moves selection based on keyboard arrow keys
+ //
+ // FIXME: Check constraints
+ if(this.hasSelected()){
+ this.saveThrottledState();
+ this.group.applyTransform({dx:evt.x, dy: evt.y});
+ }
+ },
+
+ _throttleVrl:null,
+ _throttle: false,
+ throttleTime:400,
+ _lastmxx:-1,
+ _lastmxy:-1,
+ saveMoveState: function(){
+ // summary:
+ // Internal. Used for the prototype undo stack.
+ // Saves selection position.
+ //
+ var mx = this.group.getTransform();
+ if(mx.dx == this._lastmxx && mx.dy == this._lastmxy){ return; }
+ this._lastmxx = mx.dx;
+ this._lastmxy = mx.dy;
+ //console.warn("SAVE MOVE!", mx.dx, mx.dy);
+ this.undo.add({
+ before:dojo.hitch(this.group, "setTransform", mx)
+ });
+ },
+
+ saveThrottledState: function(){
+ // summary:
+ // Internal. Used for the prototype undo stack.
+ // Prevents an undo point on every mouse move.
+ // Only does a point when the mouse hesitates.
+ //
+ clearTimeout(this._throttleVrl);
+ clearInterval(this._throttleVrl);
+ this._throttleVrl = setTimeout(dojo.hitch(this, function(){
+ this._throttle = false;
+ this.saveMoveState();
+ }), this.throttleTime);
+ if(this._throttle){ return; }
+ this._throttle = true;
+
+ this.saveMoveState();
+
+ },
+ unDelete: function(/*Array*/stencils){
+ // summary:
+ // Undeletes a stencil. Used in undo stack.
+ //
+ console.log("unDelete:", stencils);
+ for(var s in stencils){
+ stencils[s].render();
+ this.onSelect(stencils[s]);
+ }
+ },
+ onDelete: function(/*Boolean*/noundo){
+ // summary:
+ // Event fired on deletion of a stencil
+ //
+ console.log("Stencil onDelete", noundo);
+ if(noundo!==true){
+ this.undo.add({
+ before:dojo.hitch(this, "unDelete", this.selectedStencils),
+ after:dojo.hitch(this, "onDelete", true)
+ });
+ }
+ this.withSelected(function(m){
+ this.anchors.remove(m);
+ var id = m.id;
+ console.log("delete:", m);
+ m.destroy();
+ delete this.stencils[id];
+ });
+ this.selectedStencils = {};
+ },
+
+ deleteItem: function(/*Object*/stencil){
+ // summary:
+ // Deletes a stencil.
+ // NOTE: supports limited undo.
+ //
+ // manipulating the selection to fire onDelete properly
+ if(this.hasSelected()){
+ // there is a selection
+ var sids = [];
+ for(var m in this.selectedStencils){
+ if(this.selectedStencils.id == stencil.id){
+ if(this.hasSelected()==1){
+ // the deleting stencil is the only one selected
+ this.onDelete();
+ return;
+ }
+ }else{
+ sids.push(this.selectedStencils.id);
+ }
+ }
+ // remove selection, delete, restore selection
+ this.deselect();
+ this.selectItem(stencil);
+ this.onDelete();
+ dojo.forEach(sids, function(id){
+ this.selectItem(id);
+ }, this);
+ }else{
+ // there is not a selection. select it, delete it
+ this.selectItem(stencil);
+ // now delete selection
+ this.onDelete();
+ }
+ },
+
+ removeAll: function(){
+ // summary:
+ // Deletes all Stencils on the canvas.
+
+ this.selectAll();
+ this._isBusy = true;
+ this.onDelete();
+ this.stencils = {};
+ this._isBusy = false;
+ },
+
+ setSelectionGroup: function(){
+ // summary:
+ // Internal. Creates a new selection group
+ // used to hold selected stencils.
+ //
+ this.withSelected(function(m){
+ this.onDeselect(m, true);
+ });
+
+ if(this.group){
+ surface.remove(this.group);
+ this.group.removeShape();
+ }
+ this.group = surface.createGroup();
+ this.group.setTransform({dx:0, dy: 0});
+
+ this.withSelected(function(m){
+ this.group.add(m.container);
+ m.select();
+ });
+ },
+
+ setConstraint: function(){
+ // summary:
+ // Internal. Gets all selected stencils' coordinates
+ // and determines how far left and up the selection
+ // can go without going below zero
+ //
+ var t = Infinity, l = Infinity;
+ this.withSelected(function(m){
+ var o = m.getBounds();
+ t = Math.min(o.y1, t);
+ l = Math.min(o.x1, l);
+ });
+ this.constrain = {l:-l, t:-t};
+ },
+
+
+
+ onDeselect: function(stencil, keepObject){
+ // summary:
+ // Event fired on deselection of a stencil
+ //
+ if(!keepObject){
+ delete this.selectedStencils[stencil.id];
+ }
+ //console.log('onDeselect, keep:', keepObject, "stencil:", stencil.type)
+
+ this.anchors.remove(stencil);
+
+ surface.add(stencil.container);
+ stencil.selected && stencil.deselect();
+ stencil.applyTransform(this.group.getTransform());
+ },
+
+ deselectItem: function(/*Object*/stencil){
+ // summary:
+ // Deselect passed stencil
+ //
+ // note: just keeping with standardized methods
+ this.onDeselect(stencil);
+ },
+
+ deselect: function(){ // all stencils
+ // summary:
+ // Deselect all stencils
+ //
+ this.withSelected(function(m){
+ this.onDeselect(m);
+ });
+ this._dragBegun = false;
+ this._wasDragged = false;
+ },
+
+ onSelect: function(/*Object*/stencil){
+ // summary:
+ // Event fired on selection of a stencil
+ //
+ //console.log("stencil.onSelect", stencil);
+ if(!stencil){
+ console.error("null stencil is not selected:", this.stencils)
+ }
+ if(this.selectedStencils[stencil.id]){ return; }
+ this.selectedStencils[stencil.id] = stencil;
+ this.group.add(stencil.container);
+ stencil.select();
+ if(this.hasSelected()==1){
+ this.anchors.add(stencil, this.group);
+ }
+ },
+
+ selectAll: function(){
+ // summary:
+ // Selects all items
+ this._isBusy = true;
+ for(var m in this.stencils){
+ //if(!this.stencils[m].selected){
+ this.selectItem(m);
+ //}
+ }
+ this._isBusy = false;
+ },
+
+ selectItem: function(/*String|Object*/ idOrItem){
+ // summary:
+ // Method used to select a stencil.
+ //
+ var id = typeof(idOrItem)=="string" ? idOrItem : idOrItem.id;
+ var stencil = this.stencils[id];
+ this.setSelectionGroup();
+ this.onSelect(stencil);
+ this.group.moveToFront();
+ this.setConstraint();
+ },
+
+ onLabelDoubleClick: function(/*EventObject*/obj){
+ // summary:
+ // Event to connect a textbox to
+ // for label edits
+ console.info("mgr.onLabelDoubleClick:", obj);
+ if(this.selectedStencils[obj.id]){
+ this.deselect();
+ }
+ },
+
+ onStencilDoubleClick: function(/*EventObject*/obj){
+ // summary:
+ // Event fired on the double-click of a stencil
+ //
+ console.info("mgr.onStencilDoubleClick:", obj);
+ if(this.selectedStencils[obj.id]){
+ if(this.selectedStencils[obj.id].edit){
+ console.info("Mgr Stencil Edit -> ", this.selectedStencils[obj.id]);
+ var m = this.selectedStencils[obj.id];
+ // deselect must happen first to set the transform
+ // then edit knows where to set the text box
+ m.editMode = true;
+ this.deselect();
+ m.edit();
+ }
+ }
+
+ },
+
+ onAnchorUp: function(){
+ // summary:
+ // Event fire on mouseup off of an anchor point
+ this.setConstraint();
+ },
+
+ onStencilDown: function(/*EventObject*/obj, evt){
+ // summary:
+ // Event fired on mousedown on a stencil
+ //
+ console.info(" >>> onStencilDown:", obj.id, this.keys.meta);
+ if(!this.stencils[obj.id]){ return; }
+ this.setRecentStencil(this.stencils[obj.id]);
+ this._isBusy = true;
+
+
+ if(this.selectedStencils[obj.id] && this.keys.meta){
+ if(dojo.isMac && this.keys.cmmd){
+ // block context menu
+
+ }
+ console.log(" shift remove");
+ this.onDeselect(this.selectedStencils[obj.id]);
+ if(this.hasSelected()==1){
+ this.withSelected(function(m){
+ this.anchors.add(m, this.group);
+ });
+ }
+ this.group.moveToFront();
+ this.setConstraint();
+ return;
+
+ }else if(this.selectedStencils[obj.id]){
+ console.log(" clicked on selected");
+ // clicking on same selected item(s)
+ // RESET OFFSETS
+ var mx = this.group.getTransform();
+ this._offx = obj.x - mx.dx;
+ this._offy = obj.y - mx.dy;
+ return;
+
+ }else if(!this.keys.meta){
+
+ console.log(" deselect all");
+ this.deselect();
+
+ }else{
+ // meta-key add
+ //console.log("reset sel and add stencil")
+ }
+ console.log(" add stencil to selection");
+ // add a stencil
+ this.selectItem(obj.id);
+
+ mx = this.group.getTransform();
+ this._offx = obj.x - mx.dx;
+ this._offy = obj.y - mx.dx;
+
+ this.orgx = obj.x;
+ this.orgy = obj.y;
+
+ this._isBusy = false;
+
+ // TODO:
+ // dojo.style(surfaceNode, "cursor", "pointer");
+
+ // TODO:
+ this.undo.add({
+ before:function(){
+
+ },
+ after: function(){
+
+ }
+ });
+ },
+
+ onLabelDown: function(/*EventObject*/obj, evt){
+ // summary:
+ // Event fired on mousedown of a stencil's label
+ // Because it's an annotation the id will be the
+ // master stencil.
+ //console.info("===============>>>Label click: ",obj, " evt: ",evt);
+ this.onStencilDown(obj,evt);
+ },
+
+ onStencilUp: function(/*EventObject*/obj){
+ // summary:
+ // Event fired on mouseup off of a stencil
+ //
+ },
+
+ onLabelUp: function(/*EventObject*/obj){
+ this.onStencilUp(obj);
+ },
+
+ onStencilDrag: function(/*EventObject*/obj){
+ // summary:
+ // Event fired on every mousemove of a stencil drag
+ //
+ if(!this._dragBegun){
+ // bug, in FF anyway - first mouse move shows x=0
+ // the 'else' fixes it
+ this.onBeginDrag(obj);
+ this._dragBegun = true;
+ }else{
+ this.saveThrottledState();
+
+ var x = obj.x - obj.last.x,
+ y = obj.y - obj.last.y,
+ c = this.constrain,
+ mz = this.defaults.anchors.marginZero;
+
+
+ x = obj.x - this._offx;
+ y = obj.y - this._offy;
+
+ if(x < c.l + mz){
+ x = c.l + mz;
+ }
+ if(y < c.t + mz){
+ y = c.t + mz;
+ }
+
+ this.group.setTransform({
+ dx: x,
+ dy: y
+ });
+
+
+ }
+ },
+
+ onLabelDrag: function(/*EventObject*/obj){
+ this.onStencilDrag(obj);
+ },
+
+ onDragEnd: function(/*EventObject*/obj){
+ // summary:
+ // Event fired at the end of a stencil drag
+ //
+ this._dragBegun = false;
+ },
+ onBeginDrag: function(/*EventObject*/obj){
+ // summary:
+ // Event fired at the beginning of a stencil drag
+ //
+ this._wasDragged = true;
+ },
+
+ onDown: function(/*EventObject*/obj){
+ // summary:
+ // Event fired on mousedown on the canvas
+ //
+ this.deselect();
+ },
+
+
+ onStencilOver: function(obj){
+ // summary:
+ // This changes the cursor when hovering over
+ // a selectable stencil.
+ //console.log("OVER")
+ dojo.style(obj.id, "cursor", "move");
+ },
+
+ onStencilOut: function(obj){
+ // summary:
+ // This restores the cursor.
+ //console.log("OUT")
+ dojo.style(obj.id, "cursor", "crosshair");
+ },
+
+ exporter: function(){
+ // summary:
+ // Collects all Stencil data and returns an
+ // Array of objects.
+ var items = [];
+ for(var m in this.stencils){
+ this.stencils[m].enabled && items.push(this.stencils[m].exporter());
+ }
+ return items; // Array
+ },
+
+ listStencils: function(){
+ return this.stencils;
+ },
+
+ toSelected: function(/*String*/func){
+ // summary:
+ // Convenience function calls function *within*
+ // all selected stencils
+ var args = Array.prototype.slice.call(arguments).splice(1);
+ for(var m in this.selectedStencils){
+ var item = this.selectedStencils[m];
+ item[func].apply(item, args);
+ }
+ },
+
+ withSelected: function(/*Function*/func){
+ // summary:
+ // Convenience function calls function on
+ // all selected stencils
+ var f = dojo.hitch(this, func);
+ for(var m in this.selectedStencils){
+ f(this.selectedStencils[m]);
+ }
+ },
+
+ withUnselected: function(/*Function*/func){
+ // summary:
+ // Convenience function calls function on
+ // all stencils that are not selected
+ var f = dojo.hitch(this, func);
+ for(var m in this.stencils){
+ !this.stencils[m].selected && f(this.stencils[m]);
+ }
+ },
+
+ withStencils: function(/*Function*/func){
+ // summary:
+ // Convenience function calls function on
+ // all stencils
+ var f = dojo.hitch(this, func);
+ for(var m in this.stencils){
+ f(this.stencils[m]);
+ }
+ },
+
+ hasSelected: function(){
+ // summary:
+ // Returns number of selected (generally used
+ // as truthy or falsey)
+ //
+ // FIXME: should be areSelected?
+ var ln = 0;
+ for(var m in this.selectedStencils){ ln++; }
+ return ln; // Number
+ },
+
+ isSelected: function(/*Object*/stencil){
+ // summary:
+ // Returns if passed stencil is selected or not
+ // based on internal collection, not on stencil
+ // boolean
+ return !!this.selectedStencils[stencil.id]; // Boolean
+ }
+ }
+
+ );
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/drawing/manager/Stencil.xd.js b/js/dojo-1.6/dojox/drawing/manager/Stencil.xd.js
new file mode 100644
index 0000000..d921d52
--- /dev/null
+++ b/js/dojo-1.6/dojox/drawing/manager/Stencil.xd.js
@@ -0,0 +1,655 @@
+/*
+ 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.drawing.manager.Stencil"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.drawing.manager.Stencil"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.drawing.manager.Stencil"] = true;
+dojo.provide("dojox.drawing.manager.Stencil");
+
+(function(){
+ var surface, surfaceNode;
+ dojox.drawing.manager.Stencil = dojox.drawing.util.oo.declare(
+ // summary:
+ // The main class for tracking Stencils that are cretaed, added,
+ // selected, or deleted. Also handles selections, multiple
+ // selections, adding and removing from selections, and dragging
+ // selections. It's this class that triggers the anchors to
+ // appear on a Stencil and whther there are anchor on a multiple
+ // select or not (currently not)
+ //
+ function(options){
+ //
+ // TODO: mixin props
+ //
+ surface = options.surface;
+ this.canvas = options.canvas;
+
+ this.defaults = dojox.drawing.defaults.copy();
+ this.undo = options.undo;
+ this.mouse = options.mouse;
+ this.keys = options.keys;
+ this.anchors = options.anchors;
+ this.stencils = {};
+ this.selectedStencils = {};
+ this._mouseHandle = this.mouse.register(this);
+
+ dojo.connect(this.keys, "onArrow", this, "onArrow");
+ dojo.connect(this.keys, "onEsc", this, "deselect");
+ dojo.connect(this.keys, "onDelete", this, "onDelete");
+
+ },
+ {
+ _dragBegun: false,
+ _wasDragged:false,
+ _secondClick:false,
+ _isBusy:false,
+
+ setRecentStencil: function(stencil){
+ // summary:
+ // Keeps track of the most recent stencil interacted
+ // with, whether created or selected.
+ this.recent = stencil;
+ },
+
+ getRecentStencil: function(){
+ // summary:
+ // Returns the stencil most recently interacted
+ // with whether it's last created or last selected
+ return this.recent;
+ },
+
+ register: function(/*Object*/stencil){
+ // summary:
+ // Key method for adding Stencils. Stencils
+ // can be added to the canvas without adding
+ // them to this, but they won't have selection
+ // or drag ability.
+ //
+ console.log("Selection.register ::::::", stencil.id);
+ if(stencil.isText && !stencil.editMode && stencil.deleteEmptyCreate && !stencil.getText()){
+ // created empty text field
+ // defaults say to delete
+ console.warn("EMPTY CREATE DELETE", stencil);
+ stencil.destroy();
+ return false;
+ }
+
+ this.stencils[stencil.id] = stencil;
+ this.setRecentStencil(stencil);
+
+ if(stencil.execText){
+ if(stencil._text && !stencil.editMode){
+ console.log("select text");
+ this.selectItem(stencil);
+ }
+ stencil.connect("execText", this, function(){
+ if(stencil.isText && stencil.deleteEmptyModify && !stencil.getText()){
+ console.warn("EMPTY MOD DELETE", stencil);
+ // text deleted
+ // defaults say to delete
+ this.deleteItem(stencil);
+ }else if(stencil.selectOnExec){
+ this.selectItem(stencil);
+ }
+ });
+ }
+
+ stencil.connect("deselect", this, function(){
+ if(!this._isBusy && this.isSelected(stencil)){
+ // called from within stencil. do action.
+ this.deselectItem(stencil);
+ }
+ });
+
+ stencil.connect("select", this, function(){
+ if(!this._isBusy && !this.isSelected(stencil)){
+ // called from within stencil. do action.
+ this.selectItem(stencil);
+ }
+ });
+
+ return stencil;
+ },
+ unregister: function(/*Object*/stencil){
+ // summary:
+ // Method for removing Stencils from the manager.
+ // This doesn't delete them, only removes them from
+ // the list.
+ //
+ console.log("Selection.unregister ::::::", stencil.id, "sel:", stencil.selected);
+ if(stencil){
+ stencil.selected && this.onDeselect(stencil);
+ delete this.stencils[stencil.id];
+ }
+ },
+
+ onArrow: function(/*Key Event*/evt){
+ // summary:
+ // Moves selection based on keyboard arrow keys
+ //
+ // FIXME: Check constraints
+ if(this.hasSelected()){
+ this.saveThrottledState();
+ this.group.applyTransform({dx:evt.x, dy: evt.y});
+ }
+ },
+
+ _throttleVrl:null,
+ _throttle: false,
+ throttleTime:400,
+ _lastmxx:-1,
+ _lastmxy:-1,
+ saveMoveState: function(){
+ // summary:
+ // Internal. Used for the prototype undo stack.
+ // Saves selection position.
+ //
+ var mx = this.group.getTransform();
+ if(mx.dx == this._lastmxx && mx.dy == this._lastmxy){ return; }
+ this._lastmxx = mx.dx;
+ this._lastmxy = mx.dy;
+ //console.warn("SAVE MOVE!", mx.dx, mx.dy);
+ this.undo.add({
+ before:dojo.hitch(this.group, "setTransform", mx)
+ });
+ },
+
+ saveThrottledState: function(){
+ // summary:
+ // Internal. Used for the prototype undo stack.
+ // Prevents an undo point on every mouse move.
+ // Only does a point when the mouse hesitates.
+ //
+ clearTimeout(this._throttleVrl);
+ clearInterval(this._throttleVrl);
+ this._throttleVrl = setTimeout(dojo.hitch(this, function(){
+ this._throttle = false;
+ this.saveMoveState();
+ }), this.throttleTime);
+ if(this._throttle){ return; }
+ this._throttle = true;
+
+ this.saveMoveState();
+
+ },
+ unDelete: function(/*Array*/stencils){
+ // summary:
+ // Undeletes a stencil. Used in undo stack.
+ //
+ console.log("unDelete:", stencils);
+ for(var s in stencils){
+ stencils[s].render();
+ this.onSelect(stencils[s]);
+ }
+ },
+ onDelete: function(/*Boolean*/noundo){
+ // summary:
+ // Event fired on deletion of a stencil
+ //
+ console.log("Stencil onDelete", noundo);
+ if(noundo!==true){
+ this.undo.add({
+ before:dojo.hitch(this, "unDelete", this.selectedStencils),
+ after:dojo.hitch(this, "onDelete", true)
+ });
+ }
+ this.withSelected(function(m){
+ this.anchors.remove(m);
+ var id = m.id;
+ console.log("delete:", m);
+ m.destroy();
+ delete this.stencils[id];
+ });
+ this.selectedStencils = {};
+ },
+
+ deleteItem: function(/*Object*/stencil){
+ // summary:
+ // Deletes a stencil.
+ // NOTE: supports limited undo.
+ //
+ // manipulating the selection to fire onDelete properly
+ if(this.hasSelected()){
+ // there is a selection
+ var sids = [];
+ for(var m in this.selectedStencils){
+ if(this.selectedStencils.id == stencil.id){
+ if(this.hasSelected()==1){
+ // the deleting stencil is the only one selected
+ this.onDelete();
+ return;
+ }
+ }else{
+ sids.push(this.selectedStencils.id);
+ }
+ }
+ // remove selection, delete, restore selection
+ this.deselect();
+ this.selectItem(stencil);
+ this.onDelete();
+ dojo.forEach(sids, function(id){
+ this.selectItem(id);
+ }, this);
+ }else{
+ // there is not a selection. select it, delete it
+ this.selectItem(stencil);
+ // now delete selection
+ this.onDelete();
+ }
+ },
+
+ removeAll: function(){
+ // summary:
+ // Deletes all Stencils on the canvas.
+
+ this.selectAll();
+ this._isBusy = true;
+ this.onDelete();
+ this.stencils = {};
+ this._isBusy = false;
+ },
+
+ setSelectionGroup: function(){
+ // summary:
+ // Internal. Creates a new selection group
+ // used to hold selected stencils.
+ //
+ this.withSelected(function(m){
+ this.onDeselect(m, true);
+ });
+
+ if(this.group){
+ surface.remove(this.group);
+ this.group.removeShape();
+ }
+ this.group = surface.createGroup();
+ this.group.setTransform({dx:0, dy: 0});
+
+ this.withSelected(function(m){
+ this.group.add(m.container);
+ m.select();
+ });
+ },
+
+ setConstraint: function(){
+ // summary:
+ // Internal. Gets all selected stencils' coordinates
+ // and determines how far left and up the selection
+ // can go without going below zero
+ //
+ var t = Infinity, l = Infinity;
+ this.withSelected(function(m){
+ var o = m.getBounds();
+ t = Math.min(o.y1, t);
+ l = Math.min(o.x1, l);
+ });
+ this.constrain = {l:-l, t:-t};
+ },
+
+
+
+ onDeselect: function(stencil, keepObject){
+ // summary:
+ // Event fired on deselection of a stencil
+ //
+ if(!keepObject){
+ delete this.selectedStencils[stencil.id];
+ }
+ //console.log('onDeselect, keep:', keepObject, "stencil:", stencil.type)
+
+ this.anchors.remove(stencil);
+
+ surface.add(stencil.container);
+ stencil.selected && stencil.deselect();
+ stencil.applyTransform(this.group.getTransform());
+ },
+
+ deselectItem: function(/*Object*/stencil){
+ // summary:
+ // Deselect passed stencil
+ //
+ // note: just keeping with standardized methods
+ this.onDeselect(stencil);
+ },
+
+ deselect: function(){ // all stencils
+ // summary:
+ // Deselect all stencils
+ //
+ this.withSelected(function(m){
+ this.onDeselect(m);
+ });
+ this._dragBegun = false;
+ this._wasDragged = false;
+ },
+
+ onSelect: function(/*Object*/stencil){
+ // summary:
+ // Event fired on selection of a stencil
+ //
+ //console.log("stencil.onSelect", stencil);
+ if(!stencil){
+ console.error("null stencil is not selected:", this.stencils)
+ }
+ if(this.selectedStencils[stencil.id]){ return; }
+ this.selectedStencils[stencil.id] = stencil;
+ this.group.add(stencil.container);
+ stencil.select();
+ if(this.hasSelected()==1){
+ this.anchors.add(stencil, this.group);
+ }
+ },
+
+ selectAll: function(){
+ // summary:
+ // Selects all items
+ this._isBusy = true;
+ for(var m in this.stencils){
+ //if(!this.stencils[m].selected){
+ this.selectItem(m);
+ //}
+ }
+ this._isBusy = false;
+ },
+
+ selectItem: function(/*String|Object*/ idOrItem){
+ // summary:
+ // Method used to select a stencil.
+ //
+ var id = typeof(idOrItem)=="string" ? idOrItem : idOrItem.id;
+ var stencil = this.stencils[id];
+ this.setSelectionGroup();
+ this.onSelect(stencil);
+ this.group.moveToFront();
+ this.setConstraint();
+ },
+
+ onLabelDoubleClick: function(/*EventObject*/obj){
+ // summary:
+ // Event to connect a textbox to
+ // for label edits
+ console.info("mgr.onLabelDoubleClick:", obj);
+ if(this.selectedStencils[obj.id]){
+ this.deselect();
+ }
+ },
+
+ onStencilDoubleClick: function(/*EventObject*/obj){
+ // summary:
+ // Event fired on the double-click of a stencil
+ //
+ console.info("mgr.onStencilDoubleClick:", obj);
+ if(this.selectedStencils[obj.id]){
+ if(this.selectedStencils[obj.id].edit){
+ console.info("Mgr Stencil Edit -> ", this.selectedStencils[obj.id]);
+ var m = this.selectedStencils[obj.id];
+ // deselect must happen first to set the transform
+ // then edit knows where to set the text box
+ m.editMode = true;
+ this.deselect();
+ m.edit();
+ }
+ }
+
+ },
+
+ onAnchorUp: function(){
+ // summary:
+ // Event fire on mouseup off of an anchor point
+ this.setConstraint();
+ },
+
+ onStencilDown: function(/*EventObject*/obj, evt){
+ // summary:
+ // Event fired on mousedown on a stencil
+ //
+ console.info(" >>> onStencilDown:", obj.id, this.keys.meta);
+ if(!this.stencils[obj.id]){ return; }
+ this.setRecentStencil(this.stencils[obj.id]);
+ this._isBusy = true;
+
+
+ if(this.selectedStencils[obj.id] && this.keys.meta){
+ if(dojo.isMac && this.keys.cmmd){
+ // block context menu
+
+ }
+ console.log(" shift remove");
+ this.onDeselect(this.selectedStencils[obj.id]);
+ if(this.hasSelected()==1){
+ this.withSelected(function(m){
+ this.anchors.add(m, this.group);
+ });
+ }
+ this.group.moveToFront();
+ this.setConstraint();
+ return;
+
+ }else if(this.selectedStencils[obj.id]){
+ console.log(" clicked on selected");
+ // clicking on same selected item(s)
+ // RESET OFFSETS
+ var mx = this.group.getTransform();
+ this._offx = obj.x - mx.dx;
+ this._offy = obj.y - mx.dy;
+ return;
+
+ }else if(!this.keys.meta){
+
+ console.log(" deselect all");
+ this.deselect();
+
+ }else{
+ // meta-key add
+ //console.log("reset sel and add stencil")
+ }
+ console.log(" add stencil to selection");
+ // add a stencil
+ this.selectItem(obj.id);
+
+ mx = this.group.getTransform();
+ this._offx = obj.x - mx.dx;
+ this._offy = obj.y - mx.dx;
+
+ this.orgx = obj.x;
+ this.orgy = obj.y;
+
+ this._isBusy = false;
+
+ // TODO:
+ // dojo.style(surfaceNode, "cursor", "pointer");
+
+ // TODO:
+ this.undo.add({
+ before:function(){
+
+ },
+ after: function(){
+
+ }
+ });
+ },
+
+ onLabelDown: function(/*EventObject*/obj, evt){
+ // summary:
+ // Event fired on mousedown of a stencil's label
+ // Because it's an annotation the id will be the
+ // master stencil.
+ //console.info("===============>>>Label click: ",obj, " evt: ",evt);
+ this.onStencilDown(obj,evt);
+ },
+
+ onStencilUp: function(/*EventObject*/obj){
+ // summary:
+ // Event fired on mouseup off of a stencil
+ //
+ },
+
+ onLabelUp: function(/*EventObject*/obj){
+ this.onStencilUp(obj);
+ },
+
+ onStencilDrag: function(/*EventObject*/obj){
+ // summary:
+ // Event fired on every mousemove of a stencil drag
+ //
+ if(!this._dragBegun){
+ // bug, in FF anyway - first mouse move shows x=0
+ // the 'else' fixes it
+ this.onBeginDrag(obj);
+ this._dragBegun = true;
+ }else{
+ this.saveThrottledState();
+
+ var x = obj.x - obj.last.x,
+ y = obj.y - obj.last.y,
+ c = this.constrain,
+ mz = this.defaults.anchors.marginZero;
+
+
+ x = obj.x - this._offx;
+ y = obj.y - this._offy;
+
+ if(x < c.l + mz){
+ x = c.l + mz;
+ }
+ if(y < c.t + mz){
+ y = c.t + mz;
+ }
+
+ this.group.setTransform({
+ dx: x,
+ dy: y
+ });
+
+
+ }
+ },
+
+ onLabelDrag: function(/*EventObject*/obj){
+ this.onStencilDrag(obj);
+ },
+
+ onDragEnd: function(/*EventObject*/obj){
+ // summary:
+ // Event fired at the end of a stencil drag
+ //
+ this._dragBegun = false;
+ },
+ onBeginDrag: function(/*EventObject*/obj){
+ // summary:
+ // Event fired at the beginning of a stencil drag
+ //
+ this._wasDragged = true;
+ },
+
+ onDown: function(/*EventObject*/obj){
+ // summary:
+ // Event fired on mousedown on the canvas
+ //
+ this.deselect();
+ },
+
+
+ onStencilOver: function(obj){
+ // summary:
+ // This changes the cursor when hovering over
+ // a selectable stencil.
+ //console.log("OVER")
+ dojo.style(obj.id, "cursor", "move");
+ },
+
+ onStencilOut: function(obj){
+ // summary:
+ // This restores the cursor.
+ //console.log("OUT")
+ dojo.style(obj.id, "cursor", "crosshair");
+ },
+
+ exporter: function(){
+ // summary:
+ // Collects all Stencil data and returns an
+ // Array of objects.
+ var items = [];
+ for(var m in this.stencils){
+ this.stencils[m].enabled && items.push(this.stencils[m].exporter());
+ }
+ return items; // Array
+ },
+
+ listStencils: function(){
+ return this.stencils;
+ },
+
+ toSelected: function(/*String*/func){
+ // summary:
+ // Convenience function calls function *within*
+ // all selected stencils
+ var args = Array.prototype.slice.call(arguments).splice(1);
+ for(var m in this.selectedStencils){
+ var item = this.selectedStencils[m];
+ item[func].apply(item, args);
+ }
+ },
+
+ withSelected: function(/*Function*/func){
+ // summary:
+ // Convenience function calls function on
+ // all selected stencils
+ var f = dojo.hitch(this, func);
+ for(var m in this.selectedStencils){
+ f(this.selectedStencils[m]);
+ }
+ },
+
+ withUnselected: function(/*Function*/func){
+ // summary:
+ // Convenience function calls function on
+ // all stencils that are not selected
+ var f = dojo.hitch(this, func);
+ for(var m in this.stencils){
+ !this.stencils[m].selected && f(this.stencils[m]);
+ }
+ },
+
+ withStencils: function(/*Function*/func){
+ // summary:
+ // Convenience function calls function on
+ // all stencils
+ var f = dojo.hitch(this, func);
+ for(var m in this.stencils){
+ f(this.stencils[m]);
+ }
+ },
+
+ hasSelected: function(){
+ // summary:
+ // Returns number of selected (generally used
+ // as truthy or falsey)
+ //
+ // FIXME: should be areSelected?
+ var ln = 0;
+ for(var m in this.selectedStencils){ ln++; }
+ return ln; // Number
+ },
+
+ isSelected: function(/*Object*/stencil){
+ // summary:
+ // Returns if passed stencil is selected or not
+ // based on internal collection, not on stencil
+ // boolean
+ return !!this.selectedStencils[stencil.id]; // Boolean
+ }
+ }
+
+ );
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/drawing/manager/StencilUI.js b/js/dojo-1.6/dojox/drawing/manager/StencilUI.js
new file mode 100644
index 0000000..840f67e
--- /dev/null
+++ b/js/dojo-1.6/dojox/drawing/manager/StencilUI.js
@@ -0,0 +1,76 @@
+/*
+ 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
+*/
+
+
+if(!dojo._hasResource["dojox.drawing.manager.StencilUI"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.drawing.manager.StencilUI"] = true;
+dojo.provide("dojox.drawing.manager.StencilUI");
+
+(function(){
+ var surface, surfaceNode;
+ dojox.drawing.manager.StencilUI = dojox.drawing.util.oo.declare(
+ // summary:
+ // Used for handling Stencils as UI components.
+ // description:
+ // Replaces manager.Stencil. Handles basic UI mouse
+ // events like onmouseover. Does not handle selections
+ // or support delete, etc.
+ //
+ function(options){
+ //
+ // TODO: mixin props
+ //
+ surface = options.surface;
+ this.canvas = options.canvas;
+
+ this.defaults = dojox.drawing.defaults.copy();
+ this.mouse = options.mouse;
+ this.keys = options.keys;
+ this._mouseHandle = this.mouse.register(this);
+ this.stencils = {};
+ },
+ {
+ register: function(/*Object*/stencil){
+ this.stencils[stencil.id] = stencil;
+ return stencil;
+ },
+ onUiDown: function(/*EventObject*/obj){
+ // summary:
+ // Event fired on mousedown on a stencil
+ //
+ if(!this._isStencil(obj)){ return; }
+ this.stencils[obj.id].onDown(obj);
+ },
+ onUiUp: function(/*EventObject*/obj){
+ // summary:
+ // Event fired on mousedown on a stencil
+ //
+ if(!this._isStencil(obj)){ return; }
+ this.stencils[obj.id].onUp(obj);
+ },
+ onOver: function(/*EventObject*/obj){
+ // summary:
+ // Event fired on mousedown on a stencil
+ //
+ if(!this._isStencil(obj)){ return; }
+ this.stencils[obj.id].onOver(obj);
+ },
+ onOut: function(/*EventObject*/obj){
+ // summary:
+ // Event fired on mousedown on a stencil
+ //
+ if(!this._isStencil(obj)){ return; }
+ this.stencils[obj.id].onOut(obj);
+ },
+ _isStencil: function(/*EventObject*/obj){
+ return !!obj.id && !!this.stencils[obj.id] && this.stencils[obj.id].type == "drawing.library.UI.Button";
+ }
+ }
+ );
+
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/drawing/manager/StencilUI.xd.js b/js/dojo-1.6/dojox/drawing/manager/StencilUI.xd.js
new file mode 100644
index 0000000..446963e
--- /dev/null
+++ b/js/dojo-1.6/dojox/drawing/manager/StencilUI.xd.js
@@ -0,0 +1,80 @@
+/*
+ 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.drawing.manager.StencilUI"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.drawing.manager.StencilUI"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.drawing.manager.StencilUI"] = true;
+dojo.provide("dojox.drawing.manager.StencilUI");
+
+(function(){
+ var surface, surfaceNode;
+ dojox.drawing.manager.StencilUI = dojox.drawing.util.oo.declare(
+ // summary:
+ // Used for handling Stencils as UI components.
+ // description:
+ // Replaces manager.Stencil. Handles basic UI mouse
+ // events like onmouseover. Does not handle selections
+ // or support delete, etc.
+ //
+ function(options){
+ //
+ // TODO: mixin props
+ //
+ surface = options.surface;
+ this.canvas = options.canvas;
+
+ this.defaults = dojox.drawing.defaults.copy();
+ this.mouse = options.mouse;
+ this.keys = options.keys;
+ this._mouseHandle = this.mouse.register(this);
+ this.stencils = {};
+ },
+ {
+ register: function(/*Object*/stencil){
+ this.stencils[stencil.id] = stencil;
+ return stencil;
+ },
+ onUiDown: function(/*EventObject*/obj){
+ // summary:
+ // Event fired on mousedown on a stencil
+ //
+ if(!this._isStencil(obj)){ return; }
+ this.stencils[obj.id].onDown(obj);
+ },
+ onUiUp: function(/*EventObject*/obj){
+ // summary:
+ // Event fired on mousedown on a stencil
+ //
+ if(!this._isStencil(obj)){ return; }
+ this.stencils[obj.id].onUp(obj);
+ },
+ onOver: function(/*EventObject*/obj){
+ // summary:
+ // Event fired on mousedown on a stencil
+ //
+ if(!this._isStencil(obj)){ return; }
+ this.stencils[obj.id].onOver(obj);
+ },
+ onOut: function(/*EventObject*/obj){
+ // summary:
+ // Event fired on mousedown on a stencil
+ //
+ if(!this._isStencil(obj)){ return; }
+ this.stencils[obj.id].onOut(obj);
+ },
+ _isStencil: function(/*EventObject*/obj){
+ return !!obj.id && !!this.stencils[obj.id] && this.stencils[obj.id].type == "drawing.library.UI.Button";
+ }
+ }
+ );
+
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/drawing/manager/Undo.js b/js/dojo-1.6/dojox/drawing/manager/Undo.js
new file mode 100644
index 0000000..f09b93d
--- /dev/null
+++ b/js/dojo-1.6/dojox/drawing/manager/Undo.js
@@ -0,0 +1,68 @@
+/*
+ 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
+*/
+
+
+if(!dojo._hasResource["dojox.drawing.manager.Undo"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.drawing.manager.Undo"] = true;
+dojo.provide("dojox.drawing.manager.Undo");
+
+dojox.drawing.manager.Undo = dojox.drawing.util.oo.declare(
+ // summary
+ // Handles the Undo in drawing.
+ // NOTE: Only partially implemented!!! There is very
+ // little actual undo functionality!
+ //
+ function(options){
+ this.keys = options.keys;
+ this.undostack = [];
+ this.redostack = [];
+ dojo.connect(this.keys, "onKeyDown", this, "onKeyDown");
+ },
+ {
+ onKeyDown: function(evt){
+ if(!evt.cmmd){ return; }
+
+ if(evt.keyCode==90 && !evt.shift){
+ this.undo();
+ }else if((evt.keyCode == 90 && evt.shift) || evt.keyCode==89){
+ this.redo();
+ }
+
+ },
+ add: function(stack){
+ //console.log("undo add", stack)
+ stack.args = dojo.mixin({}, stack.args);
+ this.undostack.push(stack);
+ },
+ apply: function(scope, method, args){
+ dojo.hitch(scope, method)(args);
+ },
+ undo: function(){
+
+ var o = this.undostack.pop();
+ console.log("undo!", o);
+ if(!o){ return; }
+
+ o.before();
+
+ this.redostack.push(o);
+ },
+ redo: function(){
+ console.log("redo!");
+ var o = this.redostack.pop();
+ if(!o){ return; }
+ if(o.after){
+ o.after();
+ }else{
+ o.before(); ///??????
+ }
+
+ this.undostack.push(o);
+ }
+ }
+);
+
+}
diff --git a/js/dojo-1.6/dojox/drawing/manager/Undo.xd.js b/js/dojo-1.6/dojox/drawing/manager/Undo.xd.js
new file mode 100644
index 0000000..8b65c35
--- /dev/null
+++ b/js/dojo-1.6/dojox/drawing/manager/Undo.xd.js
@@ -0,0 +1,72 @@
+/*
+ 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.drawing.manager.Undo"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.drawing.manager.Undo"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.drawing.manager.Undo"] = true;
+dojo.provide("dojox.drawing.manager.Undo");
+
+dojox.drawing.manager.Undo = dojox.drawing.util.oo.declare(
+ // summary
+ // Handles the Undo in drawing.
+ // NOTE: Only partially implemented!!! There is very
+ // little actual undo functionality!
+ //
+ function(options){
+ this.keys = options.keys;
+ this.undostack = [];
+ this.redostack = [];
+ dojo.connect(this.keys, "onKeyDown", this, "onKeyDown");
+ },
+ {
+ onKeyDown: function(evt){
+ if(!evt.cmmd){ return; }
+
+ if(evt.keyCode==90 && !evt.shift){
+ this.undo();
+ }else if((evt.keyCode == 90 && evt.shift) || evt.keyCode==89){
+ this.redo();
+ }
+
+ },
+ add: function(stack){
+ //console.log("undo add", stack)
+ stack.args = dojo.mixin({}, stack.args);
+ this.undostack.push(stack);
+ },
+ apply: function(scope, method, args){
+ dojo.hitch(scope, method)(args);
+ },
+ undo: function(){
+
+ var o = this.undostack.pop();
+ console.log("undo!", o);
+ if(!o){ return; }
+
+ o.before();
+
+ this.redostack.push(o);
+ },
+ redo: function(){
+ console.log("redo!");
+ var o = this.redostack.pop();
+ if(!o){ return; }
+ if(o.after){
+ o.after();
+ }else{
+ o.before(); ///??????
+ }
+
+ this.undostack.push(o);
+ }
+ }
+);
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/drawing/manager/_registry.js b/js/dojo-1.6/dojox/drawing/manager/_registry.js
new file mode 100644
index 0000000..0dc402d
--- /dev/null
+++ b/js/dojo-1.6/dojox/drawing/manager/_registry.js
@@ -0,0 +1,42 @@
+/*
+ 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
+*/
+
+
+if(!dojo._hasResource["dojox.drawing.manager._registry"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.drawing.manager._registry"] = true;
+dojo.provide("dojox.drawing.manager._registry");
+
+(function(){
+
+ var _registered = {
+ tool:{},
+ stencil:{},
+ drawing:{},
+ plugin:{},
+ button:{}
+ };
+
+ dojox.drawing.register = function(item, type){
+ if(type=="drawing"){
+ _registered.drawing[item.id] = item;
+ }else if(type=="tool"){
+ _registered.tool[item.name] = item;
+ }else if(type=="stencil"){
+ _registered.stencil[item.name] = item;
+ }else if(type=="plugin"){
+ _registered.plugin[item.name] = item;
+ }else if(type=="button"){
+ _registered.button[item.toolType] = item;
+ }
+ };
+
+ dojox.drawing.getRegistered = function(type, id){
+ return id ? _registered[type][id] : _registered[type];
+ }
+
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/drawing/manager/_registry.xd.js b/js/dojo-1.6/dojox/drawing/manager/_registry.xd.js
new file mode 100644
index 0000000..5c8ca92
--- /dev/null
+++ b/js/dojo-1.6/dojox/drawing/manager/_registry.xd.js
@@ -0,0 +1,46 @@
+/*
+ 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.drawing.manager._registry"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.drawing.manager._registry"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.drawing.manager._registry"] = true;
+dojo.provide("dojox.drawing.manager._registry");
+
+(function(){
+
+ var _registered = {
+ tool:{},
+ stencil:{},
+ drawing:{},
+ plugin:{},
+ button:{}
+ };
+
+ dojox.drawing.register = function(item, type){
+ if(type=="drawing"){
+ _registered.drawing[item.id] = item;
+ }else if(type=="tool"){
+ _registered.tool[item.name] = item;
+ }else if(type=="stencil"){
+ _registered.stencil[item.name] = item;
+ }else if(type=="plugin"){
+ _registered.plugin[item.name] = item;
+ }else if(type=="button"){
+ _registered.button[item.toolType] = item;
+ }
+ };
+
+ dojox.drawing.getRegistered = function(type, id){
+ return id ? _registered[type][id] : _registered[type];
+ }
+
+})();
+
+}
+
+}};});
diff --git a/js/dojo-1.6/dojox/drawing/manager/keys.js b/js/dojo-1.6/dojox/drawing/manager/keys.js
new file mode 100644
index 0000000..4cbdf54
--- /dev/null
+++ b/js/dojo-1.6/dojox/drawing/manager/keys.js
@@ -0,0 +1,275 @@
+/*
+ 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
+*/
+
+
+if(!dojo._hasResource["dojox.drawing.manager.keys"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.drawing.manager.keys"] = true;
+dojo.provide("dojox.drawing.manager.keys");
+
+(function(){
+
+ // Ref: isEdit allows events to happen in Drawing, like TextBlocks
+ var isEdit = false;
+
+ // Ref: enabled = false allows inputs outside of drawing to function
+ var enabled = true;
+
+ var alphabet = "abcdefghijklmnopqrstuvwxyz";
+
+ dojox.drawing.manager.keys = {
+ // summary:
+ // A singleton, master object that detects
+ // keyboard keys and events
+ // Connect to it like:
+ // dojo.connect(this.keys, "onEnter", ....);
+ //
+ // arrowIncrement:Number
+ // The amount, in pixels, a selected Stencil will
+ // move on an arrow key event
+ arrowIncrement:1,
+ //
+ // arrowShiftIncrement: Number
+ // The amount, in pixels, a selected Stencil will
+ // move on an arrow key + SHIFT event
+ arrowShiftIncrement:10,
+ //
+ // shift: [readonly] Boolean
+ // Indicates whether the Shift key is currently pressed
+ shift:false,
+ //
+ // ctrl: [readonly] Boolean
+ // Indicates whether the Control key is currently pressed
+ ctrl:false,
+ //
+ // alt: [readonly] Boolean
+ // Indicates whether the Alt or Option key is currently pressed
+ alt:false,
+ //
+ // cmmd: [readonly] Boolean
+ // Indicates whether the Apple Command key is currently pressed
+ cmmd:false, // apple key
+ //
+ // meta: [readonly] Boolean
+ // Indicates whether any 'meta' key is currently pressed:
+ // shift || ctrl || cmmd || alt
+ meta:false, // any meta key
+
+ onDelete: function(/* Event */evt){
+ // summary:
+ // Event fires when Delete key is released
+ },
+ onEsc: function(/* Event */evt){
+ // summary:
+ // Event fires when ESC key is released
+ },
+ onEnter: function(/* Event */evt){
+ // summary:
+ // Event fires when Enter key is released
+ },
+ onArrow: function(/* Event */evt){
+ // summary:
+ // Event fires when an Arrow key is released
+ // You will have to further check if evt.keyCode
+ // is 37,38,39, or 40
+ },
+ onKeyDown: function(/* Event */evt){
+ // summary:
+ // Event fires when any key is pressed
+ },
+ onKeyUp: function(/* Event */evt){
+ // summary:
+ // Event fires when any key is released
+ },
+
+ listeners:[],
+ register: function(options){
+ // summary:
+ // Register an object and callback to be notified
+ // of events.
+ // NOTE: Not really used in code, but should work.
+ // See manager.mouse for similar usage
+ //
+ var _handle = dojox.drawing.util.uid("listener");
+ this.listeners.push({
+ handle:_handle,
+ scope: options.scope || window,
+ callback:options.callback,
+ keyCode:options.keyCode
+ });
+ },
+
+ _getLetter: function(evt){
+ if(!evt.meta && evt.keyCode>=65 && evt.keyCode<=90){
+ return alphabet.charAt(evt.keyCode-65);
+ }
+ return null;
+ },
+
+ _mixin: function(evt){
+ // summary:
+ // Internal. Mixes in key events.
+ evt.meta = this.meta;
+ evt.shift = this.shift;
+ evt.alt = this.alt;
+ evt.cmmd = this.cmmd;
+ evt.letter = this._getLetter(evt);
+ return evt;
+ },
+
+ editMode: function(_isedit){
+ // summary:
+ // Relinquishes control of events to another portion
+ // of Drawing; namely the TextBlock.
+ isEdit = _isedit;
+ },
+
+ enable: function(_enabled){
+ // summary:
+ // Enables or disables key events, to relinquish
+ // control to something outside of Drawing; input
+ // fields for example.
+ // You may need to call this directly if you are
+ // using textareas or contenteditables.
+ // NOTE: See scanForFields
+ enabled = _enabled;
+ },
+
+ scanForFields: function(){
+ // summary:
+ // Scans the document for inputs
+ // and calls this automatically. However you may need
+ // to call this if you create inputs after the fact.
+ //
+ if(this._fieldCons){
+ dojo.forEach(this._fieldCons, dojo.disconnect, dojo);
+ }
+ this._fieldCons = [];
+ dojo.query("input").forEach(function(n){
+ var a = dojo.connect(n, "focus", this, function(evt){
+ this.enable(false);
+ });
+ var b = dojo.connect(n, "blur", this, function(evt){
+ this.enable(true);
+ });
+ this._fieldCons.push(a);
+ this._fieldCons.push(b);
+ }, this);
+
+ },
+
+ init: function(){
+ // summary:
+ // Initialize the keys object
+ //
+ // a little extra time is needed in some browsers
+ setTimeout(dojo.hitch(this, "scanForFields"), 500);
+
+ dojo.connect(document, "blur", this, function(evt){
+ // when command tabbing to another application, the key "sticks"
+ // this clears any key used for such activity
+ this.meta = this.shift = this.ctrl = this.cmmd = this.alt = false;
+ });
+
+ dojo.connect(document, "keydown", this, function(evt){
+ if(!enabled){ return; }
+ if(evt.keyCode==16){
+ this.shift = true;
+ }
+ if(evt.keyCode==17){
+ this.ctrl = true;
+ }
+ if(evt.keyCode==18){
+ this.alt = true;
+ }
+ if(evt.keyCode==224){
+ this.cmmd = true;
+ }
+
+ this.meta = this.shift || this.ctrl || this.cmmd || this.alt;
+
+ if(!isEdit){
+ this.onKeyDown(this._mixin(evt));
+ if(evt.keyCode==8 || evt.keyCode==46){
+ dojo.stopEvent(evt);
+ }
+ }
+ });
+ dojo.connect(document, "keyup", this, function(evt){
+ if(!enabled){ return; }
+ //console.log("KEY UP:", evt.keyCode);
+ var _stop = false;
+ if(evt.keyCode==16){
+ this.shift = false;
+ }
+ if(evt.keyCode==17){
+ this.ctrl = false;
+ }
+ if(evt.keyCode==18){
+ this.alt = false;
+ }
+ if(evt.keyCode==224){
+ this.cmmd = false;
+ }
+
+ this.meta = this.shift || this.ctrl || this.cmmd || this.alt;
+
+ !isEdit && this.onKeyUp(this._mixin(evt));
+
+ if(evt.keyCode==13){
+ console.warn("KEY ENTER");
+ this.onEnter(evt);
+ _stop = true;
+ }
+ if(evt.keyCode==27){
+ this.onEsc(evt);
+ _stop = true;
+ }
+ if(evt.keyCode==8 || evt.keyCode==46){
+ this.onDelete(evt);
+ _stop = true;
+ }
+
+ if(_stop && !isEdit){
+ dojo.stopEvent(evt);
+ }
+ });
+
+ dojo.connect(document, "keypress", this, function(evt){
+ if(!enabled){ return; }
+ var inc = this.shift ? this.arrowIncrement*this.arrowShiftIncrement : this.arrowIncrement;
+
+ var x =0, y =0;
+ if(evt.keyCode==32 && !isEdit){ //space
+ dojo.stopEvent(evt);
+ }
+ if(evt.keyCode==37){ //left
+ x = -inc;
+ }
+ if(evt.keyCode==38){ //up
+ y = -inc;
+ }
+ if(evt.keyCode==39){ //right
+ x = inc;
+ }
+ if(evt.keyCode==40){ //down
+ y = inc;
+ }
+ if(x || y){
+ evt.x = x;
+ evt.y = y;
+ evt.shift = this.shift;
+ if(!isEdit){
+ this.onArrow(evt);
+ dojo.stopEvent(evt);
+ }
+ }
+ });
+ }
+ };
+ dojo.addOnLoad(dojox.drawing.manager.keys, "init");
+})();
+
+}
diff --git a/js/dojo-1.6/dojox/drawing/manager/keys.xd.js b/js/dojo-1.6/dojox/drawing/manager/keys.xd.js
new file mode 100644
index 0000000..829c6de
--- /dev/null
+++ b/js/dojo-1.6/dojox/drawing/manager/keys.xd.js
@@ -0,0 +1,279 @@
+/*
+ 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.drawing.manager.keys"]],
+defineResource: function(dojo, dijit, dojox){if(!dojo._hasResource["dojox.drawing.manager.keys"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.drawing.manager.keys"] = true;
+dojo.provide("dojox.drawing.manager.keys");
+
+(function(){
+
+ // Ref: isEdit allows events to happen in Drawing, like TextBlocks
+ var isEdit = false;
+
+ // Ref: enabled = false allows inputs outside of drawing to function
+ var enabled = true;
+
+ var alphabet = "abcdefghijklmnopqrstuvwxyz";
+
+ dojox.drawing.manager.keys = {
+ // summary:
+ // A singleton, master object that detects
+ // keyboard keys and events
+ // Connect to it like:
+ // dojo.connect(this.keys, "onEnter", ....);
+ //
+ // arrowIncrement:Number
+ // The amount, in pixels, a selected Stencil will
+ // move on an arrow key event
+ arrowIncrement:1,
+ //
+ // arrowShiftIncrement: Number
+ // The amount, in pixels, a selected Stencil will
+ // move on an arrow key + SHIFT event
+ arrowShiftIncrement:10,
+ //
+ // shift: [readonly] Boolean
+ // Indicates whether the Shift key is currently pressed
+ shift:false,
+ //
+ // ctrl: [readonly] Boolean
+ // Indicates whether the Control key is currently pressed
+ ctrl:false,
+ //
+ // alt: [readonly] Boolean
+ // Indicates whether the Alt or Option key is currently pressed
+ alt:false,
+ //
+ // cmmd: [readonly] Boolean
+ // Indicates whether the Apple Command key is currently pressed
+ cmmd:false, // apple key
+ //
+ // meta: [readonly] Boolean
+ // Indicates whether any 'meta' key is currently pressed:
+ // shift || ctrl || cmmd || alt
+ meta:false, // any meta key
+
+ onDelete: function(/* Event */evt){
+ // summary:
+ // Event fires when Delete key is released
+ },
+ onEsc: function(/* Event */evt){
+ // summary:
+ // Event fires when ESC key is released
+ },
+ onEnter: function(/* Event */evt){
+ // summary:
+ // Event fires when Enter key is released
+ },
+ onArrow: function(/* Event */evt){
+ // summary:
+ // Event fires when an Arrow key is released
+ // You will have to further check if evt.keyCode
+ // is 37,38,39, or 40
+ },
+ onKeyDown: function(/* Event */evt){
+ // summary:
+ // Event fires when any key is pressed
+ },
+ onKeyUp: function(/* Event */evt){
+ // summary:
+ // Event fires when any key is released
+ },
+
+ listeners:[],
+ register: function(options){
+ // summary:
+ // Register an object and callback to be notified
+ // of events.
+ // NOTE: Not really used in code, but should work.
+ // See manager.mouse for similar usage
+ //
+ var _handle = dojox.drawing.util.uid("listener");
+ this.listeners.push({
+ handle:_handle,
+ scope: options.scope || window,
+ callback:options.callback,
+ keyCode:options.keyCode
+ });
+ },
+
+ _getLetter: function(evt){
+ if(!evt.meta && evt.keyCode>=65 && evt.keyCode<=90){
+ return alphabet.charAt(evt.keyCode-65);
+ }
+ return null;
+ },
+
+ _mixin: function(evt){
+ // summary:
+ // Internal. Mixes in key events.
+ evt.meta = this.meta;
+ evt.shift = this.shift;
+ evt.alt = this.alt;
+ evt.cmmd = this.cmmd;
+ evt.letter = this._getLetter(evt);
+ return evt;
+ },
+
+ editMode: function(_isedit){
+ // summary:
+ // Relinquishes control of events to another portion
+ // of Drawing; namely the TextBlock.
+ isEdit = _isedit;
+ },
+
+ enable: function(_enabled){
+ // summary:
+ // Enables or disables key events, to relinquish
+ // control to something outside of Drawing; input
+ // fields for example.
+ // You may need to call this directly if you are
+ // using textareas or contenteditables.
+ // NOTE: See scanForFields
+ enabled = _enabled;
+ },
+
+ scanForFields: function(){
+ // summary:
+ // Scans the document for inputs
+ // and calls this automatically. However you may need
+ // to call this if you create inputs after the fact.
+ //
+ if(this._fieldCons){
+ dojo.forEach(this._fieldCons, dojo.disconnect, dojo);
+ }
+ this._fieldCons = [];
+ dojo.query("input").forEach(function(n){
+ var a = dojo.connect(n, "focus", this, function(evt){
+ this.enable(false);
+ });
+ var b = dojo.connect(n, "blur", this, function(evt){
+ this.enable(true);
+ });
+ this._fieldCons.push(a);
+ this._fieldCons.push(b);
+ }, this);
+
+ },
+
+ init: function(){
+ // summary:
+ // Initialize the keys object
+ //
+ // a little extra time is needed in some browsers
+ setTimeout(dojo.hitch(this, "scanForFields"), 500);
+
+ dojo.connect(document, "blur", this, function(evt){
+ // when command tabbing to another application, the key "sticks"
+ // this clears any key used for such activity
+ this.meta = this.shift = this.ctrl = this.cmmd = this.alt = false;
+ });
+
+ dojo.connect(document, "keydown", this, function(evt){
+ if(!enabled){ return; }
+ if(evt.keyCode==16){
+ this.shift = true;
+ }
+ if(evt.keyCode==17){
+ this.ctrl = true;
+ }
+ if(evt.keyCode==18){
+ this.alt = true;
+ }
+ if(evt.keyCode==224){
+ this.cmmd = true;
+ }
+
+ this.meta = this.shift || this.ctrl || this.cmmd || this.alt;
+
+ if(!isEdit){
+ this.onKeyDown(this._mixin(evt));
+ if(evt.keyCode==8 || evt.keyCode==46){
+ dojo.stopEvent(evt);
+ }
+ }
+ });
+ dojo.connect(document, "keyup", this, function(evt){
+ if(!enabled){ return; }
+ //console.log("KEY UP:", evt.keyCode);
+ var _stop = false;
+ if(evt.keyCode==16){
+ this.shift = false;
+ }
+ if(evt.keyCode==17){
+ this.ctrl = false;
+ }
+ if(evt.keyCode==18){
+ this.alt = false;
+ }
+ if(evt.keyCode==224){
+ this.cmmd = false;
+ }
+
+ this.meta = this.shift || this.ctrl || this.cmmd || this.alt;
+
+ !isEdit && this.onKeyUp(this._mixin(evt));
+
+ if(evt.keyCode==13){
+ console.warn("KEY ENTER");
+ this.onEnter(evt);
+ _stop = true;
+ }
+ if(evt.keyCode==27){
+ this.onEsc(evt);
+ _stop = true;
+ }
+ if(evt.keyCode==8 || evt.keyCode==46){
+ this.onDelete(evt);
+ _stop = true;
+ }
+
+ if(_stop && !isEdit){
+ dojo.stopEvent(evt);
+ }
+ });
+
+ dojo.connect(document, "keypress", this, function(evt){
+ if(!enabled){ return; }
+ var inc = this.shift ? this.arrowIncrement*this.arrowShiftIncrement : this.arrowIncrement;
+
+ var x =0, y =0;
+ if(evt.keyCode==32 && !isEdit){ //space
+ dojo.stopEvent(evt);
+ }
+ if(evt.keyCode==37){ //left
+ x = -inc;
+ }
+ if(evt.keyCode==38){ //up
+ y = -inc;
+ }
+ if(evt.keyCode==39){ //right
+ x = inc;
+ }
+ if(evt.keyCode==40){ //down
+ y = inc;
+ }
+ if(x || y){
+ evt.x = x;
+ evt.y = y;
+ evt.shift = this.shift;
+ if(!isEdit){
+ this.onArrow(evt);
+ dojo.stopEvent(evt);
+ }
+ }
+ });
+ }
+ };
+ dojo.addOnLoad(dojox.drawing.manager.keys, "init");
+})();
+
+}
+
+}};});