changeset 1730 | 64d8f52bc8c8 |
parent 1571 | 486f94a8032c |
child 1736 | 7e61baa047f0 |
1726:d51af006fa6b | 1730:64d8f52bc8c8 |
---|---|
35 """ |
35 """ |
36 Class that implements the graphic representation of a power rail |
36 Class that implements the graphic representation of a power rail |
37 """ |
37 """ |
38 |
38 |
39 class LD_PowerRail(Graphic_Element): |
39 class LD_PowerRail(Graphic_Element): |
40 |
40 |
41 # Create a new power rail |
41 # Create a new power rail |
42 def __init__(self, parent, type, id=None, connectors=1): |
42 def __init__(self, parent, type, id=None, connectors=1): |
43 Graphic_Element.__init__(self, parent) |
43 Graphic_Element.__init__(self, parent) |
44 self.Type = None |
44 self.Type = None |
45 self.Connectors = [] |
45 self.Connectors = [] |
46 self.RealConnectors = None |
46 self.RealConnectors = None |
47 self.Id = id |
47 self.Id = id |
48 self.Extensions = [LD_LINE_SIZE / 2, LD_LINE_SIZE / 2] |
48 self.Extensions = [LD_LINE_SIZE / 2, LD_LINE_SIZE / 2] |
49 self.SetType(type, connectors) |
49 self.SetType(type, connectors) |
50 |
50 |
51 def Flush(self): |
51 def Flush(self): |
52 for connector in self.Connectors: |
52 for connector in self.Connectors: |
53 connector.Flush() |
53 connector.Flush() |
54 self.Connectors = [] |
54 self.Connectors = [] |
55 |
55 |
56 # Make a clone of this LD_PowerRail |
56 # Make a clone of this LD_PowerRail |
57 def Clone(self, parent, id = None, pos = None): |
57 def Clone(self, parent, id = None, pos = None): |
58 powerrail = LD_PowerRail(parent, self.Type, id) |
58 powerrail = LD_PowerRail(parent, self.Type, id) |
59 powerrail.SetSize(self.Size[0], self.Size[1]) |
59 powerrail.SetSize(self.Size[0], self.Size[1]) |
60 if pos is not None: |
60 if pos is not None: |
63 powerrail.SetPosition(self.Pos.x, self.Pos.y) |
63 powerrail.SetPosition(self.Pos.x, self.Pos.y) |
64 powerrail.Connectors = [] |
64 powerrail.Connectors = [] |
65 for connector in self.Connectors: |
65 for connector in self.Connectors: |
66 powerrail.Connectors.append(connector.Clone(powerrail)) |
66 powerrail.Connectors.append(connector.Clone(powerrail)) |
67 return powerrail |
67 return powerrail |
68 |
68 |
69 def GetConnectorTranslation(self, element): |
69 def GetConnectorTranslation(self, element): |
70 return dict(zip([connector for connector in self.Connectors], |
70 return dict(zip([connector for connector in self.Connectors], |
71 [connector for connector in element.Connectors])) |
71 [connector for connector in element.Connectors])) |
72 |
72 |
73 # Returns the RedrawRect |
73 # Returns the RedrawRect |
74 def GetRedrawRect(self, movex = 0, movey = 0): |
74 def GetRedrawRect(self, movex = 0, movey = 0): |
75 rect = Graphic_Element.GetRedrawRect(self, movex, movey) |
75 rect = Graphic_Element.GetRedrawRect(self, movex, movey) |
76 for connector in self.Connectors: |
76 for connector in self.Connectors: |
77 rect = rect.Union(connector.GetRedrawRect(movex, movey)) |
77 rect = rect.Union(connector.GetRedrawRect(movex, movey)) |
78 if movex != 0 or movey != 0: |
78 if movex != 0 or movey != 0: |
79 for connector in self.Connectors: |
79 for connector in self.Connectors: |
80 if connector.IsConnected(): |
80 if connector.IsConnected(): |
81 rect = rect.Union(connector.GetConnectedRedrawRect(movex, movey)) |
81 rect = rect.Union(connector.GetConnectedRedrawRect(movex, movey)) |
82 return rect |
82 return rect |
83 |
83 |
84 # Forbids to change the power rail size |
84 # Forbids to change the power rail size |
85 def SetSize(self, width, height): |
85 def SetSize(self, width, height): |
86 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
86 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
87 Graphic_Element.SetSize(self, width, height) |
87 Graphic_Element.SetSize(self, width, height) |
88 else: |
88 else: |
89 Graphic_Element.SetSize(self, LD_POWERRAIL_WIDTH, height) |
89 Graphic_Element.SetSize(self, LD_POWERRAIL_WIDTH, height) |
90 self.RefreshConnectors() |
90 self.RefreshConnectors() |
91 |
91 |
92 # Forbids to select a power rail |
92 # Forbids to select a power rail |
93 def HitTest(self, pt, connectors=True): |
93 def HitTest(self, pt, connectors=True): |
94 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
94 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
95 return Graphic_Element.HitTest(self, pt, connectors) or self.TestConnector(pt, exclude=False) != None |
95 return Graphic_Element.HitTest(self, pt, connectors) or self.TestConnector(pt, exclude=False) != None |
96 return False |
96 return False |
97 |
97 |
98 # Forbids to select a power rail |
98 # Forbids to select a power rail |
99 def IsInSelection(self, rect): |
99 def IsInSelection(self, rect): |
100 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
100 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
101 return Graphic_Element.IsInSelection(self, rect) |
101 return Graphic_Element.IsInSelection(self, rect) |
102 return False |
102 return False |
103 |
103 |
104 # Deletes this power rail by calling the appropriate method |
104 # Deletes this power rail by calling the appropriate method |
105 def Delete(self): |
105 def Delete(self): |
106 self.Parent.DeletePowerRail(self) |
106 self.Parent.DeletePowerRail(self) |
107 |
107 |
108 # Unconnect all connectors |
108 # Unconnect all connectors |
109 def Clean(self): |
109 def Clean(self): |
110 for connector in self.Connectors: |
110 for connector in self.Connectors: |
111 connector.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
111 connector.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
112 |
112 |
113 # Refresh the power rail bounding box |
113 # Refresh the power rail bounding box |
114 def RefreshBoundingBox(self): |
114 def RefreshBoundingBox(self): |
115 self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) |
115 self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) |
116 |
116 |
117 # Refresh the power rail size |
117 # Refresh the power rail size |
118 def RefreshSize(self): |
118 def RefreshSize(self): |
119 self.Size = wx.Size(LD_POWERRAIL_WIDTH, max(LD_LINE_SIZE * len(self.Connectors), self.Size[1])) |
119 self.Size = wx.Size(LD_POWERRAIL_WIDTH, max(LD_LINE_SIZE * len(self.Connectors), self.Size[1])) |
120 self.RefreshBoundingBox() |
120 self.RefreshBoundingBox() |
121 |
121 |
122 # Returns the block minimum size |
122 # Returns the block minimum size |
123 def GetMinSize(self, default=False): |
123 def GetMinSize(self, default=False): |
124 height = (LD_LINE_SIZE * (len(self.Connectors) - 1) |
124 height = (LD_LINE_SIZE * (len(self.Connectors) - 1) |
125 if default else 0) |
125 if default else 0) |
126 return LD_POWERRAIL_WIDTH, height + self.Extensions[0] + self.Extensions[1] |
126 return LD_POWERRAIL_WIDTH, height + self.Extensions[0] + self.Extensions[1] |
127 |
127 |
128 # Add a connector or a blank to this power rail at the last place |
128 # Add a connector or a blank to this power rail at the last place |
129 def AddConnector(self): |
129 def AddConnector(self): |
130 self.InsertConnector(len(self.Connectors)) |
130 self.InsertConnector(len(self.Connectors)) |
131 |
131 |
132 # Add a connector or a blank to this power rail at the place given |
132 # Add a connector or a blank to this power rail at the place given |
133 def InsertConnector(self, idx): |
133 def InsertConnector(self, idx): |
134 if self.Type == LEFTRAIL: |
134 if self.Type == LEFTRAIL: |
135 connector = Connector(self, "", "BOOL", wx.Point(self.Size[0], 0), EAST) |
135 connector = Connector(self, "", "BOOL", wx.Point(self.Size[0], 0), EAST) |
136 elif self.Type == RIGHTRAIL: |
136 elif self.Type == RIGHTRAIL: |
137 connector = Connector(self, "", "BOOL", wx.Point(0, 0), WEST) |
137 connector = Connector(self, "", "BOOL", wx.Point(0, 0), WEST) |
138 self.Connectors.insert(idx, connector) |
138 self.Connectors.insert(idx, connector) |
139 self.RefreshSize() |
139 self.RefreshSize() |
140 self.RefreshConnectors() |
140 self.RefreshConnectors() |
141 |
141 |
142 # Moves the divergence connector given |
142 # Moves the divergence connector given |
143 def MoveConnector(self, connector, movey): |
143 def MoveConnector(self, connector, movey): |
144 position = connector.GetRelPosition() |
144 position = connector.GetRelPosition() |
145 connector.SetPosition(wx.Point(position.x, position.y + movey)) |
145 connector.SetPosition(wx.Point(position.x, position.y + movey)) |
146 miny = self.Size[1] |
146 miny = self.Size[1] |
161 connect_pos = connect.GetRelPosition() |
161 connect_pos = connect.GetRelPosition() |
162 maxy = max(maxy, connect_pos.y) |
162 maxy = max(maxy, connect_pos.y) |
163 self.Size[1] = max(maxy + self.Extensions[1], self.Size[1]) |
163 self.Size[1] = max(maxy + self.Extensions[1], self.Size[1]) |
164 connector.MoveConnected() |
164 connector.MoveConnected() |
165 self.RefreshBoundingBox() |
165 self.RefreshBoundingBox() |
166 |
166 |
167 # Returns the index in connectors list for the connector given |
167 # Returns the index in connectors list for the connector given |
168 def GetConnectorIndex(self, connector): |
168 def GetConnectorIndex(self, connector): |
169 if connector in self.Connectors: |
169 if connector in self.Connectors: |
170 return self.Connectors.index(connector) |
170 return self.Connectors.index(connector) |
171 return None |
171 return None |
172 |
172 |
173 # Delete the connector or blank from connectors list at the index given |
173 # Delete the connector or blank from connectors list at the index given |
174 def DeleteConnector(self, idx): |
174 def DeleteConnector(self, idx): |
175 self.Connectors.pop(idx) |
175 self.Connectors.pop(idx) |
176 self.RefreshConnectors() |
176 self.RefreshConnectors() |
177 self.RefreshSize() |
177 self.RefreshSize() |
178 |
178 |
179 # Refresh the positions of the power rail connectors |
179 # Refresh the positions of the power rail connectors |
180 def RefreshConnectors(self): |
180 def RefreshConnectors(self): |
181 scaling = self.Parent.GetScaling() |
181 scaling = self.Parent.GetScaling() |
182 height = self.Size[1] - self.Extensions[0] - self.Extensions[1] |
182 height = self.Size[1] - self.Extensions[0] - self.Extensions[1] |
183 interval = float(height) / float(max(len(self.Connectors) - 1, 1)) |
183 interval = float(height) / float(max(len(self.Connectors) - 1, 1)) |
191 if self.Type == LEFTRAIL: |
191 if self.Type == LEFTRAIL: |
192 connector.SetPosition(wx.Point(self.Size[0], position)) |
192 connector.SetPosition(wx.Point(self.Size[0], position)) |
193 elif self.Type == RIGHTRAIL: |
193 elif self.Type == RIGHTRAIL: |
194 connector.SetPosition(wx.Point(0, position)) |
194 connector.SetPosition(wx.Point(0, position)) |
195 self.RefreshConnected() |
195 self.RefreshConnected() |
196 |
196 |
197 # Refresh the position of wires connected to power rail |
197 # Refresh the position of wires connected to power rail |
198 def RefreshConnected(self, exclude = []): |
198 def RefreshConnected(self, exclude = []): |
199 for connector in self.Connectors: |
199 for connector in self.Connectors: |
200 connector.MoveConnected(exclude) |
200 connector.MoveConnected(exclude) |
201 |
201 |
202 # Returns the power rail connector that starts with the point given if it exists |
202 # Returns the power rail connector that starts with the point given if it exists |
203 def GetConnector(self, position, name = None): |
203 def GetConnector(self, position, name = None): |
204 # if a name is given |
204 # if a name is given |
205 if name is not None: |
205 if name is not None: |
206 # Test each connector if it exists |
206 # Test each connector if it exists |
207 for connector in self.Connectors: |
207 for connector in self.Connectors: |
208 if name == connector.GetName(): |
208 if name == connector.GetName(): |
209 return connector |
209 return connector |
210 return self.FindNearestConnector(position, [connector for connector in self.Connectors if connector is not None]) |
210 return self.FindNearestConnector(position, [connector for connector in self.Connectors if connector is not None]) |
211 |
211 |
212 # Returns all the power rail connectors |
212 # Returns all the power rail connectors |
213 def GetConnectors(self): |
213 def GetConnectors(self): |
214 connectors = [connector for connector in self.Connectors if connector] |
214 connectors = [connector for connector in self.Connectors if connector] |
215 if self.Type == LEFTRAIL: |
215 if self.Type == LEFTRAIL: |
216 return {"inputs": [], "outputs": connectors} |
216 return {"inputs": [], "outputs": connectors} |
217 else: |
217 else: |
218 return {"inputs": connectors, "outputs": []} |
218 return {"inputs": connectors, "outputs": []} |
219 |
219 |
220 # Test if point given is on one of the power rail connectors |
220 # Test if point given is on one of the power rail connectors |
221 def TestConnector(self, pt, direction = None, exclude = True): |
221 def TestConnector(self, pt, direction = None, exclude = True): |
222 for connector in self.Connectors: |
222 for connector in self.Connectors: |
223 if connector.TestPoint(pt, direction, exclude): |
223 if connector.TestPoint(pt, direction, exclude): |
224 return connector |
224 return connector |
225 return None |
225 return None |
226 |
226 |
227 # Returns the power rail type |
227 # Returns the power rail type |
228 def SetType(self, type, connectors): |
228 def SetType(self, type, connectors): |
229 if type != self.Type or len(self.Connectors) != connectors: |
229 if type != self.Type or len(self.Connectors) != connectors: |
230 # Create a connector or a blank according to 'connectors' and add it in |
230 # Create a connector or a blank according to 'connectors' and add it in |
231 # the connectors list |
231 # the connectors list |
233 self.Clean() |
233 self.Clean() |
234 self.Connectors = [] |
234 self.Connectors = [] |
235 for connector in xrange(connectors): |
235 for connector in xrange(connectors): |
236 self.AddConnector() |
236 self.AddConnector() |
237 self.RefreshSize() |
237 self.RefreshSize() |
238 |
238 |
239 # Returns the power rail type |
239 # Returns the power rail type |
240 def GetType(self): |
240 def GetType(self): |
241 return self.Type |
241 return self.Type |
242 |
242 |
243 # Method called when a LeftDown event have been generated |
243 # Method called when a LeftDown event have been generated |
244 def OnLeftDown(self, event, dc, scaling): |
244 def OnLeftDown(self, event, dc, scaling): |
245 self.RealConnectors = [] |
245 self.RealConnectors = [] |
246 height = self.Size[1] - self.Extensions[0] - self.Extensions[1] |
246 height = self.Size[1] - self.Extensions[0] - self.Extensions[1] |
247 if height > 0: |
247 if height > 0: |
251 elif len(self.Connectors) > 1: |
251 elif len(self.Connectors) > 1: |
252 self.RealConnectors = map(lambda x : x * 1 / (len(self.Connectors) - 1), xrange(len(self.Connectors))) |
252 self.RealConnectors = map(lambda x : x * 1 / (len(self.Connectors) - 1), xrange(len(self.Connectors))) |
253 else: |
253 else: |
254 self.RealConnectors = [0.5] |
254 self.RealConnectors = [0.5] |
255 Graphic_Element.OnLeftDown(self, event, dc, scaling) |
255 Graphic_Element.OnLeftDown(self, event, dc, scaling) |
256 |
256 |
257 # Method called when a LeftUp event have been generated |
257 # Method called when a LeftUp event have been generated |
258 def OnLeftUp(self, event, dc, scaling): |
258 def OnLeftUp(self, event, dc, scaling): |
259 Graphic_Element.OnLeftUp(self, event, dc, scaling) |
259 Graphic_Element.OnLeftUp(self, event, dc, scaling) |
260 self.RealConnectors = None |
260 self.RealConnectors = None |
261 |
261 |
262 # Method called when a LeftDown event have been generated |
262 # Method called when a LeftDown event have been generated |
263 def OnRightDown(self, event, dc, scaling): |
263 def OnRightDown(self, event, dc, scaling): |
264 pos = GetScaledEventPosition(event, dc, scaling) |
264 pos = GetScaledEventPosition(event, dc, scaling) |
265 # Test if a connector have been handled |
265 # Test if a connector have been handled |
266 connector = self.TestConnector(pos, exclude=False) |
266 connector = self.TestConnector(pos, exclude=False) |
270 self.Selected = False |
270 self.Selected = False |
271 # Initializes the last position |
271 # Initializes the last position |
272 self.oldPos = GetScaledEventPosition(event, dc, scaling) |
272 self.oldPos = GetScaledEventPosition(event, dc, scaling) |
273 else: |
273 else: |
274 Graphic_Element.OnRightDown(self, event, dc, scaling) |
274 Graphic_Element.OnRightDown(self, event, dc, scaling) |
275 |
275 |
276 # Method called when a LeftDClick event have been generated |
276 # Method called when a LeftDClick event have been generated |
277 def OnLeftDClick(self, event, dc, scaling): |
277 def OnLeftDClick(self, event, dc, scaling): |
278 # Edit the powerrail properties |
278 # Edit the powerrail properties |
279 self.Parent.EditPowerRailContent(self) |
279 self.Parent.EditPowerRailContent(self) |
280 |
280 |
281 # Method called when a RightUp event have been generated |
281 # Method called when a RightUp event have been generated |
282 def OnRightUp(self, event, dc, scaling): |
282 def OnRightUp(self, event, dc, scaling): |
283 handle_type, handle = self.Handle |
283 handle_type, handle = self.Handle |
284 if handle_type == HANDLE_CONNECTOR and self.Dragging and self.oldPos: |
284 if handle_type == HANDLE_CONNECTOR and self.Dragging and self.oldPos: |
285 wires = handle.GetWires() |
285 wires = handle.GetWires() |
290 block = wires[0][0].StartConnected.GetParentBlock() |
290 block = wires[0][0].StartConnected.GetParentBlock() |
291 block.RefreshModel(False) |
291 block.RefreshModel(False) |
292 Graphic_Element.OnRightUp(self, event, dc, scaling) |
292 Graphic_Element.OnRightUp(self, event, dc, scaling) |
293 else: |
293 else: |
294 self.Parent.PopupDefaultMenu() |
294 self.Parent.PopupDefaultMenu() |
295 |
295 |
296 def Resize(self, x, y, width, height): |
296 def Resize(self, x, y, width, height): |
297 self.Move(x, y) |
297 self.Move(x, y) |
298 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
298 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
299 self.SetSize(width, height) |
299 self.SetSize(width, height) |
300 else: |
300 else: |
312 self.MoveConnector(handle, movey) |
312 self.MoveConnector(handle, movey) |
313 return 0, movey |
313 return 0, movey |
314 elif self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
314 elif self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
315 return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling) |
315 return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling) |
316 return 0, 0 |
316 return 0, 0 |
317 |
317 |
318 # Refreshes the power rail model |
318 # Refreshes the power rail model |
319 def RefreshModel(self, move=True): |
319 def RefreshModel(self, move=True): |
320 self.Parent.RefreshPowerRailModel(self) |
320 self.Parent.RefreshPowerRailModel(self) |
321 # If power rail has moved and power rail is of type LEFT, refresh the model |
321 # If power rail has moved and power rail is of type LEFT, refresh the model |
322 # of wires connected to connectors |
322 # of wires connected to connectors |
323 if move and self.Type == LEFTRAIL: |
323 if move and self.Type == LEFTRAIL: |
324 for connector in self.Connectors: |
324 for connector in self.Connectors: |
325 connector.RefreshWires() |
325 connector.RefreshWires() |
326 |
326 |
327 # Draws power rail |
327 # Draws power rail |
328 def Draw(self, dc): |
328 def Draw(self, dc): |
329 Graphic_Element.Draw(self, dc) |
329 Graphic_Element.Draw(self, dc) |
330 dc.SetPen(MiterPen(wx.BLACK)) |
330 dc.SetPen(MiterPen(wx.BLACK)) |
331 dc.SetBrush(wx.BLACK_BRUSH) |
331 dc.SetBrush(wx.BLACK_BRUSH) |
335 else: |
335 else: |
336 dc.DrawRectangle(self.Pos.x, self.Pos.y, LD_POWERRAIL_WIDTH + 1, self.Size[1] + 1) |
336 dc.DrawRectangle(self.Pos.x, self.Pos.y, LD_POWERRAIL_WIDTH + 1, self.Size[1] + 1) |
337 # Draw connectors |
337 # Draw connectors |
338 for connector in self.Connectors: |
338 for connector in self.Connectors: |
339 connector.Draw(dc) |
339 connector.Draw(dc) |
340 |
340 |
341 |
341 |
342 #------------------------------------------------------------------------------- |
342 #------------------------------------------------------------------------------- |
343 # Ladder Diagram Contact |
343 # Ladder Diagram Contact |
344 #------------------------------------------------------------------------------- |
344 #------------------------------------------------------------------------------- |
345 |
345 |
346 """ |
346 """ |
347 Class that implements the graphic representation of a contact |
347 Class that implements the graphic representation of a contact |
348 """ |
348 """ |
349 |
349 |
350 class LD_Contact(Graphic_Element, DebugDataConsumer): |
350 class LD_Contact(Graphic_Element, DebugDataConsumer): |
351 |
351 |
352 # Create a new contact |
352 # Create a new contact |
353 def __init__(self, parent, type, name, id = None): |
353 def __init__(self, parent, type, name, id = None): |
354 Graphic_Element.__init__(self, parent) |
354 Graphic_Element.__init__(self, parent) |
355 DebugDataConsumer.__init__(self) |
355 DebugDataConsumer.__init__(self) |
356 self.Type = type |
356 self.Type = type |
363 self.Output = Connector(self, "", "BOOL", wx.Point(self.Size[0], self.Size[1] / 2 + 1), EAST) |
363 self.Output = Connector(self, "", "BOOL", wx.Point(self.Size[0], self.Size[1] / 2 + 1), EAST) |
364 self.PreviousValue = False |
364 self.PreviousValue = False |
365 self.PreviousSpreading = False |
365 self.PreviousSpreading = False |
366 self.RefreshNameSize() |
366 self.RefreshNameSize() |
367 self.RefreshTypeSize() |
367 self.RefreshTypeSize() |
368 |
368 |
369 def Flush(self): |
369 def Flush(self): |
370 if self.Input is not None: |
370 if self.Input is not None: |
371 self.Input.Flush() |
371 self.Input.Flush() |
372 self.Input = None |
372 self.Input = None |
373 if self.Output is not None: |
373 if self.Output is not None: |
374 self.Output.Flush() |
374 self.Output.Flush() |
375 self.Output = None |
375 self.Output = None |
376 |
376 |
377 def SetForced(self, forced): |
377 def SetForced(self, forced): |
378 if self.Forced != forced: |
378 if self.Forced != forced: |
379 self.Forced = forced |
379 self.Forced = forced |
380 if self.Visible: |
380 if self.Visible: |
381 self.Parent.ElementNeedRefresh(self) |
381 self.Parent.ElementNeedRefresh(self) |
382 |
382 |
383 def SetValue(self, value): |
383 def SetValue(self, value): |
384 if self.Type == CONTACT_RISING: |
384 if self.Type == CONTACT_RISING: |
385 refresh = self.Value and not self.PreviousValue |
385 refresh = self.Value and not self.PreviousValue |
386 elif self.Type == CONTACT_FALLING: |
386 elif self.Type == CONTACT_FALLING: |
387 refresh = not self.Value and self.PreviousValue |
387 refresh = not self.Value and self.PreviousValue |
391 self.Value = value |
391 self.Value = value |
392 if self.Value != self.PreviousValue or refresh: |
392 if self.Value != self.PreviousValue or refresh: |
393 if self.Visible: |
393 if self.Visible: |
394 self.Parent.ElementNeedRefresh(self) |
394 self.Parent.ElementNeedRefresh(self) |
395 self.SpreadCurrent() |
395 self.SpreadCurrent() |
396 |
396 |
397 def SpreadCurrent(self): |
397 def SpreadCurrent(self): |
398 if self.Parent.Debug: |
398 if self.Parent.Debug: |
399 if self.Value is None: |
399 if self.Value is None: |
400 self.Value = False |
400 self.Value = False |
401 spreading = self.Input.ReceivingCurrent() |
401 spreading = self.Input.ReceivingCurrent() |
412 if spreading and not self.PreviousSpreading: |
412 if spreading and not self.PreviousSpreading: |
413 self.Output.SpreadCurrent(True) |
413 self.Output.SpreadCurrent(True) |
414 elif not spreading and self.PreviousSpreading: |
414 elif not spreading and self.PreviousSpreading: |
415 self.Output.SpreadCurrent(False) |
415 self.Output.SpreadCurrent(False) |
416 self.PreviousSpreading = spreading |
416 self.PreviousSpreading = spreading |
417 |
417 |
418 # Make a clone of this LD_Contact |
418 # Make a clone of this LD_Contact |
419 def Clone(self, parent, id = None, pos = None): |
419 def Clone(self, parent, id = None, pos = None): |
420 contact = LD_Contact(parent, self.Type, self.Name, id) |
420 contact = LD_Contact(parent, self.Type, self.Name, id) |
421 contact.SetSize(self.Size[0], self.Size[1]) |
421 contact.SetSize(self.Size[0], self.Size[1]) |
422 if pos is not None: |
422 if pos is not None: |
424 else: |
424 else: |
425 contact.SetPosition(self.Pos.x, self.Pos.y) |
425 contact.SetPosition(self.Pos.x, self.Pos.y) |
426 contact.Input = self.Input.Clone(contact) |
426 contact.Input = self.Input.Clone(contact) |
427 contact.Output = self.Output.Clone(contact) |
427 contact.Output = self.Output.Clone(contact) |
428 return contact |
428 return contact |
429 |
429 |
430 def GetConnectorTranslation(self, element): |
430 def GetConnectorTranslation(self, element): |
431 return {self.Input : element.Input, self.Output : element.Output} |
431 return {self.Input : element.Input, self.Output : element.Output} |
432 |
432 |
433 # Returns the RedrawRect |
433 # Returns the RedrawRect |
434 def GetRedrawRect(self, movex = 0, movey = 0): |
434 def GetRedrawRect(self, movex = 0, movey = 0): |
435 rect = Graphic_Element.GetRedrawRect(self, movex, movey) |
435 rect = Graphic_Element.GetRedrawRect(self, movex, movey) |
436 rect = rect.Union(self.Input.GetRedrawRect(movex, movey)) |
436 rect = rect.Union(self.Input.GetRedrawRect(movex, movey)) |
437 rect = rect.Union(self.Output.GetRedrawRect(movex, movey)) |
437 rect = rect.Union(self.Output.GetRedrawRect(movex, movey)) |
444 |
444 |
445 def ProcessDragging(self, movex, movey, event, scaling): |
445 def ProcessDragging(self, movex, movey, event, scaling): |
446 if self.Parent.GetDrawingMode() != FREEDRAWING_MODE: |
446 if self.Parent.GetDrawingMode() != FREEDRAWING_MODE: |
447 movex = movey = 0 |
447 movex = movey = 0 |
448 return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling, height_fac = 2) |
448 return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling, height_fac = 2) |
449 |
449 |
450 # Forbids to change the contact size |
450 # Forbids to change the contact size |
451 def SetSize(self, width, height): |
451 def SetSize(self, width, height): |
452 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
452 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
453 Graphic_Element.SetSize(self, width, height) |
453 Graphic_Element.SetSize(self, width, height) |
454 self.RefreshConnectors() |
454 self.RefreshConnectors() |
455 |
455 |
456 # Delete this contact by calling the appropriate method |
456 # Delete this contact by calling the appropriate method |
457 def Delete(self): |
457 def Delete(self): |
458 self.Parent.DeleteContact(self) |
458 self.Parent.DeleteContact(self) |
459 |
459 |
460 # Unconnect input and output |
460 # Unconnect input and output |
461 def Clean(self): |
461 def Clean(self): |
462 self.Input.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
462 self.Input.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
463 self.Output.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
463 self.Output.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
464 |
464 |
465 # Refresh the size of text for name |
465 # Refresh the size of text for name |
466 def RefreshNameSize(self): |
466 def RefreshNameSize(self): |
467 if self.Name != "": |
467 if self.Name != "": |
468 self.NameSize = self.Parent.GetTextExtent(self.Name) |
468 self.NameSize = self.Parent.GetTextExtent(self.Name) |
469 else: |
469 else: |
470 self.NameSize = 0, 0 |
470 self.NameSize = 0, 0 |
471 |
471 |
472 # Refresh the size of text for type |
472 # Refresh the size of text for type |
473 def RefreshTypeSize(self): |
473 def RefreshTypeSize(self): |
474 typetext = "" |
474 typetext = "" |
475 if self.Type == CONTACT_REVERSE: |
475 if self.Type == CONTACT_REVERSE: |
476 typetext = "/" |
476 typetext = "/" |
480 typetext = "N" |
480 typetext = "N" |
481 if typetext != "": |
481 if typetext != "": |
482 self.TypeSize = self.Parent.GetTextExtent(typetext) |
482 self.TypeSize = self.Parent.GetTextExtent(typetext) |
483 else: |
483 else: |
484 self.TypeSize = 0, 0 |
484 self.TypeSize = 0, 0 |
485 |
485 |
486 # Refresh the contact bounding box |
486 # Refresh the contact bounding box |
487 def RefreshBoundingBox(self): |
487 def RefreshBoundingBox(self): |
488 # Calculate the size of the name outside the contact |
488 # Calculate the size of the name outside the contact |
489 text_width, text_height = self.Parent.GetTextExtent(self.Name) |
489 text_width, text_height = self.Parent.GetTextExtent(self.Name) |
490 # Calculate the bounding box size |
490 # Calculate the bounding box size |
497 bbx_x = self.Pos.x |
497 bbx_x = self.Pos.x |
498 bbx_width = self.Size[0] |
498 bbx_width = self.Size[0] |
499 bbx_y = self.Pos.y |
499 bbx_y = self.Pos.y |
500 bbx_height = self.Size[1] |
500 bbx_height = self.Size[1] |
501 self.BoundingBox = wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1) |
501 self.BoundingBox = wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1) |
502 |
502 |
503 # Returns the block minimum size |
503 # Returns the block minimum size |
504 def GetMinSize(self): |
504 def GetMinSize(self): |
505 return LD_ELEMENT_SIZE |
505 return LD_ELEMENT_SIZE |
506 |
506 |
507 # Refresh the position of wire connected to contact |
507 # Refresh the position of wire connected to contact |
508 def RefreshConnected(self, exclude = []): |
508 def RefreshConnected(self, exclude = []): |
509 self.Input.MoveConnected(exclude) |
509 self.Input.MoveConnected(exclude) |
510 self.Output.MoveConnected(exclude) |
510 self.Output.MoveConnected(exclude) |
511 |
511 |
512 # Returns the contact connector that starts with the point given if it exists |
512 # Returns the contact connector that starts with the point given if it exists |
513 def GetConnector(self, position, name = None): |
513 def GetConnector(self, position, name = None): |
514 # if a name is given |
514 # if a name is given |
515 if name is not None: |
515 if name is not None: |
516 # Test input and output connector |
516 # Test input and output connector |
517 #if name == self.Input.GetName(): |
517 #if name == self.Input.GetName(): |
518 # return self.Input |
518 # return self.Input |
519 if name == self.Output.GetName(): |
519 if name == self.Output.GetName(): |
520 return self.Output |
520 return self.Output |
521 return self.FindNearestConnector(position, [self.Input, self.Output]) |
521 return self.FindNearestConnector(position, [self.Input, self.Output]) |
522 |
522 |
523 # Returns input and output contact connectors |
523 # Returns input and output contact connectors |
524 def GetConnectors(self): |
524 def GetConnectors(self): |
525 return {"inputs": [self.Input], "outputs": [self.Output]} |
525 return {"inputs": [self.Input], "outputs": [self.Output]} |
526 |
526 |
527 # Test if point given is on contact input or output connector |
527 # Test if point given is on contact input or output connector |
528 def TestConnector(self, pt, direction = None, exclude=True): |
528 def TestConnector(self, pt, direction = None, exclude=True): |
529 # Test input connector |
529 # Test input connector |
530 if self.Input.TestPoint(pt, direction, exclude): |
530 if self.Input.TestPoint(pt, direction, exclude): |
531 return self.Input |
531 return self.Input |
559 self.RefreshTypeSize() |
559 self.RefreshTypeSize() |
560 |
560 |
561 # Returns the contact type |
561 # Returns the contact type |
562 def GetType(self): |
562 def GetType(self): |
563 return self.Type |
563 return self.Type |
564 |
564 |
565 # Method called when a LeftDClick event have been generated |
565 # Method called when a LeftDClick event have been generated |
566 def OnLeftDClick(self, event, dc, scaling): |
566 def OnLeftDClick(self, event, dc, scaling): |
567 # Edit the contact properties |
567 # Edit the contact properties |
568 self.Parent.EditContactContent(self) |
568 self.Parent.EditContactContent(self) |
569 |
569 |
570 # Method called when a RightUp event have been generated |
570 # Method called when a RightUp event have been generated |
571 def OnRightUp(self, event, dc, scaling): |
571 def OnRightUp(self, event, dc, scaling): |
572 # Popup the default menu |
572 # Popup the default menu |
573 self.Parent.PopupDefaultMenu() |
573 self.Parent.PopupDefaultMenu() |
574 |
574 |
575 # Refreshes the contact model |
575 # Refreshes the contact model |
576 def RefreshModel(self, move=True): |
576 def RefreshModel(self, move=True): |
577 self.Parent.RefreshContactModel(self) |
577 self.Parent.RefreshContactModel(self) |
578 # If contact has moved, refresh the model of wires connected to output |
578 # If contact has moved, refresh the model of wires connected to output |
579 if move: |
579 if move: |
580 self.Output.RefreshWires() |
580 self.Output.RefreshWires() |
581 |
581 |
582 # Draws the highlightment of this element if it is highlighted |
582 # Draws the highlightment of this element if it is highlighted |
583 def DrawHighlightment(self, dc): |
583 def DrawHighlightment(self, dc): |
584 scalex, scaley = dc.GetUserScale() |
584 scalex, scaley = dc.GetUserScale() |
585 dc.SetUserScale(1, 1) |
585 dc.SetUserScale(1, 1) |
586 dc.SetPen(MiterPen(HIGHLIGHTCOLOR)) |
586 dc.SetPen(MiterPen(HIGHLIGHTCOLOR)) |
590 left_left = (self.Pos.x - 1) * scalex - 2 |
590 left_left = (self.Pos.x - 1) * scalex - 2 |
591 right_left = (self.Pos.x + self.Size[0] - 2) * scalex - 2 |
591 right_left = (self.Pos.x + self.Size[0] - 2) * scalex - 2 |
592 top = (self.Pos.y - 1) * scaley - 2 |
592 top = (self.Pos.y - 1) * scaley - 2 |
593 width = 4 * scalex + 5 |
593 width = 4 * scalex + 5 |
594 height = (self.Size[1] + 3) * scaley + 5 |
594 height = (self.Size[1] + 3) * scaley + 5 |
595 |
595 |
596 dc.DrawRectangle(left_left, top, width, height) |
596 dc.DrawRectangle(left_left, top, width, height) |
597 dc.DrawRectangle(right_left, top, width, height) |
597 dc.DrawRectangle(right_left, top, width, height) |
598 dc.SetLogicalFunction(wx.COPY) |
598 dc.SetLogicalFunction(wx.COPY) |
599 dc.SetUserScale(scalex, scaley) |
599 dc.SetUserScale(scalex, scaley) |
600 |
600 |
601 # Adds an highlight to the connection |
601 # Adds an highlight to the connection |
602 def AddHighlight(self, infos, start, end, highlight_type): |
602 def AddHighlight(self, infos, start, end, highlight_type): |
603 highlights = self.Highlights.setdefault(infos[0], []) |
603 highlights = self.Highlights.setdefault(infos[0], []) |
604 if infos[0] == "reference": |
604 if infos[0] == "reference": |
605 if start[0] == 0 and end[0] == 0: |
605 if start[0] == 0 and end[0] == 0: |
606 AddHighlight(highlights, (start, end, highlight_type)) |
606 AddHighlight(highlights, (start, end, highlight_type)) |
607 else: |
607 else: |
608 AddHighlight(highlights, ((0, 0), (0, 1), highlight_type)) |
608 AddHighlight(highlights, ((0, 0), (0, 1), highlight_type)) |
609 |
609 |
610 # Removes an highlight from the connection |
610 # Removes an highlight from the connection |
611 def RemoveHighlight(self, infos, start, end, highlight_type): |
611 def RemoveHighlight(self, infos, start, end, highlight_type): |
612 highlights = self.Highlights.get(infos[0], []) |
612 highlights = self.Highlights.get(infos[0], []) |
613 if RemoveHighlight(highlights, (start, end, highlight_type)) and len(highlights) == 0: |
613 if RemoveHighlight(highlights, (start, end, highlight_type)) and len(highlights) == 0: |
614 self.Highlights.pop(infos[0]) |
614 self.Highlights.pop(infos[0]) |
615 |
615 |
616 # Removes all the highlights of one particular type from the connection |
616 # Removes all the highlights of one particular type from the connection |
617 def ClearHighlight(self, highlight_type=None): |
617 def ClearHighlight(self, highlight_type=None): |
618 if highlight_type is None: |
618 if highlight_type is None: |
619 self.Highlights = {} |
619 self.Highlights = {} |
620 else: |
620 else: |
621 highlight_items = self.Highlights.items() |
621 highlight_items = self.Highlights.items() |
622 for name, highlights in highlight_items: |
622 for name, highlights in highlight_items: |
623 highlights = ClearHighlights(highlight, highlight_type) |
623 highlights = ClearHighlights(highlight, highlight_type) |
624 if len(highlights) == 0: |
624 if len(highlights) == 0: |
625 self.Highlights.pop(name) |
625 self.Highlights.pop(name) |
626 |
626 |
627 # Draws contact |
627 # Draws contact |
628 def Draw(self, dc): |
628 def Draw(self, dc): |
629 Graphic_Element.Draw(self, dc) |
629 Graphic_Element.Draw(self, dc) |
630 if self.Value is not None: |
630 if self.Value is not None: |
631 if self.Type == CONTACT_NORMAL and self.Value or \ |
631 if self.Type == CONTACT_NORMAL and self.Value or \ |
632 self.Type == CONTACT_REVERSE and not self.Value or \ |
632 self.Type == CONTACT_REVERSE and not self.Value or \ |
633 self.Type == CONTACT_RISING and self.Value and not self.PreviousValue or \ |
633 self.Type == CONTACT_RISING and self.Value and not self.PreviousValue or \ |
634 self.Type == CONTACT_RISING and not self.Value and self.PreviousValue: |
634 self.Type == CONTACT_RISING and not self.Value and self.PreviousValue: |
635 if self.Forced: |
635 if self.Forced: |
641 else: |
641 else: |
642 dc.SetPen(MiterPen(wx.BLACK)) |
642 dc.SetPen(MiterPen(wx.BLACK)) |
643 else: |
643 else: |
644 dc.SetPen(MiterPen(wx.BLACK)) |
644 dc.SetPen(MiterPen(wx.BLACK)) |
645 dc.SetBrush(wx.BLACK_BRUSH) |
645 dc.SetBrush(wx.BLACK_BRUSH) |
646 |
646 |
647 # Compiling contact type modifier symbol |
647 # Compiling contact type modifier symbol |
648 typetext = "" |
648 typetext = "" |
649 if self.Type == CONTACT_REVERSE: |
649 if self.Type == CONTACT_REVERSE: |
650 typetext = "/" |
650 typetext = "/" |
651 elif self.Type == CONTACT_RISING: |
651 elif self.Type == CONTACT_RISING: |
652 typetext = "P" |
652 typetext = "P" |
653 elif self.Type == CONTACT_FALLING: |
653 elif self.Type == CONTACT_FALLING: |
654 typetext = "N" |
654 typetext = "N" |
655 |
655 |
656 if getattr(dc, "printing", False): |
656 if getattr(dc, "printing", False): |
657 name_size = dc.GetTextExtent(self.Name) |
657 name_size = dc.GetTextExtent(self.Name) |
658 if typetext != "": |
658 if typetext != "": |
659 type_size = dc.GetTextExtent(typetext) |
659 type_size = dc.GetTextExtent(typetext) |
660 else: |
660 else: |
661 name_size = self.NameSize |
661 name_size = self.NameSize |
662 if typetext != "": |
662 if typetext != "": |
663 type_size = self.TypeSize |
663 type_size = self.TypeSize |
664 |
664 |
665 # Draw two rectangles for representing the contact |
665 # Draw two rectangles for representing the contact |
666 dc.DrawRectangle(self.Pos.x, self.Pos.y, 2, self.Size[1] + 1) |
666 dc.DrawRectangle(self.Pos.x, self.Pos.y, 2, self.Size[1] + 1) |
667 dc.DrawRectangle(self.Pos.x + self.Size[0] - 1, self.Pos.y, 2, self.Size[1] + 1) |
667 dc.DrawRectangle(self.Pos.x + self.Size[0] - 1, self.Pos.y, 2, self.Size[1] + 1) |
668 # Draw contact name |
668 # Draw contact name |
669 name_pos = (self.Pos.x + (self.Size[0] - name_size[0]) / 2, |
669 name_pos = (self.Pos.x + (self.Size[0] - name_size[0]) / 2, |
675 self.Pos.y + (self.Size[1] - type_size[1]) / 2) |
675 self.Pos.y + (self.Size[1] - type_size[1]) / 2) |
676 dc.DrawText(typetext, type_pos[0], type_pos[1]) |
676 dc.DrawText(typetext, type_pos[0], type_pos[1]) |
677 # Draw input and output connectors |
677 # Draw input and output connectors |
678 self.Input.Draw(dc) |
678 self.Input.Draw(dc) |
679 self.Output.Draw(dc) |
679 self.Output.Draw(dc) |
680 |
680 |
681 if not getattr(dc, "printing", False): |
681 if not getattr(dc, "printing", False): |
682 for name, highlights in self.Highlights.iteritems(): |
682 for name, highlights in self.Highlights.iteritems(): |
683 if name == "reference": |
683 if name == "reference": |
684 DrawHighlightedText(dc, self.Name, highlights, name_pos[0], name_pos[1]) |
684 DrawHighlightedText(dc, self.Name, highlights, name_pos[0], name_pos[1]) |
685 elif typetext != "": |
685 elif typetext != "": |
692 """ |
692 """ |
693 Class that implements the graphic representation of a coil |
693 Class that implements the graphic representation of a coil |
694 """ |
694 """ |
695 |
695 |
696 class LD_Coil(Graphic_Element): |
696 class LD_Coil(Graphic_Element): |
697 |
697 |
698 # Create a new coil |
698 # Create a new coil |
699 def __init__(self, parent, type, name, id = None): |
699 def __init__(self, parent, type, name, id = None): |
700 Graphic_Element.__init__(self, parent) |
700 Graphic_Element.__init__(self, parent) |
701 self.Type = type |
701 self.Type = type |
702 self.Name = name |
702 self.Name = name |
708 self.Output = Connector(self, "", "BOOL", wx.Point(self.Size[0], self.Size[1] / 2 + 1), EAST) |
708 self.Output = Connector(self, "", "BOOL", wx.Point(self.Size[0], self.Size[1] / 2 + 1), EAST) |
709 self.Value = None |
709 self.Value = None |
710 self.PreviousValue = False |
710 self.PreviousValue = False |
711 self.RefreshNameSize() |
711 self.RefreshNameSize() |
712 self.RefreshTypeSize() |
712 self.RefreshTypeSize() |
713 |
713 |
714 def Flush(self): |
714 def Flush(self): |
715 if self.Input is not None: |
715 if self.Input is not None: |
716 self.Input.Flush() |
716 self.Input.Flush() |
717 self.Input = None |
717 self.Input = None |
718 if self.Output is not None: |
718 if self.Output is not None: |
719 self.Output.Flush() |
719 self.Output.Flush() |
720 self.Output = None |
720 self.Output = None |
721 |
721 |
722 def SpreadCurrent(self): |
722 def SpreadCurrent(self): |
723 if self.Parent.Debug: |
723 if self.Parent.Debug: |
724 self.PreviousValue = self.Value |
724 self.PreviousValue = self.Value |
725 self.Value = self.Input.ReceivingCurrent() |
725 self.Value = self.Input.ReceivingCurrent() |
726 if self.Value and not self.PreviousValue: |
726 if self.Value and not self.PreviousValue: |
727 self.Output.SpreadCurrent(True) |
727 self.Output.SpreadCurrent(True) |
728 elif not self.Value and self.PreviousValue: |
728 elif not self.Value and self.PreviousValue: |
729 self.Output.SpreadCurrent(False) |
729 self.Output.SpreadCurrent(False) |
730 if self.Value != self.PreviousValue and self.Visible: |
730 if self.Value != self.PreviousValue and self.Visible: |
731 self.Parent.ElementNeedRefresh(self) |
731 self.Parent.ElementNeedRefresh(self) |
732 |
732 |
733 # Make a clone of this LD_Coil |
733 # Make a clone of this LD_Coil |
734 def Clone(self, parent, id = None, pos = None): |
734 def Clone(self, parent, id = None, pos = None): |
735 coil = LD_Coil(parent, self.Type, self.Name, id) |
735 coil = LD_Coil(parent, self.Type, self.Name, id) |
736 coil.SetSize(self.Size[0], self.Size[1]) |
736 coil.SetSize(self.Size[0], self.Size[1]) |
737 if pos is not None: |
737 if pos is not None: |
739 else: |
739 else: |
740 coil.SetPosition(self.Pos.x, self.Pos.y) |
740 coil.SetPosition(self.Pos.x, self.Pos.y) |
741 coil.Input = self.Input.Clone(coil) |
741 coil.Input = self.Input.Clone(coil) |
742 coil.Output = self.Output.Clone(coil) |
742 coil.Output = self.Output.Clone(coil) |
743 return coil |
743 return coil |
744 |
744 |
745 def GetConnectorTranslation(self, element): |
745 def GetConnectorTranslation(self, element): |
746 return {self.Input : element.Input, self.Output : element.Output} |
746 return {self.Input : element.Input, self.Output : element.Output} |
747 |
747 |
748 # Returns the RedrawRect |
748 # Returns the RedrawRect |
749 def GetRedrawRect(self, movex = 0, movey = 0): |
749 def GetRedrawRect(self, movex = 0, movey = 0): |
750 rect = Graphic_Element.GetRedrawRect(self, movex, movey) |
750 rect = Graphic_Element.GetRedrawRect(self, movex, movey) |
751 rect = rect.Union(self.Input.GetRedrawRect(movex, movey)) |
751 rect = rect.Union(self.Input.GetRedrawRect(movex, movey)) |
752 rect = rect.Union(self.Output.GetRedrawRect(movex, movey)) |
752 rect = rect.Union(self.Output.GetRedrawRect(movex, movey)) |
754 if self.Input.IsConnected(): |
754 if self.Input.IsConnected(): |
755 rect = rect.Union(self.Input.GetConnectedRedrawRect(movex, movey)) |
755 rect = rect.Union(self.Input.GetConnectedRedrawRect(movex, movey)) |
756 if self.Output.IsConnected(): |
756 if self.Output.IsConnected(): |
757 rect = rect.Union(self.Output.GetConnectedRedrawRect(movex, movey)) |
757 rect = rect.Union(self.Output.GetConnectedRedrawRect(movex, movey)) |
758 return rect |
758 return rect |
759 |
759 |
760 def ProcessDragging(self, movex, movey, event, scaling): |
760 def ProcessDragging(self, movex, movey, event, scaling): |
761 if self.Parent.GetDrawingMode() != FREEDRAWING_MODE: |
761 if self.Parent.GetDrawingMode() != FREEDRAWING_MODE: |
762 movex = movey = 0 |
762 movex = movey = 0 |
763 return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling, height_fac = 2) |
763 return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling, height_fac = 2) |
764 |
764 |
765 # Forbids to change the Coil size |
765 # Forbids to change the Coil size |
766 def SetSize(self, width, height): |
766 def SetSize(self, width, height): |
767 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
767 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
768 Graphic_Element.SetSize(self, width, height) |
768 Graphic_Element.SetSize(self, width, height) |
769 self.RefreshConnectors() |
769 self.RefreshConnectors() |
770 |
770 |
771 # Delete this coil by calling the appropriate method |
771 # Delete this coil by calling the appropriate method |
772 def Delete(self): |
772 def Delete(self): |
773 self.Parent.DeleteCoil(self) |
773 self.Parent.DeleteCoil(self) |
774 |
774 |
775 # Unconnect input and output |
775 # Unconnect input and output |
776 def Clean(self): |
776 def Clean(self): |
777 self.Input.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
777 self.Input.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
778 self.Output.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
778 self.Output.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
779 |
779 |
780 # Refresh the size of text for name |
780 # Refresh the size of text for name |
781 def RefreshNameSize(self): |
781 def RefreshNameSize(self): |
782 if self.Name != "": |
782 if self.Name != "": |
783 self.NameSize = self.Parent.GetTextExtent(self.Name) |
783 self.NameSize = self.Parent.GetTextExtent(self.Name) |
784 else: |
784 else: |
785 self.NameSize = 0, 0 |
785 self.NameSize = 0, 0 |
786 |
786 |
787 # Refresh the size of text for type |
787 # Refresh the size of text for type |
788 def RefreshTypeSize(self): |
788 def RefreshTypeSize(self): |
789 typetext = "" |
789 typetext = "" |
790 if self.Type == COIL_REVERSE: |
790 if self.Type == COIL_REVERSE: |
791 typetext = "/" |
791 typetext = "/" |
799 typetext = "N" |
799 typetext = "N" |
800 if typetext != "": |
800 if typetext != "": |
801 self.TypeSize = self.Parent.GetTextExtent(typetext) |
801 self.TypeSize = self.Parent.GetTextExtent(typetext) |
802 else: |
802 else: |
803 self.TypeSize = 0, 0 |
803 self.TypeSize = 0, 0 |
804 |
804 |
805 # Refresh the coil bounding box |
805 # Refresh the coil bounding box |
806 def RefreshBoundingBox(self): |
806 def RefreshBoundingBox(self): |
807 # Calculate the size of the name outside the coil |
807 # Calculate the size of the name outside the coil |
808 text_width, text_height = self.Parent.GetTextExtent(self.Name) |
808 text_width, text_height = self.Parent.GetTextExtent(self.Name) |
809 # Calculate the bounding box size |
809 # Calculate the bounding box size |
816 bbx_x = self.Pos.x |
816 bbx_x = self.Pos.x |
817 bbx_width = self.Size[0] |
817 bbx_width = self.Size[0] |
818 bbx_y = self.Pos.y |
818 bbx_y = self.Pos.y |
819 bbx_height = self.Size[1] |
819 bbx_height = self.Size[1] |
820 self.BoundingBox = wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1) |
820 self.BoundingBox = wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1) |
821 |
821 |
822 # Returns the block minimum size |
822 # Returns the block minimum size |
823 def GetMinSize(self): |
823 def GetMinSize(self): |
824 return LD_ELEMENT_SIZE |
824 return LD_ELEMENT_SIZE |
825 |
825 |
826 # Refresh the position of wire connected to coil |
826 # Refresh the position of wire connected to coil |
827 def RefreshConnected(self, exclude = []): |
827 def RefreshConnected(self, exclude = []): |
828 self.Input.MoveConnected(exclude) |
828 self.Input.MoveConnected(exclude) |
829 self.Output.MoveConnected(exclude) |
829 self.Output.MoveConnected(exclude) |
830 |
830 |
831 # Returns the coil connector that starts with the point given if it exists |
831 # Returns the coil connector that starts with the point given if it exists |
832 def GetConnector(self, position, name = None): |
832 def GetConnector(self, position, name = None): |
833 # if a name is given |
833 # if a name is given |
834 if name is not None: |
834 if name is not None: |
835 # Test input and output connector |
835 # Test input and output connector |
836 #if self.Input and name == self.Input.GetName(): |
836 #if self.Input and name == self.Input.GetName(): |
837 # return self.Input |
837 # return self.Input |
838 if self.Output and name == self.Output.GetName(): |
838 if self.Output and name == self.Output.GetName(): |
839 return self.Output |
839 return self.Output |
840 return self.FindNearestConnector(position, [self.Input, self.Output]) |
840 return self.FindNearestConnector(position, [self.Input, self.Output]) |
841 |
841 |
842 # Returns input and output coil connectors |
842 # Returns input and output coil connectors |
843 def GetConnectors(self): |
843 def GetConnectors(self): |
844 return {"inputs": [self.Input], "outputs": [self.Output]} |
844 return {"inputs": [self.Input], "outputs": [self.Output]} |
845 |
845 |
846 # Test if point given is on coil input or output connector |
846 # Test if point given is on coil input or output connector |
847 def TestConnector(self, pt, direction = None, exclude=True): |
847 def TestConnector(self, pt, direction = None, exclude=True): |
848 # Test input connector |
848 # Test input connector |
849 if self.Input.TestPoint(pt, direction, exclude): |
849 if self.Input.TestPoint(pt, direction, exclude): |
850 return self.Input |
850 return self.Input |
851 # Test output connector |
851 # Test output connector |
852 if self.Output.TestPoint(pt, direction, exclude): |
852 if self.Output.TestPoint(pt, direction, exclude): |
853 return self.Output |
853 return self.Output |
854 return None |
854 return None |
855 |
855 |
856 # Refresh the positions of the block connectors |
856 # Refresh the positions of the block connectors |
857 def RefreshConnectors(self): |
857 def RefreshConnectors(self): |
858 scaling = self.Parent.GetScaling() |
858 scaling = self.Parent.GetScaling() |
859 position = self.Size[1] / 2 + 1 |
859 position = self.Size[1] / 2 + 1 |
860 if scaling is not None: |
860 if scaling is not None: |
861 position = round(float(self.Pos.y + position) / float(scaling[1])) * scaling[1] - self.Pos.y |
861 position = round(float(self.Pos.y + position) / float(scaling[1])) * scaling[1] - self.Pos.y |
862 self.Input.SetPosition(wx.Point(0, position)) |
862 self.Input.SetPosition(wx.Point(0, position)) |
863 self.Output.SetPosition(wx.Point(self.Size[0], position)) |
863 self.Output.SetPosition(wx.Point(self.Size[0], position)) |
864 self.RefreshConnected() |
864 self.RefreshConnected() |
865 |
865 |
866 # Changes the coil name |
866 # Changes the coil name |
867 def SetName(self, name): |
867 def SetName(self, name): |
868 self.Name = name |
868 self.Name = name |
869 self.RefreshNameSize() |
869 self.RefreshNameSize() |
870 |
870 |
871 # Returns the coil name |
871 # Returns the coil name |
872 def GetName(self): |
872 def GetName(self): |
873 return self.Name |
873 return self.Name |
874 |
874 |
875 # Changes the coil type |
875 # Changes the coil type |
876 def SetType(self, type): |
876 def SetType(self, type): |
877 self.Type = type |
877 self.Type = type |
878 self.RefreshTypeSize() |
878 self.RefreshTypeSize() |
879 |
879 |
880 # Returns the coil type |
880 # Returns the coil type |
881 def GetType(self): |
881 def GetType(self): |
882 return self.Type |
882 return self.Type |
883 |
883 |
884 # Method called when a LeftDClick event have been generated |
884 # Method called when a LeftDClick event have been generated |
885 def OnLeftDClick(self, event, dc, scaling): |
885 def OnLeftDClick(self, event, dc, scaling): |
886 # Edit the coil properties |
886 # Edit the coil properties |
887 self.Parent.EditCoilContent(self) |
887 self.Parent.EditCoilContent(self) |
888 |
888 |
889 # Method called when a RightUp event have been generated |
889 # Method called when a RightUp event have been generated |
890 def OnRightUp(self, event, dc, scaling): |
890 def OnRightUp(self, event, dc, scaling): |
891 # Popup the default menu |
891 # Popup the default menu |
892 self.Parent.PopupDefaultMenu() |
892 self.Parent.PopupDefaultMenu() |
893 |
893 |
894 # Refreshes the coil model |
894 # Refreshes the coil model |
895 def RefreshModel(self, move=True): |
895 def RefreshModel(self, move=True): |
896 self.Parent.RefreshCoilModel(self) |
896 self.Parent.RefreshCoilModel(self) |
897 # If coil has moved, refresh the model of wires connected to output |
897 # If coil has moved, refresh the model of wires connected to output |
898 if move: |
898 if move: |
899 self.Output.RefreshWires() |
899 self.Output.RefreshWires() |
900 |
900 |
901 # Draws the highlightment of this element if it is highlighted |
901 # Draws the highlightment of this element if it is highlighted |
902 def DrawHighlightment(self, dc): |
902 def DrawHighlightment(self, dc): |
903 scalex, scaley = dc.GetUserScale() |
903 scalex, scaley = dc.GetUserScale() |
904 dc.SetUserScale(1, 1) |
904 dc.SetUserScale(1, 1) |
905 dc.SetPen(MiterPen(HIGHLIGHTCOLOR, (3 * scalex + 5), wx.SOLID)) |
905 dc.SetPen(MiterPen(HIGHLIGHTCOLOR, (3 * scalex + 5), wx.SOLID)) |
906 dc.SetBrush(wx.TRANSPARENT_BRUSH) |
906 dc.SetBrush(wx.TRANSPARENT_BRUSH) |
907 dc.SetLogicalFunction(wx.AND) |
907 dc.SetLogicalFunction(wx.AND) |
908 # Draw a two circle arcs for representing the coil |
908 # Draw a two circle arcs for representing the coil |
909 dc.DrawEllipticArc(round(self.Pos.x * scalex), |
909 dc.DrawEllipticArc(round(self.Pos.x * scalex), |
910 round((self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1) * scaley), |
910 round((self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1) * scaley), |
911 round(self.Size[0] * scalex), |
911 round(self.Size[0] * scalex), |
912 round((int(self.Size[1] * sqrt(2)) - 1) * scaley), |
912 round((int(self.Size[1] * sqrt(2)) - 1) * scaley), |
913 135, 225) |
913 135, 225) |
914 dc.DrawEllipticArc(round(self.Pos.x * scalex), |
914 dc.DrawEllipticArc(round(self.Pos.x * scalex), |
915 round((self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1) * scaley), |
915 round((self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1) * scaley), |
916 round(self.Size[0] * scalex), |
916 round(self.Size[0] * scalex), |
917 round((int(self.Size[1] * sqrt(2)) - 1) * scaley), |
917 round((int(self.Size[1] * sqrt(2)) - 1) * scaley), |
918 -45, 45) |
918 -45, 45) |
919 dc.SetLogicalFunction(wx.COPY) |
919 dc.SetLogicalFunction(wx.COPY) |
920 dc.SetUserScale(scalex, scaley) |
920 dc.SetUserScale(scalex, scaley) |
921 |
921 |
922 # Adds an highlight to the connection |
922 # Adds an highlight to the connection |
923 def AddHighlight(self, infos, start, end, highlight_type): |
923 def AddHighlight(self, infos, start, end, highlight_type): |
924 highlights = self.Highlights.setdefault(infos[0], []) |
924 highlights = self.Highlights.setdefault(infos[0], []) |
925 if infos[0] == "reference": |
925 if infos[0] == "reference": |
926 if start[0] == 0 and end[0] == 0: |
926 if start[0] == 0 and end[0] == 0: |
927 AddHighlight(highlights, (start, end, highlight_type)) |
927 AddHighlight(highlights, (start, end, highlight_type)) |
928 else: |
928 else: |
929 AddHighlight(highlights, ((0, 0), (0, 1), highlight_type)) |
929 AddHighlight(highlights, ((0, 0), (0, 1), highlight_type)) |
930 |
930 |
931 # Removes an highlight from the connection |
931 # Removes an highlight from the connection |
932 def RemoveHighlight(self, infos, start, end, highlight_type): |
932 def RemoveHighlight(self, infos, start, end, highlight_type): |
933 highlights = self.Highlights.get(infos[0], []) |
933 highlights = self.Highlights.get(infos[0], []) |
934 if RemoveHighlight(highlights, (start, end, highlight_type)) and len(highlights) == 0: |
934 if RemoveHighlight(highlights, (start, end, highlight_type)) and len(highlights) == 0: |
935 self.Highlights.pop(infos[0]) |
935 self.Highlights.pop(infos[0]) |
936 |
936 |
937 # Removes all the highlights of one particular type from the connection |
937 # Removes all the highlights of one particular type from the connection |
938 def ClearHighlight(self, highlight_type=None): |
938 def ClearHighlight(self, highlight_type=None): |
939 if highlight_type is None: |
939 if highlight_type is None: |
940 self.Highlights = {} |
940 self.Highlights = {} |
941 else: |
941 else: |
942 highlight_items = self.Highlights.items() |
942 highlight_items = self.Highlights.items() |
943 for name, highlights in highlight_items: |
943 for name, highlights in highlight_items: |
944 highlights = ClearHighlights(highlight, highlight_type) |
944 highlights = ClearHighlights(highlight, highlight_type) |
945 if len(highlights) == 0: |
945 if len(highlights) == 0: |
946 self.Highlights.pop(name) |
946 self.Highlights.pop(name) |
947 |
947 |
948 # Draws coil |
948 # Draws coil |
949 def Draw(self, dc): |
949 def Draw(self, dc): |
950 Graphic_Element.Draw(self, dc) |
950 Graphic_Element.Draw(self, dc) |
951 if self.Value is not None and self.Value: |
951 if self.Value is not None and self.Value: |
952 dc.SetPen(MiterPen(wx.GREEN, 2, wx.SOLID)) |
952 dc.SetPen(MiterPen(wx.GREEN, 2, wx.SOLID)) |
953 else: |
953 else: |
954 dc.SetPen(MiterPen(wx.BLACK, 2, wx.SOLID)) |
954 dc.SetPen(MiterPen(wx.BLACK, 2, wx.SOLID)) |
955 dc.SetBrush(wx.TRANSPARENT_BRUSH) |
955 dc.SetBrush(wx.TRANSPARENT_BRUSH) |
956 |
956 |
957 # Compiling coil type modifier symbol |
957 # Compiling coil type modifier symbol |
958 typetext = "" |
958 typetext = "" |
959 if self.Type == COIL_REVERSE: |
959 if self.Type == COIL_REVERSE: |
960 typetext = "/" |
960 typetext = "/" |
961 elif self.Type == COIL_SET: |
961 elif self.Type == COIL_SET: |
962 typetext = "S" |
962 typetext = "S" |
964 typetext = "R" |
964 typetext = "R" |
965 elif self.Type == COIL_RISING: |
965 elif self.Type == COIL_RISING: |
966 typetext = "P" |
966 typetext = "P" |
967 elif self.Type == COIL_FALLING: |
967 elif self.Type == COIL_FALLING: |
968 typetext = "N" |
968 typetext = "N" |
969 |
969 |
970 if getattr(dc, "printing", False) and not isinstance(dc, wx.PostScriptDC): |
970 if getattr(dc, "printing", False) and not isinstance(dc, wx.PostScriptDC): |
971 # Draw an clipped ellipse for representing the coil |
971 # Draw an clipped ellipse for representing the coil |
972 clipping_box = dc.GetClippingBox() |
972 clipping_box = dc.GetClippingBox() |
973 dc.SetClippingRegion(self.Pos.x - 1, self.Pos.y, self.Size[0] + 2, self.Size[1] + 1) |
973 dc.SetClippingRegion(self.Pos.x - 1, self.Pos.y, self.Size[0] + 2, self.Size[1] + 1) |
974 dc.DrawEllipse(self.Pos.x, self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1, self.Size[0], int(self.Size[1] * sqrt(2)) - 1) |
974 dc.DrawEllipse(self.Pos.x, self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1, self.Size[0], int(self.Size[1] * sqrt(2)) - 1) |
990 dc.SetPen(MiterPen(wx.BLACK)) |
990 dc.SetPen(MiterPen(wx.BLACK)) |
991 dc.DrawPoint(self.Pos.x + 1, self.Pos.y + self.Size[1] / 2 + 1) |
991 dc.DrawPoint(self.Pos.x + 1, self.Pos.y + self.Size[1] / 2 + 1) |
992 name_size = self.NameSize |
992 name_size = self.NameSize |
993 if typetext != "": |
993 if typetext != "": |
994 type_size = self.TypeSize |
994 type_size = self.TypeSize |
995 |
995 |
996 # Draw coil name |
996 # Draw coil name |
997 name_pos = (self.Pos.x + (self.Size[0] - name_size[0]) / 2, |
997 name_pos = (self.Pos.x + (self.Size[0] - name_size[0]) / 2, |
998 self.Pos.y - (name_size[1] + 2)) |
998 self.Pos.y - (name_size[1] + 2)) |
999 dc.DrawText(self.Name, name_pos[0], name_pos[1]) |
999 dc.DrawText(self.Name, name_pos[0], name_pos[1]) |
1000 # Draw the modifier symbol in the middle of coil |
1000 # Draw the modifier symbol in the middle of coil |
1010 for name, highlights in self.Highlights.iteritems(): |
1010 for name, highlights in self.Highlights.iteritems(): |
1011 if name == "reference": |
1011 if name == "reference": |
1012 DrawHighlightedText(dc, self.Name, highlights, name_pos[0], name_pos[1]) |
1012 DrawHighlightedText(dc, self.Name, highlights, name_pos[0], name_pos[1]) |
1013 elif typetext != "": |
1013 elif typetext != "": |
1014 DrawHighlightedText(dc, typetext, highlights, type_pos[0], type_pos[1]) |
1014 DrawHighlightedText(dc, typetext, highlights, type_pos[0], type_pos[1]) |
1015 |
|
1016 |