20 # |
20 # |
21 #You should have received a copy of the GNU General Public |
21 #You should have received a copy of the GNU General Public |
22 #License along with this library; if not, write to the Free Software |
22 #License along with this library; if not, write to the Free Software |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 |
24 |
25 from wxPython.wx import * |
|
26 import wx |
25 import wx |
27 |
26 |
28 from GraphicCommons import * |
27 from GraphicCommons import * |
29 from plcopen.structures import * |
28 from plcopen.structures import * |
30 |
29 |
81 if connector: |
80 if connector: |
82 connector.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
81 connector.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
83 |
82 |
84 # Refresh the power rail bounding box |
83 # Refresh the power rail bounding box |
85 def RefreshBoundingBox(self): |
84 def RefreshBoundingBox(self): |
86 dc = wxClientDC(self.Parent) |
85 dc = wx.ClientDC(self.Parent) |
87 self.BoundingBox = wxRect(self.Pos.x, self.Pos.y, self.Size[0], self.Size[1] + 1) |
86 self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0], self.Size[1] + 1) |
88 |
87 |
89 # Refresh the power rail size |
88 # Refresh the power rail size |
90 def RefreshSize(self): |
89 def RefreshSize(self): |
91 self.Size = wxSize(2, LD_LINE_SIZE * len(self.Connectors)) |
90 self.Size = wx.Size(2, LD_LINE_SIZE * len(self.Connectors)) |
92 self.RefreshBoundingBox() |
91 self.RefreshBoundingBox() |
93 |
92 |
94 # Returns the block minimum size |
93 # Returns the block minimum size |
95 def GetMinSize(self): |
94 def GetMinSize(self): |
96 return 2, LD_LINE_SIZE * len(self.Connectors) |
95 return 2, LD_LINE_SIZE * len(self.Connectors) |
101 |
100 |
102 # Add a connector or a blank to this power rail at the place given |
101 # Add a connector or a blank to this power rail at the place given |
103 def InsertConnector(self, idx, connector = True): |
102 def InsertConnector(self, idx, connector = True): |
104 if connector: |
103 if connector: |
105 if self.Type == LEFTRAIL: |
104 if self.Type == LEFTRAIL: |
106 connector = Connector(self, "", "BOOL", wxPoint(2, 0), EAST) |
105 connector = Connector(self, "", "BOOL", wx.Point(2, 0), EAST) |
107 elif self.Type == RIGHTRAIL: |
106 elif self.Type == RIGHTRAIL: |
108 connector = Connector(self, "", "BOOL", wxPoint(0, 0), WEST) |
107 connector = Connector(self, "", "BOOL", wx.Point(0, 0), WEST) |
109 self.Connectors.insert(idx, connector) |
108 self.Connectors.insert(idx, connector) |
110 else: |
109 else: |
111 self.Connectors.insert(idx, None) |
110 self.Connectors.insert(idx, None) |
112 self.RefreshSize() |
111 self.RefreshSize() |
113 self.RefreshConnectors() |
112 self.RefreshConnectors() |
114 |
113 |
115 # Moves the divergence connector given |
114 # Moves the divergence connector given |
116 def MoveConnector(self, connector, movey): |
115 def MoveConnector(self, connector, movey): |
117 position = connector.GetRelPosition() |
116 position = connector.GetRelPosition() |
118 connector.SetPosition(wxPoint(position.x, position.y + movey)) |
117 connector.SetPosition(wx.Point(position.x, position.y + movey)) |
119 miny = self.Size[1] |
118 miny = self.Size[1] |
120 maxy = 0 |
119 maxy = 0 |
121 for connect in self.Connectors: |
120 for connect in self.Connectors: |
122 connect_pos = connect.GetRelPosition() |
121 connect_pos = connect.GetRelPosition() |
123 miny = min(miny, connect_pos.y) |
122 miny = min(miny, connect_pos.y) |
125 min_pos = self.Pos.y + miny - self.Extensions[0] |
124 min_pos = self.Pos.y + miny - self.Extensions[0] |
126 self.Pos.y = min(min_pos, self.Pos.y) |
125 self.Pos.y = min(min_pos, self.Pos.y) |
127 if min_pos == self.Pos.y: |
126 if min_pos == self.Pos.y: |
128 for connect in self.Connectors: |
127 for connect in self.Connectors: |
129 connect_pos = connect.GetRelPosition() |
128 connect_pos = connect.GetRelPosition() |
130 connect.SetPosition(wxPoint(connect_pos.x, connect_pos.y - miny + self.Extensions[0])) |
129 connect.SetPosition(wx.Point(connect_pos.x, connect_pos.y - miny + self.Extensions[0])) |
131 self.Size[1] = max(maxy - miny + self.Extensions[0] + self.Extensions[1], self.Size[1]) |
130 self.Size[1] = max(maxy - miny + self.Extensions[0] + self.Extensions[1], self.Size[1]) |
132 connector.MoveConnected() |
131 connector.MoveConnected() |
133 self.RefreshBoundingBox() |
132 self.RefreshBoundingBox() |
134 |
133 |
135 # Returns the index in connectors list for the connector given |
134 # Returns the index in connectors list for the connector given |
154 def RefreshConnectors(self): |
153 def RefreshConnectors(self): |
155 position = self.Extensions[0] |
154 position = self.Extensions[0] |
156 for connector in self.Connectors: |
155 for connector in self.Connectors: |
157 if connector: |
156 if connector: |
158 if self.Type == LEFTRAIL: |
157 if self.Type == LEFTRAIL: |
159 connector.SetPosition(wxPoint(self.Size[0], position)) |
158 connector.SetPosition(wx.Point(self.Size[0], position)) |
160 elif self.Type == RIGHTRAIL: |
159 elif self.Type == RIGHTRAIL: |
161 connector.SetPosition(wxPoint(0, position)) |
160 connector.SetPosition(wx.Point(0, position)) |
162 position += LD_LINE_SIZE |
161 position += LD_LINE_SIZE |
163 self.RefreshConnected() |
162 self.RefreshConnected() |
164 |
163 |
165 # Refresh the position of wires connected to power rail |
164 # Refresh the position of wires connected to power rail |
166 def RefreshConnected(self, exclude = []): |
165 def RefreshConnected(self, exclude = []): |
215 pos = GetScaledEventPosition(event, dc, scaling) |
214 pos = GetScaledEventPosition(event, dc, scaling) |
216 # Test if a connector have been handled |
215 # Test if a connector have been handled |
217 connector = self.TestConnector(pos, False) |
216 connector = self.TestConnector(pos, False) |
218 if connector: |
217 if connector: |
219 self.Handle = (HANDLE_CONNECTOR, connector) |
218 self.Handle = (HANDLE_CONNECTOR, connector) |
220 self.Parent.SetCursor(wxStockCursor(wxCURSOR_HAND)) |
219 self.Parent.SetCursor(wx.StockCursor(wx.CURSOR_HAND)) |
221 self.Selected = False |
220 self.Selected = False |
222 # Initializes the last position |
221 # Initializes the last position |
223 self.oldPos = GetScaledEventPosition(event, dc, scaling) |
222 self.oldPos = GetScaledEventPosition(event, dc, scaling) |
224 else: |
223 else: |
225 ## self.RealConnectors = {"Inputs":[],"Outputs":[]} |
224 ## self.RealConnectors = {"Inputs":[],"Outputs":[]} |
282 if connector: |
281 if connector: |
283 connector.RefreshWires() |
282 connector.RefreshWires() |
284 |
283 |
285 # Draws power rail |
284 # Draws power rail |
286 def Draw(self, dc): |
285 def Draw(self, dc): |
287 dc.SetPen(wxBLACK_PEN) |
286 dc.SetPen(wx.BLACK_PEN) |
288 dc.SetBrush(wxBLACK_BRUSH) |
287 dc.SetBrush(wx.BLACK_BRUSH) |
289 # Draw a rectangle with the power rail size |
288 # Draw a rectangle with the power rail size |
290 dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) |
289 dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) |
291 # Draw connectors |
290 # Draw connectors |
292 for connector in self.Connectors: |
291 for connector in self.Connectors: |
293 if connector: |
292 if connector: |
309 def __init__(self, parent, type, name, id = None): |
308 def __init__(self, parent, type, name, id = None): |
310 Graphic_Element.__init__(self, parent) |
309 Graphic_Element.__init__(self, parent) |
311 self.Type = type |
310 self.Type = type |
312 self.Name = name |
311 self.Name = name |
313 self.Id = id |
312 self.Id = id |
314 self.Size = wxSize(LD_ELEMENT_SIZE[0], LD_ELEMENT_SIZE[1]) |
313 self.Size = wx.Size(LD_ELEMENT_SIZE[0], LD_ELEMENT_SIZE[1]) |
315 # Create an input and output connector |
314 # Create an input and output connector |
316 self.Input = Connector(self, "", "BOOL", wxPoint(0, self.Size[1] / 2 + 1), WEST) |
315 self.Input = Connector(self, "", "BOOL", wx.Point(0, self.Size[1] / 2 + 1), WEST) |
317 self.Output = Connector(self, "", "BOOL", wxPoint(self.Size[0], self.Size[1] / 2 + 1), EAST) |
316 self.Output = Connector(self, "", "BOOL", wx.Point(self.Size[0], self.Size[1] / 2 + 1), EAST) |
318 self.RefreshNameSize() |
317 self.RefreshNameSize() |
319 self.RefreshTypeSize() |
318 self.RefreshTypeSize() |
320 |
319 |
321 # Destructor |
320 # Destructor |
322 def __del__(self): |
321 def __del__(self): |
338 self.Input.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
337 self.Input.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
339 self.Output.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
338 self.Output.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE) |
340 |
339 |
341 # Refresh the size of text for name |
340 # Refresh the size of text for name |
342 def RefreshNameSize(self): |
341 def RefreshNameSize(self): |
343 dc = wxClientDC(self.Parent) |
342 dc = wx.ClientDC(self.Parent) |
344 if self.Name != "": |
343 if self.Name != "": |
345 self.NameSize = dc.GetTextExtent(self.Name) |
344 self.NameSize = dc.GetTextExtent(self.Name) |
346 else: |
345 else: |
347 self.NameSize = 0, 0 |
346 self.NameSize = 0, 0 |
348 |
347 |
349 # Refresh the size of text for type |
348 # Refresh the size of text for type |
350 def RefreshTypeSize(self): |
349 def RefreshTypeSize(self): |
351 dc = wxClientDC(self.Parent) |
350 dc = wx.ClientDC(self.Parent) |
352 typetext = "" |
351 typetext = "" |
353 if self.Type == CONTACT_REVERSE: |
352 if self.Type == CONTACT_REVERSE: |
354 typetext = "/" |
353 typetext = "/" |
355 elif self.Type == CONTACT_RISING: |
354 elif self.Type == CONTACT_RISING: |
356 typetext = "P" |
355 typetext = "P" |
361 else: |
360 else: |
362 self.TypeSize = 0, 0 |
361 self.TypeSize = 0, 0 |
363 |
362 |
364 # Refresh the contact bounding box |
363 # Refresh the contact bounding box |
365 def RefreshBoundingBox(self): |
364 def RefreshBoundingBox(self): |
366 dc = wxClientDC(self.Parent) |
365 dc = wx.ClientDC(self.Parent) |
367 # Calculate the size of the name outside the contact |
366 # Calculate the size of the name outside the contact |
368 text_width, text_height = dc.GetTextExtent(self.Name) |
367 text_width, text_height = dc.GetTextExtent(self.Name) |
369 # Calculate the bounding box size |
368 # Calculate the bounding box size |
370 if self.Name != "": |
369 if self.Name != "": |
371 bbx_x = self.Pos.x - max(0, (text_width - self.Size[0]) / 2) |
370 bbx_x = self.Pos.x - max(0, (text_width - self.Size[0]) / 2) |
375 else: |
374 else: |
376 bbx_x = self.Pos.x |
375 bbx_x = self.Pos.x |
377 bbx_width = self.Size[0] |
376 bbx_width = self.Size[0] |
378 bbx_y = self.Pos.y |
377 bbx_y = self.Pos.y |
379 bbx_height = self.Size[1] |
378 bbx_height = self.Size[1] |
380 self.BoundingBox = wxRect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1) |
379 self.BoundingBox = wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1) |
381 |
380 |
382 # Returns the block minimum size |
381 # Returns the block minimum size |
383 def GetMinSize(self): |
382 def GetMinSize(self): |
384 return LD_ELEMENT_SIZE |
383 return LD_ELEMENT_SIZE |
385 |
384 |
421 return self.Output |
420 return self.Output |
422 return None |
421 return None |
423 |
422 |
424 # Refresh the positions of the block connectors |
423 # Refresh the positions of the block connectors |
425 def RefreshConnectors(self): |
424 def RefreshConnectors(self): |
426 self.Input.SetPosition(wxPoint(0, self.Size[1] / 2 + 1)) |
425 self.Input.SetPosition(wx.Point(0, self.Size[1] / 2 + 1)) |
427 self.Output.SetPosition(wxPoint(self.Size[0], self.Size[1] / 2 + 1)) |
426 self.Output.SetPosition(wx.Point(self.Size[0], self.Size[1] / 2 + 1)) |
428 self.RefreshConnected() |
427 self.RefreshConnected() |
429 |
428 |
430 # Changes the contact name |
429 # Changes the contact name |
431 def SetName(self, name): |
430 def SetName(self, name): |
432 self.Name = name |
431 self.Name = name |
457 if move: |
456 if move: |
458 self.Output.RefreshWires() |
457 self.Output.RefreshWires() |
459 |
458 |
460 # Draws contact |
459 # Draws contact |
461 def Draw(self, dc): |
460 def Draw(self, dc): |
462 dc.SetPen(wxBLACK_PEN) |
461 dc.SetPen(wx.BLACK_PEN) |
463 dc.SetBrush(wxBLACK_BRUSH) |
462 dc.SetBrush(wx.BLACK_BRUSH) |
464 # Draw two rectangles for representing the contact |
463 # Draw two rectangles for representing the contact |
465 dc.DrawRectangle(self.Pos.x, self.Pos.y, 2, self.Size[1] + 1) |
464 dc.DrawRectangle(self.Pos.x, self.Pos.y, 2, self.Size[1] + 1) |
466 dc.DrawRectangle(self.Pos.x + self.Size[0] - 1, self.Pos.y, 2, self.Size[1] + 1) |
465 dc.DrawRectangle(self.Pos.x + self.Size[0] - 1, self.Pos.y, 2, self.Size[1] + 1) |
467 # Draw contact name |
466 # Draw contact name |
468 dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - self.NameSize[0]) / 2, |
467 dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - self.NameSize[0]) / 2, |
498 def __init__(self, parent, type, name, id = None): |
497 def __init__(self, parent, type, name, id = None): |
499 Graphic_Element.__init__(self, parent) |
498 Graphic_Element.__init__(self, parent) |
500 self.Type = type |
499 self.Type = type |
501 self.Name = name |
500 self.Name = name |
502 self.Id = id |
501 self.Id = id |
503 self.Size = wxSize(LD_ELEMENT_SIZE[0], LD_ELEMENT_SIZE[1]) |
502 self.Size = wx.Size(LD_ELEMENT_SIZE[0], LD_ELEMENT_SIZE[1]) |
504 # Create an input and output connector |
503 # Create an input and output connector |
505 self.Input = Connector(self, "", "BOOL", wxPoint(0, self.Size[1] / 2 + 1), WEST) |
504 self.Input = Connector(self, "", "BOOL", wx.Point(0, self.Size[1] / 2 + 1), WEST) |
506 self.Output = Connector(self, "", "BOOL", wxPoint(self.Size[0], self.Size[1] / 2 + 1), EAST) |
505 self.Output = Connector(self, "", "BOOL", wx.Point(self.Size[0], self.Size[1] / 2 + 1), EAST) |
507 self.RefreshNameSize() |
506 self.RefreshNameSize() |
508 self.RefreshTypeSize() |
507 self.RefreshTypeSize() |
509 |
508 |
510 # Destructor |
509 # Destructor |
511 def __del__(self): |
510 def __del__(self): |
527 self.Input.UnConnect() |
526 self.Input.UnConnect() |
528 self.Output.UnConnect() |
527 self.Output.UnConnect() |
529 |
528 |
530 # Refresh the size of text for name |
529 # Refresh the size of text for name |
531 def RefreshNameSize(self): |
530 def RefreshNameSize(self): |
532 dc = wxClientDC(self.Parent) |
531 dc = wx.ClientDC(self.Parent) |
533 if self.Name != "": |
532 if self.Name != "": |
534 self.NameSize = dc.GetTextExtent(self.Name) |
533 self.NameSize = dc.GetTextExtent(self.Name) |
535 else: |
534 else: |
536 self.NameSize = 0, 0 |
535 self.NameSize = 0, 0 |
537 |
536 |
538 # Refresh the size of text for type |
537 # Refresh the size of text for type |
539 def RefreshTypeSize(self): |
538 def RefreshTypeSize(self): |
540 dc = wxClientDC(self.Parent) |
539 dc = wx.ClientDC(self.Parent) |
541 typetext = "" |
540 typetext = "" |
542 if self.Type == COIL_REVERSE: |
541 if self.Type == COIL_REVERSE: |
543 typetext = "/" |
542 typetext = "/" |
544 elif self.Type == COIL_SET: |
543 elif self.Type == COIL_SET: |
545 typetext = "S" |
544 typetext = "S" |
550 else: |
549 else: |
551 self.TypeSize = 0, 0 |
550 self.TypeSize = 0, 0 |
552 |
551 |
553 # Refresh the coil bounding box |
552 # Refresh the coil bounding box |
554 def RefreshBoundingBox(self): |
553 def RefreshBoundingBox(self): |
555 dc = wxClientDC(self.Parent) |
554 dc = wx.ClientDC(self.Parent) |
556 # Calculate the size of the name outside the coil |
555 # Calculate the size of the name outside the coil |
557 text_width, text_height = dc.GetTextExtent(self.Name) |
556 text_width, text_height = dc.GetTextExtent(self.Name) |
558 # Calculate the bounding box size |
557 # Calculate the bounding box size |
559 if self.Name != "": |
558 if self.Name != "": |
560 bbx_x = self.Pos.x - max(0, (text_width - self.Size[0]) / 2) |
559 bbx_x = self.Pos.x - max(0, (text_width - self.Size[0]) / 2) |
564 else: |
563 else: |
565 bbx_x = self.Pos.x |
564 bbx_x = self.Pos.x |
566 bbx_width = self.Size[0] |
565 bbx_width = self.Size[0] |
567 bbx_y = self.Pos.y |
566 bbx_y = self.Pos.y |
568 bbx_height = self.Size[1] |
567 bbx_height = self.Size[1] |
569 self.BoundingBox = wxRect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1) |
568 self.BoundingBox = wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1) |
570 |
569 |
571 # Returns the block minimum size |
570 # Returns the block minimum size |
572 def GetMinSize(self): |
571 def GetMinSize(self): |
573 return LD_ELEMENT_SIZE |
572 return LD_ELEMENT_SIZE |
574 |
573 |
610 return self.Output |
609 return self.Output |
611 return None |
610 return None |
612 |
611 |
613 # Refresh the positions of the block connectors |
612 # Refresh the positions of the block connectors |
614 def RefreshConnectors(self): |
613 def RefreshConnectors(self): |
615 self.Input.SetPosition(wxPoint(0, self.Size[1] / 2 + 1)) |
614 self.Input.SetPosition(wx.Point(0, self.Size[1] / 2 + 1)) |
616 self.Output.SetPosition(wxPoint(self.Size[0], self.Size[1] / 2 + 1)) |
615 self.Output.SetPosition(wx.Point(self.Size[0], self.Size[1] / 2 + 1)) |
617 self.RefreshConnected() |
616 self.RefreshConnected() |
618 |
617 |
619 # Changes the coil name |
618 # Changes the coil name |
620 def SetName(self, name): |
619 def SetName(self, name): |
621 self.Name = name |
620 self.Name = name |
646 if move: |
645 if move: |
647 self.Output.RefreshWires() |
646 self.Output.RefreshWires() |
648 |
647 |
649 # Draws coil |
648 # Draws coil |
650 def Draw(self, dc): |
649 def Draw(self, dc): |
651 dc.SetPen(wxPen(wxBLACK, 2, wxSOLID)) |
650 dc.SetPen(wx.Pen(wx.BLACK, 2, wx.SOLID)) |
652 dc.SetBrush(wxTRANSPARENT_BRUSH) |
651 dc.SetBrush(wx.TRANSPARENT_BRUSH) |
653 # Draw a two circle arcs for representing the coil |
652 # Draw a two circle arcs for representing the coil |
654 dc.DrawEllipticArc(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, 135, 225) |
653 dc.DrawEllipticArc(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, 135, 225) |
655 dc.DrawEllipticArc(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, -45, 45) |
654 dc.DrawEllipticArc(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, -45, 45) |
656 dc.SetPen(wxBLACK_PEN) |
655 dc.SetPen(wx.BLACK_PEN) |
657 dc.DrawPoint(self.Pos.x + 1, self.Pos.y + self.Size[1] / 2 + 1) |
656 dc.DrawPoint(self.Pos.x + 1, self.Pos.y + self.Size[1] / 2 + 1) |
658 # Draw coil name |
657 # Draw coil name |
659 dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - self.NameSize[0]) / 2, |
658 dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - self.NameSize[0]) / 2, |
660 self.Pos.y - (self.NameSize[1] + 2)) |
659 self.Pos.y - (self.NameSize[1] + 2)) |
661 # Draw the modifier symbol in the middle of coil |
660 # Draw the modifier symbol in the middle of coil |