OK, this was another fun thing to try. I implemented my second suggestion.
The following code assumes the link is not Orthogonal and that ResizesRealtime is true (which it is by default).
I also added code to automatically remove segments if moving a vertex caused both adjacent segments to make a straight line or close to it.
public override void AddSelectionHandles(GoSelection sel, GoObject selectedObj) {
base.AddSelectionHandles(sel, selectedObj);
GoView view = sel.View;
bool canresize = CanResize() && (view == null || view.CanResizeObjects());
bool canreshape = CanReshape() && (view == null || view.CanReshapeObjects());
if (canresize && canreshape && !this.Orthogonal && this.ResizesRealtime) {
// for each point, create an extra handle in the middle of each segment
for (int i = this.FirstPickIndex; i < this.LastPickIndex; i++) {
PointF a = GetPoint(i);
PointF b = GetPoint(i+1);
PointF p = new PointF((a.X+b.X)/2, (a.Y+b.Y)/2);
GoHandle h = sel.CreateResizeHandle(this, selectedObj, p, LastHandle + 2000000 + i, true) as GoHandle;
if (h != null) { // make handle smaller than the default for this view
h.Size = new SizeF(sel.View.ResizeHandleWidth2/3, sel.View.ResizeHandleHeight2/3);
h.Center = p;
}
}
}
}
public override void DoResize(GoView view, RectangleF origRect, PointF newPoint, int whichHandle, GoInputState evttype, SizeF min, SizeF max) {
if (whichHandle < LastHandle + 2000000) {
base.DoResize(view, origRect, newPoint, whichHandle, evttype, min, max);
// maybe remove a point if it results in two consecutive segments in an almost straight line
int i = whichHandle - LastHandle;
if (evttype == GoInputState.Finish && i > 0 && i < this.PointsCount-1) {
PointF a = GetPoint(i-1);
PointF b = GetPoint(i);
PointF c = GetPoint(i+1);
PointF q; // the closest point to B on the line between A and C
bool between = GoStroke.NearestPointOnLine(a, c, b, out q);
// if B is within 3 units of the line from A to C, and if Q is between A and C,
// remove that point from the stroke
if (between && ((q.X-b.X)(q.X-b.X) + (q.Y-b.Y)(q.Y-b.Y)) < this.PickMargin*this.PickMargin) {
RemovePoint(i);
}
}
} else {
// this code assumes !this.Orthogonal and this.ResizesRealtime, enforced in AddSelectionHandles
// insert the point in the stroke AFTER the point index given by whichHandle
int i = whichHandle - LastHandle - 2000000 + 1;
if (evttype == GoInputState.Start)
InsertPoint(i, newPoint);
else if (evttype == GoInputState.Cancel)
RemovePoint(i);
else
SetPoint(i, newPoint);
}
}