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