graphics/SFC_Objects.py
changeset 145 4fb225afddf4
parent 144 b67a5de5a24a
child 146 cc70dd430601
equal deleted inserted replaced
144:b67a5de5a24a 145:4fb225afddf4
   123             self.RefreshBoundingBox()
   123             self.RefreshBoundingBox()
   124     
   124     
   125     # Add output connector to step
   125     # Add output connector to step
   126     def AddOutput(self):
   126     def AddOutput(self):
   127         if not self.Output:
   127         if not self.Output:
   128             self.Output = Connector(self, "", None, wx.Point(self.Size[0] / 2, self.Size[1]), SOUTH)
   128             self.Output = Connector(self, "", None, wx.Point(self.Size[0] / 2, self.Size[1]), SOUTH, onlyone = True)
   129             self.RefreshBoundingBox()
   129             self.RefreshBoundingBox()
   130     
   130     
   131     # Remove output connector from step
   131     # Remove output connector from step
   132     def RemoveOutput(self):
   132     def RemoveOutput(self):
   133         if self.Output:
   133         if self.Output:
   136             self.RefreshBoundingBox()
   136             self.RefreshBoundingBox()
   137     
   137     
   138     # Add action connector to step
   138     # Add action connector to step
   139     def AddAction(self):
   139     def AddAction(self):
   140         if not self.Action:
   140         if not self.Action:
   141             self.Action = Connector(self, "", None, wx.Point(self.Size[0], self.Size[1] / 2), EAST)
   141             self.Action = Connector(self, "", None, wx.Point(self.Size[0], self.Size[1] / 2), EAST, onlyone = True)
   142             self.RefreshBoundingBox()
   142             self.RefreshBoundingBox()
   143     
   143     
   144     # Remove action connector from step
   144     # Remove action connector from step
   145     def RemoveAction(self):
   145     def RemoveAction(self):
   146         if self.Action:
   146         if self.Action:
   169         #self.BoundingBox = wx.Rect(self.Pos.x, bbx_y, bbx_width + 1, bbx_height + 1)
   169         #self.BoundingBox = wx.Rect(self.Pos.x, bbx_y, bbx_width + 1, bbx_height + 1)
   170         self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1)
   170         self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1)
   171         
   171         
   172     # Refresh the positions of the step connectors
   172     # Refresh the positions of the step connectors
   173     def RefreshConnectors(self):
   173     def RefreshConnectors(self):
       
   174         scaling = self.Parent.GetScaling()
       
   175         horizontal_pos = self.Size[0] / 2
       
   176         vertical_pos = self.Size[1] / 2
       
   177         if scaling is not None:
       
   178             horizontal_pos = round(float(self.Pos.x + horizontal_pos) / float(scaling[0])) * scaling[0] - self.Pos.x
       
   179             vertical_pos = round(float(self.Pos.y + vertical_pos) / float(scaling[1])) * scaling[1] - self.Pos.y
   174         # Update input position if it exists
   180         # Update input position if it exists
   175         if self.Input:
   181         if self.Input:
   176             self.Input.SetPosition(wx.Point(self.Size[0] / 2, 0))
   182             self.Input.SetPosition(wx.Point(horizontal_pos, 0))
   177         # Update output position
   183         # Update output position
   178         if self.Output:
   184         if self.Output:
   179             self.Output.SetPosition(wx.Point(self.Size[0] / 2, self.Size[1]))
   185             self.Output.SetPosition(wx.Point(horizontal_pos, self.Size[1]))
   180         # Update action position if it exists
   186         # Update action position if it exists
   181         if self.Action:
   187         if self.Action:
   182             self.Action.SetPosition(wx.Point(self.Size[0], self.Size[1] / 2))
   188             self.Action.SetPosition(wx.Point(self.Size[0], vertical_pos))
   183         self.RefreshConnected()
   189         self.RefreshConnected()
   184     
   190     
   185     # Refresh the position of wires connected to step
   191     # Refresh the position of wires connected to step
   186     def RefreshConnected(self, exclude = []):
   192     def RefreshConnected(self, exclude = []):
   187         if self.Input:
   193         if self.Input:
   251     # Returns the connector connected to input
   257     # Returns the connector connected to input
   252     def GetPreviousConnector(self):
   258     def GetPreviousConnector(self):
   253         if self.Input:
   259         if self.Input:
   254             wires = self.Input.GetWires()
   260             wires = self.Input.GetWires()
   255             if len(wires) == 1:
   261             if len(wires) == 1:
   256                 return wires[0][0].EndConnected
   262                 return wires[0][0].GetOtherConnected(self.Input)
   257         return None
   263         return None
   258     
   264     
   259     # Returns the connector connected to output
   265     # Returns the connector connected to output
   260     def GetNextConnector(self):
   266     def GetNextConnector(self):
   261         if self.Output:
   267         if self.Output:
   262             wires = self.Output.GetWires()
   268             wires = self.Output.GetWires()
   263             if len(wires) == 1:
   269             if len(wires) == 1:
   264                 return wires[0][0].StartConnected
   270                 return wires[0][0].GetOtherConnected(self.Output)
   265         return None
   271         return None
   266     
   272     
   267     # Returns the connector connected to action
   273     # Returns the connector connected to action
   268     def GetActionConnector(self):
   274     def GetActionConnector(self):
   269         if self.Action:
   275         if self.Action:
   270             wires = self.Action.GetWires()
   276             wires = self.Action.GetWires()
   271             if len(wires) == 1:
   277             if len(wires) == 1:
   272                 return wires[0][0].StartConnected
   278                 return wires[0][0].GetOtherConnected(self.Action)
   273         return None
   279         return None
   274     
   280     
   275     # Returns the number of action line
   281     # Returns the number of action line
   276     def GetActionExtraLineNumber(self):
   282     def GetActionExtraLineNumber(self):
   277         if self.Action:
   283         if self.Action:
   278             wires = self.Action.GetWires()
   284             wires = self.Action.GetWires()
   279             if len(wires) != 1:
   285             if len(wires) != 1:
   280                 return 0
   286                 return 0
   281             action_block = wires[0][0].StartConnected.GetParentBlock()
   287             action_block = wires[0][0].GetOtherConnected(self.Action).GetParentBlock()
   282             return max(0, action_block.GetLineNumber() - 1)
   288             return max(0, action_block.GetLineNumber() - 1)
   283         return 0
   289         return 0
   284     
   290     
   285     # Returns the step minimum size
   291     # Returns the step minimum size
   286     def GetMinSize(self):
   292     def GetMinSize(self):
   324         if self.Output:
   330         if self.Output:
   325             wires = self.Output.GetWires()
   331             wires = self.Output.GetWires()
   326             if len(wires) != 1:
   332             if len(wires) != 1:
   327                 return
   333                 return
   328             current_pos = self.Output.GetPosition(False)
   334             current_pos = self.Output.GetPosition(False)
   329             output = wires[0][0].StartConnected
   335             output = wires[0][0].GetOtherConnected(self.Output)
   330             output_pos = output.GetPosition(False)
   336             output_pos = output.GetPosition(False)
   331             diffx = current_pos.x - output_pos.x
   337             diffx = current_pos.x - output_pos.x
   332             output_block = output.GetParentBlock()
   338             output_block = output.GetParentBlock()
   333             wire_size = SFC_WIRE_MIN_SIZE + self.GetActionExtraLineNumber() * SFC_ACTION_MIN_SIZE[1]
   339             wire_size = SFC_WIRE_MIN_SIZE + self.GetActionExtraLineNumber() * SFC_ACTION_MIN_SIZE[1]
   334             diffy = wire_size - output_pos.y + current_pos.y
   340             diffy = wire_size - output_pos.y + current_pos.y
   363     def MoveActionBlock(self, move):
   369     def MoveActionBlock(self, move):
   364         if self.Action:
   370         if self.Action:
   365             wires = self.Action.GetWires()
   371             wires = self.Action.GetWires()
   366             if len(wires) != 1:
   372             if len(wires) != 1:
   367                 return
   373                 return
   368             action_block = wires[0][0].StartConnected.GetParentBlock()
   374             action_block = wires[0][0].GetOtherConnected(self.Action).GetParentBlock()
   369             action_block.Move(move[0], move[1], self.Parent.Wires)
   375             action_block.Move(move[0], move[1], self.Parent.Wires)
   370             wires[0][0].Move(move[0], move[1], True)
   376             wires[0][0].Move(move[0], move[1], True)
   371     
   377     
   372     # Resize the divergence from position and size given
   378     # Resize the divergence from position and size given
   373     def Resize(self, x, y, width, height):
   379     def Resize(self, x, y, width, height):
   385     def OnRightUp(self, event, dc, scaling):
   391     def OnRightUp(self, event, dc, scaling):
   386         # Popup the menu with special items for a step
   392         # Popup the menu with special items for a step
   387         self.Parent.PopupDefaultMenu()
   393         self.Parent.PopupDefaultMenu()
   388     
   394     
   389     # Refreshes the step state according to move defined and handle selected
   395     # Refreshes the step state according to move defined and handle selected
   390     def ProcessDragging(self, movex, movey):
   396     def ProcessDragging(self, movex, movey, scaling):
   391         handle_type, handle = self.Handle
   397         handle_type, handle = self.Handle
   392         if handle_type == HANDLE_MOVE:
   398         if handle_type == HANDLE_MOVE:
   393             movex = max(-self.BoundingBox.x, movex)
   399             movex = max(-self.BoundingBox.x, movex)
   394             movey = max(-self.BoundingBox.y, movey)
   400             movey = max(-self.BoundingBox.y, movey)
       
   401             if scaling is not None:
       
   402                 movex = round(float(self.Pos.x + movex) / float(scaling[0])) * scaling[0] - self.Pos.x
       
   403                 movey = round(float(self.Pos.y + movey) / float(scaling[1])) * scaling[1] - self.Pos.y
   395             action_block = None
   404             action_block = None
   396             if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
   405             if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
   397                 self.Move(movex, movey)
   406                 self.Move(movex, movey)
   398                 self.RefreshConnected()
   407                 self.RefreshConnected()
   399                 return movex, movey
   408                 return movex, movey
   407                 self.Move(movex, 0)
   416                 self.Move(movex, 0)
   408                 self.RefreshInputPosition()
   417                 self.RefreshInputPosition()
   409                 self.RefreshOutputPosition()
   418                 self.RefreshOutputPosition()
   410                 return movex, 0
   419                 return movex, 0
   411         else:
   420         else:
   412             return Graphic_Element.ProcessDragging(self, movex, movey)
   421             return Graphic_Element.ProcessDragging(self, movex, movey, scaling)
   413     
   422     
   414     # Refresh input element model
   423     # Refresh input element model
   415     def RefreshInputModel(self):
   424     def RefreshInputModel(self):
   416         if self.Input:
   425         if self.Input:
   417             input = self.GetPreviousConnector()
   426             input = self.GetPreviousConnector()
   485         self.Type = None
   494         self.Type = None
   486         self.Id = id
   495         self.Id = id
   487         self.Priority = 0
   496         self.Priority = 0
   488         self.Size = wx.Size(SFC_TRANSITION_SIZE[0], SFC_TRANSITION_SIZE[1])
   497         self.Size = wx.Size(SFC_TRANSITION_SIZE[0], SFC_TRANSITION_SIZE[1])
   489         # Create an input and output connector
   498         # Create an input and output connector
   490         self.Input = Connector(self, "", None, wx.Point(self.Size[0] / 2, 0), NORTH)
   499         self.Input = Connector(self, "", None, wx.Point(self.Size[0] / 2, 0), NORTH, onlyone = True)
   491         self.Output = Connector(self, "", None, wx.Point(self.Size[0] / 2, self.Size[1]), SOUTH)
   500         self.Output = Connector(self, "", None, wx.Point(self.Size[0] / 2, self.Size[1]), SOUTH, onlyone = True)
   492         self.SetType(type, condition)
   501         self.SetType(type, condition)
   493         self.SetPriority(priority)
   502         self.SetPriority(priority)
   494     
   503     
   495     # Destructor
   504     # Destructor
   496     def __del__(self):
   505     def __del__(self):
   580         
   589         
   581     # Returns the connector connected to input
   590     # Returns the connector connected to input
   582     def GetPreviousConnector(self):
   591     def GetPreviousConnector(self):
   583         wires = self.Input.GetWires()
   592         wires = self.Input.GetWires()
   584         if len(wires) == 1:
   593         if len(wires) == 1:
   585             return wires[0][0].EndConnected
   594             return wires[0][0].GetOtherConnected(self.Input)
   586         return None
   595         return None
   587     
   596     
   588     # Returns the connector connected to output
   597     # Returns the connector connected to output
   589     def GetNextConnector(self):
   598     def GetNextConnector(self):
   590         wires = self.Output.GetWires()
   599         wires = self.Output.GetWires()
   591         if len(wires) == 1:
   600         if len(wires) == 1:
   592             return wires[0][0].StartConnected
   601             return wires[0][0].GetOtherConnected(self.Output)
   593         return None
   602         return None
   594     
   603     
   595     # Refresh the positions of the transition connectors
   604     # Refresh the positions of the transition connectors
   596     def RefreshConnectors(self):
   605     def RefreshConnectors(self):
       
   606         scaling = self.Parent.GetScaling()
       
   607         horizontal_pos = self.Size[0] / 2
       
   608         vertical_pos = self.Size[1] / 2
       
   609         if scaling is not None:
       
   610             horizontal_pos = round(float(self.Pos.x + horizontal_pos) / float(scaling[0])) * scaling[0] - self.Pos.x
       
   611             vertical_pos = round(float(self.Pos.y + vertical_pos) / float(scaling[1])) * scaling[1] - self.Pos.y
   597         # Update input position
   612         # Update input position
   598         self.Input.SetPosition(wx.Point(self.Size[0] / 2, 0))
   613         self.Input.SetPosition(wx.Point(horizontal_pos, 0))
   599         # Update output position
   614         # Update output position
   600         self.Output.SetPosition(wx.Point(self.Size[0] / 2, self.Size[1]))
   615         self.Output.SetPosition(wx.Point(horizontal_pos, self.Size[1]))
   601         if self.Type == "connection":
   616         if self.Type == "connection":
   602             self.Condition.SetPosition(wx.Point(0, self.Size[1] / 2))
   617             self.Condition.SetPosition(wx.Point(0, vertical_pos))
   603         self.RefreshConnected()
   618         self.RefreshConnected()
   604     
   619     
   605     # Refresh the position of the wires connected to transition
   620     # Refresh the position of the wires connected to transition
   606     def RefreshConnected(self, exclude = []):
   621     def RefreshConnected(self, exclude = []):
   607         self.Input.MoveConnected(exclude)
   622         self.Input.MoveConnected(exclude)
   720     def RefreshOutputPosition(self, move = None):
   735     def RefreshOutputPosition(self, move = None):
   721         wires = self.Output.GetWires()
   736         wires = self.Output.GetWires()
   722         if len(wires) != 1:
   737         if len(wires) != 1:
   723             return
   738             return
   724         current_pos = self.Output.GetPosition(False)
   739         current_pos = self.Output.GetPosition(False)
   725         output = wires[0][0].StartConnected
   740         output = wires[0][0].GetOtherConnected(self.Output)
   726         output_pos = output.GetPosition(False)
   741         output_pos = output.GetPosition(False)
   727         diffx = current_pos.x - output_pos.x
   742         diffx = current_pos.x - output_pos.x
   728         output_block = output.GetParentBlock()
   743         output_block = output.GetParentBlock()
   729         if move:
   744         if move:
   730             if isinstance(output_block, SFC_Step):
   745             if isinstance(output_block, SFC_Step):
   752     def OnRightUp(self, event, dc, scaling):
   767     def OnRightUp(self, event, dc, scaling):
   753         # Popup the menu with special items for a step
   768         # Popup the menu with special items for a step
   754         self.Parent.PopupDefaultMenu()
   769         self.Parent.PopupDefaultMenu()
   755     
   770     
   756     # Refreshes the transition state according to move defined and handle selected
   771     # Refreshes the transition state according to move defined and handle selected
   757     def ProcessDragging(self, movex, movey):
   772     def ProcessDragging(self, movex, movey, scaling):
   758         if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
   773         if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
   759             movex = max(-self.BoundingBox.x, movex)
   774             movex = max(-self.BoundingBox.x, movex)
       
   775             if scaling is not None:
       
   776                 movex = round(float(self.Pos.x + movex) / float(scaling[0])) * scaling[0] - self.Pos.x
   760             self.Move(movex, 0)
   777             self.Move(movex, 0)
   761             self.RefreshInputPosition()
   778             self.RefreshInputPosition()
   762             self.RefreshOutputPosition()
   779             self.RefreshOutputPosition()
   763             return movex, 0
   780             return movex, 0
   764         else:
   781         else:
   765             return Graphic_Element.ProcessDragging(self, movex, movey)
   782             return Graphic_Element.ProcessDragging(self, movex, movey, scaling)
   766     
   783     
   767     # Refresh input element model
   784     # Refresh input element model
   768     def RefreshInputModel(self):
   785     def RefreshInputModel(self):
   769         if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
   786         if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
   770             input = self.GetPreviousConnector()
   787             input = self.GetPreviousConnector()
   843             self.Size = wx.Size((number - 1) * SFC_DEFAULT_SEQUENCE_INTERVAL, 1)
   860             self.Size = wx.Size((number - 1) * SFC_DEFAULT_SEQUENCE_INTERVAL, 1)
   844         elif self.Type in [SIMULTANEOUS_DIVERGENCE, SIMULTANEOUS_CONVERGENCE]:
   861         elif self.Type in [SIMULTANEOUS_DIVERGENCE, SIMULTANEOUS_CONVERGENCE]:
   845             self.Size = wx.Size((number - 1) * SFC_DEFAULT_SEQUENCE_INTERVAL, 3)
   862             self.Size = wx.Size((number - 1) * SFC_DEFAULT_SEQUENCE_INTERVAL, 3)
   846         # Create an input and output connector
   863         # Create an input and output connector
   847         if self.Type in [SELECTION_DIVERGENCE, SIMULTANEOUS_DIVERGENCE]:
   864         if self.Type in [SELECTION_DIVERGENCE, SIMULTANEOUS_DIVERGENCE]:
   848             self.Inputs = [Connector(self, "", None, wx.Point(self.Size[0] / 2, 0), NORTH)]
   865             self.Inputs = [Connector(self, "", None, wx.Point(self.Size[0] / 2, 0), NORTH, onlyone = True)]
   849             self.Outputs = []
   866             self.Outputs = []
   850             for i in xrange(number):
   867             for i in xrange(number):
   851                 self.Outputs.append(Connector(self, "", None, wx.Point(i * SFC_DEFAULT_SEQUENCE_INTERVAL, self.Size[1]), SOUTH))
   868                 self.Outputs.append(Connector(self, "", None, wx.Point(i * SFC_DEFAULT_SEQUENCE_INTERVAL, self.Size[1]), SOUTH, onlyone = True))
   852         elif self.Type in [SELECTION_CONVERGENCE, SIMULTANEOUS_CONVERGENCE]:
   869         elif self.Type in [SELECTION_CONVERGENCE, SIMULTANEOUS_CONVERGENCE]:
   853             self.Inputs = []
   870             self.Inputs = []
   854             for i in xrange(number):
   871             for i in xrange(number):
   855                 self.Inputs.append(Connector(self, "", None, wx.Point(i * SFC_DEFAULT_SEQUENCE_INTERVAL, 0), NORTH))
   872                 self.Inputs.append(Connector(self, "", None, wx.Point(i * SFC_DEFAULT_SEQUENCE_INTERVAL, 0), NORTH, onlyone = True))
   856             self.Outputs = [Connector(self, "", None, wx.Point(self.Size[0] / 2, self.Size[1]), SOUTH)]
   873             self.Outputs = [Connector(self, "", None, wx.Point(self.Size[0] / 2, self.Size[1]), SOUTH, onlyone = True)]
   857     
   874     
   858     # Destructor
   875     # Destructor
   859     def __del__(self):
   876     def __del__(self):
   860         self.Inputs = []
   877         self.Inputs = []
   861         self.Outputs = []
   878         self.Outputs = []
   907         if self.Type in [SELECTION_DIVERGENCE, SIMULTANEOUS_DIVERGENCE]:
   924         if self.Type in [SELECTION_DIVERGENCE, SIMULTANEOUS_DIVERGENCE]:
   908             maxx = 0
   925             maxx = 0
   909             for output in self.Outputs:
   926             for output in self.Outputs:
   910                 pos = output.GetRelPosition()
   927                 pos = output.GetRelPosition()
   911                 maxx = max(maxx, pos.x)
   928                 maxx = max(maxx, pos.x)
   912             connector = Connector(self, "", None, wx.Point(maxx + SFC_DEFAULT_SEQUENCE_INTERVAL, self.Size[1]), SOUTH)
   929             connector = Connector(self, "", None, wx.Point(maxx + SFC_DEFAULT_SEQUENCE_INTERVAL, self.Size[1]), SOUTH, onlyone = True)
   913             self.Outputs.append(connector)
   930             self.Outputs.append(connector)
   914             self.MoveConnector(connector, 0)
   931             self.MoveConnector(connector, 0)
   915         elif self.Type in [SELECTION_CONVERGENCE, SIMULTANEOUS_CONVERGENCE]:
   932         elif self.Type in [SELECTION_CONVERGENCE, SIMULTANEOUS_CONVERGENCE]:
   916             maxx = 0
   933             maxx = 0
   917             for input in self.Inputs:
   934             for input in self.Inputs:
   918                 pos = input.GetRelPosition()
   935                 pos = input.GetRelPosition()
   919                 maxx = max(maxx, pos.x)
   936                 maxx = max(maxx, pos.x)
   920             connector = Connector(self, "", None, wx.Point(maxx + SFC_DEFAULT_SEQUENCE_INTERVAL, 0), NORTH)
   937             connector = Connector(self, "", None, wx.Point(maxx + SFC_DEFAULT_SEQUENCE_INTERVAL, 0), NORTH, onlyone = True)
   921             self.Inputs.append(connector)
   938             self.Inputs.append(connector)
   922             self.MoveConnector(connector, SFC_DEFAULT_SEQUENCE_INTERVAL)
   939             self.MoveConnector(connector, SFC_DEFAULT_SEQUENCE_INTERVAL)
   923     
   940     
   924     # Remove a branch from the divergence
   941     # Remove a branch from the divergence
   925     def RemoveBranch(self, connector):
   942     def RemoveBranch(self, connector):
   952         return rect.InsideXY(pt.x, pt.y) or self.TestConnector(pt, False) != None
   969         return rect.InsideXY(pt.x, pt.y) or self.TestConnector(pt, False) != None
   953     
   970     
   954     # Refresh the divergence bounding box
   971     # Refresh the divergence bounding box
   955     def RefreshBoundingBox(self):
   972     def RefreshBoundingBox(self):
   956         if self.Type in [SELECTION_DIVERGENCE, SELECTION_CONVERGENCE]:
   973         if self.Type in [SELECTION_DIVERGENCE, SELECTION_CONVERGENCE]:
   957             self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y - 2, 
   974             self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, 
   958                 self.Size[0] + 1, self.Size[1] + 5)
   975                 self.Size[0] + 1, self.Size[1] + 1)
   959         elif self.Type in [SIMULTANEOUS_DIVERGENCE, SIMULTANEOUS_CONVERGENCE]:
   976         elif self.Type in [SIMULTANEOUS_DIVERGENCE, SIMULTANEOUS_CONVERGENCE]:
   960             self.BoundingBox = wx.Rect(self.Pos.x - SFC_SIMULTANEOUS_SEQUENCE_EXTRA, self.Pos.y - 2, 
   977             self.BoundingBox = wx.Rect(self.Pos.x - SFC_SIMULTANEOUS_SEQUENCE_EXTRA, self.Pos.y, 
   961                 self.Size[0] + 2 * SFC_SIMULTANEOUS_SEQUENCE_EXTRA + 1, self.Size[1] + 5)
   978                 self.Size[0] + 2 * SFC_SIMULTANEOUS_SEQUENCE_EXTRA + 1, self.Size[1] + 1)
   962     
   979     
   963     # Refresh the position of wires connected to divergence
   980     # Refresh the position of wires connected to divergence
   964     def RefreshConnected(self, exclude = []):
   981     def RefreshConnected(self, exclude = []):
   965         for input in self.Inputs:
   982         for input in self.Inputs:
   966             input.MoveConnected(exclude)
   983             input.MoveConnected(exclude)
  1071     def RefreshConnectedPosition(self, connector):
  1088     def RefreshConnectedPosition(self, connector):
  1072         wires = connector.GetWires()
  1089         wires = connector.GetWires()
  1073         if len(wires) != 1:
  1090         if len(wires) != 1:
  1074             return
  1091             return
  1075         current_pos = connector.GetPosition(False)
  1092         current_pos = connector.GetPosition(False)
  1076         if connector in self.Inputs:
  1093         next = wires[0][0].GetOtherConnected(connector)
  1077             next = wires[0][0].EndConnected
       
  1078         else:
       
  1079             next = wires[0][0].StartConnected
       
  1080         next_pos = next.GetPosition(False)
  1094         next_pos = next.GetPosition(False)
  1081         diffx = current_pos.x - next_pos.x
  1095         diffx = current_pos.x - next_pos.x
  1082         next_block = next.GetParentBlock()
  1096         next_block = next.GetParentBlock()
  1083         if isinstance(next_block, SFC_Divergence):
  1097         if isinstance(next_block, SFC_Divergence):
  1084             next_block.MoveConnector(next, diffx)
  1098             next_block.MoveConnector(next, diffx)
  1094         y = 0
  1108         y = 0
  1095         for input in self.Inputs:
  1109         for input in self.Inputs:
  1096             wires = input.GetWires()
  1110             wires = input.GetWires()
  1097             if len(wires) != 1:
  1111             if len(wires) != 1:
  1098                 return
  1112                 return
  1099             previous = wires[0][0].EndConnected
  1113             previous = wires[0][0].GetOtherConnected(input)
  1100             previous_pos = previous.GetPosition(False)
  1114             previous_pos = previous.GetPosition(False)
  1101             y = max(y, previous_pos.y + GetWireSize(previous.GetParentBlock()))
  1115             y = max(y, previous_pos.y + GetWireSize(previous.GetParentBlock()))
  1102         diffy = y - self.Pos.y
  1116         diffy = y - self.Pos.y
  1103         if diffy != 0:
  1117         if diffy != 0:
  1104             self.Move(0, diffy, self.Parent.Wires)
  1118             self.Move(0, diffy, self.Parent.Wires)
  1112             for output_connector in self.Outputs:
  1126             for output_connector in self.Outputs:
  1113                 wires = output_connector.GetWires()
  1127                 wires = output_connector.GetWires()
  1114                 if len(wires) != 1:
  1128                 if len(wires) != 1:
  1115                     return
  1129                     return
  1116                 current_pos = output_connector.GetPosition(False)
  1130                 current_pos = output_connector.GetPosition(False)
  1117                 output = wires[0][0].StartConnected
  1131                 output = wires[0][0].GetOtherConnected(self.Output)
  1118                 output_pos = output.GetPosition(False)
  1132                 output_pos = output.GetPosition(False)
  1119                 diffx = current_pos.x - output_pos.x
  1133                 diffx = current_pos.x - output_pos.x
  1120                 output_block = output.GetParentBlock()
  1134                 output_block = output.GetParentBlock()
  1121                 if isinstance(output_block, SFC_Step):
  1135                 if isinstance(output_block, SFC_Step):
  1122                     output_block.MoveActionBlock(move)
  1136                     output_block.MoveActionBlock(move)
  1125                     output_block.Move(move[0], move[1], self.Parent.Wires)
  1139                     output_block.Move(move[0], move[1], self.Parent.Wires)
  1126                     output_block.RefreshOutputPosition(move)
  1140                     output_block.RefreshOutputPosition(move)
  1127     
  1141     
  1128     # Method called when a LeftDown event have been generated
  1142     # Method called when a LeftDown event have been generated
  1129     def OnLeftDown(self, event, dc, scaling):
  1143     def OnLeftDown(self, event, dc, scaling):
       
  1144         self.RealConnectors = {"Inputs":[],"Outputs":[]}
       
  1145         for input in self.Inputs:
       
  1146             position = input.GetRelPosition()
       
  1147             self.RealConnectors["Inputs"].append(float(position.x)/float(self.Size[0]))
       
  1148         for output in self.Outputs:
       
  1149             position = output.GetRelPosition()
       
  1150             self.RealConnectors["Outputs"].append(float(position.x)/float(self.Size[0]))
       
  1151         Graphic_Element.OnLeftDown(self, event, dc, scaling)
       
  1152     
       
  1153     # Method called when a LeftUp event have been generated
       
  1154     def OnLeftUp(self, event, dc, scaling):
       
  1155         Graphic_Element.OnLeftUp(self, event, dc, scaling)
       
  1156         self.RealConnectors = None
       
  1157     
       
  1158     # Method called when a RightDown event have been generated
       
  1159     def OnRightDown(self, event, dc, scaling):
  1130         pos = GetScaledEventPosition(event, dc, scaling)
  1160         pos = GetScaledEventPosition(event, dc, scaling)
  1131         # Test if a connector have been handled
  1161         # Test if a connector have been handled
  1132         connector = self.TestConnector(pos, False)
  1162         connector = self.TestConnector(pos, False)
  1133         if connector:
  1163         if connector:
  1134             self.Handle = (HANDLE_CONNECTOR, connector)
  1164             self.Handle = (HANDLE_CONNECTOR, connector)
  1135             self.Parent.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
  1165             self.Parent.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
  1136             self.Selected = False
  1166             self.Selected = False
  1137             # Initializes the last position
  1167             # Initializes the last position
  1138             self.oldPos = GetScaledEventPosition(event, dc, scaling)
  1168             self.oldPos = GetScaledEventPosition(event, dc, scaling)
  1139         else:
  1169         else:
  1140             self.RealConnectors = {"Inputs":[],"Outputs":[]}
  1170             Graphic_Element.OnRightDown(self, event, dc, scaling)
  1141             for input in self.Inputs:
  1171     
  1142                 position = input.GetRelPosition()
  1172     # Method called when a RightUp event have been generated
  1143                 self.RealConnectors["Inputs"].append(float(position.x)/float(self.Size[0]))
  1173     def OnRightUp(self, event, dc, scaling):
  1144             for output in self.Outputs:
       
  1145                 position = output.GetRelPosition()
       
  1146                 self.RealConnectors["Outputs"].append(float(position.x)/float(self.Size[0]))
       
  1147             Graphic_Element.OnLeftDown(self, event, dc, scaling)
       
  1148     
       
  1149     # Method called when a LeftUp event have been generated
       
  1150     def OnLeftUp(self, event, dc, scaling):
       
  1151         self.RealConnectors = None
       
  1152         handle_type, handle = self.Handle
  1174         handle_type, handle = self.Handle
  1153         if handle_type == HANDLE_CONNECTOR:
  1175         if handle_type == HANDLE_CONNECTOR:
  1154             wires = handle.GetWires()
  1176             wires = handle.GetWires()
  1155             if len(wires) != 1:
  1177             if len(wires) != 1:
  1156                 return
  1178                 return
  1157             if handle in self.Inputs:
  1179             block = wires[0][0].GetOtherConnected(handle).GetParentBlock()
  1158                 block = wires[0][0].EndConnected.GetParentBlock()
       
  1159             else:
       
  1160                 block = wires[0][0].StartConnected.GetParentBlock()
       
  1161             block.RefreshModel(False)
  1180             block.RefreshModel(False)
  1162             if not isinstance(block, SFC_Divergence):
  1181             if not isinstance(block, SFC_Divergence):
  1163                 if handle in self.Inputs:
  1182                 if handle in self.Inputs:
  1164                     block.RefreshInputModel()
  1183                     block.RefreshInputModel()
  1165                 else:
  1184                 else:
  1166                     block.RefreshOutputModel()
  1185                     block.RefreshOutputModel()
  1167         Graphic_Element.OnLeftUp(self, event, dc, scaling)
  1186             Graphic_Element.OnRightUp(self, event, dc, scaling)
  1168     
  1187         else:
  1169     # Method called when a RightUp event have been generated
  1188             pos = GetScaledEventPosition(event, dc, scaling)
  1170     def OnRightUp(self, event, dc, scaling):
  1189             # Popup the menu with special items for a block and a connector if one is handled
  1171         pos = GetScaledEventPosition(event, dc, scaling)
  1190             connector = self.TestConnector(pos, False)
  1172         # Popup the menu with special items for a block and a connector if one is handled
  1191             if connector:
  1173         connector = self.TestConnector(pos, False)
  1192                 self.Handle = (HANDLE_CONNECTOR, connector)
  1174         if connector:
  1193                 self.Parent.PopupDivergenceMenu(True)
  1175             self.Handle = (HANDLE_CONNECTOR, connector)
  1194             else:
  1176             self.Parent.PopupDivergenceMenu(True)
  1195                 # Popup the divergence menu without delete branch
  1177         else:
  1196                 self.Parent.PopupDivergenceMenu(False)
  1178             # Popup the divergence menu without delete branch
       
  1179             self.Parent.PopupDivergenceMenu(False)
       
  1180     
  1197     
  1181     # Refreshes the divergence state according to move defined and handle selected
  1198     # Refreshes the divergence state according to move defined and handle selected
  1182     def ProcessDragging(self, movex, movey):
  1199     def ProcessDragging(self, movex, movey, scaling):
  1183         handle_type, handle = self.Handle
  1200         handle_type, handle = self.Handle
  1184         # A connector has been handled
  1201         # A connector has been handled
  1185         if handle_type == HANDLE_CONNECTOR:
  1202         if handle_type == HANDLE_CONNECTOR:
  1186             movex = max(-self.BoundingBox.x, movex)
  1203             movex = max(-self.BoundingBox.x, movex)
       
  1204             if scaling is not None:
       
  1205                 movex = round(float(self.Pos.x + movex) / float(scaling[0])) * scaling[0] - self.Pos.x
  1187             self.MoveConnector(handle, movex)
  1206             self.MoveConnector(handle, movex)
  1188             if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
  1207             if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
  1189                 self.RefreshConnectedPosition(handle)
  1208                 self.RefreshConnectedPosition(handle)
  1190             return movex, 0
  1209             return movex, 0
  1191         elif self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
  1210         elif self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
  1192             return Graphic_Element.ProcessDragging(self, movex, movey)
  1211             return Graphic_Element.ProcessDragging(self, movex, movey, scaling)
  1193         return 0, 0
  1212         return 0, 0
  1194     
  1213     
  1195     # Refresh output element model
  1214     # Refresh output element model
  1196     def RefreshOutputModel(self, move=False):
  1215     def RefreshOutputModel(self, move=False):
  1197         if move and self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
  1216         if move and self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
  1198             for output in self.Outputs:
  1217             for output in self.Outputs:
  1199                 wires = output.GetWires()
  1218                 wires = output.GetWires()
  1200                 if len(wires) != 1:
  1219                 if len(wires) != 1:
  1201                     return
  1220                     return
  1202                 output_block = wires[0][0].StartConnected.GetParentBlock()
  1221                 output_block = wires[0][0].GetOtherConnected(output).GetParentBlock()
  1203                 output_block.RefreshModel(False)
  1222                 output_block.RefreshModel(False)
  1204                 if not isinstance(output_block, SFC_Divergence) or move:
  1223                 if not isinstance(output_block, SFC_Divergence) or move:
  1205                     output_block.RefreshOutputModel(move)
  1224                     output_block.RefreshOutputModel(move)
  1206     
  1225     
  1207     # Refreshes the divergence model
  1226     # Refreshes the divergence model
  1264         Graphic_Element.__init__(self, parent)
  1283         Graphic_Element.__init__(self, parent)
  1265         self.Target = target
  1284         self.Target = target
  1266         self.Id = id
  1285         self.Id = id
  1267         self.Size = wx.Size(SFC_JUMP_SIZE[0], SFC_JUMP_SIZE[1])
  1286         self.Size = wx.Size(SFC_JUMP_SIZE[0], SFC_JUMP_SIZE[1])
  1268         # Create an input and output connector
  1287         # Create an input and output connector
  1269         self.Input = Connector(self, "", None, wx.Point(self.Size[0] / 2, 0), NORTH)
  1288         self.Input = Connector(self, "", None, wx.Point(self.Size[0] / 2, 0), NORTH, onlyone = True)
  1270         
  1289         
  1271     # Destructor
  1290     # Destructor
  1272     def __del__(self):
  1291     def __del__(self):
  1273         self.Input = None
  1292         self.Input = None
  1274     
  1293     
  1319     
  1338     
  1320     # Returns the connector connected to input
  1339     # Returns the connector connected to input
  1321     def GetPreviousConnector(self):
  1340     def GetPreviousConnector(self):
  1322         wires = self.Input.GetWires()
  1341         wires = self.Input.GetWires()
  1323         if len(wires) == 1:
  1342         if len(wires) == 1:
  1324             return wires[0][0].EndConnected
  1343             return wires[0][0].GetOtherConnected(self.Input)
  1325         return None
  1344         return None
  1326     
  1345     
  1327     # Refresh the element connectors position
  1346     # Refresh the element connectors position
  1328     def RefreshConnectors(self):
  1347     def RefreshConnectors(self):
  1329         self.Input.SetPosition(wx.Point(self.Size[0] / 2, 0))
  1348         scaling = self.Parent.GetScaling()
       
  1349         horizontal_pos = self.Size[0] / 2
       
  1350         if scaling is not None:
       
  1351             horizontal_pos = round(float(self.Pos.x + horizontal_pos) / float(scaling[0])) * scaling[0] - self.Pos.x
       
  1352         self.Input.SetPosition(wx.Point(horizontal_pos, 0))
  1330         self.RefreshConnected()
  1353         self.RefreshConnected()
  1331     
  1354     
  1332     # Refresh the position of wires connected to jump
  1355     # Refresh the position of wires connected to jump
  1333     def RefreshConnected(self, exclude = []):
  1356     def RefreshConnected(self, exclude = []):
  1334         if self.Input:
  1357         if self.Input:
  1388     def OnRightUp(self, event, dc, scaling):
  1411     def OnRightUp(self, event, dc, scaling):
  1389         # Popup the default menu
  1412         # Popup the default menu
  1390         self.Parent.PopupDefaultMenu()
  1413         self.Parent.PopupDefaultMenu()
  1391     
  1414     
  1392     # Refreshes the jump state according to move defined and handle selected
  1415     # Refreshes the jump state according to move defined and handle selected
  1393     def ProcessDragging(self, movex, movey):
  1416     def ProcessDragging(self, movex, movey, scaling):
  1394         if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
  1417         if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
  1395             movex = max(-self.BoundingBox.x, movex)
  1418             movex = max(-self.BoundingBox.x, movex)
       
  1419             if scaling is not None:
       
  1420                 movex = round(float(self.Pos.x + movex) / float(scaling[0])) * scaling[0] - self.Pos.x
  1396             self.Move(movex, 0)
  1421             self.Move(movex, 0)
  1397             self.RefreshInputPosition()
  1422             self.RefreshInputPosition()
  1398             return movex, 0
  1423             return movex, 0
  1399         else:
  1424         else:
  1400             return Graphic_Element.ProcessDragging(self, movex, movey)
  1425             return Graphic_Element.ProcessDragging(self, movex, movey, scaling)
  1401     
  1426     
  1402     # Refresh input element model
  1427     # Refresh input element model
  1403     def RefreshInputModel(self):
  1428     def RefreshInputModel(self):
  1404         if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
  1429         if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
  1405             input = self.GetPreviousConnector()
  1430             input = self.GetPreviousConnector()
  1466         Graphic_Element.__init__(self, parent)
  1491         Graphic_Element.__init__(self, parent)
  1467         self.Id = id
  1492         self.Id = id
  1468         self.Size = wx.Size(SFC_ACTION_MIN_SIZE[0], SFC_ACTION_MIN_SIZE[1])
  1493         self.Size = wx.Size(SFC_ACTION_MIN_SIZE[0], SFC_ACTION_MIN_SIZE[1])
  1469         self.MinSize = wx.Size(SFC_ACTION_MIN_SIZE[0], SFC_ACTION_MIN_SIZE[1])
  1494         self.MinSize = wx.Size(SFC_ACTION_MIN_SIZE[0], SFC_ACTION_MIN_SIZE[1])
  1470         # Create an input and output connector
  1495         # Create an input and output connector
  1471         self.Input = Connector(self, "", None, wx.Point(0, SFC_ACTION_MIN_SIZE[1] / 2), WEST)
  1496         self.Input = Connector(self, "", None, wx.Point(0, SFC_ACTION_MIN_SIZE[1] / 2), WEST, onlyone = True)
  1472         self.SetActions(actions)
  1497         self.SetActions(actions)
  1473     
  1498     
  1474     # Destructor
  1499     # Destructor
  1475     def __del__(self):
  1500     def __del__(self):
  1476         self.Input = None
  1501         self.Input = None
  1536     def TestConnector(self, pt, exclude = True):
  1561     def TestConnector(self, pt, exclude = True):
  1537         # Test input connector
  1562         # Test input connector
  1538         if self.Input.TestPoint(pt, exclude):
  1563         if self.Input.TestPoint(pt, exclude):
  1539             return self.Input
  1564             return self.Input
  1540         return None
  1565         return None
       
  1566     
       
  1567     # Refresh the element connectors position
       
  1568     def RefreshConnectors(self):
       
  1569         scaling = self.Parent.GetScaling()
       
  1570         vertical_pos = SFC_ACTION_MIN_SIZE[1] / 2
       
  1571         if scaling is not None:
       
  1572             vertical_pos = round(float(self.Pos.y + vertical_pos) / float(scaling[1])) * scaling[1] - self.Pos.y
       
  1573         self.Input.SetPosition(wx.Point(0, vertical_pos))
       
  1574         self.RefreshConnected()
  1541     
  1575     
  1542     # Changes the action block actions
  1576     # Changes the action block actions
  1543     def SetActions(self, actions):
  1577     def SetActions(self, actions):
  1544         dc = wx.ClientDC(self.Parent)
  1578         dc = wx.ClientDC(self.Parent)
  1545         self.Actions = actions
  1579         self.Actions = actions
  1573                 SFC_ACTION_MIN_SIZE[0]), len(self.Actions) * SFC_ACTION_MIN_SIZE[1]
  1607                 SFC_ACTION_MIN_SIZE[0]), len(self.Actions) * SFC_ACTION_MIN_SIZE[1]
  1574             self.RefreshBoundingBox()
  1608             self.RefreshBoundingBox()
  1575             if self.Input:
  1609             if self.Input:
  1576                 wires = self.Input.GetWires()
  1610                 wires = self.Input.GetWires()
  1577                 if len(wires) == 1:
  1611                 if len(wires) == 1:
  1578                     input_block = wires[0][0].EndConnected.GetParentBlock()
  1612                     input_block = wires[0][0].GetOtherConnected(self.Input).GetParentBlock()
  1579                     input_block.RefreshOutputPosition()
  1613                     input_block.RefreshOutputPosition()
  1580                     input_block.RefreshOutputModel(True)
  1614                     input_block.RefreshOutputModel(True)
  1581     
  1615     
  1582     # Returns the action block actions
  1616     # Returns the action block actions
  1583     def GetActions(self):
  1617     def GetActions(self):
  1596     def OnRightUp(self, event, dc, scaling):
  1630     def OnRightUp(self, event, dc, scaling):
  1597         # Popup the default menu
  1631         # Popup the default menu
  1598         self.Parent.PopupDefaultMenu()
  1632         self.Parent.PopupDefaultMenu()
  1599     
  1633     
  1600     # Refreshes the action block state according to move defined and handle selected
  1634     # Refreshes the action block state according to move defined and handle selected
  1601     def ProcessDragging(self, movex, movey):
  1635     def ProcessDragging(self, movex, movey, scaling):
  1602         if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
  1636         if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
  1603             handle_type, handle = self.Handle
  1637             handle_type, handle = self.Handle
  1604             if handle_type == HANDLE_MOVE:
  1638             if handle_type == HANDLE_MOVE:
  1605                 movex = max(-self.BoundingBox.x, movex)
  1639                 movex = max(-self.BoundingBox.x, movex)
       
  1640                 if scaling is not None:
       
  1641                     movex = round(float(self.Pos.x + movex) / float(scaling[0])) * scaling[0] - self.Pos.x
  1606                 wires = self.Input.GetWires()
  1642                 wires = self.Input.GetWires()
  1607                 if len(wires) == 1:
  1643                 if len(wires) == 1:
  1608                     input_pos = wires[0][0].EndConnected.GetPosition(False)
  1644                     input_pos = wires[0][0].GetOtherConnected(self.Input).GetPosition(False)
  1609                     if self.Pos.x - input_pos.x + movex >= SFC_WIRE_MIN_SIZE:
  1645                     if self.Pos.x - input_pos.x + movex >= SFC_WIRE_MIN_SIZE:
  1610                         self.Move(movex, 0)
  1646                         self.Move(movex, 0)
  1611                         return movex, 0
  1647                         return movex, 0
  1612                 return 0, 0
  1648                 return 0, 0
  1613             else:
  1649             else:
  1614                 return Graphic_Element.ProcessDragging(self, movex, movey)
  1650                 return Graphic_Element.ProcessDragging(self, movex, movey, scaling)
  1615         else:
  1651         else:
  1616             return Graphic_Element.ProcessDragging(self, movex, movey)
  1652             return Graphic_Element.ProcessDragging(self, movex, movey, scaling)
  1617 
  1653 
  1618     
  1654     
  1619    # Refreshes the action block model
  1655    # Refreshes the action block model
  1620     def RefreshModel(self, move=True):
  1656     def RefreshModel(self, move=True):
  1621         self.Parent.RefreshActionBlockModel(self)
  1657         self.Parent.RefreshActionBlockModel(self)