Avoids Nodes

Hi,
I have othogonal links with AvoidsNodes property set to true. This works fine when the user moves the nodes, but I would also like this feature when the user grabs one of the selection handles of the link and tries to extend or contract the link while it is connected. That is the user should not be allowed to move the link through one of the to or from nodes.
From one of the earlier posts I understand that calling CalculateStroke can solve the problem. Can you please tell me which would be ideal place to make this call?
Thanks,
Rafique

No, what you’ll want to do is override DoResize to make it smarter about where one of those middle resize handles can be dragged.
The default behavior of GoLink.DoResize depends on which resize handle is being dragged, since the ones at GoLink.FirstPickIndex+1 and at GoLink.LastPickIndex-1 are constrained to only go either horizontally or vertically, depending. The rest of the middle resize handles can go anywhere, but as the resize handle is dragged, both adjacent points need to move correspondingly, in order to maintain orthogonality.
Presumably you need to change the DoResize behavior so that both segments adjacent to the point being dragged stay in areas that are GoDocument.IsUnoccupied. Here’s the source code:
public override void DoResize(GoView view, RectangleF origRect, PointF newPoint,
int whichHandle, GoInputState evttype, SizeF min, SizeF max) {
if (this.ResizesRealtime ||
evttype == GoInputState.Finish || evttype == GoInputState.Cancel) {
int midfirst = this.FirstPickIndex+1;
int midlast = this.LastPickIndex-1;
switch (whichHandle) {
case MiddleTop:
// move segment vertically
SetPoint(midfirst, new PointF(GetPoint(midfirst-1).X, newPoint.Y));
SetPoint(midfirst+1, new PointF(GetPoint(midfirst+2).X, newPoint.Y));
break;
case MiddleLeft:
// move segment horizontally
SetPoint(midfirst, new PointF(newPoint.X, GetPoint(midfirst-1).Y));
SetPoint(midfirst+1, new PointF(newPoint.X, GetPoint(midfirst+2).Y));
break;
case MiddleBottom:
// move segment vertically
SetPoint(midlast-1, new PointF(GetPoint(midlast-2).X, newPoint.Y));
SetPoint(midlast, new PointF(GetPoint(midlast+1).X, newPoint.Y));
break;
case MiddleRight:
// move segment horizontally
SetPoint(midlast-1, new PointF(newPoint.X, GetPoint(midlast-2).Y));
SetPoint(midlast, new PointF(newPoint.X, GetPoint(midlast+1).Y));
break;
default:
int numpts = this.PointsCount;
if (numpts >= 2 && whichHandle >= LastHandle) { // otherwise let the point at the handle follow the mouse
int i = whichHandle - LastHandle;
PointF oldpt = GetPoint(i);
if (this.Orthogonal) {
// can move anywhere, but need to keep adjacent segments orthogonal
PointF before = GetPoint(i-1);
PointF after = GetPoint(i+1);
if (IsApprox(before.X, oldpt.X) && IsApprox(oldpt.Y, after.Y)) {
SetPoint(i-1, new PointF(newPoint.X, before.Y));
SetPoint(i+1, new PointF(after.X, newPoint.Y));
} else if (IsApprox(before.Y, oldpt.Y) && IsApprox(oldpt.X, after.X)) {
SetPoint(i-1, new PointF(before.X, newPoint.Y));
SetPoint(i+1, new PointF(newPoint.X, after.Y));
} else if (IsApprox(before.X, oldpt.X) && IsApprox(oldpt.X, after.X)) {
SetPoint(i-1, new PointF(newPoint.X, before.Y));
SetPoint(i+1, new PointF(newPoint.X, after.Y));
} else if (IsApprox(before.Y, oldpt.Y) && IsApprox(oldpt.Y, after.Y)) {
SetPoint(i-1, new PointF(before.X, newPoint.Y));
SetPoint(i+1, new PointF(after.X, newPoint.Y));
}
}
SetPoint(i, newPoint);
if (numpts >= 3) {
// maybe adjust the end points if needs recalculating
if (i == 1 && this.FromPort != null) {
GoPort p = this.FromPort.GoObject as GoPort;
if (p != null)
SetPoint(0, p.GetFromLinkPoint(this.AbstractLink));
}
if (i == numpts-2 && this.ToPort != null) {
GoPort p = this.ToPort.GoObject as GoPort;
if (p != null)
SetPoint(numpts-1, p.GetToLinkPoint(this.AbstractLink));
}
}
}
break;
}
}
}

IsApprox is an internal predicate that checks whether two numbers are reasonably close to each other, since equality comparison of floating point numbers is unreliable.