// Change the gaps associated with a leg. public static void ChangeLegGaps(EventDB eventDB, Id<ControlPoint> controlId1, Id<ControlPoint> controlId2, LegGap[] newGaps) { // Get the leg object for this leg. Create one if needed. Id<Leg> legId = QueryEvent.FindLeg(eventDB, controlId1, controlId2); Leg leg; if (legId.IsNone) leg = new Leg(controlId1, controlId2); else leg = (Leg) eventDB.GetLeg(legId).Clone(); // Change the gaps. leg.gaps = (newGaps == null) ? null : (LegGap[]) newGaps.Clone(); // Write the change leg object to the event DB. If the leg is vacuous, could involve removing the leg. if (leg.IsVacuous()) { if (legId.IsNotNone) eventDB.RemoveLeg(legId); } else { if (legId.IsNone) eventDB.AddLeg(leg); else eventDB.ReplaceLeg(legId, leg); } }
// Change the flagging associated with a leg. If changing to Begin/End flagging, then a bend will be introduced if no bends currently exist // in the leg. If the leg ends in the finish, the finish symbol may be changed to match if appropriate. public static void ChangeFlagging(EventDB eventDB, Id<ControlPoint> controlId1, Id<ControlPoint> controlId2, FlaggingKind flagging) { ControlPoint control1 = eventDB.GetControl(controlId1); ControlPoint control2 = eventDB.GetControl(controlId2); if (control2.kind == ControlPointKind.Finish && flagging == FlaggingKind.All) { // If the leg ends in the finish control, we can set all flagging by just changing the finish control symbol. ChangeDescriptionSymbol(eventDB, controlId2, 0, "14.1"); return; } // We need a leg object. Create a new one or get the existing one. Id<Leg> legId = QueryEvent.FindLeg(eventDB, controlId1, controlId2); Leg leg; if (legId.IsNone) leg = new Leg(controlId1, controlId2); else leg = (Leg) eventDB.GetLeg(legId).Clone(); // Set the flagging kind. leg.flagging = flagging; if (flagging == FlaggingKind.Begin || flagging == FlaggingKind.End) { // These kinds of flagging require a bend in the flaggingStartStop field. if (leg.bends != null && leg.bends.Length > 0) { // Already have a bend we can use. leg.flagStartStop = (flagging == FlaggingKind.Begin) ? leg.bends[leg.bends.Length - 1] : leg.bends[0]; } else { // Create a bend half-way along the leg. leg.flagStartStop = new PointF((control1.location.X + control2.location.X) / 2, (control1.location.Y + control2.location.Y) / 2); leg.bends = new PointF[] { leg.flagStartStop }; } } // Update the leg object. if (legId.IsNone) eventDB.AddLeg(leg); else { if (leg.IsVacuous()) eventDB.RemoveLeg(legId); else eventDB.ReplaceLeg(legId, leg); } // Update the finish control symbol if reasonable. if (control2.kind == ControlPointKind.Finish) { // Update the finish control symbol. if ((flagging == FlaggingKind.None || flagging == FlaggingKind.Begin) && control2.symbolIds[0] == "14.1") { // Remove the "flagged from last control symbol" and change it to "no flagging". ChangeDescriptionSymbol(eventDB, controlId2, 0, "14.3"); } else if (flagging == FlaggingKind.End) { // If partial flagging on the end part of the leg, change the symbol to finish funnel. ChangeDescriptionSymbol(eventDB, controlId2, 0, "14.2"); } } }
// Remove a bend from a leg. public static void RemoveLegBend(EventDB eventDB, Id<ControlPoint> controlId1, Id<ControlPoint> controlId2, PointF bendToRemove) { bool newFlagging = false; FlaggingKind newFlaggingKind = FlaggingKind.None; // Get the leg object for this leg. One must exists Id<Leg> legId = QueryEvent.FindLeg(eventDB, controlId1, controlId2); Leg leg = (Leg) eventDB.GetLeg(legId).Clone(); SymPath oldPath = QueryEvent.GetLegPath(eventDB, controlId1, controlId2, legId); if (leg.flagging == FlaggingKind.Begin || leg.flagging == FlaggingKind.End && leg.flagStartStop == bendToRemove) { // We are removing the point at which flagging starts/stop. The start/stop point must move to another, unless there are no // other bends left. if (leg.bends.Length == 1) { // No other bends left. Make leg all flagging. newFlagging = true; newFlaggingKind = FlaggingKind.All; } else { // Basic idea is to move to the bend that is at the flagging end, unless there is no such bend. // Where is the bend? int index = Array.IndexOf(leg.bends, bendToRemove); if ((index == 0 || leg.flagging == FlaggingKind.End) && index != leg.bends.Length - 1) { // move to next bend after the one removed. leg.flagStartStop = leg.bends[index + 1]; } else { // move to previous bend before the one removed. leg.flagStartStop = leg.bends[index - 1]; } } } // Remove the bend from the bend array. leg.bends = Util.RemovePointFromArray(leg.bends, bendToRemove); if (leg.bends.Length == 0) leg.bends = null; // Update the leg objects. if (leg.IsVacuous()) eventDB.RemoveLeg(legId); else eventDB.ReplaceLeg(legId, leg); // Change flagging if we need to. This is more complex that just setting the flagging kind in the leg object. if (newFlagging) ChangeFlagging(eventDB, controlId1, controlId2, newFlaggingKind); // If the leg had gaps, update the gaps for the new path. if (leg.gaps != null) { SymPath newPath = QueryEvent.GetLegPath(eventDB, controlId1, controlId2); LegGap[] newGaps = LegGap.MoveGapsToNewPath(leg.gaps, oldPath, newPath); ChangeLegGaps(eventDB, controlId1, controlId2, newGaps); } }
// Add a bend to a leg. public static void AddLegBend(EventDB eventDB, Id<ControlPoint> controlId1, Id<ControlPoint> controlId2, PointF newBend) { // Get the leg object for this leg. Create one if needed. Id<Leg> legId = QueryEvent.FindLeg(eventDB, controlId1, controlId2); Leg leg; if (legId.IsNone) leg = new Leg(controlId1, controlId2); else leg = (Leg) eventDB.GetLeg(legId).Clone(); SymPath oldPath = QueryEvent.GetLegPath(eventDB, controlId1, controlId2, legId); // Get an array with the start/end points and the bends. PointF[] oldBendArray = new PointF[(leg.bends == null) ? 2 : leg.bends.Length + 2]; if (leg.bends != null) Array.Copy(leg.bends, 0, oldBendArray, 1, leg.bends.Length); oldBendArray[0] = eventDB.GetControl(controlId1).location; oldBendArray[oldBendArray.Length - 1] = eventDB.GetControl(controlId2).location; // Insert the new point into the array at the right place. PointF[] newBendArray = Util.AddPointToArray(oldBendArray, newBend); // Copy the new bend parts into the bends array. leg.bends = new PointF[newBendArray.Length - 2]; Array.Copy(newBendArray, 1, leg.bends, 0, newBendArray.Length - 2); // Update the leg. if (legId.IsNone) eventDB.AddLeg(leg); else eventDB.ReplaceLeg(legId, leg); // If the leg had gaps, update the gaps for the new path. if (leg.gaps != null) { SymPath newPath = QueryEvent.GetLegPath(eventDB, controlId1, controlId2); LegGap[] newGaps = LegGap.MoveGapsToNewPath(leg.gaps, oldPath, newPath); ChangeLegGaps(eventDB, controlId1, controlId2, newGaps); } }
// Move the bend in a leg to a new location. public static void MoveLegBend(EventDB eventDB, Id<ControlPoint> controlId1, Id<ControlPoint> controlId2, PointF oldBend, PointF newBend) { // Get the old leg. Id<Leg> legId = QueryEvent.FindLeg(eventDB, controlId1, controlId2); Debug.Assert(legId.IsNotNone); Leg leg = (Leg) eventDB.GetLeg(legId).Clone(); SymPath oldPath = QueryEvent.GetLegPath(eventDB, controlId1, controlId2, legId); // Change the bend. for (int i = 0; i < leg.bends.Length; ++i) { if (leg.bends[i] == oldBend) leg.bends[i] = newBend; } if (leg.flagStartStop == oldBend) leg.flagStartStop = newBend; // Update the leg. eventDB.ReplaceLeg(legId, leg); // If the leg had gaps, update the gaps for the new path. if (leg.gaps != null) { SymPath newPath = QueryEvent.GetLegPath(eventDB, controlId1, controlId2); leg.gaps = LegGap.MoveGapsToNewPath(leg.gaps, oldPath, newPath); eventDB.ReplaceLeg(legId, leg); } }