26 |
26 |
27 from graphics.GraphicCommons import * |
27 from graphics.GraphicCommons import * |
28 from graphics.DebugDataConsumer import DebugDataConsumer |
28 from graphics.DebugDataConsumer import DebugDataConsumer |
29 from plcopen.structures import * |
29 from plcopen.structures import * |
30 |
30 |
31 #------------------------------------------------------------------------------- |
31 |
|
32 # ------------------------------------------------------------------------------- |
32 # Ladder Diagram PowerRail |
33 # Ladder Diagram PowerRail |
33 #------------------------------------------------------------------------------- |
34 # ------------------------------------------------------------------------------- |
34 |
35 |
35 """ |
|
36 Class that implements the graphic representation of a power rail |
|
37 """ |
|
38 |
36 |
39 class LD_PowerRail(Graphic_Element): |
37 class LD_PowerRail(Graphic_Element): |
40 |
38 """ |
|
39 Class that implements the graphic representation of a power rail |
|
40 """ |
|
41 |
41 # Create a new power rail |
42 # Create a new power rail |
42 def __init__(self, parent, type, id=None, connectors=1): |
43 def __init__(self, parent, type, id=None, connectors=1): |
43 Graphic_Element.__init__(self, parent) |
44 Graphic_Element.__init__(self, parent) |
44 self.Type = None |
45 self.Type = None |
45 self.Connectors = [] |
46 self.Connectors = [] |
46 self.RealConnectors = None |
47 self.RealConnectors = None |
47 self.Id = id |
48 self.Id = id |
48 self.Extensions = [LD_LINE_SIZE / 2, LD_LINE_SIZE / 2] |
49 self.Extensions = [LD_LINE_SIZE / 2, LD_LINE_SIZE / 2] |
49 self.SetType(type, connectors) |
50 self.SetType(type, connectors) |
50 |
51 |
51 def Flush(self): |
52 def Flush(self): |
52 for connector in self.Connectors: |
53 for connector in self.Connectors: |
53 connector.Flush() |
54 connector.Flush() |
54 self.Connectors = [] |
55 self.Connectors = [] |
55 |
56 |
56 # Make a clone of this LD_PowerRail |
57 # Make a clone of this LD_PowerRail |
57 def Clone(self, parent, id = None, pos = None): |
58 def Clone(self, parent, id=None, pos=None): |
58 powerrail = LD_PowerRail(parent, self.Type, id) |
59 powerrail = LD_PowerRail(parent, self.Type, id) |
59 powerrail.SetSize(self.Size[0], self.Size[1]) |
60 powerrail.SetSize(self.Size[0], self.Size[1]) |
60 if pos is not None: |
61 if pos is not None: |
61 powerrail.SetPosition(pos.x, pos.y) |
62 powerrail.SetPosition(pos.x, pos.y) |
62 else: |
63 else: |
63 powerrail.SetPosition(self.Pos.x, self.Pos.y) |
64 powerrail.SetPosition(self.Pos.x, self.Pos.y) |
64 powerrail.Connectors = [] |
65 powerrail.Connectors = [] |
65 for connector in self.Connectors: |
66 for connector in self.Connectors: |
66 powerrail.Connectors.append(connector.Clone(powerrail)) |
67 powerrail.Connectors.append(connector.Clone(powerrail)) |
67 return powerrail |
68 return powerrail |
68 |
69 |
69 def GetConnectorTranslation(self, element): |
70 def GetConnectorTranslation(self, element): |
70 return dict(zip([connector for connector in self.Connectors], |
71 return dict(zip([connector for connector in self.Connectors], |
71 [connector for connector in element.Connectors])) |
72 [connector for connector in element.Connectors])) |
72 |
73 |
73 # Returns the RedrawRect |
74 # Returns the RedrawRect |
74 def GetRedrawRect(self, movex = 0, movey = 0): |
75 def GetRedrawRect(self, movex=0, movey=0): |
75 rect = Graphic_Element.GetRedrawRect(self, movex, movey) |
76 rect = Graphic_Element.GetRedrawRect(self, movex, movey) |
76 for connector in self.Connectors: |
77 for connector in self.Connectors: |
77 rect = rect.Union(connector.GetRedrawRect(movex, movey)) |
78 rect = rect.Union(connector.GetRedrawRect(movex, movey)) |
78 if movex != 0 or movey != 0: |
79 if movex != 0 or movey != 0: |
79 for connector in self.Connectors: |
80 for connector in self.Connectors: |
80 if connector.IsConnected(): |
81 if connector.IsConnected(): |
81 rect = rect.Union(connector.GetConnectedRedrawRect(movex, movey)) |
82 rect = rect.Union(connector.GetConnectedRedrawRect(movex, movey)) |
82 return rect |
83 return rect |
83 |
84 |
84 # Forbids to change the power rail size |
85 # Forbids to change the power rail size |
85 def SetSize(self, width, height): |
86 def SetSize(self, width, height): |
86 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
87 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
87 Graphic_Element.SetSize(self, width, height) |
88 Graphic_Element.SetSize(self, width, height) |
88 else: |
89 else: |
89 Graphic_Element.SetSize(self, LD_POWERRAIL_WIDTH, height) |
90 Graphic_Element.SetSize(self, LD_POWERRAIL_WIDTH, height) |
90 self.RefreshConnectors() |
91 self.RefreshConnectors() |
91 |
92 |
92 # Forbids to select a power rail |
93 # Forbids to select a power rail |
93 def HitTest(self, pt, connectors=True): |
94 def HitTest(self, pt, connectors=True): |
94 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
95 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
95 return Graphic_Element.HitTest(self, pt, connectors) or self.TestConnector(pt, exclude=False) != None |
96 return Graphic_Element.HitTest(self, pt, connectors) or self.TestConnector(pt, exclude=False) is not None |
96 return False |
97 return False |
97 |
98 |
98 # Forbids to select a power rail |
99 # Forbids to select a power rail |
99 def IsInSelection(self, rect): |
100 def IsInSelection(self, rect): |
100 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
101 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
101 return Graphic_Element.IsInSelection(self, rect) |
102 return Graphic_Element.IsInSelection(self, rect) |
102 return False |
103 return False |
103 |
104 |
104 # Deletes this power rail by calling the appropriate method |
105 # Deletes this power rail by calling the appropriate method |
105 def Delete(self): |
106 def Delete(self): |
106 self.Parent.DeletePowerRail(self) |
107 self.Parent.DeletePowerRail(self) |
107 |
108 |
108 # Unconnect all connectors |
109 # Unconnect all connectors |
109 def Clean(self): |
110 def Clean(self): |
110 for connector in self.Connectors: |
111 for connector in self.Connectors: |
111 connector.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
112 connector.UnConnect(delete=self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
112 |
113 |
113 # Refresh the power rail bounding box |
114 # Refresh the power rail bounding box |
114 def RefreshBoundingBox(self): |
115 def RefreshBoundingBox(self): |
115 self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) |
116 self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) |
116 |
117 |
117 # Refresh the power rail size |
118 # Refresh the power rail size |
118 def RefreshSize(self): |
119 def RefreshSize(self): |
119 self.Size = wx.Size(LD_POWERRAIL_WIDTH, max(LD_LINE_SIZE * len(self.Connectors), self.Size[1])) |
120 self.Size = wx.Size(LD_POWERRAIL_WIDTH, max(LD_LINE_SIZE * len(self.Connectors), self.Size[1])) |
120 self.RefreshBoundingBox() |
121 self.RefreshBoundingBox() |
121 |
122 |
122 # Returns the block minimum size |
123 # Returns the block minimum size |
123 def GetMinSize(self, default=False): |
124 def GetMinSize(self, default=False): |
124 height = (LD_LINE_SIZE * (len(self.Connectors) - 1) |
125 height = (LD_LINE_SIZE * (len(self.Connectors) - 1) |
125 if default else 0) |
126 if default else 0) |
126 return LD_POWERRAIL_WIDTH, height + self.Extensions[0] + self.Extensions[1] |
127 return LD_POWERRAIL_WIDTH, height + self.Extensions[0] + self.Extensions[1] |
127 |
128 |
128 # Add a connector or a blank to this power rail at the last place |
129 # Add a connector or a blank to this power rail at the last place |
129 def AddConnector(self): |
130 def AddConnector(self): |
130 self.InsertConnector(len(self.Connectors)) |
131 self.InsertConnector(len(self.Connectors)) |
131 |
132 |
132 # Add a connector or a blank to this power rail at the place given |
133 # Add a connector or a blank to this power rail at the place given |
133 def InsertConnector(self, idx): |
134 def InsertConnector(self, idx): |
134 if self.Type == LEFTRAIL: |
135 if self.Type == LEFTRAIL: |
135 connector = Connector(self, "", "BOOL", wx.Point(self.Size[0], 0), EAST) |
136 connector = Connector(self, "", "BOOL", wx.Point(self.Size[0], 0), EAST) |
136 elif self.Type == RIGHTRAIL: |
137 elif self.Type == RIGHTRAIL: |
137 connector = Connector(self, "", "BOOL", wx.Point(0, 0), WEST) |
138 connector = Connector(self, "", "BOOL", wx.Point(0, 0), WEST) |
138 self.Connectors.insert(idx, connector) |
139 self.Connectors.insert(idx, connector) |
139 self.RefreshSize() |
140 self.RefreshSize() |
140 self.RefreshConnectors() |
141 self.RefreshConnectors() |
141 |
142 |
142 # Moves the divergence connector given |
143 # Moves the divergence connector given |
143 def MoveConnector(self, connector, movey): |
144 def MoveConnector(self, connector, movey): |
144 position = connector.GetRelPosition() |
145 position = connector.GetRelPosition() |
145 connector.SetPosition(wx.Point(position.x, position.y + movey)) |
146 connector.SetPosition(wx.Point(position.x, position.y + movey)) |
146 miny = self.Size[1] |
147 miny = self.Size[1] |
191 if self.Type == LEFTRAIL: |
192 if self.Type == LEFTRAIL: |
192 connector.SetPosition(wx.Point(self.Size[0], position)) |
193 connector.SetPosition(wx.Point(self.Size[0], position)) |
193 elif self.Type == RIGHTRAIL: |
194 elif self.Type == RIGHTRAIL: |
194 connector.SetPosition(wx.Point(0, position)) |
195 connector.SetPosition(wx.Point(0, position)) |
195 self.RefreshConnected() |
196 self.RefreshConnected() |
196 |
197 |
197 # Refresh the position of wires connected to power rail |
198 # Refresh the position of wires connected to power rail |
198 def RefreshConnected(self, exclude = []): |
199 def RefreshConnected(self, exclude=[]): |
199 for connector in self.Connectors: |
200 for connector in self.Connectors: |
200 connector.MoveConnected(exclude) |
201 connector.MoveConnected(exclude) |
201 |
202 |
202 # Returns the power rail connector that starts with the point given if it exists |
203 # Returns the power rail connector that starts with the point given if it exists |
203 def GetConnector(self, position, name = None): |
204 def GetConnector(self, position, name=None): |
204 # if a name is given |
205 # if a name is given |
205 if name is not None: |
206 if name is not None: |
206 # Test each connector if it exists |
207 # Test each connector if it exists |
207 for connector in self.Connectors: |
208 for connector in self.Connectors: |
208 if name == connector.GetName(): |
209 if name == connector.GetName(): |
209 return connector |
210 return connector |
210 return self.FindNearestConnector(position, [connector for connector in self.Connectors if connector is not None]) |
211 return self.FindNearestConnector(position, [connector for connector in self.Connectors if connector is not None]) |
211 |
212 |
212 # Returns all the power rail connectors |
213 # Returns all the power rail connectors |
213 def GetConnectors(self): |
214 def GetConnectors(self): |
214 connectors = [connector for connector in self.Connectors if connector] |
215 connectors = [connector for connector in self.Connectors if connector] |
215 if self.Type == LEFTRAIL: |
216 if self.Type == LEFTRAIL: |
216 return {"inputs": [], "outputs": connectors} |
217 return {"inputs": [], "outputs": connectors} |
217 else: |
218 else: |
218 return {"inputs": connectors, "outputs": []} |
219 return {"inputs": connectors, "outputs": []} |
219 |
220 |
220 # Test if point given is on one of the power rail connectors |
221 # Test if point given is on one of the power rail connectors |
221 def TestConnector(self, pt, direction = None, exclude = True): |
222 def TestConnector(self, pt, direction=None, exclude=True): |
222 for connector in self.Connectors: |
223 for connector in self.Connectors: |
223 if connector.TestPoint(pt, direction, exclude): |
224 if connector.TestPoint(pt, direction, exclude): |
224 return connector |
225 return connector |
225 return None |
226 return None |
226 |
227 |
227 # Returns the power rail type |
228 # Returns the power rail type |
228 def SetType(self, type, connectors): |
229 def SetType(self, type, connectors): |
229 if type != self.Type or len(self.Connectors) != connectors: |
230 if type != self.Type or len(self.Connectors) != connectors: |
230 # Create a connector or a blank according to 'connectors' and add it in |
231 # Create a connector or a blank according to 'connectors' and add it in |
231 # the connectors list |
232 # the connectors list |
233 self.Clean() |
234 self.Clean() |
234 self.Connectors = [] |
235 self.Connectors = [] |
235 for connector in xrange(connectors): |
236 for connector in xrange(connectors): |
236 self.AddConnector() |
237 self.AddConnector() |
237 self.RefreshSize() |
238 self.RefreshSize() |
238 |
239 |
239 # Returns the power rail type |
240 # Returns the power rail type |
240 def GetType(self): |
241 def GetType(self): |
241 return self.Type |
242 return self.Type |
242 |
243 |
243 # Method called when a LeftDown event have been generated |
244 # Method called when a LeftDown event have been generated |
244 def OnLeftDown(self, event, dc, scaling): |
245 def OnLeftDown(self, event, dc, scaling): |
245 self.RealConnectors = [] |
246 self.RealConnectors = [] |
246 height = self.Size[1] - self.Extensions[0] - self.Extensions[1] |
247 height = self.Size[1] - self.Extensions[0] - self.Extensions[1] |
247 if height > 0: |
248 if height > 0: |
248 for connector in self.Connectors: |
249 for connector in self.Connectors: |
249 position = connector.GetRelPosition() |
250 position = connector.GetRelPosition() |
250 self.RealConnectors.append(max(0., min(float(position.y - self.Extensions[0]) / float(height), 1.))) |
251 self.RealConnectors.append(max(0., min(float(position.y - self.Extensions[0]) / float(height), 1.))) |
251 elif len(self.Connectors) > 1: |
252 elif len(self.Connectors) > 1: |
252 self.RealConnectors = map(lambda x : x * 1 / (len(self.Connectors) - 1), xrange(len(self.Connectors))) |
253 self.RealConnectors = map(lambda x: x * 1 / (len(self.Connectors) - 1), xrange(len(self.Connectors))) |
253 else: |
254 else: |
254 self.RealConnectors = [0.5] |
255 self.RealConnectors = [0.5] |
255 Graphic_Element.OnLeftDown(self, event, dc, scaling) |
256 Graphic_Element.OnLeftDown(self, event, dc, scaling) |
256 |
257 |
257 # Method called when a LeftUp event have been generated |
258 # Method called when a LeftUp event have been generated |
258 def OnLeftUp(self, event, dc, scaling): |
259 def OnLeftUp(self, event, dc, scaling): |
259 Graphic_Element.OnLeftUp(self, event, dc, scaling) |
260 Graphic_Element.OnLeftUp(self, event, dc, scaling) |
260 self.RealConnectors = None |
261 self.RealConnectors = None |
261 |
262 |
262 # Method called when a LeftDown event have been generated |
263 # Method called when a LeftDown event have been generated |
263 def OnRightDown(self, event, dc, scaling): |
264 def OnRightDown(self, event, dc, scaling): |
264 pos = GetScaledEventPosition(event, dc, scaling) |
265 pos = GetScaledEventPosition(event, dc, scaling) |
265 # Test if a connector have been handled |
266 # Test if a connector have been handled |
266 connector = self.TestConnector(pos, exclude=False) |
267 connector = self.TestConnector(pos, exclude=False) |
412 if spreading and not self.PreviousSpreading: |
413 if spreading and not self.PreviousSpreading: |
413 self.Output.SpreadCurrent(True) |
414 self.Output.SpreadCurrent(True) |
414 elif not spreading and self.PreviousSpreading: |
415 elif not spreading and self.PreviousSpreading: |
415 self.Output.SpreadCurrent(False) |
416 self.Output.SpreadCurrent(False) |
416 self.PreviousSpreading = spreading |
417 self.PreviousSpreading = spreading |
417 |
418 |
418 # Make a clone of this LD_Contact |
419 # Make a clone of this LD_Contact |
419 def Clone(self, parent, id = None, pos = None): |
420 def Clone(self, parent, id=None, pos=None): |
420 contact = LD_Contact(parent, self.Type, self.Name, id) |
421 contact = LD_Contact(parent, self.Type, self.Name, id) |
421 contact.SetSize(self.Size[0], self.Size[1]) |
422 contact.SetSize(self.Size[0], self.Size[1]) |
422 if pos is not None: |
423 if pos is not None: |
423 contact.SetPosition(pos.x, pos.y) |
424 contact.SetPosition(pos.x, pos.y) |
424 else: |
425 else: |
425 contact.SetPosition(self.Pos.x, self.Pos.y) |
426 contact.SetPosition(self.Pos.x, self.Pos.y) |
426 contact.Input = self.Input.Clone(contact) |
427 contact.Input = self.Input.Clone(contact) |
427 contact.Output = self.Output.Clone(contact) |
428 contact.Output = self.Output.Clone(contact) |
428 return contact |
429 return contact |
429 |
430 |
430 def GetConnectorTranslation(self, element): |
431 def GetConnectorTranslation(self, element): |
431 return {self.Input : element.Input, self.Output : element.Output} |
432 return {self.Input: element.Input, self.Output: element.Output} |
432 |
433 |
433 # Returns the RedrawRect |
434 # Returns the RedrawRect |
434 def GetRedrawRect(self, movex = 0, movey = 0): |
435 def GetRedrawRect(self, movex=0, movey=0): |
435 rect = Graphic_Element.GetRedrawRect(self, movex, movey) |
436 rect = Graphic_Element.GetRedrawRect(self, movex, movey) |
436 rect = rect.Union(self.Input.GetRedrawRect(movex, movey)) |
437 rect = rect.Union(self.Input.GetRedrawRect(movex, movey)) |
437 rect = rect.Union(self.Output.GetRedrawRect(movex, movey)) |
438 rect = rect.Union(self.Output.GetRedrawRect(movex, movey)) |
438 if movex != 0 or movey != 0: |
439 if movex != 0 or movey != 0: |
439 if self.Input.IsConnected(): |
440 if self.Input.IsConnected(): |
497 bbx_x = self.Pos.x |
498 bbx_x = self.Pos.x |
498 bbx_width = self.Size[0] |
499 bbx_width = self.Size[0] |
499 bbx_y = self.Pos.y |
500 bbx_y = self.Pos.y |
500 bbx_height = self.Size[1] |
501 bbx_height = self.Size[1] |
501 self.BoundingBox = wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1) |
502 self.BoundingBox = wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1) |
502 |
503 |
503 # Returns the block minimum size |
504 # Returns the block minimum size |
504 def GetMinSize(self): |
505 def GetMinSize(self): |
505 return LD_ELEMENT_SIZE |
506 return LD_ELEMENT_SIZE |
506 |
507 |
507 # Refresh the position of wire connected to contact |
508 # Refresh the position of wire connected to contact |
508 def RefreshConnected(self, exclude = []): |
509 def RefreshConnected(self, exclude=[]): |
509 self.Input.MoveConnected(exclude) |
510 self.Input.MoveConnected(exclude) |
510 self.Output.MoveConnected(exclude) |
511 self.Output.MoveConnected(exclude) |
511 |
512 |
512 # Returns the contact connector that starts with the point given if it exists |
513 # Returns the contact connector that starts with the point given if it exists |
513 def GetConnector(self, position, name = None): |
514 def GetConnector(self, position, name=None): |
514 # if a name is given |
515 # if a name is given |
515 if name is not None: |
516 if name is not None: |
516 # Test input and output connector |
517 # Test input and output connector |
517 #if name == self.Input.GetName(): |
518 # if name == self.Input.GetName(): |
518 # return self.Input |
519 # return self.Input |
519 if name == self.Output.GetName(): |
520 if name == self.Output.GetName(): |
520 return self.Output |
521 return self.Output |
521 return self.FindNearestConnector(position, [self.Input, self.Output]) |
522 return self.FindNearestConnector(position, [self.Input, self.Output]) |
522 |
523 |
523 # Returns input and output contact connectors |
524 # Returns input and output contact connectors |
524 def GetConnectors(self): |
525 def GetConnectors(self): |
525 return {"inputs": [self.Input], "outputs": [self.Output]} |
526 return {"inputs": [self.Input], "outputs": [self.Output]} |
526 |
527 |
527 # Test if point given is on contact input or output connector |
528 # Test if point given is on contact input or output connector |
528 def TestConnector(self, pt, direction = None, exclude=True): |
529 def TestConnector(self, pt, direction=None, exclude=True): |
529 # Test input connector |
530 # Test input connector |
530 if self.Input.TestPoint(pt, direction, exclude): |
531 if self.Input.TestPoint(pt, direction, exclude): |
531 return self.Input |
532 return self.Input |
532 # Test output connector |
533 # Test output connector |
533 if self.Output.TestPoint(pt, direction, exclude): |
534 if self.Output.TestPoint(pt, direction, exclude): |
590 left_left = (self.Pos.x - 1) * scalex - 2 |
591 left_left = (self.Pos.x - 1) * scalex - 2 |
591 right_left = (self.Pos.x + self.Size[0] - 2) * scalex - 2 |
592 right_left = (self.Pos.x + self.Size[0] - 2) * scalex - 2 |
592 top = (self.Pos.y - 1) * scaley - 2 |
593 top = (self.Pos.y - 1) * scaley - 2 |
593 width = 4 * scalex + 5 |
594 width = 4 * scalex + 5 |
594 height = (self.Size[1] + 3) * scaley + 5 |
595 height = (self.Size[1] + 3) * scaley + 5 |
595 |
596 |
596 dc.DrawRectangle(left_left, top, width, height) |
597 dc.DrawRectangle(left_left, top, width, height) |
597 dc.DrawRectangle(right_left, top, width, height) |
598 dc.DrawRectangle(right_left, top, width, height) |
598 dc.SetLogicalFunction(wx.COPY) |
599 dc.SetLogicalFunction(wx.COPY) |
599 dc.SetUserScale(scalex, scaley) |
600 dc.SetUserScale(scalex, scaley) |
600 |
601 |
601 # Adds an highlight to the connection |
602 # Adds an highlight to the connection |
602 def AddHighlight(self, infos, start, end, highlight_type): |
603 def AddHighlight(self, infos, start, end, highlight_type): |
603 highlights = self.Highlights.setdefault(infos[0], []) |
604 highlights = self.Highlights.setdefault(infos[0], []) |
604 if infos[0] == "reference": |
605 if infos[0] == "reference": |
605 if start[0] == 0 and end[0] == 0: |
606 if start[0] == 0 and end[0] == 0: |
606 AddHighlight(highlights, (start, end, highlight_type)) |
607 AddHighlight(highlights, (start, end, highlight_type)) |
607 else: |
608 else: |
608 AddHighlight(highlights, ((0, 0), (0, 1), highlight_type)) |
609 AddHighlight(highlights, ((0, 0), (0, 1), highlight_type)) |
609 |
610 |
610 # Removes an highlight from the connection |
611 # Removes an highlight from the connection |
611 def RemoveHighlight(self, infos, start, end, highlight_type): |
612 def RemoveHighlight(self, infos, start, end, highlight_type): |
612 highlights = self.Highlights.get(infos[0], []) |
613 highlights = self.Highlights.get(infos[0], []) |
613 if RemoveHighlight(highlights, (start, end, highlight_type)) and len(highlights) == 0: |
614 if RemoveHighlight(highlights, (start, end, highlight_type)) and len(highlights) == 0: |
614 self.Highlights.pop(infos[0]) |
615 self.Highlights.pop(infos[0]) |
615 |
616 |
616 # Removes all the highlights of one particular type from the connection |
617 # Removes all the highlights of one particular type from the connection |
617 def ClearHighlight(self, highlight_type=None): |
618 def ClearHighlight(self, highlight_type=None): |
618 if highlight_type is None: |
619 if highlight_type is None: |
619 self.Highlights = {} |
620 self.Highlights = {} |
620 else: |
621 else: |
621 highlight_items = self.Highlights.items() |
622 highlight_items = self.Highlights.items() |
622 for name, highlights in highlight_items: |
623 for name, highlights in highlight_items: |
623 highlights = ClearHighlights(highlight, highlight_type) |
624 highlights = ClearHighlights(highlight, highlight_type) |
624 if len(highlights) == 0: |
625 if len(highlights) == 0: |
625 self.Highlights.pop(name) |
626 self.Highlights.pop(name) |
626 |
627 |
627 # Draws contact |
628 # Draws contact |
628 def Draw(self, dc): |
629 def Draw(self, dc): |
629 Graphic_Element.Draw(self, dc) |
630 Graphic_Element.Draw(self, dc) |
630 if self.Value is not None: |
631 if self.Value is not None: |
631 if self.Type == CONTACT_NORMAL and self.Value or \ |
632 if self.Type == CONTACT_NORMAL and self.Value or \ |
632 self.Type == CONTACT_REVERSE and not self.Value or \ |
633 self.Type == CONTACT_REVERSE and not self.Value or \ |
633 self.Type == CONTACT_RISING and self.Value and not self.PreviousValue or \ |
634 self.Type == CONTACT_RISING and self.Value and not self.PreviousValue or \ |
634 self.Type == CONTACT_RISING and not self.Value and self.PreviousValue: |
635 self.Type == CONTACT_RISING and not self.Value and self.PreviousValue: |
635 if self.Forced: |
636 if self.Forced: |
708 self.Output = Connector(self, "", "BOOL", wx.Point(self.Size[0], self.Size[1] / 2 + 1), EAST) |
710 self.Output = Connector(self, "", "BOOL", wx.Point(self.Size[0], self.Size[1] / 2 + 1), EAST) |
709 self.Value = None |
711 self.Value = None |
710 self.PreviousValue = False |
712 self.PreviousValue = False |
711 self.RefreshNameSize() |
713 self.RefreshNameSize() |
712 self.RefreshTypeSize() |
714 self.RefreshTypeSize() |
713 |
715 |
714 def Flush(self): |
716 def Flush(self): |
715 if self.Input is not None: |
717 if self.Input is not None: |
716 self.Input.Flush() |
718 self.Input.Flush() |
717 self.Input = None |
719 self.Input = None |
718 if self.Output is not None: |
720 if self.Output is not None: |
719 self.Output.Flush() |
721 self.Output.Flush() |
720 self.Output = None |
722 self.Output = None |
721 |
723 |
722 def SpreadCurrent(self): |
724 def SpreadCurrent(self): |
723 if self.Parent.Debug: |
725 if self.Parent.Debug: |
724 self.PreviousValue = self.Value |
726 self.PreviousValue = self.Value |
725 self.Value = self.Input.ReceivingCurrent() |
727 self.Value = self.Input.ReceivingCurrent() |
726 if self.Value and not self.PreviousValue: |
728 if self.Value and not self.PreviousValue: |
727 self.Output.SpreadCurrent(True) |
729 self.Output.SpreadCurrent(True) |
728 elif not self.Value and self.PreviousValue: |
730 elif not self.Value and self.PreviousValue: |
729 self.Output.SpreadCurrent(False) |
731 self.Output.SpreadCurrent(False) |
730 if self.Value != self.PreviousValue and self.Visible: |
732 if self.Value != self.PreviousValue and self.Visible: |
731 self.Parent.ElementNeedRefresh(self) |
733 self.Parent.ElementNeedRefresh(self) |
732 |
734 |
733 # Make a clone of this LD_Coil |
735 # Make a clone of this LD_Coil |
734 def Clone(self, parent, id = None, pos = None): |
736 def Clone(self, parent, id=None, pos=None): |
735 coil = LD_Coil(parent, self.Type, self.Name, id) |
737 coil = LD_Coil(parent, self.Type, self.Name, id) |
736 coil.SetSize(self.Size[0], self.Size[1]) |
738 coil.SetSize(self.Size[0], self.Size[1]) |
737 if pos is not None: |
739 if pos is not None: |
738 coil.SetPosition(pos.x, pos.y) |
740 coil.SetPosition(pos.x, pos.y) |
739 else: |
741 else: |
740 coil.SetPosition(self.Pos.x, self.Pos.y) |
742 coil.SetPosition(self.Pos.x, self.Pos.y) |
741 coil.Input = self.Input.Clone(coil) |
743 coil.Input = self.Input.Clone(coil) |
742 coil.Output = self.Output.Clone(coil) |
744 coil.Output = self.Output.Clone(coil) |
743 return coil |
745 return coil |
744 |
746 |
745 def GetConnectorTranslation(self, element): |
747 def GetConnectorTranslation(self, element): |
746 return {self.Input : element.Input, self.Output : element.Output} |
748 return {self.Input: element.Input, self.Output: element.Output} |
747 |
749 |
748 # Returns the RedrawRect |
750 # Returns the RedrawRect |
749 def GetRedrawRect(self, movex = 0, movey = 0): |
751 def GetRedrawRect(self, movex=0, movey=0): |
750 rect = Graphic_Element.GetRedrawRect(self, movex, movey) |
752 rect = Graphic_Element.GetRedrawRect(self, movex, movey) |
751 rect = rect.Union(self.Input.GetRedrawRect(movex, movey)) |
753 rect = rect.Union(self.Input.GetRedrawRect(movex, movey)) |
752 rect = rect.Union(self.Output.GetRedrawRect(movex, movey)) |
754 rect = rect.Union(self.Output.GetRedrawRect(movex, movey)) |
753 if movex != 0 or movey != 0: |
755 if movex != 0 or movey != 0: |
754 if self.Input.IsConnected(): |
756 if self.Input.IsConnected(): |
755 rect = rect.Union(self.Input.GetConnectedRedrawRect(movex, movey)) |
757 rect = rect.Union(self.Input.GetConnectedRedrawRect(movex, movey)) |
756 if self.Output.IsConnected(): |
758 if self.Output.IsConnected(): |
757 rect = rect.Union(self.Output.GetConnectedRedrawRect(movex, movey)) |
759 rect = rect.Union(self.Output.GetConnectedRedrawRect(movex, movey)) |
758 return rect |
760 return rect |
759 |
761 |
760 def ProcessDragging(self, movex, movey, event, scaling): |
762 def ProcessDragging(self, movex, movey, event, scaling): |
761 if self.Parent.GetDrawingMode() != FREEDRAWING_MODE: |
763 if self.Parent.GetDrawingMode() != FREEDRAWING_MODE: |
762 movex = movey = 0 |
764 movex = movey = 0 |
763 return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling, height_fac = 2) |
765 return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling, height_fac=2) |
764 |
766 |
765 # Forbids to change the Coil size |
767 # Forbids to change the Coil size |
766 def SetSize(self, width, height): |
768 def SetSize(self, width, height): |
767 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
769 if self.Parent.GetDrawingMode() == FREEDRAWING_MODE: |
768 Graphic_Element.SetSize(self, width, height) |
770 Graphic_Element.SetSize(self, width, height) |
769 self.RefreshConnectors() |
771 self.RefreshConnectors() |
770 |
772 |
771 # Delete this coil by calling the appropriate method |
773 # Delete this coil by calling the appropriate method |
772 def Delete(self): |
774 def Delete(self): |
773 self.Parent.DeleteCoil(self) |
775 self.Parent.DeleteCoil(self) |
774 |
776 |
775 # Unconnect input and output |
777 # Unconnect input and output |
776 def Clean(self): |
778 def Clean(self): |
777 self.Input.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
779 self.Input.UnConnect(delete=self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
778 self.Output.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
780 self.Output.UnConnect(delete=self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
779 |
781 |
780 # Refresh the size of text for name |
782 # Refresh the size of text for name |
781 def RefreshNameSize(self): |
783 def RefreshNameSize(self): |
782 if self.Name != "": |
784 if self.Name != "": |
783 self.NameSize = self.Parent.GetTextExtent(self.Name) |
785 self.NameSize = self.Parent.GetTextExtent(self.Name) |
784 else: |
786 else: |
785 self.NameSize = 0, 0 |
787 self.NameSize = 0, 0 |
786 |
788 |
787 # Refresh the size of text for type |
789 # Refresh the size of text for type |
788 def RefreshTypeSize(self): |
790 def RefreshTypeSize(self): |
789 typetext = "" |
791 typetext = "" |
790 if self.Type == COIL_REVERSE: |
792 if self.Type == COIL_REVERSE: |
791 typetext = "/" |
793 typetext = "/" |
816 bbx_x = self.Pos.x |
818 bbx_x = self.Pos.x |
817 bbx_width = self.Size[0] |
819 bbx_width = self.Size[0] |
818 bbx_y = self.Pos.y |
820 bbx_y = self.Pos.y |
819 bbx_height = self.Size[1] |
821 bbx_height = self.Size[1] |
820 self.BoundingBox = wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1) |
822 self.BoundingBox = wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1) |
821 |
823 |
822 # Returns the block minimum size |
824 # Returns the block minimum size |
823 def GetMinSize(self): |
825 def GetMinSize(self): |
824 return LD_ELEMENT_SIZE |
826 return LD_ELEMENT_SIZE |
825 |
827 |
826 # Refresh the position of wire connected to coil |
828 # Refresh the position of wire connected to coil |
827 def RefreshConnected(self, exclude = []): |
829 def RefreshConnected(self, exclude=[]): |
828 self.Input.MoveConnected(exclude) |
830 self.Input.MoveConnected(exclude) |
829 self.Output.MoveConnected(exclude) |
831 self.Output.MoveConnected(exclude) |
830 |
832 |
831 # Returns the coil connector that starts with the point given if it exists |
833 # Returns the coil connector that starts with the point given if it exists |
832 def GetConnector(self, position, name = None): |
834 def GetConnector(self, position, name=None): |
833 # if a name is given |
835 # if a name is given |
834 if name is not None: |
836 if name is not None: |
835 # Test input and output connector |
837 # Test input and output connector |
836 #if self.Input and name == self.Input.GetName(): |
838 # if self.Input and name == self.Input.GetName(): |
837 # return self.Input |
839 # return self.Input |
838 if self.Output and name == self.Output.GetName(): |
840 if self.Output and name == self.Output.GetName(): |
839 return self.Output |
841 return self.Output |
840 return self.FindNearestConnector(position, [self.Input, self.Output]) |
842 return self.FindNearestConnector(position, [self.Input, self.Output]) |
841 |
843 |
842 # Returns input and output coil connectors |
844 # Returns input and output coil connectors |
843 def GetConnectors(self): |
845 def GetConnectors(self): |
844 return {"inputs": [self.Input], "outputs": [self.Output]} |
846 return {"inputs": [self.Input], "outputs": [self.Output]} |
845 |
847 |
846 # Test if point given is on coil input or output connector |
848 # Test if point given is on coil input or output connector |
847 def TestConnector(self, pt, direction = None, exclude=True): |
849 def TestConnector(self, pt, direction=None, exclude=True): |
848 # Test input connector |
850 # Test input connector |
849 if self.Input.TestPoint(pt, direction, exclude): |
851 if self.Input.TestPoint(pt, direction, exclude): |
850 return self.Input |
852 return self.Input |
851 # Test output connector |
853 # Test output connector |
852 if self.Output.TestPoint(pt, direction, exclude): |
854 if self.Output.TestPoint(pt, direction, exclude): |
853 return self.Output |
855 return self.Output |
854 return None |
856 return None |
855 |
857 |
856 # Refresh the positions of the block connectors |
858 # Refresh the positions of the block connectors |
857 def RefreshConnectors(self): |
859 def RefreshConnectors(self): |
858 scaling = self.Parent.GetScaling() |
860 scaling = self.Parent.GetScaling() |
859 position = self.Size[1] / 2 + 1 |
861 position = self.Size[1] / 2 + 1 |
860 if scaling is not None: |
862 if scaling is not None: |
861 position = round(float(self.Pos.y + position) / float(scaling[1])) * scaling[1] - self.Pos.y |
863 position = round(float(self.Pos.y + position) / float(scaling[1])) * scaling[1] - self.Pos.y |
862 self.Input.SetPosition(wx.Point(0, position)) |
864 self.Input.SetPosition(wx.Point(0, position)) |
863 self.Output.SetPosition(wx.Point(self.Size[0], position)) |
865 self.Output.SetPosition(wx.Point(self.Size[0], position)) |
864 self.RefreshConnected() |
866 self.RefreshConnected() |
865 |
867 |
866 # Changes the coil name |
868 # Changes the coil name |
867 def SetName(self, name): |
869 def SetName(self, name): |
868 self.Name = name |
870 self.Name = name |
869 self.RefreshNameSize() |
871 self.RefreshNameSize() |
870 |
872 |
871 # Returns the coil name |
873 # Returns the coil name |
872 def GetName(self): |
874 def GetName(self): |
873 return self.Name |
875 return self.Name |
874 |
876 |
875 # Changes the coil type |
877 # Changes the coil type |
876 def SetType(self, type): |
878 def SetType(self, type): |
877 self.Type = type |
879 self.Type = type |
878 self.RefreshTypeSize() |
880 self.RefreshTypeSize() |
879 |
881 |
880 # Returns the coil type |
882 # Returns the coil type |
881 def GetType(self): |
883 def GetType(self): |
882 return self.Type |
884 return self.Type |
883 |
885 |
884 # Method called when a LeftDClick event have been generated |
886 # Method called when a LeftDClick event have been generated |
885 def OnLeftDClick(self, event, dc, scaling): |
887 def OnLeftDClick(self, event, dc, scaling): |
886 # Edit the coil properties |
888 # Edit the coil properties |
887 self.Parent.EditCoilContent(self) |
889 self.Parent.EditCoilContent(self) |
888 |
890 |
889 # Method called when a RightUp event have been generated |
891 # Method called when a RightUp event have been generated |
890 def OnRightUp(self, event, dc, scaling): |
892 def OnRightUp(self, event, dc, scaling): |
891 # Popup the default menu |
893 # Popup the default menu |
892 self.Parent.PopupDefaultMenu() |
894 self.Parent.PopupDefaultMenu() |
893 |
895 |
894 # Refreshes the coil model |
896 # Refreshes the coil model |
895 def RefreshModel(self, move=True): |
897 def RefreshModel(self, move=True): |
896 self.Parent.RefreshCoilModel(self) |
898 self.Parent.RefreshCoilModel(self) |
897 # If coil has moved, refresh the model of wires connected to output |
899 # If coil has moved, refresh the model of wires connected to output |
898 if move: |
900 if move: |
899 self.Output.RefreshWires() |
901 self.Output.RefreshWires() |
900 |
902 |
901 # Draws the highlightment of this element if it is highlighted |
903 # Draws the highlightment of this element if it is highlighted |
902 def DrawHighlightment(self, dc): |
904 def DrawHighlightment(self, dc): |
903 scalex, scaley = dc.GetUserScale() |
905 scalex, scaley = dc.GetUserScale() |
904 dc.SetUserScale(1, 1) |
906 dc.SetUserScale(1, 1) |
905 dc.SetPen(MiterPen(HIGHLIGHTCOLOR, (3 * scalex + 5), wx.SOLID)) |
907 dc.SetPen(MiterPen(HIGHLIGHTCOLOR, (3 * scalex + 5), wx.SOLID)) |
906 dc.SetBrush(wx.TRANSPARENT_BRUSH) |
908 dc.SetBrush(wx.TRANSPARENT_BRUSH) |
907 dc.SetLogicalFunction(wx.AND) |
909 dc.SetLogicalFunction(wx.AND) |
908 # Draw a two circle arcs for representing the coil |
910 # Draw a two circle arcs for representing the coil |
909 dc.DrawEllipticArc(round(self.Pos.x * scalex), |
911 dc.DrawEllipticArc(round(self.Pos.x * scalex), |
910 round((self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1) * scaley), |
912 round((self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1) * scaley), |
911 round(self.Size[0] * scalex), |
913 round(self.Size[0] * scalex), |
912 round((int(self.Size[1] * sqrt(2)) - 1) * scaley), |
914 round((int(self.Size[1] * sqrt(2)) - 1) * scaley), |
913 135, 225) |
915 135, 225) |
914 dc.DrawEllipticArc(round(self.Pos.x * scalex), |
916 dc.DrawEllipticArc(round(self.Pos.x * scalex), |
915 round((self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1) * scaley), |
917 round((self.Pos.y - int(self.Size[1] * (sqrt(2) - 1.) / 2.) + 1) * scaley), |
916 round(self.Size[0] * scalex), |
918 round(self.Size[0] * scalex), |
917 round((int(self.Size[1] * sqrt(2)) - 1) * scaley), |
919 round((int(self.Size[1] * sqrt(2)) - 1) * scaley), |
918 -45, 45) |
920 -45, 45) |
919 dc.SetLogicalFunction(wx.COPY) |
921 dc.SetLogicalFunction(wx.COPY) |
920 dc.SetUserScale(scalex, scaley) |
922 dc.SetUserScale(scalex, scaley) |
921 |
923 |
922 # Adds an highlight to the connection |
924 # Adds an highlight to the connection |
923 def AddHighlight(self, infos, start, end, highlight_type): |
925 def AddHighlight(self, infos, start, end, highlight_type): |
924 highlights = self.Highlights.setdefault(infos[0], []) |
926 highlights = self.Highlights.setdefault(infos[0], []) |
925 if infos[0] == "reference": |
927 if infos[0] == "reference": |
926 if start[0] == 0 and end[0] == 0: |
928 if start[0] == 0 and end[0] == 0: |
927 AddHighlight(highlights, (start, end, highlight_type)) |
929 AddHighlight(highlights, (start, end, highlight_type)) |
928 else: |
930 else: |
929 AddHighlight(highlights, ((0, 0), (0, 1), highlight_type)) |
931 AddHighlight(highlights, ((0, 0), (0, 1), highlight_type)) |
930 |
932 |
931 # Removes an highlight from the connection |
933 # Removes an highlight from the connection |
932 def RemoveHighlight(self, infos, start, end, highlight_type): |
934 def RemoveHighlight(self, infos, start, end, highlight_type): |
933 highlights = self.Highlights.get(infos[0], []) |
935 highlights = self.Highlights.get(infos[0], []) |
934 if RemoveHighlight(highlights, (start, end, highlight_type)) and len(highlights) == 0: |
936 if RemoveHighlight(highlights, (start, end, highlight_type)) and len(highlights) == 0: |
935 self.Highlights.pop(infos[0]) |
937 self.Highlights.pop(infos[0]) |
936 |
938 |
937 # Removes all the highlights of one particular type from the connection |
939 # Removes all the highlights of one particular type from the connection |
938 def ClearHighlight(self, highlight_type=None): |
940 def ClearHighlight(self, highlight_type=None): |
939 if highlight_type is None: |
941 if highlight_type is None: |
940 self.Highlights = {} |
942 self.Highlights = {} |
941 else: |
943 else: |
942 highlight_items = self.Highlights.items() |
944 highlight_items = self.Highlights.items() |
943 for name, highlights in highlight_items: |
945 for name, highlights in highlight_items: |
944 highlights = ClearHighlights(highlight, highlight_type) |
946 highlights = ClearHighlights(highlight, highlight_type) |
945 if len(highlights) == 0: |
947 if len(highlights) == 0: |
946 self.Highlights.pop(name) |
948 self.Highlights.pop(name) |
947 |
949 |
948 # Draws coil |
950 # Draws coil |
949 def Draw(self, dc): |
951 def Draw(self, dc): |
950 Graphic_Element.Draw(self, dc) |
952 Graphic_Element.Draw(self, dc) |
951 if self.Value is not None and self.Value: |
953 if self.Value is not None and self.Value: |
952 dc.SetPen(MiterPen(wx.GREEN, 2, wx.SOLID)) |
954 dc.SetPen(MiterPen(wx.GREEN, 2, wx.SOLID)) |
953 else: |
955 else: |
954 dc.SetPen(MiterPen(wx.BLACK, 2, wx.SOLID)) |
956 dc.SetPen(MiterPen(wx.BLACK, 2, wx.SOLID)) |
955 dc.SetBrush(wx.TRANSPARENT_BRUSH) |
957 dc.SetBrush(wx.TRANSPARENT_BRUSH) |
956 |
958 |
957 # Compiling coil type modifier symbol |
959 # Compiling coil type modifier symbol |
958 typetext = "" |
960 typetext = "" |
959 if self.Type == COIL_REVERSE: |
961 if self.Type == COIL_REVERSE: |
960 typetext = "/" |
962 typetext = "/" |
961 elif self.Type == COIL_SET: |
963 elif self.Type == COIL_SET: |
962 typetext = "S" |
964 typetext = "S" |