private void canNetwork_MouseUp(object sender, MouseEventArgs e) { switch (e.Button) { case MouseButtons.Left: { switch (State) { case CanvasState.None: { break; } case CanvasState.Create: { var node = new Node { X = e.X, Y = e.Y }; var nodes = Nodes; var index = 0; var name = $"node_{index}"; while (nodes.Count((x) => x.Name == name) > 0) { name = $"node_{++index}"; } node.Name = name; canNetwork.AddItem(node); break; } case CanvasState.Move: { State = CanvasState.None; ClickItem = null; break; } case CanvasState.Link: { break; } default: { break; } } break; } case MouseButtons.None: { break; } case MouseButtons.Right: { switch (State) { case CanvasState.None: { if (Connection == null && ClickItem != null) { var itemType = ClickItem is Node?nameof(Node) : ClickItem is Link?nameof(Link) : ClickItem is Stream?nameof(Stream) : nameof(Domain); ContextMenu.MenuItems.Clear(); ContextMenu.MenuItems.Add($"Edit {itemType}", EditElement); ContextMenu.MenuItems.Add($"Delete {itemType}", DeleteElement); ContextMenu.MenuItems.Add("Close Menu"); ContextMenu.Show(this, new Point(e.X, e.Y)); } break; } case CanvasState.Create: { var domain = new Domain { X = e.X, Y = e.Y, }; var domains = Domains; var index = 0; var name = $"domain_{index}"; while (domains.Count((x) => x.Name == name) > 0) { name = $"domain_{++index}"; } domain.Name = name; canNetwork.AddItem(domain); break; } case CanvasState.Move: { State = CanvasState.None; ClickItem = null; break; } case CanvasState.Domain: { var domain = Connection as Domain; // TODO: add nodes to domain. var nodes = Nodes.Where((x) => x.Position.Distance(domain.Position) < domain.Radius); domain.Nodes.AddRange(nodes); Connection = null; ClickItem = null; canNetwork.Invalidate(); break; } case CanvasState.Link: { var item = canNetwork.GetItem(e.X, e.Y, (x) => x is Node); if (item != null && ClickItem != null && ClickItem is Node) { var start = ClickItem as Node; var end = item as Node; var link = Connection as Link; link.EndNode = end; link.X = (start.X + end.X) / 2; link.Y = (start.Y + end.Y) / 2; // Update drawn area. canNetwork.UpdateItem(link); Connection = null; ClickItem = null; } else { canNetwork.Items.Remove(Connection); canNetwork.Invalidate(); } break; } } break; } case MouseButtons.Middle: { switch (State) { case CanvasState.None: { break; } case CanvasState.Create: { break; } case CanvasState.Move: { State = CanvasState.None; ClickItem = null; break; } case CanvasState.Stream: { var item = canNetwork.GetItem(e.X, e.Y, (x) => x is Node); if (item != null && ClickItem != null && ClickItem is Node) { var start = ClickItem as Node; var end = item as Node; var stream = Connection as Stream; stream.EndNode = end; stream.X = (start.X + end.X) / 2; stream.Y = (start.Y + end.Y) / 2; // Update drawn area. canNetwork.UpdateItem(stream); Connection = null; ClickItem = null; } else { canNetwork.Items.Remove(Connection); canNetwork.Invalidate(); } break; } default: { break; } } break; } case MouseButtons.XButton1: { break; } case MouseButtons.XButton2: { break; } default: { break; } } }
private void canNetwork_MouseMove(object sender, MouseEventArgs e) { if (Math.Abs(e.X - ClickPosition.X) + Math.Abs(e.Y - ClickPosition.Y) > 5) { if (ClickItem != null) { switch (e.Button) { case MouseButtons.Left: { switch (State) { case CanvasState.Move: case CanvasState.None: { State = CanvasState.Move; if (ClickItem is Node) { var node = ClickItem as Node; var startRect = node.DrawableBounds(); var oldPos = node.Position; node.X = e.X; node.Y = e.Y; var drawRect = node.DrawableBounds().Merge(startRect); // Update link positions. var links = canNetwork.Items.Where((x) => x is Link); foreach (Link link in links) { if (link.StartNode == node || link.EndNode == node) { var other = link.StartNode == node ? link.EndNode.Position : link.StartNode.Position; var mid = link.StartNode.Position.Mid(link.EndNode.Position); var oldMid = oldPos.Mid(other); // Reset to the midpoint if within tolerance. if (link.Position.Distance(oldMid) < 10) { link.Position = mid; } // Shift link label otherwise. else { var oldAngle = oldPos.Angle(); var newAngle = node.Position.Angle(); var oldMidAngle = oldMid.Angle(link.Position); var newMidAngle = oldMidAngle + newAngle - oldAngle; var dist = oldMid.Distance(link.Position); var unit = new PointF((float)Math.Cos(newMidAngle), (float)Math.Sin(newMidAngle)); var offset = unit.Multiply((float)dist); link.X = mid.X + offset.X; link.Y = mid.Y + offset.Y; } drawRect = link.DrawableBounds().Merge(drawRect); } } // Update stream positions. foreach (Stream stream in Streams) { if (stream.StartNode == node || stream.EndNode == node) { var other = stream.StartNode == node ? stream.EndNode.Position : stream.StartNode.Position; var mid = stream.StartNode.Position.Mid(stream.EndNode.Position); var oldMid = oldPos.Mid(other); // Reset to the midpoint if within tolerance. if (stream.Position.Distance(oldMid) < 10) { stream.Position = mid; } // Shift link label otherwise. else { var oldAngle = oldPos.Angle(); var newAngle = node.Position.Angle(); var oldMidAngle = oldMid.Angle(stream.Position); var newMidAngle = oldMidAngle + newAngle - oldAngle; var dist = oldMid.Distance(stream.Position); var unit = new PointF((float)Math.Cos(newMidAngle), (float)Math.Sin(newMidAngle)); var offset = unit.Multiply((float)dist); stream.X = mid.X + offset.X; stream.Y = mid.Y + offset.Y; } drawRect = stream.DrawableBounds().Merge(drawRect); } } // Redraw changed region. canNetwork.Invalidate(startRect.Merge(drawRect)); } else if (ClickItem is Link) { var link = ClickItem as Link; var startRect = link.DrawableBounds(); link.X = e.X; link.Y = e.Y; var endRect = link.DrawableBounds(); // Redraw changed region. canNetwork.Invalidate(startRect.Merge(endRect)); } else if (ClickItem is Stream) { var stream = ClickItem as Stream; var startRect = stream.DrawableBounds(); stream.X = e.X; stream.Y = e.Y; var endRect = stream.DrawableBounds(); // Redraw changed region. canNetwork.Invalidate(startRect.Merge(endRect)); } else if (ClickItem is Domain) { var domain = ClickItem as Domain; var startRect = domain.DrawableBounds(); domain.X = e.X; domain.Y = e.Y; var endRect = domain.DrawableBounds(); // Redraw changed region. canNetwork.Invalidate(startRect.Merge(endRect)); } break; } case CanvasState.Create: { break; } case CanvasState.Link: { break; } case CanvasState.Select: { break; } } break; } case MouseButtons.None: { break; } case MouseButtons.Right: { switch (State) { case CanvasState.Move: case CanvasState.None: { if (ClickItem is Node) { State = CanvasState.Link; var node = ClickItem as Node; var link = new Link { X = e.X, Y = e.Y, StartNode = node }; var links = Links; var index = 0; var name = $"link_{index}"; while (links.Count((x) => x.Name == name) > 0) { name = $"link_{++index}"; } link.Name = name; link.BaseAddress = $"10.0.{index + 1}.0"; Connection = link; canNetwork.AddItem(link); } break; } case CanvasState.Create: { break; } case CanvasState.Link: { var link = Connection as Link; var startRect = link.DrawableBounds(); link.X = e.X; link.Y = e.Y; var endRect = link.DrawableBounds(); // Redraw changed region. canNetwork.Invalidate(startRect.Merge(endRect)); break; } case CanvasState.Domain: { break; } case CanvasState.Select: { break; } } break; } case MouseButtons.Middle: { switch (State) { case CanvasState.Move: case CanvasState.None: { if (ClickItem is Node) { State = CanvasState.Stream; var node = ClickItem as Node; var stream = new Stream { X = e.X, Y = e.Y, StartNode = node }; var streams = Streams; var index = 0; var name = $"stream_{index}"; while (streams.Count((x) => x.Name == name) > 0) { name = $"stream_{++index}"; } stream.Name = name; Connection = stream; canNetwork.AddItem(stream); } break; } case CanvasState.Stream: { var stream = Connection as Stream; var startRect = stream.DrawableBounds(); stream.X = e.X; stream.Y = e.Y; var endRect = stream.DrawableBounds(); // Redraw changed region. canNetwork.Invalidate(startRect.Merge(endRect)); break; } } break; } case MouseButtons.XButton1: { break; } case MouseButtons.XButton2: { break; } } } else { if (e.Button == MouseButtons.Right) { switch (State) { case CanvasState.Create: { State = CanvasState.Domain; var domain = new Domain { X = e.X, Y = e.Y, Radius = (float)e.Location.Distance(ClickPosition) }; Connection = domain; var domains = Domains; var index = 0; var name = $"domain_{index}"; while (domains.Count((x) => x.Name == name) > 0) { name = $"domain_{++index}"; } domain.Name = name; canNetwork.AddItem(domain); break; } case CanvasState.Domain: { var domain = Connection as Domain; var startRect = domain.DrawableBounds(); domain.Radius = (float)e.Location.Distance(ClickPosition); var endRect = domain.DrawableBounds(); // Redraw changed region. canNetwork.Invalidate(startRect.Merge(endRect)); break; } } } } } }