123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475 |
- /*
- Copyright (c) 2004-2012, 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();
- }
- }
- );
- }
|