private static void ProcessEdges(Graph graph, Microsoft.Msagl.GeometryGraph msaglGraph) { foreach (Edge drawingEdge in graph.Edges) { Microsoft.Msagl.Node sourceNode = msaglGraph.FindNode(drawingEdge.Source); Microsoft.Msagl.Node targetNode = msaglGraph.FindNode(drawingEdge.Target); if (sourceNode == null) { sourceNode = CreateGeometryNode(msaglGraph, graph.FindNode(drawingEdge.Source) as Node, Connection.Connected); } if (targetNode == null) { targetNode = CreateGeometryNode(msaglGraph, graph.FindNode(drawingEdge.Target) as Node, Connection.Connected); } Microsoft.Msagl.Edge msaglEdge = new Microsoft.Msagl.Edge(sourceNode, targetNode); if (drawingEdge.Label != null && graph.LayoutAlgorithmSettings is SugiyamaLayoutSettings) { msaglEdge.Label = drawingEdge.Label.GeometryLabel; msaglEdge.Label.Parent = msaglEdge; } msaglEdge.Weight = drawingEdge.Attr.Weight; msaglEdge.Length = drawingEdge.Attr.Length; msaglEdge.Separation = drawingEdge.Attr.Separation; msaglEdge.ArrowheadAtSource = drawingEdge.Attr.ArrowAtSource; msaglEdge.ArrowheadAtTarget = drawingEdge.Attr.ArrowAtTarget; msaglGraph.AddEdge(msaglEdge); msaglEdge.UserData = drawingEdge; msaglEdge.ArrowheadLength = drawingEdge.Attr.ArrowheadLength; msaglEdge.LineWidth = drawingEdge.Attr.LineWidth; } }
///// <summary> ///// Creates a curve by using the underlying polyline ///// </summary> ///// <param name="underlyingPoly"></param> ///// <returns></returns> // [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Polyline")] // static public Curve CreateCurveFromEdgeUnderlyingPolyline(UnderlyingPolyline underlyingPoly) { // Curve curve = new Curve(); // Site a = underlyingPoly.HeadSite;//the corner start // Site b; //the corner origin // Site c;//the corner other end // while (SmoothedPolyline.FindCorner(a, out b, out c)) { // CubicBezierSegment seg = SmoothedPolyline.CreateBezierSeg(b.bezierSegmentShrinkCoefficient, a, b, c); // if (curve.Segments.Count == 0) { // if (!Curve.Close(a.Point, seg.Start)) // Curve.AddLineSeg(curve, a.Point, seg.Start); // } else if (!Curve.Close(curve.End, seg.Start)) // Routing.ContinueWithLineSeg(curve, seg.Start); // curve.AddSegment(seg); // a = b; // } // System.Diagnostics.Debug.Assert(a.Next.Next == null); // if (curve.Segments.Count == 0) { // if (!Curve.Close(a.Point, a.Next.Point)) { // Curve.AddLineSeg(curve, a.Point, a.Next.Point); // } else { // double w=5; // curve.Segments.Add(new CubicBezierSegment(a.Point, a.Point+new Point(w,w),a.Point+new Point(-w,w), b.Point)); // } // } else if (!Curve.Close(curve.End, a.Next.Point)) // Routing.ContinueWithLineSeg(curve, a.Next.Point); // return curve; // } static private void TranslateEdge(GeomEdge e, Point delta, EdgeRestoreData edgeRestoreData) { e.Curve = edgeRestoreData.Curve.Translate(delta); if (e.UnderlyingPolyline != null) { for (Site s = e.UnderlyingPolyline.HeadSite, s0 = edgeRestoreData.Polyline.HeadSite; s != null; s = s.Next, s0 = s0.Next) { s.Point = s0.Point + delta; } } if (e.ArrowheadAtSource) { e.ArrowheadAtSourcePosition = edgeRestoreData.ArrowheadAtSourcePosition + delta; } if (e.ArrowheadAtTarget) { e.ArrowheadAtTargetPosition = edgeRestoreData.ArrowheadAtTargetPosition + delta; } if (e.Label != null) { e.Label.Center = edgeRestoreData.LabelCenter + delta; } }
static internal void DragEdge(Point delta, GeomEdge e, EdgeRestoreData edgeRestoreData, Set <GeometryObject> objectsMarkedToDrag) { Site site = null; Point point = new Point(0, 0); if (objectsMarkedToDrag.Contains(e.Source)) { if (!objectsMarkedToDrag.Contains(e.Target)) { site = e.UnderlyingPolyline.HeadSite; point = edgeRestoreData.Polyline.HeadSite.Point; } } else { site = e.UnderlyingPolyline.LastSite; point = edgeRestoreData.Polyline.LastSite.Point; } if (site == null) { TranslateEdge(e, delta, edgeRestoreData); } else { DragEdgeWithSite(delta, e, edgeRestoreData, site, point); } }
static private void DragLabelOfTheEdge(GeomEdge e, EdgeRestoreData edgeRestoreData, Curve untrimmedCurve) { if (e.Label != null) { e.Label.Center = untrimmedCurve[edgeRestoreData.LabelAttachmentParameter] + edgeRestoreData.LabelOffsetFromTheAttachmentPoint; } }
/// <summary> /// deletes the polyline corner /// </summary> /// <param name="edge"></param> /// <param name="site"></param> /// <param name="userData">an object to be stored in the unde action</param> public void DeleteSite(GeomEdge edge, Site site, object userData) { this.EditedEdge = edge; PrepareForPolylineCornerRemoval(userData, site); site.Previous.Next = site.Next;//removing the site from the list site.Next.Previous = site.Previous; //just to recalc everything in a correct way DragEdgeWithSite(new Point(0, 0), edge, CurrentUndoAction.GetRestoreData(edge) as EdgeRestoreData, site.Previous, site.Previous.Point); }
/// <summary> /// preparing for an edge corner dragging /// </summary> /// <param name="affectedObjects"></param> /// <param name="geometryEdge"></param> /// <param name="site"></param> /// <returns></returns> public UndoRedoAction PrepareForEdgeCornerDragging(Set <object> affectedObjects, GeomEdge geometryEdge, Site site) { this.EditedEdge = geometryEdge; UndoRedoAction edgeDragUndoRedoAction = (EdgeDragUndoRedoAction)CreateEdgeEditUndoRedoAction(affectedObjects); EdgeRestoreData edgeRestoreDate = (EdgeRestoreData)edgeDragUndoRedoAction.GetRestoreData(geometryEdge); edgeRestoreDate.Site = site; return(InsertToListAndFixTheBox(edgeDragUndoRedoAction)); }
private static void CreateCurveOnChangedPolyline(Point delta, GeomEdge e, EdgeRestoreData edgeRestoreData) { Curve curve = e.UnderlyingPolyline.CreateCurve(); if (!Curve.TrimSplineAndCalculateArrowheads(e, curve, false)) { Curve.CreateBigEnoughSpline(e); } if (delta.X != 0 || delta.Y != 0) { DragLabelOfTheEdge(e, edgeRestoreData, curve); } }
/// <summary> /// insert a polyline corner /// </summary> /// <param name="edge"></param> /// <param name="point">the point to insert the corner</param> /// <param name="siteBeforeInsertion"></param> ///<param name="affectedEntity">an object to be stored in the undo action</param> public void InsertSite(GeomEdge edge, Point point, Site siteBeforeInsertion, object affectedEntity) { this.EditedEdge = edge; //creating the new site Site first = siteBeforeInsertion; Site second = first.Next; Site s = new Site(first, point, second); PrepareForPolylineCornerInsertion(affectedEntity, s); //just to recalc everything in a correct way DragEdgeWithSite(new Point(0, 0), edge, CurrentUndoAction.GetRestoreData(edge) as EdgeRestoreData, s, point); }
private void CalculateDragSetsAndSubscribeToLayoutChangedEvent(IEnumerable <GeometryObject> markedObjects) { foreach (GeometryObject geometryObject in markedObjects) { this.objectsToDrag.Insert(geometryObject); GeomEdge edge = geometryObject as GeomEdge; if (edge != null) { objectsToDrag.Insert(edge.Source); objectsToDrag.Insert(edge.Target); } } CalculateDragSetsForEdges(); }
void UpdateGraphBoundingBoxWithCheck(GeometryObject geomObj) { Rectangle bBox = geomObj.BoundingBox; { GeomEdge edge = geomObj as GeomEdge; if (edge != null && edge.Label != null) { bBox.Add(edge.Label.BoundingBox); } } Point p = new Point(-graph.Margins, graph.Margins); GraphBoundingBoxGetsExtended |= graph.ExtendBoundingBoxWithCheck(bBox.LeftTop + p) || graph.ExtendBoundingBoxWithCheck(bBox.RightBottom - p); }
/// <summary> /// drags elements by the delta /// </summary> /// <param name="delta"></param> public void Drag(Point delta) { GraphBoundingBoxGetsExtended = false; if (delta.X != 0 || delta.Y != 0) { if (EditedEdge == null) { foreach (GeometryObject geomObj in objectsToDrag) { GeomNode node = geomObj as GeomNode; if (node != null) { DragNode(node, delta, CurrentUndoAction.GetRestoreData(node) as NodeRestoreData); } else { GeomEdge edge = geomObj as GeomEdge; if (edge != null) { TranslateEdge(edge, delta, CurrentUndoAction.GetRestoreData(edge) as EdgeRestoreData); } else { GeomLabel label = geomObj as GeomLabel; if (label != null) { DragLabel(label, delta, (CurrentUndoAction.GetRestoreData(label) as LabelRestoreData).Center); } else { throw new NotImplementedException(); } } } UpdateGraphBoundingBoxWithCheck(geomObj); } DragEdgesWithSource(delta); DragEdgesWithTarget(delta); } else if (EditedEdge != null) { DragEdgeEdit(delta); UpdateGraphBoundingBoxWithCheck(EditedEdge); } } }
/// <summary> /// gets the enumerator pointing to the polyline corner before the point /// </summary> /// <param name="edge"></param> /// <param name="point"></param> /// <returns></returns> static public Site GetPreviousSite(GeomEdge edge, Point point) { Site prevSite = edge.UnderlyingPolyline.HeadSite; Site nextSite = prevSite.Next; do { if (BetweenSites(prevSite, nextSite, point)) { return(prevSite); } prevSite = nextSite; nextSite = nextSite.Next; }while(nextSite != null); return(null); }
/// <summary> /// redoes the editing /// </summary> public override void Redo() { base.Redo(); foreach (GeometryObject geomObj in movedObjects) { GeomNode node = geomObj as GeomNode; if (node != null) { GeometryGraphEditor.DragNode(node, Delta, GetRestoreData(node) as NodeRestoreData); foreach (GeomEdge edge in node.OutEdges) { GeometryGraphEditor.DragEdgeWithSource(Delta, edge, GetRestoreData(edge) as EdgeRestoreData); } foreach (GeomEdge edge in node.InEdges) { GeometryGraphEditor.DragEdgeWithTarget(Delta, edge, GetRestoreData(edge) as EdgeRestoreData); } foreach (GeomEdge edge in node.SelfEdges) { GeometryGraphEditor.DragEdge(Delta, edge, GetRestoreData(edge) as EdgeRestoreData, movedObjects); } } else { GeomEdge edge = geomObj as GeomEdge; if (edge != null) { GeometryGraphEditor.DragEdge(Delta, edge, GetRestoreData(edge) as EdgeRestoreData, movedObjects); } else { GeomLabel label = geomObj as GeomLabel; if (label != null) { GeometryGraphEditor.DragLabel(label, Delta, (GetRestoreData(label) as LabelRestoreData).Center); } else { throw new System.NotImplementedException(); } } } } }
private void RestoreEdge(GeomEdge edge) { EdgeRestoreData edgeRestoreData = GetRestoreData(edge) as EdgeRestoreData; Site liveSite = edge.UnderlyingPolyline.HeadSite; Site restoreSite = edgeRestoreData.Polyline.HeadSite; while (liveSite != null) { liveSite.Point = restoreSite.Point; liveSite = liveSite.Next; restoreSite = restoreSite.Next; } edge.Curve = edgeRestoreData.Curve.Clone(); edge.ArrowheadAtSourcePosition = edgeRestoreData.ArrowheadAtSourcePosition; edge.ArrowheadAtTargetPosition = edgeRestoreData.ArrowheadAtTargetPosition; if (edge.Label != null) { edge.Label.Center = edgeRestoreData.LabelCenter; } }
static internal void DragLabel(GeomLabel label, Point delta, Point dragStartCenter) { label.Center = dragStartCenter + delta; GeomEdge edge = label.Parent as GeomEdge; if (edge != null) { CalculateAttachedSegmentEnd(label, edge); label.AttachmentSegmentStart = label.Center; if (!Curve.Close(label.AttachmentSegmentEnd, label.Center)) { foreach (IntersectionInfo x in Curve.CurveCurveIntersect(CreateLabelBoundary(label), new LineSegment(label.AttachmentSegmentEnd, label.Center), false)) { label.AttachmentSegmentStart = x.IntersectionPoint; break; } } } }
/// <summary> /// Undoes the editing /// </summary> public override void Undo() { base.Undo(); Point point = new Point(); foreach (GeometryObject geomObj in movedObjects) { GeomNode node = geomObj as GeomNode; if (node != null) { GeometryGraphEditor.DragNode(node, point, GetRestoreData(node) as NodeRestoreData); foreach (GeomEdge edge in node.Edges) { RestoreEdge(edge); } } else { GeomEdge edge = geomObj as GeomEdge; if (edge != null) { GeometryGraphEditor.DragEdge(point, edge, GetRestoreData(edge) as EdgeRestoreData, movedObjects); } else { GeomLabel label = geomObj as GeomLabel; if (label != null) { GeometryGraphEditor.DragLabel(label, point, (GetRestoreData(label) as LabelRestoreData).Center); } else { throw new System.NotImplementedException(); } } } } }
static internal void DragEdgeWithTarget(Point delta, GeomEdge edge, EdgeRestoreData edgeRestoreData) { double closenessToLine = Math.Min(1.0, (delta.Length / edgeRestoreData.DistanceWhenEdgeIsTurningToLine)); Point lineStart = edgeRestoreData.Polyline.HeadSite.Point; Point lineEnd = edgeRestoreData.Polyline.LastSite.Point + delta; edge.UnderlyingPolyline.LastSite.Point = lineEnd; Point lineVectorBetweenToPolylinePoints = (lineEnd - lineStart) / edgeRestoreData.NumberOfPolylineSegments; Site liveSite = edge.UnderlyingPolyline.HeadSite; Site restoreSite = edgeRestoreData.Polyline.HeadSite; for (int i = 1; i < edgeRestoreData.NumberOfPolylineSegments; i++) { Point linePoint = lineStart + ((double)i) * lineVectorBetweenToPolylinePoints; liveSite = liveSite.Next; restoreSite = restoreSite.Next; liveSite.Point = closenessToLine * linePoint + (1 - closenessToLine) * restoreSite.Point; } CreateCurveOnChangedPolyline(delta, edge, edgeRestoreData); }
/// <summary> /// /// </summary> /// <param name="delta">delta of the drag</param> /// <param name="e">the modified edge</param> /// <param name="edgeRestoreData"></param> /// <param name="site"></param> /// <param name="previousSitePosition"></param> static internal void DragEdgeWithSite(Point delta, GeomEdge e, EdgeRestoreData edgeRestoreData, Site site, Point previousSitePosition) { site.Point = previousSitePosition + delta; CreateCurveOnChangedPolyline(delta, e, edgeRestoreData); }
private IEnumerable <GeometryObject> ChangedElements() { if (this.EditedEdge == null) { foreach (GeometryObject obj in ObjectsToDrag) { GeomNode node = obj as GeomNode; if (node != null) { yield return(node); foreach (GeomEdge e in node.OutEdges) { yield return(e); } foreach (GeomEdge e in node.SelfEdges) { yield return(e); } foreach (GeomEdge e in node.InEdges) { yield return(e); } } else { GeomEdge edge = obj as GeomEdge; if (edge != null) { yield return(edge); yield return(edge.Source); foreach (GeomEdge e in edge.Source.Edges) { yield return(e); } yield return(edge.Target); foreach (GeomEdge e in edge.Target.Edges) { yield return(e); } } else { GeomLabel label = obj as GeomLabel; if (label != null) { yield return(label); } else { throw new NotImplementedException(); } } } } } else { yield return(this.EditedEdge); } }
/// <summary> /// Constructor. At the moment of the constructor call the site should not be inserted yet /// </summary> /// <param name="edgePar"></param> public SiteRemoveUndoAction(GeomEdge edgePar) : base((GeometryGraph)edgePar.Parent) { this.editedEdge = edgePar; this.AddRestoreData(editedEdge, (EdgeRestoreData)editedEdge.GetRestoreData()); }
static void CalculateAttachedSegmentEnd(GeomLabel label, GeomEdge edge) { label.AttachmentSegmentEnd = edge.Curve[edge.Curve.ClosestParameter(label.Center)]; }
/// <summary> /// constructor /// </summary> /// <param name="editedEdgePar"></param> public EdgeDragUndoRedoAction(GeomEdge editedEdgePar) : base((GeometryGraph)editedEdgePar.Parent) { this.editedEdge = editedEdgePar; this.AddRestoreData(editedEdgePar, (EdgeRestoreData)editedEdgePar.GetRestoreData()); }
/// <summary> /// Constructor. At the moment of the constructor call the site should not be inserted yet /// </summary> /// <param name="edgeToEdit"></param> public SiteInsertUndoAction(GeomEdge edgeToEdit) : base((GeometryGraph)edgeToEdit.Parent) { this.editedEdge = edgeToEdit; this.AddRestoreData(editedEdge, (EdgeRestoreData)editedEdge.GetRestoreData()); }