/// <summary> /// Add a new line to the graph between two nodes /// </summary> /// <remarks>If line already exists and direction matches will return the same line</remarks> /// <param name="source">The source node</param> /// <param name="dest">The destination node</param> /// <param name="biDirection">Indicates the line is bi-directional</param> /// <param name="label">Label for the line, can be null</param> /// <returns>The newly created line</returns> public GraphLine AddLine(GraphNode source, GraphNode dest) { // Check if we have already assigned this line or we have the other way foreach (GraphLine line in _lines) { if ((line.SourceShape == source) && (line.DestShape == dest)) { return(line); } if ((line.SourceShape == dest) && (line.DestShape == source)) { if (AllowBidirectionLines) { line.BiDirection = true; Dirty = true; } return(line); } } GraphLine l = AddNewLine(source, dest, false, null); Dirty = true; return(l); }
/// <summary> /// Delete a line /// </summary> /// <param name="line">The line to delete</param> public void DeleteLine(GraphLine line) { _lines.Remove(line); if (_selectedObject == line) { SelectedObject = null; } Dirty = true; Invalidate(); }
private GraphLine AddNewLine(GraphNode sourceShape, GraphNode destShape, bool biDirection, string label) { GraphLine l = new GraphLine(); l.SourceShape = sourceShape; l.DestShape = destShape; l.LineColor = Color.Black; l.BiDirection = biDirection; l.Label = label; _lines.Add(l); return(l); }
/// <summary> /// TODO: Implement proper clipping to improve performance with alot of objects /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void GraphEditorClass_Paint(object sender, PaintEventArgs e) { if (DesignMode) { GraphNode node = new GraphNodeRoundedRectangle(Guid.NewGuid(), new RectangleF(10.0f, 10.0f, 100.0f, 50.0f), 0.0f, Color.AliceBlue, Color.Black, Color.Red, Color.Black, Color.Black); node.Label = "DEMO1"; var g = e.Graphics; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; if (DrawDropShadow) { node.DrawDropShadow(g, DropShadowOffsetX, DropShadowOffsetY); } node.Draw(g, this.Font, false); } else { Graphics g = e.Graphics; //List<GraphNode> drawNodes = new List<GraphNode>(); //List<GraphLine> drawLines = new List<GraphLine>(); List <GraphNode> drawNodes = new List <GraphNode>(_nodes); List <GraphLine> drawLines = new List <GraphLine>(_lines); List <GraphLinkLine> drawLinkLines = new List <GraphLinkLine>(_linkLines); g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.ScaleTransform(_zoom, _zoom); g.TranslateTransform(-_scrollPosition.X, -_scrollPosition.Y); //g.ScaleTransform(_zoom, _zoom); //g.TranslateTransform(-_scrollPosition.X, -_scrollPosition.Y); //foreach (GraphNode n in _nodes) //{ // RectangleF boundary = n.Boundary; // if (DrawDropShadow) // { // boundary = new RectangleF(boundary.Location, new SizeF(boundary.Width + DropShadowOffsetX, boundary.Height + DropShadowOffsetY)); // } // if (g.Clip.IsVisible(boundary)) // { // drawNodes.Add(n); // } //} //foreach (GraphLine l in _lines) //{ // if (g.Clip.IsVisible(GraphUtils.GetLineBoundingBox(l.SourceShape.Center, l.DestShape.Center))) // { // drawLines.Add(l); // } //} if (DrawDropShadow) { foreach (var n in drawNodes) { n.DrawDropShadow(g, DropShadowOffsetX, DropShadowOffsetY); } } foreach (var l in drawLinkLines) { l.Draw(g); } foreach (var l in drawLines) { if (l != _selectedObject) { l.Draw(g, this.Font, false); } } foreach (var s in drawNodes) { s.Draw(g, this.Font, s == _selectedObject); } // Always draw a selected line above everything if (_selectedObject is GraphLine) { GraphLine l = _selectedObject as GraphLine; l.Draw(g, this.Font, true); } // We are dragging a line from a graph node if ((_draggingMode == DraggingMode.DrawLine) && (_selectedObject != null) && (_selectedObject is GraphNode)) { Pen p = null; GraphNode node = _selectedObject as GraphNode; try { p = new Pen(Brushes.Black); g.DrawLine(p, node.Center, _lastDragPoint); } finally { if (p != null) { p.Dispose(); } } } } }
/// <summary> /// Add a pre configured node to the graph /// </summary> /// <param name="p">The point location of the centre (in document co-ordinates)</param> /// <param name="z">The z level of the node</param> /// <param name="id">The ID of the node</param> /// <param name="name">The text for the node</param> /// <param name="shape">The shape type</param> /// <param name="width">The width</param> /// <param name="height">The height</param> /// <param name="backColor">The back color</param> /// <param name="lineColor">The line color</param> /// <param name="selectedLineColor">The selected line color</param> /// <param name="textColor">The text color</param> /// <param name="hatchedColor">The hatched color</param> /// <param name="tag">A opaque object to store in the node</param> /// <exception cref="System.ArgumentException">Throw if node shape is unknown</exception> /// <returns>The created node</returns> private GraphNode AddNodeInternal(PointF p, float z, Guid id, string name, GraphNodeShape shape, float width, float height, Color backColor, Color lineColor, Color selectedLineColor, Color textColor, Color hatchedColor, object tag) { GraphNode s; switch (shape) { case GraphNodeShape.Ellipse: s = new GraphNodeCircle(id, CreateBoundary(p, width, height), z, backColor, lineColor, selectedLineColor, textColor, hatchedColor); break; case GraphNodeShape.Rectangle: s = new GraphNodeRectangle(id, CreateBoundary(p, width, height), z, backColor, lineColor, selectedLineColor, textColor, hatchedColor); break; case GraphNodeShape.RoundedRectangle: s = new GraphNodeRoundedRectangle(id, CreateBoundary(p, width, height), z, backColor, lineColor, selectedLineColor, textColor, hatchedColor); break; case GraphNodeShape.Triangle: s = new GraphNodeTriangle(id, CreateBoundary(p, width, height), z, backColor, lineColor, selectedLineColor, textColor, hatchedColor); break; case GraphNodeShape.Rhombus: s = new GraphNodeRhombus(id, CreateBoundary(p, width, height), z, backColor, lineColor, selectedLineColor, textColor, hatchedColor); break; default: throw new ArgumentException(CANAPE.Controls.GraphEditor.Properties.Resources.GraphEditorControl_InvalidNodeType); } GraphLine line = GetHitObjectInternal(p) as GraphLine; if (line != null) { if (MessageBox.Show(this, CANAPE.Controls.GraphEditor.Properties.Resources.GraphEditorControl_SplitLineMessage, CANAPE.Controls.GraphEditor.Properties.Resources.GraphEditorControl_SplitLineCaption, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { string label = line.Label; _lines.Remove(line); if (_selectedObject == line) { SelectedObject = null; } AddNewLine(line.SourceShape, s, line.BiDirection, label); AddNewLine(s, line.DestShape, line.BiDirection, null); } } s.Label = name; s.Tag = tag; _nodes.Add(s); // Use the move location function to adjust the position to fit within the boundary s.MoveLocation(new SizeF(), new RectangleF(0, 0, DocumentWidth, DocumentHeight)); Dirty = true; Invalidate(); return(s); }
/// <summary> /// TODO: Implement proper clipping to improve performance with alot of objects /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void GraphEditorClass_Paint(object sender, PaintEventArgs e) { if (DesignMode) { GraphNode node = new GraphNodeRoundedRectangle(Guid.NewGuid(), new RectangleF(10.0f, 10.0f, 100.0f, 50.0f), 0.0f, Color.AliceBlue, Color.Black, Color.Red, Color.Black, Color.Black); node.Label = "DEMO1"; var g = e.Graphics; g.SmoothingMode = SmoothingMode.AntiAlias; if (DrawDropShadow) { node.DrawDropShadow(g, DropShadowOffsetX, DropShadowOffsetY); } node.Draw(g, this.Font, false); } else { Graphics g = e.Graphics; List <GraphNode> drawNodes = new List <GraphNode>(_nodes); List <GraphLine> drawLines = new List <GraphLine>(_lines); List <GraphLinkLine> drawLinkLines = new List <GraphLinkLine>(_linkLines); g.SmoothingMode = SmoothingMode.AntiAlias; g.TranslateTransform(-_scrollPosition.X, -_scrollPosition.Y); if (DrawDropShadow) { foreach (var n in drawNodes) { n.DrawDropShadow(g, DropShadowOffsetX, DropShadowOffsetY); } } foreach (var l in drawLinkLines) { l.Draw(g); } foreach (var l in drawLines) { if (l != _selectedObject) { l.Draw(g, this.Font, false); } } foreach (var s in drawNodes) { s.Draw(g, this.Font, s == _selectedObject); } // Always draw a selected line above everything if (_selectedObject is GraphLine) { GraphLine l = _selectedObject as GraphLine; l.Draw(g, this.Font, true); } // We are dragging a line from a graph node if ((_draggingMode == DraggingMode.DrawLine) && (_selectedObject != null) && (_selectedObject is GraphNode)) { Pen p = null; GraphNode node = _selectedObject as GraphNode; try { p = new Pen(Brushes.Black); g.DrawLine(p, node.Center, _lastDragPoint); } finally { if (p != null) { p.Dispose(); } } } } }
private GraphLine AddNewLine(GraphNode sourceShape, GraphNode destShape, bool biDirection, string label) { GraphLine l = new GraphLine(); l.SourceShape = sourceShape; l.DestShape = destShape; l.LineColor = Color.Black; l.BiDirection = biDirection; l.Label = label; _lines.Add(l); return l; }
public LineContainer(GraphLine line, GraphEditorControl control) { _line = line; _control = control; }