/// <summary> /// Sets the new z-order value stored for <paramref name="key"/>. /// </summary> /// <remarks> /// An <see cref="IUndoUnit"/> for the changed z-order is added as well if undo is /// <see cref="GraphExtensions.IsUndoEngineEnabled">enabled</see>. /// </remarks> public void SetZOrder(INode key, int newZOrder) { var master = MasterOf(key); int oldZOrder = 0; zOrders.TryGetValue(master, out oldZOrder); if (oldZOrder != newZOrder) { if (MasterGraph.IsUndoEngineEnabled()) { MasterGraph.AddUndoUnit("Undo Z-order Change", "Redo Z-order Change", () => { SetZOrderCore(master, oldZOrder); Update(master); }, () => { SetZOrderCore(master, newZOrder); Update(master); }); } SetZOrderCore(master, newZOrder); OnZOrderChanged(key, newZOrder, oldZOrder); } }
private static IBend CreateBends([NotNull] IGraph graph, [NotNull] IEdge edge, int segmentIndex, double ratio, [NotNull] IListEnumerable <IPoint> pathPoints) { //Create 3 bends and adjust the neighbors //The first bend we need to touch is at startIndex var startIndex = segmentIndex * 3; //This holds the new coordinates left and right of the split point //We don't actually need all of them, but this keeps the algorithm more straightforward. var left = new PointD[4]; var right = new PointD[4]; //Determine the new control points to cleanly split the curve GetCubicSplitPoints(ratio, new[] { pathPoints[startIndex].ToPointD(), pathPoints[startIndex + 1].ToPointD(), pathPoints[startIndex + 2].ToPointD(), pathPoints[startIndex + 3].ToPointD() }, left, right); //Previous control point - does always exist as a bend, given our precondition var previousBend = edge.Bends[startIndex]; //Next control point - also always exists given the precondition for bend counts (i.e. there have to be at least two) var nextBend = edge.Bends[startIndex + 1]; //We create the three new bends between previous bend and next bend and adjust these two. //We don't have to adjust more bends, since we just have a cubic curve. IBend bendToMove; var engine = graph.GetUndoEngine(); //Wrap everything into a single compound edit, so that everything can be undone in a single unit using (var edit = graph.BeginEdit("Create Bezier Bend", "Create Bezier Bend")) { try { //Adjust the previous bend - given the split algorithm, its coordinate is in left[1] //(left[0] is actually kept unchanged from the initial value) var oldPrevLocation = previousBend.Location.ToPointD(); var newPrevLocation = left[1]; graph.SetBendLocation(previousBend, newPrevLocation); // Add unit to engine graph.AddUndoUnit("Set bend location", "Set bend location", () => graph.SetBendLocation(previousBend, oldPrevLocation), () => graph.SetBendLocation(previousBend, newPrevLocation)); //Insert the new triple, using the values from left and right in order graph.AddBend(edge, left[2], startIndex + 1); bendToMove = graph.AddBend(edge, left[3], startIndex + 2); //right[0] == left[3], so right[1] is the next new control point graph.AddBend(edge, right[1], startIndex + 3); //Adjust the next bend var oldNextLocation = nextBend.Location.ToPointD(); var newNextLocation = right[2]; graph.SetBendLocation(nextBend, newNextLocation); // Add unit to engine graph.AddUndoUnit("Set bend location", "Set bend location", () => graph.SetBendLocation(nextBend, oldNextLocation), () => graph.SetBendLocation(nextBend, newNextLocation)); } catch { //Cancel the edit in case anything goes wrong. edit.Cancel(); throw; } } return(bendToMove); }