Hi,
I want to know this is possible to move a link with the link itself and not the points of the link.
For instance : One link, 2 points and I draw example of the cursor on the link at different location.
Thanks a lot !
Hi,
I want to know this is possible to move a link with the link itself and not the points of the link.
For instance : One link, 2 points and I draw example of the cursor on the link at different location.
Thanks a lot !
I haven’t really tested this code, but you could try replacing the standard LinkReshapingTool with an instance of this:
[code] public class CustomLinkReshapingTool : LinkReshapingTool {
public const String ToolCategory = “ReshapeLink”;
public override void UpdateAdornments(Part part) {
Link link = part as Link;
if (link == null) return; // no Nodes
Adornment adornment = null;
if (link.IsSelected) {
FrameworkElement selelt = link.Path;
if (selelt != null && link.CanReshape() && Part.IsVisibleElement(selelt)) {
adornment = link.GetAdornment(ToolCategory);
if (adornment == null) {
Route route = link.Route;
IEnumerable<Point> pts = route.Points;
int numpts = route.PointsCount;
if (numpts < 2) return;
bool ortho = route.Orthogonal;
// this Adornment consists of a LinkPanel holding a bunch of ToolHandles
LinkPanel panel = new LinkPanel();
int firstindex = route.FirstPickIndex;
int lastindex = route.LastPickIndex;
int orthadjust = (ortho ? 1 : 0);
if (/*route.Resegmentable &&*/ route.Curve != LinkCurve.Bezier) {
for (int i = firstindex+orthadjust; i < lastindex-orthadjust; i++) {
Point a = route.GetPoint(i);
Point b = route.GetPoint(i + 1);
if (IsApprox(a, b)) continue;
FrameworkElement mh = null;
// now the handle at the middle of each segment:
if (IsApprox(a.X, b.X)) {
mh = new ToolHandle() {
Width = 6,
Height = 16,
Fill = Brushes.Yellow,
Stroke = Brushes.Black,
StrokeThickness = 1
};
}
else {
mh = new ToolHandle() {
Width = 16,
Height = 6,
Fill = Brushes.Yellow,
Stroke = Brushes.Black,
StrokeThickness = 1
};
}
NodePanel.SetFigure(mh, NodeFigure.Rectangle);
// identify this particular handle within the LinkPanel
LinkPanel.SetIndex(mh, i); // the segment
LinkPanel.SetFraction(mh, 0.5); // how far along the segment
if (IsApprox(a.X, b.X)) {
SetReshapeBehavior(mh, ReshapeBehavior.Horizontal);
mh.Cursor = Cursors.SizeWE;
}
else {
SetReshapeBehavior(mh, ReshapeBehavior.Vertical);
mh.Cursor = Cursors.SizeNS;
}
panel.Children.Add(mh);
}
}
// don't bother creating handles for firstindex or lastindex
for (int i = firstindex + 1; i < lastindex; i++) {
// the handle at each vertex point:
FrameworkElement h = new ToolHandle() {
Width = 6,
Height = 6,
Fill = Brushes.Yellow,
Stroke = Brushes.Black,
StrokeThickness = 1
};
NodePanel.SetFigure(h, NodeFigure.Rectangle);
// identify the segment for this particular handle
LinkPanel.SetIndex(h, i);
// now determines its reshape behavior and cursor, depending on whether Orthogonal et al.
if (i == firstindex + 1 && ortho) {
Point a = route.GetPoint(firstindex);
Point b = route.GetPoint(firstindex + 1);
if (IsApprox(a, b)) {
b = route.GetPoint(firstindex - 1);
if (IsApprox(a.X, b.X)) {
SetReshapeBehavior(h, ReshapeBehavior.Vertical);
h.Cursor = Cursors.SizeNS;
} else if (IsApprox(a.Y, b.Y)) {
SetReshapeBehavior(h, ReshapeBehavior.Horizontal);
h.Cursor = Cursors.SizeWE;
}
} else if (IsApprox(a.X, b.X)) {
SetReshapeBehavior(h, ReshapeBehavior.Vertical);
h.Cursor = Cursors.SizeNS;
} else if (IsApprox(a.Y, b.Y)) {
SetReshapeBehavior(h, ReshapeBehavior.Horizontal);
h.Cursor = Cursors.SizeWE;
}
} else if (i == lastindex - 1 && ortho) {
Point a = route.GetPoint(lastindex - 1);
Point b = route.GetPoint(lastindex);
if (IsApprox(a, b)) {
a = route.GetPoint(lastindex + 1);
if (IsApprox(a.X, b.X)) {
SetReshapeBehavior(h, ReshapeBehavior.Vertical);
h.Cursor = Cursors.SizeNS;
} else if (IsApprox(a.Y, b.Y)) {
SetReshapeBehavior(h, ReshapeBehavior.Horizontal);
h.Cursor = Cursors.SizeWE;
}
} else if (IsApprox(a.X, b.X)) {
SetReshapeBehavior(h, ReshapeBehavior.Vertical);
h.Cursor = Cursors.SizeNS;
} else if (IsApprox(a.Y, b.Y)) {
SetReshapeBehavior(h, ReshapeBehavior.Horizontal);
h.Cursor = Cursors.SizeWE;
}
} else {
SetReshapeBehavior(h, ReshapeBehavior.All);
h.Cursor = Cursors.SizeAll;
}
panel.Children.Add(h);
}
adornment = new Adornment();
adornment.AdornedElement = selelt;
adornment.Category = ToolCategory;
adornment.Content = panel; // just provide the FrameworkElement as the Content and as the Visual Child
adornment.LocationSpot = Spot.TopLeft;
}
}
if (adornment != null) {
Point loc = link.GetElementPoint(selelt, Spot.TopLeft);
adornment.Position = loc;
//adornment.RotationAngle = link.GetAngle(selelt);
adornment.Remeasure();
}
}
link.SetAdornment(ToolCategory, adornment);
}
protected override void DoReshape(Point newPoint) {
Link link = this.AdornedLink;
Route route = link.Route;
int index = this.HandleIndex;
ReshapeBehavior behavior = GetReshapeBehavior(this.Handle);
if (behavior == ReshapeBehavior.None) return;
if (route.Orthogonal) { // need to adjust adjacent points as well
if (index == route.FirstPickIndex+1) {
int midfirst = route.FirstPickIndex+1;
if (behavior == ReshapeBehavior.Vertical) {
// move segment vertically
route.SetPoint(midfirst, new Point(route.GetPoint(midfirst-1).X, newPoint.Y));
route.SetPoint(midfirst+1, new Point(route.GetPoint(midfirst+2).X, newPoint.Y));
} else if (behavior == ReshapeBehavior.Horizontal) {
// move segment horizontally
route.SetPoint(midfirst, new Point(newPoint.X, route.GetPoint(midfirst-1).Y));
route.SetPoint(midfirst+1, new Point(newPoint.X, route.GetPoint(midfirst+2).Y));
}
} else if (index == route.LastPickIndex-1) {
int midlast = route.LastPickIndex-1;
if (behavior == ReshapeBehavior.Vertical) {
// move segment vertically
route.SetPoint(midlast-1, new Point(route.GetPoint(midlast-2).X, newPoint.Y));
route.SetPoint(midlast, new Point(route.GetPoint(midlast+1).X, newPoint.Y));
} else if (behavior == ReshapeBehavior.Horizontal) {
// move segment horizontally
route.SetPoint(midlast-1, new Point(newPoint.X, route.GetPoint(midlast-2).Y));
route.SetPoint(midlast, new Point(newPoint.X, route.GetPoint(midlast+1).Y));
}
} else {
// can move anywhere, but need to keep adjacent segments orthogonal
int i = index;
Point oldpt = route.GetPoint(i);
Point before = route.GetPoint(i-1);
Point after = route.GetPoint(i+1);
if (IsApprox(before.X, oldpt.X) && IsApprox(oldpt.Y, after.Y)) {
if (IsApprox(before.X, route.GetPoint(i-2).X) && !IsApprox(before.Y, route.GetPoint(i-2).Y)) {
route.InsertPoint(i, new Point(newPoint.X, before.Y));
index++;
i++;
} else route.SetPoint(i-1, new Point(newPoint.X, before.Y));
if (IsApprox(after.Y, route.GetPoint(i+2).Y) && !IsApprox(after.X, route.GetPoint(i+2).X)) {
route.InsertPoint(i+1, new Point(after.X, newPoint.Y));
} else route.SetPoint(i+1, new Point(after.X, newPoint.Y));
} else if (IsApprox(before.Y, oldpt.Y) && IsApprox(oldpt.X, after.X)) {
if (IsApprox(before.Y, route.GetPoint(i-2).Y) && !IsApprox(before.X, route.GetPoint(i-2).X)) {
route.InsertPoint(i, new Point(before.X, newPoint.Y));
index++;
i++;
} else route.SetPoint(i-1, new Point(before.X, newPoint.Y));
if (IsApprox(after.X, route.GetPoint(i+2).X) && !IsApprox(after.Y, route.GetPoint(i+2).Y)) {
route.InsertPoint(i+1, new Point(newPoint.X, after.Y));
} else route.SetPoint(i+1, new Point(newPoint.X, after.Y));
} else if (IsApprox(before.X, oldpt.X) && IsApprox(oldpt.X, after.X)) {
if (IsApprox(before.X, route.GetPoint(i-2).X) && !IsApprox(before.Y, route.GetPoint(i-2).Y)) {
route.InsertPoint(i, new Point(newPoint.X, before.Y));
index++;
i++;
} else route.SetPoint(i-1, new Point(newPoint.X, before.Y));
if (IsApprox(after.X, route.GetPoint(i+2).X) && !IsApprox(after.Y, route.GetPoint(i+2).Y)) {
route.InsertPoint(i+1, new Point(newPoint.X, after.Y));
} else route.SetPoint(i+1, new Point(newPoint.X, after.Y));
} else if (IsApprox(before.Y, oldpt.Y) && IsApprox(oldpt.Y, after.Y)) {
if (IsApprox(before.Y, route.GetPoint(i-2).Y) && !IsApprox(before.X, route.GetPoint(i-2).X)) {
route.InsertPoint(i, new Point(before.X, newPoint.Y));
index++;
i++;
} else route.SetPoint(i-1, new Point(before.X, newPoint.Y));
if (IsApprox(after.Y, route.GetPoint(i+2).Y) && !IsApprox(after.X, route.GetPoint(i+2).X)) {
route.InsertPoint(i+1, new Point(after.X, newPoint.Y));
} else route.SetPoint(i+1, new Point(after.X, newPoint.Y));
}
route.SetPoint(index, newPoint);
}
} else { // no Orthogonal constraints, just set the new point
route.SetPoint(this.HandleIndex, newPoint);
// also adjust the end point if there is no spot for the port
var fromNode = link.FromNode;
var fromPort = link.FromPort;
var fromSpot = Node.GetFromSpot(fromPort);
var toNode = link.ToNode;
var toPort = link.ToPort;
var toSpot = Node.GetToSpot(toPort);
if (this.HandleIndex == 1 && fromSpot.IsNoSpot) {
var endpt = route.GetLinkPoint(fromNode, fromPort, Spot.None, true, false, toNode, toPort);
route.SetPoint(0, endpt);
}
if (this.HandleIndex == route.PointsCount - 2 && toSpot.IsNoSpot) {
var endpt = route.GetLinkPoint(toNode, toPort, Spot.None, false, false, fromNode, fromPort);
route.SetPoint(route.PointsCount - 1, endpt);
}
}
}
public static bool IsApprox(double x, double y) {
double d = x - y;
return d < 0.5 && d > -0.5;
}
public static bool IsApprox(Point a, Point b) {
return IsApprox(a.X, b.X) && IsApprox(a.Y, b.Y);
}
}[/code]
Thanks, it works !