graphics/LD_Objects.py
changeset 64 dd6f693e46a1
parent 61 dc7142ae9438
child 71 0578bc212c20
equal deleted inserted replaced
63:04a02b4b2a57 64:dd6f693e46a1
    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