graphics/LD_Objects.py
changeset 2437 105c20fdeb19
parent 2432 dbc065a2f7a5
child 2457 9deec258ab1a
equal deleted inserted replaced
2436:82bfc75bcd9d 2437:105c20fdeb19
    22 # along with this program; if not, write to the Free Software
    22 # along with this program; if not, write to the Free Software
    23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    24 
    24 
    25 
    25 
    26 from __future__ import absolute_import
    26 from __future__ import absolute_import
       
    27 from __future__ import division
    27 import wx
    28 import wx
    28 from six.moves import xrange
    29 from six.moves import xrange
    29 
    30 
    30 from graphics.GraphicCommons import *
    31 from graphics.GraphicCommons import *
    31 from graphics.DebugDataConsumer import DebugDataConsumer
    32 from graphics.DebugDataConsumer import DebugDataConsumer
    47         Graphic_Element.__init__(self, parent)
    48         Graphic_Element.__init__(self, parent)
    48         self.Type = None
    49         self.Type = None
    49         self.Connectors = []
    50         self.Connectors = []
    50         self.RealConnectors = None
    51         self.RealConnectors = None
    51         self.Id = id
    52         self.Id = id
    52         self.Extensions = [LD_LINE_SIZE / 2, LD_LINE_SIZE / 2]
    53         self.Extensions = [LD_LINE_SIZE // 2, LD_LINE_SIZE // 2]
    53         self.SetType(type, connectors)
    54         self.SetType(type, connectors)
    54 
    55 
    55     def Flush(self):
    56     def Flush(self):
    56         for connector in self.Connectors:
    57         for connector in self.Connectors:
    57             connector.Flush()
    58             connector.Flush()
   182 
   183 
   183     # Refresh the positions of the power rail connectors
   184     # Refresh the positions of the power rail connectors
   184     def RefreshConnectors(self):
   185     def RefreshConnectors(self):
   185         scaling = self.Parent.GetScaling()
   186         scaling = self.Parent.GetScaling()
   186         height = self.Size[1] - self.Extensions[0] - self.Extensions[1]
   187         height = self.Size[1] - self.Extensions[0] - self.Extensions[1]
   187         interval = float(height) / float(max(len(self.Connectors) - 1, 1))
   188         interval = height / max(len(self.Connectors) - 1, 1)
   188         for i, connector in enumerate(self.Connectors):
   189         for i, connector in enumerate(self.Connectors):
   189             if self.RealConnectors:
   190             if self.RealConnectors:
   190                 position = self.Extensions[0] + int(round(self.RealConnectors[i] * height))
   191                 position = self.Extensions[0] + int(round(self.RealConnectors[i] * height))
   191             else:
   192             else:
   192                 position = self.Extensions[0] + int(round(i * interval))
   193                 position = self.Extensions[0] + int(round(i * interval))
   193             if scaling is not None:
   194             if scaling is not None:
   194                 position = round(float(self.Pos.y + position) / float(scaling[1])) * scaling[1] - self.Pos.y
   195                 position = round((self.Pos.y + position) / scaling[1]) * scaling[1] - self.Pos.y
   195             if self.Type == LEFTRAIL:
   196             if self.Type == LEFTRAIL:
   196                 connector.SetPosition(wx.Point(self.Size[0], position))
   197                 connector.SetPosition(wx.Point(self.Size[0], position))
   197             elif self.Type == RIGHTRAIL:
   198             elif self.Type == RIGHTRAIL:
   198                 connector.SetPosition(wx.Point(0, position))
   199                 connector.SetPosition(wx.Point(0, position))
   199         self.RefreshConnected()
   200         self.RefreshConnected()
   249         self.RealConnectors = []
   250         self.RealConnectors = []
   250         height = self.Size[1] - self.Extensions[0] - self.Extensions[1]
   251         height = self.Size[1] - self.Extensions[0] - self.Extensions[1]
   251         if height > 0:
   252         if height > 0:
   252             for connector in self.Connectors:
   253             for connector in self.Connectors:
   253                 position = connector.GetRelPosition()
   254                 position = connector.GetRelPosition()
   254                 self.RealConnectors.append(max(0., min(float(position.y - self.Extensions[0]) / float(height), 1.)))
   255                 self.RealConnectors.append(max(0., min((position.y - self.Extensions[0]) / height, 1.)))
   255         elif len(self.Connectors) > 1:
   256         elif len(self.Connectors) > 1:
   256             self.RealConnectors = map(lambda x: x * 1 / (len(self.Connectors) - 1), xrange(len(self.Connectors)))
   257             self.RealConnectors = map(lambda x: x * 1 / (len(self.Connectors) - 1), xrange(len(self.Connectors)))
   257         else:
   258         else:
   258             self.RealConnectors = [0.5]
   259             self.RealConnectors = [0.5]
   259         Graphic_Element.OnLeftDown(self, event, dc, scaling)
   260         Graphic_Element.OnLeftDown(self, event, dc, scaling)
   310         # A connector has been handled
   311         # A connector has been handled
   311         if handle_type == HANDLE_CONNECTOR:
   312         if handle_type == HANDLE_CONNECTOR:
   312             movey = max(-self.BoundingBox.y, movey)
   313             movey = max(-self.BoundingBox.y, movey)
   313             if scaling is not None:
   314             if scaling is not None:
   314                 position = handle.GetRelPosition()
   315                 position = handle.GetRelPosition()
   315                 movey = round(float(self.Pos.y + position.y + movey) / float(scaling[1])) * scaling[1] - self.Pos.y - position.y
   316                 movey = round((self.Pos.y + position.y + movey) / scaling[1]) * scaling[1] - self.Pos.y - position.y
   316             self.MoveConnector(handle, movey)
   317             self.MoveConnector(handle, movey)
   317             return 0, movey
   318             return 0, movey
   318         elif self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
   319         elif self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
   319             return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling)
   320             return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling)
   320         return 0, 0
   321         return 0, 0
   361         self.Name = name
   362         self.Name = name
   362         self.Id = id
   363         self.Id = id
   363         self.Size = wx.Size(LD_ELEMENT_SIZE[0], LD_ELEMENT_SIZE[1])
   364         self.Size = wx.Size(LD_ELEMENT_SIZE[0], LD_ELEMENT_SIZE[1])
   364         self.Highlights = {}
   365         self.Highlights = {}
   365         # Create an input and output connector
   366         # Create an input and output connector
   366         self.Input = Connector(self, "", "BOOL", wx.Point(0, self.Size[1] / 2 + 1), WEST)
   367         self.Input = Connector(self, "", "BOOL", wx.Point(0, self.Size[1] // 2 + 1), WEST)
   367         self.Output = Connector(self, "", "BOOL", wx.Point(self.Size[0], self.Size[1] / 2 + 1), EAST)
   368         self.Output = Connector(self, "", "BOOL", wx.Point(self.Size[0], self.Size[1] // 2 + 1), EAST)
   368         self.PreviousValue = False
   369         self.PreviousValue = False
   369         self.PreviousSpreading = False
   370         self.PreviousSpreading = False
   370         self.RefreshNameSize()
   371         self.RefreshNameSize()
   371         self.RefreshTypeSize()
   372         self.RefreshTypeSize()
   372 
   373 
   491     def RefreshBoundingBox(self):
   492     def RefreshBoundingBox(self):
   492         # Calculate the size of the name outside the contact
   493         # Calculate the size of the name outside the contact
   493         text_width, text_height = self.Parent.GetTextExtent(self.Name)
   494         text_width, text_height = self.Parent.GetTextExtent(self.Name)
   494         # Calculate the bounding box size
   495         # Calculate the bounding box size
   495         if self.Name != "":
   496         if self.Name != "":
   496             bbx_x = self.Pos.x - max(0, (text_width - self.Size[0]) / 2)
   497             bbx_x = self.Pos.x - max(0, (text_width - self.Size[0]) // 2)
   497             bbx_width = max(self.Size[0], text_width)
   498             bbx_width = max(self.Size[0], text_width)
   498             bbx_y = self.Pos.y - (text_height + 2)
   499             bbx_y = self.Pos.y - (text_height + 2)
   499             bbx_height = self.Size[1] + (text_height + 2)
   500             bbx_height = self.Size[1] + (text_height + 2)
   500         else:
   501         else:
   501             bbx_x = self.Pos.x
   502             bbx_x = self.Pos.x
   539         return None
   540         return None
   540 
   541 
   541     # Refresh the positions of the block connectors
   542     # Refresh the positions of the block connectors
   542     def RefreshConnectors(self):
   543     def RefreshConnectors(self):
   543         scaling = self.Parent.GetScaling()
   544         scaling = self.Parent.GetScaling()
   544         position = self.Size[1] / 2 + 1
   545         position = self.Size[1] // 2 + 1
   545         if scaling is not None:
   546         if scaling is not None:
   546             position = round(float(self.Pos.y + position) / float(scaling[1])) * scaling[1] - self.Pos.y
   547             position = round((self.Pos.y + position) / scaling[1]) * scaling[1] - self.Pos.y
   547         self.Input.SetPosition(wx.Point(0, position))
   548         self.Input.SetPosition(wx.Point(0, position))
   548         self.Output.SetPosition(wx.Point(self.Size[0], position))
   549         self.Output.SetPosition(wx.Point(self.Size[0], position))
   549         self.RefreshConnected()
   550         self.RefreshConnected()
   550 
   551 
   551     # Changes the contact name
   552     # Changes the contact name
   668 
   669 
   669         # Draw two rectangles for representing the contact
   670         # Draw two rectangles for representing the contact
   670         dc.DrawRectangle(self.Pos.x, self.Pos.y, 2, self.Size[1] + 1)
   671         dc.DrawRectangle(self.Pos.x, self.Pos.y, 2, self.Size[1] + 1)
   671         dc.DrawRectangle(self.Pos.x + self.Size[0] - 1, self.Pos.y, 2, self.Size[1] + 1)
   672         dc.DrawRectangle(self.Pos.x + self.Size[0] - 1, self.Pos.y, 2, self.Size[1] + 1)
   672         # Draw contact name
   673         # Draw contact name
   673         name_pos = (self.Pos.x + (self.Size[0] - name_size[0]) / 2,
   674         name_pos = (self.Pos.x + (self.Size[0] - name_size[0]) // 2,
   674                     self.Pos.y - (name_size[1] + 2))
   675                     self.Pos.y - (name_size[1] + 2))
   675         dc.DrawText(self.Name, name_pos[0], name_pos[1])
   676         dc.DrawText(self.Name, name_pos[0], name_pos[1])
   676         # Draw the modifier symbol in the middle of contact
   677         # Draw the modifier symbol in the middle of contact
   677         if typetext != "":
   678         if typetext != "":
   678             type_pos = (self.Pos.x + (self.Size[0] - type_size[0]) / 2 + 1,
   679             type_pos = (self.Pos.x + (self.Size[0] - type_size[0]) // 2 + 1,
   679                         self.Pos.y + (self.Size[1] - type_size[1]) / 2)
   680                         self.Pos.y + (self.Size[1] - type_size[1]) // 2)
   680             dc.DrawText(typetext, type_pos[0], type_pos[1])
   681             dc.DrawText(typetext, type_pos[0], type_pos[1])
   681         # Draw input and output connectors
   682         # Draw input and output connectors
   682         self.Input.Draw(dc)
   683         self.Input.Draw(dc)
   683         self.Output.Draw(dc)
   684         self.Output.Draw(dc)
   684 
   685 
   707         self.Name = name
   708         self.Name = name
   708         self.Id = id
   709         self.Id = id
   709         self.Size = wx.Size(LD_ELEMENT_SIZE[0], LD_ELEMENT_SIZE[1])
   710         self.Size = wx.Size(LD_ELEMENT_SIZE[0], LD_ELEMENT_SIZE[1])
   710         self.Highlights = {}
   711         self.Highlights = {}
   711         # Create an input and output connector
   712         # Create an input and output connector
   712         self.Input = Connector(self, "", "BOOL", wx.Point(0, self.Size[1] / 2 + 1), WEST)
   713         self.Input = Connector(self, "", "BOOL", wx.Point(0, self.Size[1] // 2 + 1), WEST)
   713         self.Output = Connector(self, "", "BOOL", wx.Point(self.Size[0], self.Size[1] / 2 + 1), EAST)
   714         self.Output = Connector(self, "", "BOOL", wx.Point(self.Size[0], self.Size[1] // 2 + 1), EAST)
   714         self.Value = None
   715         self.Value = None
   715         self.PreviousValue = False
   716         self.PreviousValue = False
   716         self.RefreshNameSize()
   717         self.RefreshNameSize()
   717         self.RefreshTypeSize()
   718         self.RefreshTypeSize()
   718 
   719 
   811     def RefreshBoundingBox(self):
   812     def RefreshBoundingBox(self):
   812         # Calculate the size of the name outside the coil
   813         # Calculate the size of the name outside the coil
   813         text_width, text_height = self.Parent.GetTextExtent(self.Name)
   814         text_width, text_height = self.Parent.GetTextExtent(self.Name)
   814         # Calculate the bounding box size
   815         # Calculate the bounding box size
   815         if self.Name != "":
   816         if self.Name != "":
   816             bbx_x = self.Pos.x - max(0, (text_width - self.Size[0]) / 2)
   817             bbx_x = self.Pos.x - max(0, (text_width - self.Size[0]) // 2)
   817             bbx_width = max(self.Size[0], text_width)
   818             bbx_width = max(self.Size[0], text_width)
   818             bbx_y = self.Pos.y - (text_height + 2)
   819             bbx_y = self.Pos.y - (text_height + 2)
   819             bbx_height = self.Size[1] + (text_height + 2)
   820             bbx_height = self.Size[1] + (text_height + 2)
   820         else:
   821         else:
   821             bbx_x = self.Pos.x
   822             bbx_x = self.Pos.x
   859         return None
   860         return None
   860 
   861 
   861     # Refresh the positions of the block connectors
   862     # Refresh the positions of the block connectors
   862     def RefreshConnectors(self):
   863     def RefreshConnectors(self):
   863         scaling = self.Parent.GetScaling()
   864         scaling = self.Parent.GetScaling()
   864         position = self.Size[1] / 2 + 1
   865         position = self.Size[1] // 2 + 1
   865         if scaling is not None:
   866         if scaling is not None:
   866             position = round(float(self.Pos.y + position) / float(scaling[1])) * scaling[1] - self.Pos.y
   867             position = round((self.Pos.y + position) / scaling[1]) * scaling[1] - self.Pos.y
   867         self.Input.SetPosition(wx.Point(0, position))
   868         self.Input.SetPosition(wx.Point(0, position))
   868         self.Output.SetPosition(wx.Point(self.Size[0], position))
   869         self.Output.SetPosition(wx.Point(self.Size[0], position))
   869         self.RefreshConnected()
   870         self.RefreshConnected()
   870 
   871 
   871     # Changes the coil name
   872     # Changes the coil name
   991             if not getattr(dc, "printing", False):
   992             if not getattr(dc, "printing", False):
   992                 if self.Value is not None and self.Value:
   993                 if self.Value is not None and self.Value:
   993                     dc.SetPen(MiterPen(wx.GREEN))
   994                     dc.SetPen(MiterPen(wx.GREEN))
   994                 else:
   995                 else:
   995                     dc.SetPen(MiterPen(wx.BLACK))
   996                     dc.SetPen(MiterPen(wx.BLACK))
   996                 dc.DrawPoint(self.Pos.x + 1, self.Pos.y + self.Size[1] / 2 + 1)
   997                 dc.DrawPoint(self.Pos.x + 1, self.Pos.y + self.Size[1] // 2 + 1)
   997             name_size = self.NameSize
   998             name_size = self.NameSize
   998             if typetext != "":
   999             if typetext != "":
   999                 type_size = self.TypeSize
  1000                 type_size = self.TypeSize
  1000 
  1001 
  1001         # Draw coil name
  1002         # Draw coil name
  1002         name_pos = (self.Pos.x + (self.Size[0] - name_size[0]) / 2,
  1003         name_pos = (self.Pos.x + (self.Size[0] - name_size[0]) // 2,
  1003                     self.Pos.y - (name_size[1] + 2))
  1004                     self.Pos.y - (name_size[1] + 2))
  1004         dc.DrawText(self.Name, name_pos[0], name_pos[1])
  1005         dc.DrawText(self.Name, name_pos[0], name_pos[1])
  1005         # Draw the modifier symbol in the middle of coil
  1006         # Draw the modifier symbol in the middle of coil
  1006         if typetext != "":
  1007         if typetext != "":
  1007             type_pos = (self.Pos.x + (self.Size[0] - type_size[0]) / 2 + 1,
  1008             type_pos = (self.Pos.x + (self.Size[0] - type_size[0]) // 2 + 1,
  1008                         self.Pos.y + (self.Size[1] - type_size[1]) / 2)
  1009                         self.Pos.y + (self.Size[1] - type_size[1]) // 2)
  1009             dc.DrawText(typetext, type_pos[0], type_pos[1])
  1010             dc.DrawText(typetext, type_pos[0], type_pos[1])
  1010         # Draw input and output connectors
  1011         # Draw input and output connectors
  1011         self.Input.Draw(dc)
  1012         self.Input.Draw(dc)
  1012         self.Output.Draw(dc)
  1013         self.Output.Draw(dc)
  1013 
  1014