-
Notifications
You must be signed in to change notification settings - Fork 1
/
FrmDevices.vb
412 lines (348 loc) · 19 KB
/
FrmDevices.vb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
Public Class FrmDevices
Public WithEvents PCB As PCB
'these dictionaries hold the treenodes for each device / devicepin or pad
Dim DeviceTreeNodes As Dictionary(Of Device, TreeNode)
Dim DevicePinTreeNodes As Dictionary(Of DevicePin, TreeNode)
Dim PadTreeNodes As Dictionary(Of Pad, TreeNode)
Private Enum DeviceTreeNodeType As Integer
DeviceTreeNodeRoot = 0
DeviceTreeNodeDevice = 1
DeviceTreeNodePin = 2
DeviceTreeNodePad = 4
End Enum
Private Class DeviceTreeNode
Public Type As DeviceTreeNodeType
Public NodeObject As Object
Public Device As Device
Public Pad As Pad
Public Pin As DevicePin
Public Sub New()
Type = DeviceTreeNodeType.DeviceTreeNodeRoot
End Sub
Public Sub New(ByVal Type As DeviceTreeNodeType, ByVal NodeObject As Object)
Me.Type = Type
Me.NodeObject = NodeObject
Select Case Type
Case DeviceTreeNodeType.DeviceTreeNodeDevice
Device = CType(NodeObject, Device)
Case DeviceTreeNodeType.DeviceTreeNodePad
Pad = CType(NodeObject, Pad)
Case DeviceTreeNodeType.DeviceTreeNodePin
Pin = CType(NodeObject, DevicePin)
End Select
End Sub
Public Sub New(ByVal Pin As DevicePin)
Type = DeviceTreeNodeType.DeviceTreeNodePin
Me.Pin = Pin
NodeObject = Pin
End Sub
Public Sub New(ByVal Pad As Pad)
Type = DeviceTreeNodeType.DeviceTreeNodePad
Me.Pad = Pad
NodeObject = Pad
End Sub
Public Sub New(ByVal Device As Device)
Type = DeviceTreeNodeType.DeviceTreeNodeDevice
Me.Device = Device
NodeObject = Device
End Sub
End Class
Public Sub New(ByVal PCB As PCB)
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.PCB = PCB
'
End Sub
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
MyBase.OnLoad(e)
UpdateDeviceList()
AddEventHandlers()
End Sub
Private Sub ToolStripButtonAddDevice_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButtonAddDevice.Click
Dim AddDevice As New FrmAddDevice(PCB)
AddDevice.ShowDialog(Me)
End Sub
Private Shared Function GetDeviceTreeNodeName(ByVal Device As Device) As String
Dim res As String = Device.Name
Dim PinCount As Integer = Device.Pins.Count
If Device.Value <> "" Then res &= " (" & Device.Value & ")"
res &= " [" & (PinCount - Device.UnconnectedPinCount) & "/" & PinCount & "]"
Return res
End Function
Private Shared Function GetPinTreeNodeName(ByVal Pin As DevicePin) As String
Return Pin.Name
End Function
Private Sub GetExpandedNodes(ByVal Nodes As TreeNode, ByVal Prefix As String, ByVal ExpandedNodes As List(Of String))
For Each Node As TreeNode In Nodes.Nodes
If Node.IsExpanded Then
ExpandedNodes.Add(Prefix & "/" & Node.Name)
End If
GetExpandedNodes(Node, Prefix & "/" & Node.Name, ExpandedNodes)
Next
If Nodes.IsExpanded Then ExpandedNodes.Add(Prefix & "/" & Nodes.Name)
End Sub
Private Sub AddEventHandlers()
For Each Device As KeyValuePair(Of String, Device) In PCB.Devices
AddEventHandler(Device.Value)
Next
End Sub
Private Sub AddEventHandler(ByVal Device As Device)
AddHandler Device.NameChanged, AddressOf DeviceNameChanged
AddHandler Device.ValueChanged, AddressOf DeviceValueChanged
For Each Pin As DevicePin In Device.Pins()
AddHandler Pin.PadAdded, AddressOf DevicePinPadAdded
AddHandler Pin.PadRemoved, AddressOf DevicePinPadRemoved
Next
End Sub
Private Sub RemoveEventHandler(ByVal Device As Device)
RemoveHandler Device.NameChanged, AddressOf DeviceNameChanged
RemoveHandler Device.ValueChanged, AddressOf DeviceValueChanged
For Each pin As DevicePin In Device.Pins()
RemoveHandler pin.PadAdded, AddressOf DevicePinPadAdded
RemoveHandler pin.PadRemoved, AddressOf DevicePinPadRemoved
Next
End Sub
Private Sub AddDeviceNode(ByVal RootName As String, ByVal Device As Device, ByVal Root As TreeNode, Optional ByVal ExpandedNodes As List(Of String) = Nothing)
Dim DeviceNode As TreeNode = Root.Nodes.Add(Device.Name, GetDeviceTreeNodeName(Device))
DeviceNode.Tag = New DeviceTreeNode(Device)
DeviceNode.ContextMenuStrip = MenuConnectDevice
DeviceTreeNodes.Add(Device, DeviceNode)
If ExpandedNodes IsNot Nothing AndAlso ExpandedNodes.Contains(RootName & "/" & Device.Name) Then
DeviceNode.Expand()
End If
For Each DevicePin As DevicePin In Device.Pins
AddDevicePinNode(RootName & "/" & Device.Name, DevicePin, DeviceNode)
Next
End Sub
Private Sub AddDevicePinNode(ByVal RootName As String, ByVal DevicePin As DevicePin, ByVal DeviceNode As TreeNode, Optional ByVal ExpandedNodes As List(Of String) = Nothing)
Dim PinNode As TreeNode = DeviceNode.Nodes.Add(DevicePin.Name, GetPinTreeNodeName(DevicePin))
PinNode.Tag = New DeviceTreeNode(DevicePin)
PinNode.ContextMenuStrip = MenuConnectPin
DevicePinTreeNodes.Add(DevicePin, PinNode)
If ExpandedNodes IsNot Nothing AndAlso ExpandedNodes.Contains(RootName & "/" & DevicePin.Name) Then
PinNode.Expand()
End If
For Each Pad As Pad In DevicePin.Pads
AddPadNode(RootName & "/" & DevicePin.Name, Pad, PinNode, ExpandedNodes)
Next
End Sub
Private Sub AddPadNode(ByVal RootName As String, ByVal Pad As Pad, ByVal DevicePinNode As TreeNode, Optional ByVal ExpandedNodes As List(Of String) = Nothing)
Dim PadNode As TreeNode = DevicePinNode.Nodes.Add(Pad.Name, Pad.Name)
PadNode.Tag = New DeviceTreeNode(Pad)
PadNode.ContextMenuStrip = MenuPad
If ExpandedNodes IsNot Nothing AndAlso ExpandedNodes.Contains(RootName & "/" & Pad.Name) Then
DevicePinNode.Expand()
End If
PadTreeNodes.Add(Pad, PadNode)
End Sub
Private Sub UpdateDeviceList()
Dim Devices As ReadOnlyDictionary(Of String, Device) = PCB.Devices
Dim ExpandedNodes As New List(Of String)
Dim Root As SortableTreeNode = New SortableTreeNode(PCB.Name())
DeviceTreeNodes = New Dictionary(Of Device, TreeNode)
DevicePinTreeNodes = New Dictionary(Of DevicePin, TreeNode)
PadTreeNodes = New Dictionary(Of Pad, TreeNode)
Root.Name = PCB.Name()
If TrvDevices.Nodes.Count > 0 Then GetExpandedNodes(TrvDevices.Nodes(0), PCB.Name, ExpandedNodes)
For Each Device As KeyValuePair(Of String, Device) In Devices
AddDeviceNode(PCB.Name, Device.Value, Root, ExpandedNodes)
Next
Root.Sort()
Root.Expand()
TrvDevices.Nodes.Clear()
TrvDevices.Nodes.Add(Root)
End Sub
Private Sub TrvDevices_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TrvDevices.AfterSelect
Dim DeviceTreeNode As DeviceTreeNode = CType(e.Node.Tag, DeviceTreeNode)
If DeviceTreeNode IsNot Nothing Then
Select Case DeviceTreeNode.Type
Case DeviceTreeNodeType.DeviceTreeNodeDevice
Case DeviceTreeNodeType.DeviceTreeNodePad
'PCB.DeselectAllObjects()
'PCB.SelectObject(DeviceTreeNode.Pad)
Case DeviceTreeNodeType.DeviceTreeNodePin
'PCB.DeselectAllObjects()
'For Each Pad As Pad In DeviceTreeNode.Pin.Pads
' PCB.SelectObject(Pad)
'Next
Case DeviceTreeNodeType.DeviceTreeNodeRoot
End Select
End If
End Sub
Private Sub PadNameChanged(ByVal Sender As LayerObject, ByVal OldName As String, ByRef NewName As String)
Static PNewName As String
If PNewName = NewName Then Exit Sub
If PadTreeNodes.ContainsKey(CType(Sender, Pad)) Then
PadTreeNodes(CType(Sender, Pad)).Text = NewName
Else
UpdateDeviceList()
End If
PNewName = NewName
End Sub
Private Sub DevicePinPadAdded(ByVal Sender As DevicePin, ByVal Pad As Pad)
'UpdateDeviceList()
If Not DevicePinTreeNodes.ContainsKey(Sender) Then
UpdateDeviceList()
Else
AddPadNode(PCB.Name & "/" & Sender.Device.Name & "/" & Sender.Name, Pad, DevicePinTreeNodes(Sender))
DeviceTreeNodes(Sender.Device).Text = GetDeviceTreeNodeName(Sender.Device)
AddHandler Pad.NameChanged, AddressOf PadNameChanged
End If
End Sub
Private Sub DevicePinPadRemoved(ByVal Sender As DevicePin, ByVal Pad As Pad)
UpdateDeviceList()
RemoveHandler Pad.NameChanged, AddressOf PadNameChanged
End Sub
Private Sub DeviceNameChanged(ByVal Sender As Device, ByVal OldName As String, ByRef NewName As String)
DeviceTreeNodes(Sender).Text = GetDeviceTreeNodeName(Sender)
End Sub
Private Sub DeviceValueChanged(ByVal Sender As Device, ByVal OldValue As String, ByRef NewName As String)
DeviceTreeNodes(Sender).Text = GetDeviceTreeNodeName(Sender)
End Sub
Private Sub FrmDevices_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Private Sub MenuConnectPinToSelectedPad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuConnectPinToSelectedPad.Click
Dim SelectedNode As TreeNode = TrvDevices.SelectedNode
Dim SelectedDevicePin As DevicePin
If SelectedNode.Tag IsNot Nothing AndAlso CType(SelectedNode.Tag, DeviceTreeNode).Type = DeviceTreeNodeType.DeviceTreeNodePin Then
SelectedDevicePin = CType(SelectedNode.Tag.nodeobject, DevicePin)
Dim SelectedObjects As List(Of SelectableLayerObject) = PCB.GetSelectedLayerObjects(GetType(Pad))
If SelectedObjects.Count <> 0 Then
For Each SelectedObject As SelectableLayerObject In SelectedObjects
Dim SelectedPad As Pad = CType(SelectedObject, Pad)
If SelectedPad.DevicePin IsNot Nothing Then
If MsgBox("The pad " & SelectedPad.Name & " is already connected to device " & SelectedPad.DevicePin.Device.Name & " pin " & SelectedPad.DevicePin.Name & " (" & Join(SelectedPad.DevicePin.PadNames, ", ") & ") do you want to disconnect it?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
PCB.AddUndoItem(New UndoRedoDisconnectPin(PCB, SelectedDevicePin, SelectedPad))
SelectedPad.DevicePin.RemovePad(SelectedPad)
SelectedPad.DevicePin = Nothing
End If
End If
If SelectedPad.DevicePin Is Nothing Then
PCB.AddUndoItem(New UndoRedoConnectPin(PCB, SelectedDevicePin, SelectedPad))
Dim EaglePadName As String
Dim EaglePadNames As List(Of String) = SelectedDevicePin.GetUnconnectedPadNames()
If EaglePadNames.Count > 1 Then
MsgBox("More padnames possible for this pin, taking " & EaglePadNames(0))
End If
If EaglePadNames.Count = 0 Then
MsgBox("This pin has the maximum connected pads!" & vbCrLf & "Disconnect one of the pads first before adding more.", MsgBoxStyle.Critical)
Exit Sub
End If
EaglePadName = EaglePadNames(0)
SelectedPad.Name = SelectedDevicePin.GetUniquePadName(EaglePadName)
SelectedDevicePin.AddPad(SelectedPad, EaglePadName)
End If
Next
UpdateDeviceList()
Else
MsgBox("Select pads to connect with first!", MsgBoxStyle.Critical)
End If
End If
End Sub
Private Sub PlaceAPadForEachPinToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PlaceAPadForEachPinToolStripMenuItem.Click
Dim SelectedNode As TreeNode = TrvDevices.SelectedNode
If SelectedNode IsNot Nothing AndAlso SelectedNode.Tag IsNot Nothing AndAlso CType(SelectedNode.Tag, DeviceTreeNode).Type = DeviceTreeNodeType.DeviceTreeNodeDevice Then
Dim SelectedDevice As Device = CType(SelectedNode.Tag.nodeobject, Device)
FrmLayer.DrawDevicePins(SelectedDevice)
End If
End Sub
Private Sub DeleteDeviceToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DeleteDeviceToolStripMenuItem.Click
Dim SelectedNode As TreeNode = TrvDevices.SelectedNode
If SelectedNode IsNot Nothing AndAlso SelectedNode.Tag IsNot Nothing AndAlso CType(SelectedNode.Tag, DeviceTreeNode).Type = DeviceTreeNodeType.DeviceTreeNodeDevice Then
Dim SelectedDevice As Device = CType(SelectedNode.Tag.nodeobject, Device)
If MsgBox("Are you sure you want to delete this device and it's pins/pads?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
If FrmLayer.CurrentDrawState = FrmLayer.DrawStates.DrawDevicePins Then FrmLayer.ResetDrawState()
PCB.UnHighlightAllObjects()
PCB.DeselectAllObjects()
PCB.AddUndoItem(New UndoRedoDeleteDevice(PCB, SelectedDevice))
PCB.RemoveDevice(SelectedDevice)
End If
End If
End Sub
Private Sub SelectAllPadsToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectAllPadsToolStripMenuItem.Click
Dim SelectedNode As TreeNode = TrvDevices.SelectedNode
If SelectedNode IsNot Nothing AndAlso SelectedNode.Tag IsNot Nothing AndAlso CType(SelectedNode.Tag, DeviceTreeNode).Type = DeviceTreeNodeType.DeviceTreeNodeDevice Then
Dim DeviceTreeNode As DeviceTreeNode = CType(SelectedNode.Tag, DeviceTreeNode)
PCB.DeselectAllObjects()
For Each Pin As DevicePin In DeviceTreeNode.Device.Pins
For Each Pad As Pad In Pin.Pads
PCB.SelectObject(Pad)
Next
Next
End If
End Sub
Private Sub PCB_DeviceAdded(ByVal Sender As PCB, ByVal Device As Device) Handles PCB.DeviceAdded
UpdateDeviceList()
AddEventHandler(Device)
End Sub
Private Sub PCB_DeviceRemoved(ByVal Sender As PCB, ByVal Device As Device) Handles PCB.DeviceRemoved
UpdateDeviceList()
RemoveEventHandler(Device)
End Sub
Private Sub PCB_NameChanged(ByVal Sender As PCB, ByVal Name As String) Handles PCB.NameChanged
If TrvDevices.Nodes.Count > 0 Then
TrvDevices.Nodes(0).Text = Name
Else
UpdateDeviceList()
End If
End Sub
Private Sub PCB_ProjectLoaded(ByVal Sender As PCB, ByVal ZipFile As Ionic.Zip.ZipFile) Handles PCB.ProjectLoaded
AddEventHandlers()
End Sub
Private Sub RenameDeviceToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RenameDeviceToolStripMenuItem.Click
Dim SelectedNode As TreeNode = TrvDevices.SelectedNode
If SelectedNode IsNot Nothing AndAlso SelectedNode.Tag IsNot Nothing AndAlso CType(SelectedNode.Tag, DeviceTreeNode).Type = DeviceTreeNodeType.DeviceTreeNodeDevice Then
Dim DeviceTreeNode As DeviceTreeNode = CType(SelectedNode.Tag, DeviceTreeNode)
Dim OldName As String = DeviceTreeNode.Device.Name
Dim NewName As String = InputBox("Enter new name.", "Rename device", OldName)
If NewName <> "" Then
If NewName <> DeviceTreeNode.Device.Name Then
If Not PCB.Devices.ContainsKey(NewName) Then
PCB.AddUndoItem(New UndoRedoDeviceNameChange(PCB, DeviceTreeNode.Device, OldName, NewName))
DeviceTreeNode.Device.Name = NewName
UpdateDeviceList()
Else
MsgBox("This name already exists.", MsgBoxStyle.Critical)
End If
End If
End If
End If
End Sub
Private Sub ChangeDeviceValueToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ChangeDeviceValueToolStripMenuItem.Click
Dim SelectedNode As TreeNode = TrvDevices.SelectedNode
If SelectedNode IsNot Nothing AndAlso SelectedNode.Tag IsNot Nothing AndAlso CType(SelectedNode.Tag, DeviceTreeNode).Type = DeviceTreeNodeType.DeviceTreeNodeDevice Then
Dim DeviceTreeNode As DeviceTreeNode = CType(SelectedNode.Tag, DeviceTreeNode)
Dim OldValue As String = DeviceTreeNode.Device.Value
Dim NewValue As String = InputBox("Enter new value.", "Change device value", OldValue)
If NewValue <> DeviceTreeNode.Device.Value Then
PCB.AddUndoItem(New UndoRedoDeviceValueChange(PCB, DeviceTreeNode.Device, OldValue, NewValue))
DeviceTreeNode.Device.Value = NewValue
UpdateDeviceList()
End If
End If
End Sub
Private Sub SelectAllPadsToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectAllPadsToolStripMenuItem1.Click
Dim SelectedNode As TreeNode = TrvDevices.SelectedNode
If SelectedNode IsNot Nothing AndAlso SelectedNode.Tag IsNot Nothing AndAlso CType(SelectedNode.Tag, DeviceTreeNode).Type = DeviceTreeNodeType.DeviceTreeNodePin Then
Dim DeviceTreeNode As DeviceTreeNode = CType(SelectedNode.Tag, DeviceTreeNode)
PCB.DeselectAllObjects()
For Each Pad As Pad In DeviceTreeNode.Pin.Pads
PCB.SelectObject(Pad)
Next
End If
End Sub
Private Sub SelectPadToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SelectPadToolStripMenuItem.Click
Dim SelectedNode As TreeNode = TrvDevices.SelectedNode
If SelectedNode IsNot Nothing AndAlso SelectedNode.Tag IsNot Nothing AndAlso CType(SelectedNode.Tag, DeviceTreeNode).Type = DeviceTreeNodeType.DeviceTreeNodePad Then
Dim DeviceTreeNode As DeviceTreeNode = CType(SelectedNode.Tag, DeviceTreeNode)
PCB.DeselectAllObjects()
PCB.SelectObject(DeviceTreeNode.Pad)
End If
End Sub
Private Sub PCB_UndoRedoAction(ByVal Sender As PCB, ByVal UndoRedoItem As UndoRedoItem, ByVal Undo As Boolean) Handles PCB.UndoRedoAction
UpdateDeviceList()
End Sub
Private Sub MenuPad_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MenuPad.Opening
End Sub
End Class