<@doc hierarchy="GMLDOM"> Aspect for drawing curved lines using quadratic bezier function <copyright>(c) SAP AG 2003-2006. All rights reserved.</copyright> </doc@> Aspect CurvedLine for GmlDrawing; inherit Line; ////////////////////////////////////////////////////////////////////////////////////// // PROPERTIES ////////////////////////////////////////////////////////////////////////////////////// // METHODS override virtual method reroute() if (this.diagram.bufferedReroute(this)) return; var p1=this.srcpin.getCP(this.trgpin); var p2=this.trgpin.getCP(this.srcpin); var dx=p2.x-p1.x, dy=p2.y-p1.y, C=SPLITN(base.@controls); if (C.length==5 && C[0]==(p2.rot*4+p1.rot)) { var cx1=C[1], cy1=C[2], cx2=C[3], cy2=C[4]; } else { var leg1=20*p1.scale, leg2=20*p2.scale; var cx1=(p1.rot==0 ? leg1 : p1.rot==2 ? -leg1 : 0), cy1=(p1.rot==3 ? leg1 : p1.rot==1 ? -leg1 : 0); var cx2=(p2.rot==0 ? leg2 : p2.rot==2 ? -leg2 : 0), cy2=(p2.rot==3 ? leg2 : p2.rot==1 ? -leg2 : 0); this.diagram.silentUpdate(this, '@controls', ''); // Silent update: (see Line.reroute) } var mx=(cx1+cx2+dx)/2, my=(cy1+cy2+dy)/2; // Silent update: (see Line.reroute) this.diagram.silentUpdate(this, '@path', this.path2str('q', cx1, cy1, mx, my, 'q', cx2+dx-mx, cy2+dy-my, dx-mx, dy-my)); this.lineNode.setAttribute ('d', 'M'+p1.x+','+p1.y+base.@path); // calculate label position var x1 = p1.x+cx1; var x2 = p2.x+cx2; var y1 = p1.y+cy1 var y2 = p2.y+cy2; var lx = (x1+x2)/2; var ly = (y1+y2)/2; var la = Math.atan2(y2-y1, x2-x1)*SVG.R2D; if (Math.abs(la) > 90) la += 180; this.labelNode.setAttribute('x', lx); this.labelNode.setAttribute('y', ly-3); this.labelNode.setAttribute('transform', 'rotate('+la+' '+lx+' '+ly+')'); end override virtual method getHandlesData() var path=SPLITN(base.@path); if (path.length != 10) return null; var p1=this.srcpin.getCP(this.trgpin); return { C1: {cx:path[1]+p1.x,cy:path[2]+p1.y}, C2: {cx:path[3]+path[6]+p1.x,cy:path[4]+path[7]+p1.y} } end override virtual method onHandleMove(ptr) switch (ptr.phase) { case #[PTR_START]: ptr.scrollMode = #[PTR_AUTOSCROLL]; ptr.handle = ptr.source.getAttribute('handle'); ptr.wire = SVG.createElement(this.diagram.linesLayer, 'path', {fill:'none', 'stroke':this.base.@strokeColor, 'stroke-dasharray':'4 3', 'pointer-events':'none'}); var path=SPLITN(base.@path); if (path.length != 10) { ptr.cancel=true; break; } ptr.p1 = this.srcpin.getCP(this.trgpin); ptr.p2 = this.trgpin.getCP(this.srcpin); ptr.dx = ptr.p2.x-ptr.p1.x; ptr.dy = ptr.p2.y-ptr.p1.y; ptr.cx1 = path[1]; ptr.cy1 = path[2]; ptr.cx2 = path[3]+path[6]-ptr.dx; ptr.cy2 = path[4]+path[7]-ptr.dy; break; case #[PTR_MOVE]: var p1=ptr.p1, p2=ptr.p2, dx=ptr.dx, dy=ptr.dy; var cx1=ptr.cx1, cy1=ptr.cy1, cx2=ptr.cx2, cy2=ptr.cy2; switch (ptr.handle) { case 'C1': cx1 += ptr.offset.x; cy1 += ptr.offset.y; break; case 'C2': cx2 += ptr.offset.x; cy2 += ptr.offset.y; break; } var mx=(cx1+cx2+dx)/2, my=(cy1+cy2+dy)/2; ptr.path = this.path2str('q', cx1, cy1, mx, my, 'q', cx2+dx-mx, cy2+dy-my, dx-mx, dy-my); ptr.controls = this.path2str(p2.rot*4+p1.rot, cx1, cy1, cx2, cy2); ptr.wire.setAttribute('d', 'M'+p1.x+','+p1.y+ptr.path); this.diagram.moveHandle(ptr.handle, ptr.pos.x, ptr.pos.y); break; case #[PTR_FINISH]: // Silent update: (see Line.reroute) this.diagram.silentUpdate(this, '@path', ptr.path); this.diagram.silentUpdate(this, '@controls', ptr.controls); this.reroute(); SVG.removeElement(ptr.wire); if (!ptr.isOverSource) SVG.setProperty(ptr.source, 'class', 'handleNormal'); break; case #[PTR_CANCEL]: SVG.removeElement(ptr.wire); if (!ptr.isOverSource) SVG.setProperty(ptr.source, 'class', 'handleNormal'); var data=this.getHandlesData(); this.diagram.moveHandle(ptr.handle, data[ptr.handle].cx, data[ptr.handle].cy); break; } end