// Helpers private IEnumerable <KeyValuePair <int, Point> > CalculateInputPortLocations(NodeEntry entry) { for (int i = 0; i < entry.Node.InputCount; i++) { yield return(new KeyValuePair <int, Point>(i + 1, CalculateInputPortLocation(entry, i))); } }
private void DrawBulb(Graphics g, Rectangle backgroundRect, NodeEntry entry, bool isOn) { var brush = isOn ? this._onBrush : this._offBrush; g.FillEllipse(brush, backgroundRect); g.DrawEllipse(this._outlinePen, backgroundRect); }
private void DrawGateName(Graphics g, Rectangle backgroundRect, NodeEntry entry) { if (entry.Node.GateName != null) { var stringSize = g.MeasureString(entry.Node.GateName, this._gateNameFont); var center = CalculateCenter(entry.Rect); g.DrawString(entry.Node.GateName, this._gateNameFont, Brushes.Black, new Point(center.X - (int)(stringSize.Width / 2), center.Y - (int)(stringSize.Height / 2))); } }
private void CircuitPanel_MouseUp(object sender, MouseEventArgs e) { if (this._interacted != null && this._interacted.Node is InteractiveNode intN && this._isPressed) { intN.Release(); } this._interacted = null; this._isPressed = false; this._startedDragging = false; this._didDragging = false; }
private void DrawSWITCH(Graphics g, Rectangle backgroundRect, NodeEntry entry, bool isOn) { g.FillRectangle(this._iconBackgroundBrush, backgroundRect); g.DrawRectangle(this._outlinePen, backgroundRect); var interactiveRect = this.CalculateInteractiveZone(backgroundRect); var brush = isOn ? this._onBrush : this._offBrush; g.FillRectangle(brush, interactiveRect); g.DrawRectangle(this._outlinePen, interactiveRect); }
private void DrawXOR(Graphics g, Rectangle backgroundRect, NodeEntry entry) { int cY = backgroundRect.Y + (backgroundRect.Height / 2); this.DrawOR(g, new Rectangle(backgroundRect.X + XorLeftOffset, backgroundRect.Y, backgroundRect.Width - XorLeftOffset, backgroundRect.Height), entry); g.DrawCurve(this._outlinePen, new Point[] { new Point(backgroundRect.Left, backgroundRect.Top), new Point(backgroundRect.Left + OrCurvatureOffset, cY), new Point(backgroundRect.Left, backgroundRect.Bottom), }, OrCurvatureTension); }
private Point CalculateInputPortLocation(NodeEntry entry, int portIndex) { var partSize = entry.InputOnly ? (entry.Rect.Width - (this._portsMargin * 2)) / entry.Node.InputCount : (entry.Rect.Height - (this._portsMargin * 2)) / entry.Node.InputCount; var partHalf = partSize / 2; return (entry.InputOnly ? new Point(entry.Rect.X + (portIndex * partSize) + partHalf + this._portsMargin, entry.Rect.Bottom - this._portRadius) // Input port on bottom : new Point(entry.Rect.X + this._portRadius, entry.Rect.Y + (portIndex * partSize) + partHalf + this._portsMargin)); // Input port on left }
private void AddNode(Node node) { var nodeEntry = new NodeEntry(node, new Point(150, 150), new Size(100, 100)); nodeEntry.Size = nodeEntry.InputOnly ? new Size(100, 100 + this._portRadius * 2) : new Size(100 + this._portRadius * 2, 100); this._nodes.Add(nodeEntry); this._circuit.AddNode(node); this.CircuitPanel.Refresh(); }
private void DrawNOT(Graphics g, Rectangle backgroundRect, NodeEntry entry) { var cY = backgroundRect.Y + (backgroundRect.Height / 2); GraphicsPath path = new GraphicsPath(); path.AddLine(new Point(backgroundRect.Left, backgroundRect.Top), new Point(backgroundRect.Left, backgroundRect.Bottom)); // Rear Line path.AddLine(new Point(backgroundRect.Left, backgroundRect.Bottom), new Point(backgroundRect.Right - NotTipRadius * 2, cY)); path.CloseFigure(); path.AddEllipse(new Rectangle(new Point(backgroundRect.Right - NotTipRadius * 2, cY - NotTipRadius), new Size(NotTipRadius * 2, NotTipRadius * 2))); g.FillPath(this._iconBackgroundBrush, path); g.DrawPath(this._outlinePen, path); }
private void DrawAND(Graphics g, Rectangle backgroundRect, NodeEntry entry) { var hX = backgroundRect.Width / 2; var cX = backgroundRect.X + hX; GraphicsPath path = new GraphicsPath(); path.AddArc(cX, backgroundRect.Top, hX, backgroundRect.Height, 270, 180); path.AddLine(new Point(backgroundRect.Left, backgroundRect.Bottom), new Point(cX, backgroundRect.Bottom)); // Bottom path.AddLine(new Point(backgroundRect.Left, backgroundRect.Bottom), new Point(backgroundRect.Left, backgroundRect.Top)); // Left path.AddLine(new Point(cX, backgroundRect.Top), new Point(backgroundRect.Left, backgroundRect.Top)); // Top path.CloseFigure(); g.FillPath(this._iconBackgroundBrush, path); g.DrawPath(this._outlinePen, path); }
private bool IsNodeInputPortClicked(NodeEntry entry, Point clickLocation, out int portNumber) { for (int i = 0; i < entry.Node.InputCount; i++) { var pos = this.CalculateInputPortLocation(this._interacted, i); if (DistanceBetween(pos, clickLocation) < this._portRadius + this._outlinePen.Width) { portNumber = i + 1; return(true); } } portNumber = -1; return(false); }
private void DeleteToolStripMenuItem1_Click(object sender, EventArgs e) // Node { if (this._selected != null && this._selectedPort == null) { this._circuit.RemoveNode(this._selected.Node); // Delete all wire var deletedWires = this._wires.Where(w => w.Wire.InputNode == this._selected.Node || w.Wire.OutputNode == this._selected.Node).ToArray(); foreach (var wire in deletedWires) { this._wires.Remove(wire); } this._nodes.Remove(this._selected); this._selected = null; this.CircuitPanel.Refresh(); } }
private void CircuitPanel_MouseDown(object sender, MouseEventArgs e) { this._interacted = this.GetNodeAtLocation(e.Location); if (this._interacted != null && e.Button == MouseButtons.Left) { this._nodeLocationAtDragStart = this._interacted.Location; if (this._interacted.IsInteractive && this.CalculateInteractiveZone(this.CalculateIconRect(this._interacted.Rect, this._interacted.InputOnly)).Contains(e.Location)) { this._isPressed = true; ((InteractiveNode)this._interacted.Node).Press(); } else { this._dragStart = e.Location; this._startedDragging = true; } } }
private void DrawOR(Graphics g, Rectangle backgroundRect, NodeEntry entry) { int cX = backgroundRect.X + (backgroundRect.Width / 2); int cY = backgroundRect.Y + (backgroundRect.Height / 2); // Draw enough curves so that it can fully connect with the rectangle GraphicsPath path = new GraphicsPath(); path.AddCurve(new Point[] // Left Curve { new Point(backgroundRect.Left, backgroundRect.Top), new Point(backgroundRect.Left + OrCurvatureOffset, cY), new Point(backgroundRect.Left, backgroundRect.Bottom), }, OrCurvatureTension); path.AddLine(new Point(backgroundRect.Left, backgroundRect.Bottom), new Point(cX, backgroundRect.Bottom)); // Bottom Line path.AddCurve(new Point[] // Right bottom curve { new Point(cX, backgroundRect.Bottom), new Point(cX + OrCurvatureOffset, backgroundRect.Bottom - (OrCurvatureOffset / 2)), new Point(backgroundRect.Right - OrCurvatureOffset, cY + (OrCurvatureOffset / 2)), new Point(backgroundRect.Right, cY), }, OrCurvatureTension); path.AddCurve(new Point[] // Right Top curve { new Point(backgroundRect.Right, cY), new Point(backgroundRect.Right - OrCurvatureOffset, cY - (OrCurvatureOffset / 2)), new Point(cX + OrCurvatureOffset, backgroundRect.Top + (OrCurvatureOffset / 2)), new Point(cX, backgroundRect.Top), }, OrCurvatureTension); //path.AddLine(new Point(centerX, centerY - halfSide), new Point(centerX - halfSide, centerY - halfSide)); // Top path.CloseFigure(); g.FillPath(this._iconBackgroundBrush, path); g.DrawPath(this._outlinePen, path); }
private void CircuitPanel_MouseClick(object sender, MouseEventArgs e) { if (this._selectedPort != null && this._selected == null) { throw new Exception("Unexpected selection error"); } if (this._didDragging) { return; } if (e.Button == MouseButtons.Left) { if (this._interacted != null) // _dragging should be auto-filled in the MouseDown listener, if it's null => the user hasn't clicked on a node { if (this.IsNodeInputPortClicked(this._interacted, e.Location, out int portNumber)) // Check if we clicked on an input port { // There is already have a selected output port and not on the same object if (this._selectedPort != null && this._selectedPort == 0 && this._selected != this._interacted) { this.AddWire(new Wire(this._selected.Node, this._interacted.Node, portNumber)); // Clear port selection this._selected = null; this._selectedPort = null; } else // No port selected OR there was an input port selected OR we tried to connect a gate with itself => replace the selection { // Mark port selection this._selected = this._interacted; this._selectedPort = portNumber; // No current selected port => select the clicked one } } else if (IsNodeOutputPortClicked(this._interacted, e.Location)) // No input port was selected => Check is the output port was selected { // There was an input port selected and not on the same object => connect if (this._selectedPort != null && this._selectedPort > 0 && this._selected != this._interacted) { this.AddWire(new Wire(this._interacted.Node, this._selected.Node, this._selectedPort.Value)); // Clear port selection this._selected = null; this._selectedPort = null; } else // There was no port selected OR there was an input port selected OR we clicked on an input port but on the same object => replace the selection { this._selected = this._interacted; this._selectedPort = 0; } } else // Not clicked on output port either => simply clicked on the object somewhere { } } else // Clicked outside of a node { this._selected = null; this._selectedPort = null; } } else if (e.Button == MouseButtons.Right) { WireEntry wireEntry; if (this._interacted != null) // Clicked on node { this._selected = _interacted; this._selectedPort = null; this.nodeRightClickMenu.Show(this.CircuitPanel.PointToScreen(e.Location)); } else if ((wireEntry = GetWireAt(e.Location)) != null) // Clicked near wire { this._selectedWire = wireEntry; wireRightClickMenu.Show(this.CircuitPanel.PointToScreen(e.Location)); } else { this._selected = null; this._selectedWire = null; this._selectedPort = null; } } // Stop Dragging this._interacted = null; this.CircuitPanel.Refresh(); }
private Point CalculateOutputPortLocation(NodeEntry entry) { var heightHalf = entry.Size.Height / 2; return(new Point(entry.Location.X + entry.Size.Width - this._portRadius, entry.Location.Y + heightHalf)); }
private bool IsNodeOutputPortClicked(NodeEntry entry, Point clickLocation) { Point outputPos = this.CalculateOutputPortLocation(entry); return(DistanceBetween(outputPos, clickLocation) < this._portRadius + this._outlinePen.Width); }