webui-aria2/js/libs/dojox/drawing/manager/Anchors.js.uncompressed.js
2012-05-01 19:52:07 +08:00

470 lines
12 KiB
JavaScript

//>>built
// wrapped by build app
define("dojox/drawing/manager/Anchors", ["dijit","dojo","dojox"], function(dijit,dojo,dojox){
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();
}
}
);
});