Skip to content

Commit 536325c

Browse files
committed
Add wires.
1 parent 3ee90a2 commit 536325c

File tree

7 files changed

+196
-28
lines changed

7 files changed

+196
-28
lines changed

LogicSandbox/Forms/FormMain.cs

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Drawing.Drawing2D;
88
using System.Linq;
99
using System.Windows.Forms;
10+
using Maxstupo.LogicSandbox.Logic;
1011
using Maxstupo.LogicSandbox.Logic.Components;
1112
using Maxstupo.LogicSandbox.Properties;
1213
using Maxstupo.LogicSandbox.Shapes;
@@ -17,15 +18,16 @@ public partial class FormMain : Form {
1718
private Keys AdditiveKey { get; set; } = Keys.Control;
1819
private Keys InclusiveKey { get; set; } = Keys.Shift;
1920

20-
private readonly List<DigitalComponent> digitalComponents = new List<DigitalComponent>();
21-
21+
private Circuit circuit = new Circuit();
2222
private readonly Selector<DigitalComponent> selector;
2323
private readonly Transformer<DigitalComponent> transformer = new Transformer<DigitalComponent>();
2424

25+
private Pin selectedPin;
26+
2527
public FormMain() {
2628
InitializeComponent();
2729

28-
selector = new Selector<DigitalComponent>(digitalComponents);
30+
selector = new Selector<DigitalComponent>(circuit.Components);
2931
selector.OnDragging += (s, e) => canvas.Refresh();
3032
selector.OnEndDrag += Selector_OnEndDrag;
3133

@@ -40,14 +42,15 @@ public FormMain() {
4042
}
4143

4244
private void FormMain_Load(object sender, EventArgs e) {
45+
canvas.Zoom = 2;
4346
canvas.Center();
4447

4548

46-
digitalComponents.Add(new NotGate("not_gate0", 10, 60));
47-
digitalComponents.Add(new NotGate("not_gate0", -40, 20));
48-
digitalComponents.Add(new NotGate("not_gate0", 50, -20));
49-
digitalComponents.Add(new NotGate("not_gate0", -20, -50));
50-
digitalComponents.Add(new NotGate("not_gate0", 90, -90));
49+
circuit.Components.Add(new NotGate("not_gate0", 10, 60));
50+
circuit.Components.Add(new NotGate("not_gate0", -40, 20));
51+
circuit.Components.Add(new NotGate("not_gate0", 50, -20));
52+
circuit.Components.Add(new NotGate("not_gate0", -20, -50));
53+
circuit.Components.Add(new NotGate("not_gate0", 90, -90));
5154
}
5255

5356
private void Canvas_Paint(object sender, PaintEventArgs e) {
@@ -57,33 +60,47 @@ private void Canvas_Paint(object sender, PaintEventArgs e) {
5760
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
5861
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
5962

60-
foreach (DigitalComponent component in digitalComponents)
61-
component.Draw(g);
63+
circuit.Draw(g);
64+
65+
if (selectedPin != null)
66+
g.DrawLine(Pens.Blue, canvas.MouseWorldX, canvas.MouseWorldY, selectedPin.GlobalX, selectedPin.GlobalY);
6267

6368
selector.Draw(g);
6469
}
6570

6671
private void Canvas_MouseDown(object sender, MouseEventArgs e) {
6772
if (e.Button == MouseButtons.Left) {
6873

69-
bool additiveMode = ModifierKeys.HasFlag(AdditiveKey); // Previous selection not cleared.
74+
selectedPin = circuit.GetPinOver();
75+
if (selectedPin == null) {
7076

71-
if (!selector.Start(canvas.MouseWorldX, canvas.MouseWorldY, additiveMode, GetItemOver)) {
77+
bool additiveMode = ModifierKeys.HasFlag(AdditiveKey); // Previous selection not cleared.
7278

73-
transformer.Clear();
74-
transformer.AddItems(selector.SelectedItems);
75-
transformer.StartDrag(canvas.MouseWorldX, canvas.MouseWorldY);
79+
if (!selector.Start(canvas.MouseWorldX, canvas.MouseWorldY, additiveMode, (x, y) => circuit.GetComponentOver())) {
80+
81+
transformer.Clear();
82+
transformer.AddItems(selector.SelectedItems);
83+
transformer.StartDrag(canvas.MouseWorldX, canvas.MouseWorldY);
84+
85+
canvas.Refresh();
86+
}
7687

77-
canvas.Refresh();
7888
}
7989

90+
} else if (e.Button == MouseButtons.Right) {
91+
8092
}
93+
8194
}
8295

8396
private void Canvas_MouseMove(object sender, MouseEventArgs e) {
84-
selector.Drag(canvas.MouseWorldX, canvas.MouseWorldY);
97+
bool needsRefresh = circuit.Update(canvas.MouseWorldX, canvas.MouseWorldY);
8598

99+
selector.Drag(canvas.MouseWorldX, canvas.MouseWorldY);
86100
transformer.Drag(canvas.MouseWorldX, canvas.MouseWorldY);
101+
102+
if (needsRefresh || selectedPin != null)
103+
canvas.Refresh();
87104
}
88105

89106
private void Canvas_MouseUp(object sender, MouseEventArgs e) {
@@ -94,8 +111,19 @@ private void Canvas_MouseUp(object sender, MouseEventArgs e) {
94111

95112
selector.EndDrag(canvas.MouseWorldX, canvas.MouseWorldY, additiveMode, inclusiveMode);
96113
transformer.EndDrag();
114+
115+
if (selectedPin != null) {
116+
117+
Pin nextSelectedPin = circuit.GetPinOver();
118+
if (nextSelectedPin != null)
119+
circuit.AddWire(selectedPin, nextSelectedPin);
120+
121+
selectedPin = null;
122+
canvas.Refresh();
123+
}
124+
97125
}
98-
canvas.Refresh();
126+
99127
}
100128

101129
private void Selector_OnEndDrag(object sender, List<DigitalComponent> selectedItems) {
@@ -105,14 +133,7 @@ private void Selector_OnEndDrag(object sender, List<DigitalComponent> selectedIt
105133
}
106134

107135

108-
// TODO: Improve method.
109-
private DigitalComponent GetItemOver(float x, float y) {
110-
foreach (DigitalComponent component in digitalComponents) {
111-
if (component.ContainsPoint(x, y))
112-
return component;
113-
}
114-
return null;
115-
}
136+
116137

117138
#region Menu Strip
118139

LogicSandbox/Logic/Circuit.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
namespace Maxstupo.LogicSandbox.Logic {
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Drawing;
5+
using Maxstupo.LogicSandbox.Logic.Components;
6+
7+
public class Circuit {
8+
9+
public List<DigitalComponent> Components { get; } = new List<DigitalComponent>();
10+
11+
private readonly List<Wire> wires = new List<Wire>();
12+
13+
14+
15+
public void Draw(Graphics g) {
16+
foreach (DigitalComponent component in Components)
17+
component.Draw(g);
18+
19+
foreach (Wire wire in wires)
20+
wire.Draw(g);
21+
}
22+
23+
public bool Update(float x, float y) {
24+
bool needsRefresh = false;
25+
26+
foreach (DigitalComponent component in Components)
27+
needsRefresh |= component.Update(x, y);
28+
29+
return needsRefresh;
30+
}
31+
32+
public Pin GetPinOver() {
33+
foreach (DigitalComponent component in Components) {
34+
foreach (Pin pin in component) {
35+
if (pin.IsMouseOver)
36+
return pin;
37+
}
38+
}
39+
return null;
40+
}
41+
42+
public DigitalComponent GetComponentOver() {
43+
foreach (DigitalComponent component in Components) {
44+
if (component.IsMouseOver)
45+
return component;
46+
}
47+
return null;
48+
}
49+
50+
public void AddWire(Pin pinA, Pin pinB) {
51+
wires.Add(new Wire(pinA, pinB));
52+
}
53+
54+
}
55+
56+
}

LogicSandbox/Logic/Pin.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,29 @@
11
namespace Maxstupo.LogicSandbox.Logic {
2-
2+
using System;
33
using System.Drawing;
44
using Maxstupo.LogicSandbox.Logic.Components;
55
using Maxstupo.LogicSandbox.Shapes;
66

77
public class Pin : CircleShape {
88

9+
public static Color PinHighColor { get; set; } = Color.Red;
10+
public static Color PinLowColor { get; set; } = Color.Black;
11+
public static Color PinSelectedColor { get; set; } = Color.FromArgb(200, 200, 0);
12+
13+
914
public string Id { get; }
1015

1116
public Polarity Polarity { get; }
1217

18+
private bool value = false;
19+
public bool Value {
20+
get => value;
21+
set {
22+
this.value = value;
23+
OutlineColor = IsMouseOver ? PinSelectedColor : Value ? PinHighColor : PinLowColor;
24+
}
25+
}
26+
1327
public Pin(DigitalComponent component, string id, Polarity polarity, float x, float y, float diameter) : base(x, y, diameter, component) {
1428
Id = id;
1529
Polarity = polarity;
@@ -18,6 +32,17 @@ public Pin(DigitalComponent component, string id, Polarity polarity, float x, fl
1832

1933
OutlineColor = Color.Black;
2034
OutlineThickness = 1;
35+
36+
OnMouseEnter += Pin_OnMouseEnter;
37+
OnMouseLeave += Pin_OnMouseLeave;
38+
}
39+
40+
private void Pin_OnMouseLeave(object sender, EventArgs e) {
41+
OutlineColor = Value ? PinHighColor : PinLowColor;
42+
}
43+
44+
private void Pin_OnMouseEnter(object sender, EventArgs e) {
45+
OutlineColor = PinSelectedColor;
2146
}
2247

2348
}

LogicSandbox/Logic/Polarity.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
namespace Maxstupo.LogicSandbox.Logic {
2+
23
public enum Polarity {
34
Input,
45
Output

LogicSandbox/Logic/Wire.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
namespace Maxstupo.LogicSandbox.Logic {
2+
3+
using System;
4+
using System.Drawing;
5+
6+
public class Wire {
7+
8+
public Pin P1 { get; }
9+
10+
public Pin P2 { get; }
11+
12+
public Wire(Pin p1, Pin p2) {
13+
this.P1 = p1 ?? throw new ArgumentNullException(nameof(p1));
14+
this.P2 = p2 ?? throw new ArgumentNullException(nameof(p2));
15+
}
16+
17+
public void Draw(Graphics g) {
18+
g.DrawLine(!P1.Value ? Pens.Blue : Pens.Red, P1.GlobalX, P1.GlobalY, P2.GlobalX, P2.GlobalY);
19+
}
20+
21+
}
22+
23+
}

LogicSandbox/LogicSandbox.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,12 @@
5858
<Compile Include="Forms\FormMain.Designer.cs">
5959
<DependentUpon>FormMain.cs</DependentUpon>
6060
</Compile>
61+
<Compile Include="Logic\Circuit.cs" />
6162
<Compile Include="Logic\Components\DigitalComponent.cs" />
6263
<Compile Include="Logic\Components\NotGate.cs" />
6364
<Compile Include="Logic\Pin.cs" />
6465
<Compile Include="Logic\Polarity.cs" />
66+
<Compile Include="Logic\Wire.cs" />
6567
<Compile Include="Program.cs" />
6668
<Compile Include="Properties\AssemblyInfo.cs" />
6769
<Compile Include="Shapes\CircleShape.cs" />

LogicSandbox/Shapes/Shape.cs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
namespace Maxstupo.LogicSandbox.Shapes {
2-
2+
using System;
33
using System.Drawing;
44
using Maxstupo.LogicSandbox.Utility;
55
using Maxstupo.LogicSandbox.Utility.Interaction;
@@ -57,6 +57,12 @@ public bool PercentagePosition {
5757
public float CornerRadius { get; set; } = 0;
5858

5959

60+
public bool IsMouseOver { get; private set; } = false;
61+
62+
public event EventHandler OnMouseEnter;
63+
public event EventHandler OnMouseLeave;
64+
65+
6066
public Shape(float x, float y, float width, float height, Shape parent = null) {
6167
X = x;
6268
Y = y;
@@ -68,6 +74,40 @@ public Shape(float x, float y, float width, float height, Shape parent = null) {
6874
}
6975

7076

77+
public bool Update(float mx, float my) {
78+
79+
foreach (Shape child in this) { // Check descendants first.
80+
if (child.Update(mx, my)) {
81+
if (IsMouseOver) {
82+
IsMouseOver = false;
83+
OnMouseLeave?.Invoke(this, EventArgs.Empty);
84+
}
85+
return true;
86+
}
87+
}
88+
89+
bool mouseOver = ContainsPoint(mx, my);
90+
91+
if (mouseOver && !IsMouseOver) { // Mouse Enter
92+
IsMouseOver = true;
93+
94+
OnMouseEnter?.Invoke(this, EventArgs.Empty);
95+
return true;
96+
97+
} else if (!mouseOver && IsMouseOver) { // Mouse Leave
98+
IsMouseOver = false;
99+
100+
OnMouseLeave?.Invoke(this, EventArgs.Empty);
101+
return true;
102+
103+
}
104+
105+
106+
return mouseOver;
107+
}
108+
109+
110+
71111
protected abstract void DrawShape(Graphics g);
72112

73113
public virtual void Draw(Graphics g) {

0 commit comments

Comments
 (0)