graphics/SFC_Objects.py
changeset 2459 21164625b393
parent 2457 9deec258ab1a
child 3303 0ffb41625592
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
       
    28 from future.builtins import round
       
    29 
    27 import wx
    30 import wx
       
    31 from six.moves import xrange
    28 
    32 
    29 from graphics.GraphicCommons import *
    33 from graphics.GraphicCommons import *
    30 from graphics.DebugDataConsumer import DebugDataConsumer
    34 from graphics.DebugDataConsumer import DebugDataConsumer
    31 from plcopen.structures import *
    35 from plcopen.structures import *
    32 
    36 
    56         self.Id = id
    60         self.Id = id
    57         self.Highlights = []
    61         self.Highlights = []
    58         self.Size = wx.Size(SFC_STEP_DEFAULT_SIZE[0], SFC_STEP_DEFAULT_SIZE[1])
    62         self.Size = wx.Size(SFC_STEP_DEFAULT_SIZE[0], SFC_STEP_DEFAULT_SIZE[1])
    59         # Create an input and output connector
    63         # Create an input and output connector
    60         if not self.Initial:
    64         if not self.Initial:
    61             self.Input = Connector(self, "", None, wx.Point(self.Size[0] / 2, 0), NORTH)
    65             self.Input = Connector(self, "", None, wx.Point(self.Size[0] // 2, 0), NORTH)
    62         else:
    66         else:
    63             self.Input = None
    67             self.Input = None
    64         self.Output = None
    68         self.Output = None
    65         self.Action = None
    69         self.Action = None
    66         self.PreviousValue = None
    70         self.PreviousValue = None
   168         self.NameSize = self.Parent.GetTextExtent(self.Name)
   172         self.NameSize = self.Parent.GetTextExtent(self.Name)
   169 
   173 
   170     # Add output connector to step
   174     # Add output connector to step
   171     def AddInput(self):
   175     def AddInput(self):
   172         if not self.Input:
   176         if not self.Input:
   173             self.Input = Connector(self, "", None, wx.Point(self.Size[0] / 2, 0), NORTH)
   177             self.Input = Connector(self, "", None, wx.Point(self.Size[0] // 2, 0), NORTH)
   174             self.RefreshBoundingBox()
   178             self.RefreshBoundingBox()
   175 
   179 
   176     # Remove output connector from step
   180     # Remove output connector from step
   177     def RemoveInput(self):
   181     def RemoveInput(self):
   178         if self.Input:
   182         if self.Input:
   181             self.RefreshBoundingBox()
   185             self.RefreshBoundingBox()
   182 
   186 
   183     # Add output connector to step
   187     # Add output connector to step
   184     def AddOutput(self):
   188     def AddOutput(self):
   185         if not self.Output:
   189         if not self.Output:
   186             self.Output = Connector(self, "", None, wx.Point(self.Size[0] / 2, self.Size[1]), SOUTH, onlyone=True)
   190             self.Output = Connector(self, "", None, wx.Point(self.Size[0] // 2, self.Size[1]), SOUTH, onlyone=True)
   187             self.RefreshBoundingBox()
   191             self.RefreshBoundingBox()
   188 
   192 
   189     # Remove output connector from step
   193     # Remove output connector from step
   190     def RemoveOutput(self):
   194     def RemoveOutput(self):
   191         if self.Output:
   195         if self.Output:
   194             self.RefreshBoundingBox()
   198             self.RefreshBoundingBox()
   195 
   199 
   196     # Add action connector to step
   200     # Add action connector to step
   197     def AddAction(self):
   201     def AddAction(self):
   198         if not self.Action:
   202         if not self.Action:
   199             self.Action = Connector(self, "", None, wx.Point(self.Size[0], self.Size[1] / 2), EAST, onlyone=True)
   203             self.Action = Connector(self, "", None, wx.Point(self.Size[0], self.Size[1] // 2), EAST, onlyone=True)
   200             self.RefreshBoundingBox()
   204             self.RefreshBoundingBox()
   201 
   205 
   202     # Remove action connector from step
   206     # Remove action connector from step
   203     def RemoveAction(self):
   207     def RemoveAction(self):
   204         if self.Action:
   208         if self.Action:
   229         self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1)
   233         self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1)
   230 
   234 
   231     # Refresh the positions of the step connectors
   235     # Refresh the positions of the step connectors
   232     def RefreshConnectors(self):
   236     def RefreshConnectors(self):
   233         scaling = self.Parent.GetScaling()
   237         scaling = self.Parent.GetScaling()
   234         horizontal_pos = self.Size[0] / 2
   238         horizontal_pos = self.Size[0] // 2
   235         vertical_pos = self.Size[1] / 2
   239         vertical_pos = self.Size[1] // 2
   236         if scaling is not None:
   240         if scaling is not None:
   237             horizontal_pos = round(float(self.Pos.x + horizontal_pos) / float(scaling[0])) * scaling[0] - self.Pos.x
   241             horizontal_pos = round((self.Pos.x + horizontal_pos) / scaling[0]) * scaling[0] - self.Pos.x
   238             vertical_pos = round(float(self.Pos.y + vertical_pos) / float(scaling[1])) * scaling[1] - self.Pos.y
   242             vertical_pos = round((self.Pos.y + vertical_pos) / scaling[1]) * scaling[1] - self.Pos.y
   239         # Update input position if it exists
   243         # Update input position if it exists
   240         if self.Input:
   244         if self.Input:
   241             self.Input.SetPosition(wx.Point(horizontal_pos, 0))
   245             self.Input.SetPosition(wx.Point(horizontal_pos, 0))
   242         # Update output position
   246         # Update output position
   243         if self.Output:
   247         if self.Output:
   360         else:
   364         else:
   361             return text_width + 10, text_height + 10
   365             return text_width + 10, text_height + 10
   362 
   366 
   363     # Updates the step size
   367     # Updates the step size
   364     def UpdateSize(self, width, height):
   368     def UpdateSize(self, width, height):
   365         diffx = self.Size.GetWidth() / 2 - width / 2
   369         diffx = self.Size.GetWidth() // 2 - width // 2
   366         diffy = height - self.Size.GetHeight()
   370         diffy = height - self.Size.GetHeight()
   367         self.Move(diffx, 0)
   371         self.Move(diffx, 0)
   368         Graphic_Element.SetSize(self, width, height)
   372         Graphic_Element.SetSize(self, width, height)
   369         if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
   373         if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
   370             self.RefreshConnected()
   374             self.RefreshConnected()
   460         handle_type, _handle = self.Handle
   464         handle_type, _handle = self.Handle
   461         if handle_type == HANDLE_MOVE:
   465         if handle_type == HANDLE_MOVE:
   462             movex = max(-self.BoundingBox.x, movex)
   466             movex = max(-self.BoundingBox.x, movex)
   463             movey = max(-self.BoundingBox.y, movey)
   467             movey = max(-self.BoundingBox.y, movey)
   464             if scaling is not None:
   468             if scaling is not None:
   465                 movex = round(float(self.Pos.x + movex) / float(scaling[0])) * scaling[0] - self.Pos.x
   469                 movex = round((self.Pos.x + movex) / scaling[0]) * scaling[0] - self.Pos.x
   466                 movey = round(float(self.Pos.y + movey) / float(scaling[1])) * scaling[1] - self.Pos.y
   470                 movey = round((self.Pos.y + movey) / scaling[1]) * scaling[1] - self.Pos.y
   467             if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
   471             if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
   468                 self.Move(movex, movey)
   472                 self.Move(movex, movey)
   469                 self.RefreshConnected()
   473                 self.RefreshConnected()
   470                 return movex, movey
   474                 return movex, movey
   471             elif self.Initial:
   475             elif self.Initial:
   554         # Draw two rectangles for representing the step
   558         # Draw two rectangles for representing the step
   555         dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1)
   559         dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1)
   556         if self.Initial:
   560         if self.Initial:
   557             dc.DrawRectangle(self.Pos.x + 2, self.Pos.y + 2, self.Size[0] - 3, self.Size[1] - 3)
   561             dc.DrawRectangle(self.Pos.x + 2, self.Pos.y + 2, self.Size[0] - 3, self.Size[1] - 3)
   558         # Draw step name
   562         # Draw step name
   559         name_pos = (self.Pos.x + (self.Size[0] - name_size[0]) / 2,
   563         name_pos = (self.Pos.x + (self.Size[0] - name_size[0]) // 2,
   560                     self.Pos.y + (self.Size[1] - name_size[1]) / 2)
   564                     self.Pos.y + (self.Size[1] - name_size[1]) // 2)
   561         dc.DrawText(self.Name, name_pos[0], name_pos[1])
   565         dc.DrawText(self.Name, name_pos[0], name_pos[1])
   562         # Draw input and output connectors
   566         # Draw input and output connectors
   563         if self.Input:
   567         if self.Input:
   564             self.Input.Draw(dc)
   568             self.Input.Draw(dc)
   565         if self.Output:
   569         if self.Output:
   588         self.Type = None
   592         self.Type = None
   589         self.Id = id
   593         self.Id = id
   590         self.Priority = 0
   594         self.Priority = 0
   591         self.Size = wx.Size(SFC_TRANSITION_SIZE[0], SFC_TRANSITION_SIZE[1])
   595         self.Size = wx.Size(SFC_TRANSITION_SIZE[0], SFC_TRANSITION_SIZE[1])
   592         # Create an input and output connector
   596         # Create an input and output connector
   593         self.Input = Connector(self,  "", None, wx.Point(self.Size[0] / 2, 0),            NORTH, onlyone=True)
   597         self.Input = Connector(self,  "", None, wx.Point(self.Size[0] // 2, 0),            NORTH, onlyone=True)
   594         self.Output = Connector(self, "", None, wx.Point(self.Size[0] / 2, self.Size[1]), SOUTH, onlyone=True)
   598         self.Output = Connector(self, "", None, wx.Point(self.Size[0] // 2, self.Size[1]), SOUTH, onlyone=True)
   595         self.SetType(type, condition)
   599         self.SetType(type, condition)
   596         self.SetPriority(priority)
   600         self.SetPriority(priority)
   597         self.Highlights = {}
   601         self.Highlights = {}
   598         self.PreviousValue = None
   602         self.PreviousValue = None
   599         self.PreviousSpreading = False
   603         self.PreviousSpreading = False
   710     def HitTest(self, pt, connectors=True):
   714     def HitTest(self, pt, connectors=True):
   711         if self.Type != "connection":
   715         if self.Type != "connection":
   712             # Calculate the bounding box of the condition outside the transition
   716             # Calculate the bounding box of the condition outside the transition
   713             text_width, text_height = self.ConditionSize
   717             text_width, text_height = self.ConditionSize
   714             text_bbx = wx.Rect(self.Pos.x + self.Size[0] + 5,
   718             text_bbx = wx.Rect(self.Pos.x + self.Size[0] + 5,
   715                                self.Pos.y + (self.Size[1] - text_height) / 2,
   719                                self.Pos.y + (self.Size[1] - text_height) // 2,
   716                                text_width,
   720                                text_width,
   717                                text_height)
   721                                text_height)
   718             test_text = text_bbx.InsideXY(pt.x, pt.y)
   722             test_text = text_bbx.InsideXY(pt.x, pt.y)
   719         else:
   723         else:
   720             test_text = False
   724             test_text = False
   732             bbx_width = bbx_width + CONNECTOR_SIZE
   736             bbx_width = bbx_width + CONNECTOR_SIZE
   733         else:
   737         else:
   734             text_width, text_height = self.ConditionSize
   738             text_width, text_height = self.ConditionSize
   735             # Calculate the bounding box size
   739             # Calculate the bounding box size
   736             bbx_width = max(bbx_width, self.Size[0] + 5 + text_width)
   740             bbx_width = max(bbx_width, self.Size[0] + 5 + text_width)
   737             bbx_y = min(bbx_y, self.Pos.y - max(0, (text_height - self.Size[1]) / 2))
   741             bbx_y = min(bbx_y, self.Pos.y - max(0, (text_height - self.Size[1]) // 2))
   738             bbx_height = max(bbx_height, self.Pos.y - bbx_y + (self.Size[1] + text_height) / 2)
   742             bbx_height = max(bbx_height, self.Pos.y - bbx_y + (self.Size[1] + text_height) // 2)
   739         self.BoundingBox = wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1)
   743         self.BoundingBox = wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1)
   740 
   744 
   741     # Returns the connector connected to input
   745     # Returns the connector connected to input
   742     def GetPreviousConnector(self):
   746     def GetPreviousConnector(self):
   743         wires = self.Input.GetWires()
   747         wires = self.Input.GetWires()
   753         return None
   757         return None
   754 
   758 
   755     # Refresh the positions of the transition connectors
   759     # Refresh the positions of the transition connectors
   756     def RefreshConnectors(self):
   760     def RefreshConnectors(self):
   757         scaling = self.Parent.GetScaling()
   761         scaling = self.Parent.GetScaling()
   758         horizontal_pos = self.Size[0] / 2
   762         horizontal_pos = self.Size[0] // 2
   759         vertical_pos = self.Size[1] / 2
   763         vertical_pos = self.Size[1] // 2
   760         if scaling is not None:
   764         if scaling is not None:
   761             horizontal_pos = round(float(self.Pos.x + horizontal_pos) / float(scaling[0])) * scaling[0] - self.Pos.x
   765             horizontal_pos = round((self.Pos.x + horizontal_pos) / scaling[0]) * scaling[0] - self.Pos.x
   762             vertical_pos = round(float(self.Pos.y + vertical_pos) / float(scaling[1])) * scaling[1] - self.Pos.y
   766             vertical_pos = round((self.Pos.y + vertical_pos) / scaling[1]) * scaling[1] - self.Pos.y
   763         # Update input position
   767         # Update input position
   764         self.Input.SetPosition(wx.Point(horizontal_pos, 0))
   768         self.Input.SetPosition(wx.Point(horizontal_pos, 0))
   765         # Update output position
   769         # Update output position
   766         self.Output.SetPosition(wx.Point(horizontal_pos, self.Size[1]))
   770         self.Output.SetPosition(wx.Point(horizontal_pos, self.Size[1]))
   767         if self.Type == "connection":
   771         if self.Type == "connection":
   819         if self.Type != type:
   823         if self.Type != type:
   820             if self.Type == "connection":
   824             if self.Type == "connection":
   821                 self.Condition.UnConnect(delete=self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
   825                 self.Condition.UnConnect(delete=self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
   822             self.Type = type
   826             self.Type = type
   823             if type == "connection":
   827             if type == "connection":
   824                 self.Condition = Connector(self, "", "BOOL", wx.Point(0, self.Size[1] / 2), WEST)
   828                 self.Condition = Connector(self, "", "BOOL", wx.Point(0, self.Size[1] // 2), WEST)
   825             else:
   829             else:
   826                 if condition is None:
   830                 if condition is None:
   827                     condition = ""
   831                     condition = ""
   828                 self.Condition = condition
   832                 self.Condition = condition
   829                 self.RefreshConditionSize()
   833                 self.RefreshConditionSize()
   914     # Refreshes the transition state according to move defined and handle selected
   918     # Refreshes the transition state according to move defined and handle selected
   915     def ProcessDragging(self, movex, movey, event, scaling):
   919     def ProcessDragging(self, movex, movey, event, scaling):
   916         if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
   920         if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
   917             movex = max(-self.BoundingBox.x, movex)
   921             movex = max(-self.BoundingBox.x, movex)
   918             if scaling is not None:
   922             if scaling is not None:
   919                 movex = round(float(self.Pos.x + movex) / float(scaling[0])) * scaling[0] - self.Pos.x
   923                 movex = round((self.Pos.x + movex) / scaling[0]) * scaling[0] - self.Pos.x
   920             self.Move(movex, 0)
   924             self.Move(movex, 0)
   921             self.RefreshInputPosition()
   925             self.RefreshInputPosition()
   922             self.RefreshOutputPosition()
   926             self.RefreshOutputPosition()
   923             return movex, 0
   927             return movex, 0
   924         else:
   928         else:
  1006             if self.Priority != 0:
  1010             if self.Priority != 0:
  1007                 priority_size = self.PrioritySize
  1011                 priority_size = self.PrioritySize
  1008 
  1012 
  1009         # Draw plain rectangle for representing the transition
  1013         # Draw plain rectangle for representing the transition
  1010         dc.DrawRectangle(self.Pos.x,
  1014         dc.DrawRectangle(self.Pos.x,
  1011                          self.Pos.y + (self.Size[1] - SFC_TRANSITION_SIZE[1])/2,
  1015                          self.Pos.y + (self.Size[1] - SFC_TRANSITION_SIZE[1]) // 2,
  1012                          self.Size[0] + 1,
  1016                          self.Size[0] + 1,
  1013                          SFC_TRANSITION_SIZE[1] + 1)
  1017                          SFC_TRANSITION_SIZE[1] + 1)
  1014         vertical_line_x = self.Input.GetPosition()[0]
  1018         vertical_line_x = self.Input.GetPosition()[0]
  1015         dc.DrawLine(vertical_line_x, self.Pos.y, vertical_line_x, self.Pos.y + self.Size[1] + 1)
  1019         dc.DrawLine(vertical_line_x, self.Pos.y, vertical_line_x, self.Pos.y + self.Size[1] + 1)
  1016         # Draw transition condition
  1020         # Draw transition condition
  1018             if self.Condition != "":
  1022             if self.Condition != "":
  1019                 condition = self.Condition
  1023                 condition = self.Condition
  1020             else:
  1024             else:
  1021                 condition = "Transition"
  1025                 condition = "Transition"
  1022             condition_pos = (self.Pos.x + self.Size[0] + 5,
  1026             condition_pos = (self.Pos.x + self.Size[0] + 5,
  1023                              self.Pos.y + (self.Size[1] - condition_size[1]) / 2)
  1027                              self.Pos.y + (self.Size[1] - condition_size[1]) // 2)
  1024             dc.DrawText(condition, condition_pos[0], condition_pos[1])
  1028             dc.DrawText(condition, condition_pos[0], condition_pos[1])
  1025         # Draw priority number
  1029         # Draw priority number
  1026         if self.Priority != 0:
  1030         if self.Priority != 0:
  1027             priority_pos = (self.Pos.x, self.Pos.y - priority_size[1] - 2)
  1031             priority_pos = (self.Pos.x, self.Pos.y - priority_size[1] - 2)
  1028             dc.DrawText(str(self.Priority), priority_pos[0], priority_pos[1])
  1032             dc.DrawText(str(self.Priority), priority_pos[0], priority_pos[1])
  1059         self.RealConnectors = None
  1063         self.RealConnectors = None
  1060         number = max(2, number)
  1064         number = max(2, number)
  1061         self.Size = wx.Size((number - 1) * SFC_DEFAULT_SEQUENCE_INTERVAL, self.GetMinSize()[1])
  1065         self.Size = wx.Size((number - 1) * SFC_DEFAULT_SEQUENCE_INTERVAL, self.GetMinSize()[1])
  1062         # Create an input and output connector
  1066         # Create an input and output connector
  1063         if self.Type in [SELECTION_DIVERGENCE, SIMULTANEOUS_DIVERGENCE]:
  1067         if self.Type in [SELECTION_DIVERGENCE, SIMULTANEOUS_DIVERGENCE]:
  1064             self.Inputs = [Connector(self, "", None, wx.Point(self.Size[0] / 2, 0), NORTH, onlyone=True)]
  1068             self.Inputs = [Connector(self, "", None, wx.Point(self.Size[0] // 2, 0), NORTH, onlyone=True)]
  1065             self.Outputs = []
  1069             self.Outputs = []
  1066             for i in xrange(number):
  1070             for i in xrange(number):
  1067                 self.Outputs.append(Connector(self, "", None, wx.Point(i * SFC_DEFAULT_SEQUENCE_INTERVAL, self.Size[1]), SOUTH, onlyone=True))
  1071                 self.Outputs.append(Connector(self, "", None, wx.Point(i * SFC_DEFAULT_SEQUENCE_INTERVAL, self.Size[1]), SOUTH, onlyone=True))
  1068         elif self.Type in [SELECTION_CONVERGENCE, SIMULTANEOUS_CONVERGENCE]:
  1072         elif self.Type in [SELECTION_CONVERGENCE, SIMULTANEOUS_CONVERGENCE]:
  1069             self.Inputs = []
  1073             self.Inputs = []
  1070             for i in xrange(number):
  1074             for i in xrange(number):
  1071                 self.Inputs.append(Connector(self, "", None, wx.Point(i * SFC_DEFAULT_SEQUENCE_INTERVAL, 0), NORTH, onlyone=True))
  1075                 self.Inputs.append(Connector(self, "", None, wx.Point(i * SFC_DEFAULT_SEQUENCE_INTERVAL, 0), NORTH, onlyone=True))
  1072             self.Outputs = [Connector(self, "", None, wx.Point(self.Size[0] / 2, self.Size[1]), SOUTH, onlyone=True)]
  1076             self.Outputs = [Connector(self, "", None, wx.Point(self.Size[0] // 2, self.Size[1]), SOUTH, onlyone=True)]
  1073         self.Value = None
  1077         self.Value = None
  1074         self.PreviousValue = None
  1078         self.PreviousValue = None
  1075 
  1079 
  1076     def Flush(self):
  1080     def Flush(self):
  1077         for input in self.Inputs:
  1081         for input in self.Inputs:
  1282         for i, input in enumerate(self.Inputs):
  1286         for i, input in enumerate(self.Inputs):
  1283             position = input.GetRelPosition()
  1287             position = input.GetRelPosition()
  1284             if self.RealConnectors:
  1288             if self.RealConnectors:
  1285                 input.SetPosition(wx.Point(int(round(self.RealConnectors["Inputs"][i] * width)), 0))
  1289                 input.SetPosition(wx.Point(int(round(self.RealConnectors["Inputs"][i] * width)), 0))
  1286             else:
  1290             else:
  1287                 input.SetPosition(wx.Point(int(round(float(position.x)*float(width)/float(self.Size[0]))), 0))
  1291                 input.SetPosition(wx.Point(int(round(position.x*width / self.Size[0])), 0))
  1288             input.MoveConnected()
  1292             input.MoveConnected()
  1289         for i, output in enumerate(self.Outputs):
  1293         for i, output in enumerate(self.Outputs):
  1290             position = output.GetRelPosition()
  1294             position = output.GetRelPosition()
  1291             if self.RealConnectors:
  1295             if self.RealConnectors:
  1292                 output.SetPosition(wx.Point(int(round(self.RealConnectors["Outputs"][i] * width)), height))
  1296                 output.SetPosition(wx.Point(int(round(self.RealConnectors["Outputs"][i] * width)), height))
  1293             else:
  1297             else:
  1294                 output.SetPosition(wx.Point(int(round(float(position.x)*float(width)/float(self.Size[0]))), height))
  1298                 output.SetPosition(wx.Point(int(round(position.x*width / self.Size[0])), height))
  1295             output.MoveConnected()
  1299             output.MoveConnected()
  1296         self.Size = wx.Size(width, height)
  1300         self.Size = wx.Size(width, height)
  1297         self.RefreshBoundingBox()
  1301         self.RefreshBoundingBox()
  1298 
  1302 
  1299     # Returns the divergence minimum size
  1303     # Returns the divergence minimum size
  1365     # Method called when a LeftDown event have been generated
  1369     # Method called when a LeftDown event have been generated
  1366     def OnLeftDown(self, event, dc, scaling):
  1370     def OnLeftDown(self, event, dc, scaling):
  1367         self.RealConnectors = {"Inputs": [], "Outputs": []}
  1371         self.RealConnectors = {"Inputs": [], "Outputs": []}
  1368         for input in self.Inputs:
  1372         for input in self.Inputs:
  1369             position = input.GetRelPosition()
  1373             position = input.GetRelPosition()
  1370             self.RealConnectors["Inputs"].append(float(position.x)/float(self.Size[0]))
  1374             self.RealConnectors["Inputs"].append(position.x / self.Size[0])
  1371         for output in self.Outputs:
  1375         for output in self.Outputs:
  1372             position = output.GetRelPosition()
  1376             position = output.GetRelPosition()
  1373             self.RealConnectors["Outputs"].append(float(position.x)/float(self.Size[0]))
  1377             self.RealConnectors["Outputs"].append(position.x / self.Size[0])
  1374         Graphic_Element.OnLeftDown(self, event, dc, scaling)
  1378         Graphic_Element.OnLeftDown(self, event, dc, scaling)
  1375 
  1379 
  1376     # Method called when a LeftUp event have been generated
  1380     # Method called when a LeftUp event have been generated
  1377     def OnLeftUp(self, event, dc, scaling):
  1381     def OnLeftUp(self, event, dc, scaling):
  1378         Graphic_Element.OnLeftUp(self, event, dc, scaling)
  1382         Graphic_Element.OnLeftUp(self, event, dc, scaling)
  1422         handle_type, handle = self.Handle
  1426         handle_type, handle = self.Handle
  1423         # A connector has been handled
  1427         # A connector has been handled
  1424         if handle_type == HANDLE_CONNECTOR:
  1428         if handle_type == HANDLE_CONNECTOR:
  1425             movex = max(-self.BoundingBox.x, movex)
  1429             movex = max(-self.BoundingBox.x, movex)
  1426             if scaling is not None:
  1430             if scaling is not None:
  1427                 movex = round(float(self.Pos.x + movex) / float(scaling[0])) * scaling[0] - self.Pos.x
  1431                 movex = round((self.Pos.x + movex) / scaling[0]) * scaling[0] - self.Pos.x
  1428             self.MoveConnector(handle, movex)
  1432             self.MoveConnector(handle, movex)
  1429             if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
  1433             if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
  1430                 self.RefreshConnectedPosition(handle)
  1434                 self.RefreshConnectedPosition(handle)
  1431             return movex, 0
  1435             return movex, 0
  1432         elif self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
  1436         elif self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
  1516         self.SetTarget(target)
  1520         self.SetTarget(target)
  1517         self.Id = id
  1521         self.Id = id
  1518         self.Size = wx.Size(SFC_JUMP_SIZE[0], SFC_JUMP_SIZE[1])
  1522         self.Size = wx.Size(SFC_JUMP_SIZE[0], SFC_JUMP_SIZE[1])
  1519         self.Highlights = []
  1523         self.Highlights = []
  1520         # Create an input and output connector
  1524         # Create an input and output connector
  1521         self.Input = Connector(self, "", None, wx.Point(self.Size[0] / 2, 0), NORTH, onlyone=True)
  1525         self.Input = Connector(self, "", None, wx.Point(self.Size[0] // 2, 0), NORTH, onlyone=True)
  1522         self.Value = None
  1526         self.Value = None
  1523         self.PreviousValue = None
  1527         self.PreviousValue = None
  1524 
  1528 
  1525     def Flush(self):
  1529     def Flush(self):
  1526         if self.Input is not None:
  1530         if self.Input is not None:
  1583     # Returns if the point given is in the bounding box
  1587     # Returns if the point given is in the bounding box
  1584     def HitTest(self, pt, connectors=True):
  1588     def HitTest(self, pt, connectors=True):
  1585         # Calculate the bounding box of the condition outside the transition
  1589         # Calculate the bounding box of the condition outside the transition
  1586         text_width, text_height = self.TargetSize
  1590         text_width, text_height = self.TargetSize
  1587         text_bbx = wx.Rect(self.Pos.x + self.Size[0] + 2,
  1591         text_bbx = wx.Rect(self.Pos.x + self.Size[0] + 2,
  1588                            self.Pos.y + (self.Size[1] - text_height) / 2,
  1592                            self.Pos.y + (self.Size[1] - text_height) // 2,
  1589                            text_width,
  1593                            text_width,
  1590                            text_height)
  1594                            text_height)
  1591         return text_bbx.InsideXY(pt.x, pt.y) or Graphic_Element.HitTest(self, pt, connectors)
  1595         return text_bbx.InsideXY(pt.x, pt.y) or Graphic_Element.HitTest(self, pt, connectors)
  1592 
  1596 
  1593     # Refresh the jump bounding box
  1597     # Refresh the jump bounding box
  1606         return None
  1610         return None
  1607 
  1611 
  1608     # Refresh the element connectors position
  1612     # Refresh the element connectors position
  1609     def RefreshConnectors(self):
  1613     def RefreshConnectors(self):
  1610         scaling = self.Parent.GetScaling()
  1614         scaling = self.Parent.GetScaling()
  1611         horizontal_pos = self.Size[0] / 2
  1615         horizontal_pos = self.Size[0] // 2
  1612         if scaling is not None:
  1616         if scaling is not None:
  1613             horizontal_pos = round(float(self.Pos.x + horizontal_pos) / float(scaling[0])) * scaling[0] - self.Pos.x
  1617             horizontal_pos = round((self.Pos.x + horizontal_pos) / scaling[0]) * scaling[0] - self.Pos.x
  1614         self.Input.SetPosition(wx.Point(horizontal_pos, 0))
  1618         self.Input.SetPosition(wx.Point(horizontal_pos, 0))
  1615         self.RefreshConnected()
  1619         self.RefreshConnected()
  1616 
  1620 
  1617     # Refresh the position of wires connected to jump
  1621     # Refresh the position of wires connected to jump
  1618     def RefreshConnected(self, exclude=None):
  1622     def RefreshConnected(self, exclude=None):
  1682     # Refreshes the jump state according to move defined and handle selected
  1686     # Refreshes the jump state according to move defined and handle selected
  1683     def ProcessDragging(self, movex, movey, event, scaling):
  1687     def ProcessDragging(self, movex, movey, event, scaling):
  1684         if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
  1688         if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
  1685             movex = max(-self.BoundingBox.x, movex)
  1689             movex = max(-self.BoundingBox.x, movex)
  1686             if scaling is not None:
  1690             if scaling is not None:
  1687                 movex = round(float(self.Pos.x + movex) / float(scaling[0])) * scaling[0] - self.Pos.x
  1691                 movex = round((self.Pos.x + movex) / scaling[0]) * scaling[0] - self.Pos.x
  1688             self.Move(movex, 0)
  1692             self.Move(movex, 0)
  1689             self.RefreshInputPosition()
  1693             self.RefreshInputPosition()
  1690             return movex, 0
  1694             return movex, 0
  1691         else:
  1695         else:
  1692             return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling, width_fac=2)
  1696             return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling, width_fac=2)
  1757             target_size = dc.GetTextExtent(self.Target)
  1761             target_size = dc.GetTextExtent(self.Target)
  1758         else:
  1762         else:
  1759             target_size = self.TargetSize
  1763             target_size = self.TargetSize
  1760 
  1764 
  1761         # Draw plain rectangle for representing the divergence
  1765         # Draw plain rectangle for representing the divergence
  1762         dc.DrawLine(self.Pos.x + self.Size[0] / 2, self.Pos.y, self.Pos.x + self.Size[0] / 2, self.Pos.y + self.Size[1])
  1766         dc.DrawLine(self.Pos.x + self.Size[0] // 2, self.Pos.y, self.Pos.x + self.Size[0] // 2, self.Pos.y + self.Size[1])
  1763         points = [wx.Point(self.Pos.x, self.Pos.y),
  1767         points = [wx.Point(self.Pos.x, self.Pos.y),
  1764                   wx.Point(self.Pos.x + self.Size[0] / 2, self.Pos.y + self.Size[1] / 3),
  1768                   wx.Point(self.Pos.x + self.Size[0] // 2, self.Pos.y + self.Size[1] // 3),
  1765                   wx.Point(self.Pos.x + self.Size[0], self.Pos.y),
  1769                   wx.Point(self.Pos.x + self.Size[0], self.Pos.y),
  1766                   wx.Point(self.Pos.x + self.Size[0] / 2, self.Pos.y + self.Size[1])]
  1770                   wx.Point(self.Pos.x + self.Size[0] // 2, self.Pos.y + self.Size[1])]
  1767         dc.DrawPolygon(points)
  1771         dc.DrawPolygon(points)
  1768         target_pos = (self.Pos.x + self.Size[0] + 2,
  1772         target_pos = (self.Pos.x + self.Size[0] + 2,
  1769                       self.Pos.y + (self.Size[1] - target_size[1]) / 2)
  1773                       self.Pos.y + (self.Size[1] - target_size[1]) // 2)
  1770         dc.DrawText(self.Target, target_pos[0], target_pos[1])
  1774         dc.DrawText(self.Target, target_pos[0], target_pos[1])
  1771         # Draw input connector
  1775         # Draw input connector
  1772         if self.Input:
  1776         if self.Input:
  1773             self.Input.Draw(dc)
  1777             self.Input.Draw(dc)
  1774 
  1778 
  1792         self.Id = id
  1796         self.Id = id
  1793         self.Size = wx.Size(SFC_ACTION_MIN_SIZE[0], SFC_ACTION_MIN_SIZE[1])
  1797         self.Size = wx.Size(SFC_ACTION_MIN_SIZE[0], SFC_ACTION_MIN_SIZE[1])
  1794         self.MinSize = wx.Size(SFC_ACTION_MIN_SIZE[0], SFC_ACTION_MIN_SIZE[1])
  1798         self.MinSize = wx.Size(SFC_ACTION_MIN_SIZE[0], SFC_ACTION_MIN_SIZE[1])
  1795         self.Highlights = {}
  1799         self.Highlights = {}
  1796         # Create an input and output connector
  1800         # Create an input and output connector
  1797         self.Input = Connector(self, "", None, wx.Point(0, SFC_ACTION_MIN_SIZE[1] / 2), WEST, onlyone=True)
  1801         self.Input = Connector(self, "", None, wx.Point(0, SFC_ACTION_MIN_SIZE[1] // 2), WEST, onlyone=True)
  1798         self.SetActions(actions)
  1802         self.SetActions(actions)
  1799         self.Value = None
  1803         self.Value = None
  1800         self.PreviousValue = None
  1804         self.PreviousValue = None
  1801 
  1805 
  1802     def Flush(self):
  1806     def Flush(self):
  1840     def GetLineNumber(self):
  1844     def GetLineNumber(self):
  1841         return len(self.Actions)
  1845         return len(self.Actions)
  1842 
  1846 
  1843     def GetLineSize(self):
  1847     def GetLineSize(self):
  1844         if len(self.Actions) > 0:
  1848         if len(self.Actions) > 0:
  1845             return self.Size[1] / len(self.Actions)
  1849             return self.Size[1] // len(self.Actions)
  1846         else:
  1850         else:
  1847             return SFC_ACTION_MIN_SIZE[1]
  1851             return SFC_ACTION_MIN_SIZE[1]
  1848 
  1852 
  1849     # Forbids to resize the action block
  1853     # Forbids to resize the action block
  1850     def Resize(self, x, y, width, height):
  1854     def Resize(self, x, y, width, height):
  1886         return None
  1890         return None
  1887 
  1891 
  1888     # Refresh the element connectors position
  1892     # Refresh the element connectors position
  1889     def RefreshConnectors(self):
  1893     def RefreshConnectors(self):
  1890         scaling = self.Parent.GetScaling()
  1894         scaling = self.Parent.GetScaling()
  1891         vertical_pos = SFC_ACTION_MIN_SIZE[1] / 2
  1895         vertical_pos = SFC_ACTION_MIN_SIZE[1] // 2
  1892         if scaling is not None:
  1896         if scaling is not None:
  1893             vertical_pos = round(float(self.Pos.y + vertical_pos) / float(scaling[1])) * scaling[1] - self.Pos.y
  1897             vertical_pos = round((self.Pos.y + vertical_pos) / scaling[1]) * scaling[1] - self.Pos.y
  1894         self.Input.SetPosition(wx.Point(0, vertical_pos))
  1898         self.Input.SetPosition(wx.Point(0, vertical_pos))
  1895         self.RefreshConnected()
  1899         self.RefreshConnected()
  1896 
  1900 
  1897     # Changes the action block actions
  1901     # Changes the action block actions
  1898     def SetActions(self, actions=None):
  1902     def SetActions(self, actions=None):
  1959         if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
  1963         if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
  1960             handle_type, _handle = self.Handle
  1964             handle_type, _handle = self.Handle
  1961             if handle_type == HANDLE_MOVE:
  1965             if handle_type == HANDLE_MOVE:
  1962                 movex = max(-self.BoundingBox.x, movex)
  1966                 movex = max(-self.BoundingBox.x, movex)
  1963                 if scaling is not None:
  1967                 if scaling is not None:
  1964                     movex = round(float(self.Pos.x + movex) / float(scaling[0])) * scaling[0] - self.Pos.x
  1968                     movex = round((self.Pos.x + movex) / scaling[0]) * scaling[0] - self.Pos.x
  1965                 wires = self.Input.GetWires()
  1969                 wires = self.Input.GetWires()
  1966                 if len(wires) == 1:
  1970                 if len(wires) == 1:
  1967                     input_pos = wires[0][0].GetOtherConnected(self.Input).GetPosition(False)
  1971                     input_pos = wires[0][0].GetOtherConnected(self.Input).GetPosition(False)
  1968                     if self.Pos.x - input_pos.x + movex >= SFC_WIRE_MIN_SIZE:
  1972                     if self.Pos.x - input_pos.x + movex >= SFC_WIRE_MIN_SIZE:
  1969                         self.Move(movex, 0)
  1973                         self.Move(movex, 0)
  2030             if i != 0:
  2034             if i != 0:
  2031                 dc.DrawLine(self.Pos.x, self.Pos.y + i * line_size,
  2035                 dc.DrawLine(self.Pos.x, self.Pos.y + i * line_size,
  2032                             self.Pos.x + self.Size[0], self.Pos.y + i * line_size)
  2036                             self.Pos.x + self.Size[0], self.Pos.y + i * line_size)
  2033             qualifier_size = dc.GetTextExtent(action.qualifier)
  2037             qualifier_size = dc.GetTextExtent(action.qualifier)
  2034             if action.duration != "":
  2038             if action.duration != "":
  2035                 qualifier_pos = (self.Pos.x + (colsize[0] - qualifier_size[0]) / 2,
  2039                 qualifier_pos = (self.Pos.x + (colsize[0] - qualifier_size[0]) // 2,
  2036                                  self.Pos.y + i * line_size + line_size / 2 - qualifier_size[1])
  2040                                  self.Pos.y + i * line_size + line_size // 2 - qualifier_size[1])
  2037                 duration_size = dc.GetTextExtent(action.duration)
  2041                 duration_size = dc.GetTextExtent(action.duration)
  2038                 duration_pos = (self.Pos.x + (colsize[0] - duration_size[0]) / 2,
  2042                 duration_pos = (self.Pos.x + (colsize[0] - duration_size[0]) // 2,
  2039                                 self.Pos.y + i * line_size + line_size / 2)
  2043                                 self.Pos.y + i * line_size + line_size // 2)
  2040                 dc.DrawText(action.duration, duration_pos[0], duration_pos[1])
  2044                 dc.DrawText(action.duration, duration_pos[0], duration_pos[1])
  2041             else:
  2045             else:
  2042                 qualifier_pos = (self.Pos.x + (colsize[0] - qualifier_size[0]) / 2,
  2046                 qualifier_pos = (self.Pos.x + (colsize[0] - qualifier_size[0]) // 2,
  2043                                  self.Pos.y + i * line_size + (line_size - qualifier_size[1]) / 2)
  2047                                  self.Pos.y + i * line_size + (line_size - qualifier_size[1]) // 2)
  2044             dc.DrawText(action.qualifier, qualifier_pos[0], qualifier_pos[1])
  2048             dc.DrawText(action.qualifier, qualifier_pos[0], qualifier_pos[1])
  2045             content_size = dc.GetTextExtent(action.value)
  2049             content_size = dc.GetTextExtent(action.value)
  2046             content_pos = (self.Pos.x + colsize[0] + (colsize[1] - content_size[0]) / 2,
  2050             content_pos = (self.Pos.x + colsize[0] + (colsize[1] - content_size[0]) // 2,
  2047                            self.Pos.y + i * line_size + (line_size - content_size[1]) / 2)
  2051                            self.Pos.y + i * line_size + (line_size - content_size[1]) // 2)
  2048             dc.DrawText(action.value, content_pos[0], content_pos[1])
  2052             dc.DrawText(action.value, content_pos[0], content_pos[1])
  2049             if action.indicator != "":
  2053             if action.indicator != "":
  2050                 indicator_size = dc.GetTextExtent(action.indicator)
  2054                 indicator_size = dc.GetTextExtent(action.indicator)
  2051                 indicator_pos = (self.Pos.x + colsize[0] + colsize[1] + (colsize[2] - indicator_size[0]) / 2,
  2055                 indicator_pos = (self.Pos.x + colsize[0] + colsize[1] + (colsize[2] - indicator_size[0]) // 2,
  2052                                  self.Pos.y + i * line_size + (line_size - indicator_size[1]) / 2)
  2056                                  self.Pos.y + i * line_size + (line_size - indicator_size[1]) // 2)
  2053                 dc.DrawText(action.indicator, indicator_pos[0], indicator_pos[1])
  2057                 dc.DrawText(action.indicator, indicator_pos[0], indicator_pos[1])
  2054 
  2058 
  2055             if not getattr(dc, "printing", False):
  2059             if not getattr(dc, "printing", False):
  2056                 action_highlights = self.Highlights.get(i, {})
  2060                 action_highlights = self.Highlights.get(i, {})
  2057                 for name, attribute_highlights in action_highlights.iteritems():
  2061                 for name, attribute_highlights in action_highlights.iteritems():