コード例 #1
0
ファイル: Form1.cs プロジェクト: rabirland/LogicCircuit
 // 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)));
     }
 }
コード例 #2
0
ファイル: Form1.cs プロジェクト: rabirland/LogicCircuit
        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);
        }
コード例 #3
0
ファイル: Form1.cs プロジェクト: rabirland/LogicCircuit
        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)));
            }
        }
コード例 #4
0
ファイル: Form1.cs プロジェクト: rabirland/LogicCircuit
 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;
 }
コード例 #5
0
ファイル: Form1.cs プロジェクト: rabirland/LogicCircuit
        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);
        }
コード例 #6
0
ファイル: Form1.cs プロジェクト: rabirland/LogicCircuit
        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);
        }
コード例 #7
0
ファイル: Form1.cs プロジェクト: rabirland/LogicCircuit
        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
        }
コード例 #8
0
ファイル: Form1.cs プロジェクト: rabirland/LogicCircuit
        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();
        }
コード例 #9
0
ファイル: Form1.cs プロジェクト: rabirland/LogicCircuit
        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);
        }
コード例 #10
0
ファイル: Form1.cs プロジェクト: rabirland/LogicCircuit
        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);
        }
コード例 #11
0
ファイル: Form1.cs プロジェクト: rabirland/LogicCircuit
        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);
        }
コード例 #12
0
ファイル: Form1.cs プロジェクト: rabirland/LogicCircuit
        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();
            }
        }
コード例 #13
0
ファイル: Form1.cs プロジェクト: rabirland/LogicCircuit
        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;
                }
            }
        }
コード例 #14
0
ファイル: Form1.cs プロジェクト: rabirland/LogicCircuit
        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);
        }
コード例 #15
0
ファイル: Form1.cs プロジェクト: rabirland/LogicCircuit
        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();
        }
コード例 #16
0
ファイル: Form1.cs プロジェクト: rabirland/LogicCircuit
        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));
        }
コード例 #17
0
ファイル: Form1.cs プロジェクト: rabirland/LogicCircuit
        private bool IsNodeOutputPortClicked(NodeEntry entry, Point clickLocation)
        {
            Point outputPos = this.CalculateOutputPortLocation(entry);

            return(DistanceBetween(outputPos, clickLocation) < this._portRadius + this._outlinePen.Width);
        }