/// <summary> /// Sets the value of the <c>ReshapeBehavior</c> attached dependency property. /// </summary> public static void SetReshapeBehavior(DependencyObject d, ReshapeBehavior v) { d.SetValue(ReshapeBehaviorProperty, v); }
/// <summary> /// Modify the <see cref="Route"/> of the <see cref="AdornedLink"/> to a new point, /// considering also which reshape handle is being dragged and whether the route /// is <see cref="Route.Orthogonal"/>. /// </summary> /// <param name="newPoint"></param> /// <remarks> /// If the <see cref="Route"/> is <see cref="Route.Orthogonal"/> this /// modifies the adjacent points as well in order to keep adjacent segments orthogonal. /// For handles that are near either end of the route, the movement may be constrained /// to be only vertical or only horizontal, in order to maintain orthogonality. /// The decision is based on the value of <see cref="ReshapingBaseTool.GetReshapeBehavior"/> /// on the <see cref="ReshapingBaseTool.Handle"/>. /// This method is called during a "ReshapeLink" transaction. /// </remarks> protected virtual void DoReshape(Point newPoint) { Link link = this.AdornedLink; Route route = link.Route; ReshapeBehavior behavior = GetReshapeBehavior(this.Handle); if (route.Orthogonal) // need to adjust adjacent points as well { if (this.HandleIndex == 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 (this.HandleIndex == 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 = this.HandleIndex; Point oldpt = route.GetPoint(i); Point before = route.GetPoint(i - 1); Point after = route.GetPoint(i + 1); if (Geo.IsApprox(before.X, oldpt.X) && Geo.IsApprox(oldpt.Y, after.Y)) { route.SetPoint(i - 1, new Point(newPoint.X, before.Y)); route.SetPoint(i + 1, new Point(after.X, newPoint.Y)); } else if (Geo.IsApprox(before.Y, oldpt.Y) && Geo.IsApprox(oldpt.X, after.X)) { route.SetPoint(i - 1, new Point(before.X, newPoint.Y)); route.SetPoint(i + 1, new Point(newPoint.X, after.Y)); } else if (Geo.IsApprox(before.X, oldpt.X) && Geo.IsApprox(oldpt.X, after.X)) { route.SetPoint(i - 1, new Point(newPoint.X, before.Y)); route.SetPoint(i + 1, new Point(newPoint.X, after.Y)); } else if (Geo.IsApprox(before.Y, oldpt.Y) && Geo.IsApprox(oldpt.Y, after.Y)) { route.SetPoint(i - 1, new Point(before.X, newPoint.Y)); route.SetPoint(i + 1, new Point(after.X, newPoint.Y)); } route.SetPoint(this.HandleIndex, newPoint); } } else // no Orthogonal constraints, just set the new point { route.SetPoint(this.HandleIndex, newPoint); } }