graphics/SFC_Objects.py
changeset 27 dae55dd9ee14
parent 5 f8652b073e84
child 42 4a8400732001
--- a/graphics/SFC_Objects.py	Sat Jul 07 11:35:17 2007 +0200
+++ b/graphics/SFC_Objects.py	Mon Jul 09 11:10:14 2007 +0200
@@ -148,7 +148,16 @@
             self.Action.MoveConnected(exclude)
     
     # Returns the step connector that starts with the point given if it exists 
-    def GetConnector(self, position):
+    def GetConnector(self, position, name = None):
+        # if a name is given
+        if name:
+            # Test input, output and action connector if they exists
+            if self.Input and name == self.Input.GetName():
+                return self.Input
+            if self.Output and name == self.Output.GetName():
+                return self.Output
+            if self.Action and name == self.Action.GetName():
+                return self.Action
         # Test input connector if it exists
         if self.Input:
             input_pos = self.Input.GetRelPosition()
@@ -312,7 +321,10 @@
     
     # Resize the divergence from position and size given
     def Resize(self, x, y, width, height):
-        self.UpdateSize(width, height)
+        if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
+            self.UpdateSize(width, height)
+        else:
+            Graphic_Element.Resize(self, x, y, width, height)
     
     # Method called when a LeftDClick event have been generated
     def OnLeftDClick(self, event, scaling):
@@ -320,7 +332,7 @@
         self.Parent.EditStepContent(self)
     
     # Method called when a RightUp event have been generated
-    def OnRightUp(self, event, scaling):
+    def OnRightUp(self, event, dc, scaling):
         # Popup the menu with special items for a step
         self.Parent.PopupDefaultMenu()
     
@@ -329,7 +341,10 @@
         handle_type, handle = self.Handle
         if handle_type == HANDLE_MOVE:
             action_block = None
-            if self.Initial:
+            if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
+                self.Move(movex, movey)
+                self.RefreshConnected()
+            elif self.Initial:
                 self.MoveActionBlock((movex, movey))
                 self.Move(movex, movey, self.Parent.Wires)
                 self.RefreshOutputPosition((movex, movey))
@@ -371,8 +386,11 @@
                 action_block.RefreshModel(False)
         # If step has moved, refresh the model of wires connected to output
         if move:
-            self.RefreshInputModel()
-            self.RefreshOutputModel(self.Initial)
+            if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
+                self.RefreshInputModel()
+                self.RefreshOutputModel(self.Initial)
+            elif self.Output:
+                self.Output.RefreshWires()
     
     # Draws step
     def Draw(self, dc):
@@ -423,11 +441,13 @@
     
     # Forbids to change the transition size
     def SetSize(self, width, height):
-        pass
+        if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
+            Graphic_Element.SetSize(self, width, height)
     
     # Forbids to resize the transition
     def Resize(self, x, y, width, height):
-        pass
+        if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
+            Graphic_Element.Resize(self, x, y, width, height)
     
     # Delete this transition by calling the appropriate method
     def Delete(self):
@@ -479,7 +499,14 @@
         self.Output.MoveConnected(exclude)
     
     # Returns the transition connector that starts with the point given if it exists 
-    def GetConnector(self, position):
+    def GetConnector(self, position, name = None):
+        # if a name is given
+        if name:
+            # Test input and output connector
+            if name == self.Input.GetName():
+                return self.Input
+            if name == self.Output.GetName():
+                return self.Output
         # Test input connector
         input_pos = self.Input.GetRelPosition()
         if position.x == self.Pos.x + input_pos.x and position.y == self.Pos.y + input_pos.y:
@@ -568,31 +595,35 @@
                 output_block.MoveActionBlock((diffx, 0))
             output_block.Move(diffx, 0)
             output_block.RefreshOutputPosition()
-    
+
     # Method called when a LeftDClick event have been generated
-    def OnLeftDClick(self, event, scaling):
+    def OnLeftDClick(self, event, dc, scaling):
         # Edit the transition properties
         self.Parent.EditTransitionContent(self)
     
     # Method called when a RightUp event have been generated
-    def OnRightUp(self, event, scaling):
+    def OnRightUp(self, event, dc, scaling):
         # Popup the menu with special items for a step
         self.Parent.PopupDefaultMenu()
     
     # Refreshes the transition state according to move defined and handle selected
     def ProcessDragging(self, movex, movey):
-        self.Move(movex, 0)
-        self.RefreshInputPosition()
-        self.RefreshOutputPosition()
+        if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
+            self.Move(movex, 0)
+            self.RefreshInputPosition()
+            self.RefreshOutputPosition()
+        else:
+            Graphic_Element.ProcessDragging(self, movex, movey)
     
     # Refresh input element model
     def RefreshInputModel(self):
-        input = self.GetPreviousConnector()
-        if input:
-            input_block = input.GetParentBlock()
-            input_block.RefreshModel(False)
-            if not isinstance(input_block, SFC_Divergence):
-                input_block.RefreshInputModel()
+        if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
+            input = self.GetPreviousConnector()
+            if input:
+                input_block = input.GetParentBlock()
+                input_block.RefreshModel(False)
+                if not isinstance(input_block, SFC_Divergence):
+                    input_block.RefreshInputModel()
     
     # Refresh output element model
     def RefreshOutputModel(self, move=False):
@@ -608,8 +639,11 @@
         self.Parent.RefreshTransitionModel(self)
         # If transition has moved, refresh the model of wires connected to output
         if move:
-            self.RefreshInputModel()
-            self.RefreshOutputModel()
+            if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
+                self.RefreshInputModel()
+                self.RefreshOutputModel()
+            else:
+                self.Output.RefreshWires()
     
     # Draws transition
     def Draw(self, dc):
@@ -672,7 +706,8 @@
     
     # Forbids to resize the divergence
     def Resize(self, x, y, width, height):
-        pass
+        if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
+            Graphic_Element.Resize(self, x, y, width, height)
     
     # Delete this divergence by calling the appropriate method
     def Delete(self):
@@ -774,7 +809,16 @@
         self.RefreshBoundingBox()
     
     # Returns the divergence connector that starts with the point given if it exists 
-    def GetConnector(self, position):
+    def GetConnector(self, position, name = None):
+        # if a name is given
+        if name:
+            # Test each input and output connector
+            for input in self.Inputs:
+                if name == input.GetName():
+                    return input
+            for output in self.Outputs:
+                if name == output.GetName():
+                    return output
         # Test input connector
         for input in self.Inputs:
             input_pos = input.GetPosition(False)
@@ -808,23 +852,27 @@
         for i, input in enumerate(self.Inputs):
             position = input.GetRelPosition()
             if self.RealConnectors:
-                input.SetPosition(wxPoint(int(round(self.RealConnectors["Inputs"][i] * width)), position.y))
+                input.SetPosition(wxPoint(int(round(self.RealConnectors["Inputs"][i] * width)), 0))
             else:
-                input.SetPosition(wxPoint(int(round(float(position.x)*float(width)/float(self.Size[0]))), position.y))
+                input.SetPosition(wxPoint(int(round(float(position.x)*float(width)/float(self.Size[0]))), 0))
             input.MoveConnected()
         for i, output in enumerate(self.Outputs):
             position = output.GetRelPosition()
             if self.RealConnectors:
-                output.SetPosition(wxPoint(int(round(self.RealConnectors["Outputs"][i] * width)), position.y))
+                output.SetPosition(wxPoint(int(round(self.RealConnectors["Outputs"][i] * width)), self.Size[1]))
             else:
-                output.SetPosition(wxPoint(int(round(float(position.x)*float(width)/float(self.Size[0]))), position.y))
+                output.SetPosition(wxPoint(int(round(float(position.x)*float(width)/float(self.Size[0]))), self.Size[1]))
             output.MoveConnected()
-        self.Size = wxSize(width, self.Size[1])
+        self.Size = wxSize(width, height)
         self.RefreshBoundingBox()
     
     # Returns the divergence minimum size
     def GetMinSize(self):
-        return 0, self.Size[1]
+        if self.Type in [SELECTION_DIVERGENCE, SELECTION_CONVERGENCE]:
+            return 0, 1
+        elif self.Type in [SIMULTANEOUS_DIVERGENCE, SIMULTANEOUS_CONVERGENCE]:
+            return 0, 3
+        return 0, 0
     
     # Refresh the position of the block connected to connector
     def RefreshConnectedPosition(self, connector):
@@ -847,7 +895,7 @@
                 next_block.RefreshInputPosition()
             else:
                 next_block.RefreshOutputPosition()
-    
+
     # Refresh the position of this divergence
     def RefreshPosition(self):
         y = 0
@@ -885,8 +933,8 @@
                     output_block.RefreshOutputPosition(move)
     
     # Method called when a LeftDown event have been generated
-    def OnLeftDown(self, event, scaling):
-        pos = GetScaledEventPosition(event, scaling)
+    def OnLeftDown(self, event, dc, scaling):
+        pos = GetScaledEventPosition(event, dc, scaling)
         # Test if a connector have been handled
         connector = self.TestConnector(pos, False)
         if connector:
@@ -894,7 +942,7 @@
             self.Parent.SetCursor(wxStockCursor(wxCURSOR_HAND))
             self.Selected = False
             # Initializes the last position
-            self.oldPos = GetScaledEventPosition(event, scaling)
+            self.oldPos = GetScaledEventPosition(event, dc, scaling)
         else:
             self.RealConnectors = {"Inputs":[],"Outputs":[]}
             for input in self.Inputs:
@@ -903,10 +951,10 @@
             for output in self.Outputs:
                 position = output.GetRelPosition()
                 self.RealConnectors["Outputs"].append(float(position.x)/float(self.Size[0]))
-            Graphic_Element.OnLeftDown(self, event, scaling)
+            Graphic_Element.OnLeftDown(self, event, dc, scaling)
     
     # Method called when a LeftUp event have been generated
-    def OnLeftUp(self, event, scaling):
+    def OnLeftUp(self, event, dc, scaling):
         self.RealConnectors = None
         handle_type, handle = self.Handle
         if handle_type == HANDLE_CONNECTOR:
@@ -923,11 +971,11 @@
                     block.RefreshInputModel()
                 else:
                     block.RefreshOutputModel()
-        Graphic_Element.OnLeftUp(self, event, scaling)
+        Graphic_Element.OnLeftUp(self, event, dc, scaling)
     
     # Method called when a RightUp event have been generated
-    def OnRightUp(self, event, scaling):
-        pos = GetScaledEventPosition(event, scaling)
+    def OnRightUp(self, event, dc, scaling):
+        pos = GetScaledEventPosition(event, dc, scaling)
         # Popup the menu with special items for a block and a connector if one is handled
         connector = self.TestConnector(pos, False)
         if connector:
@@ -943,11 +991,14 @@
         # A connector has been handled
         if handle_type == HANDLE_CONNECTOR:
             self.MoveConnector(handle, movex)
-            self.RefreshConnectedPosition(handle)
+            if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
+                self.RefreshConnectedPosition(handle)
+        elif self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
+            Graphic_Element.ProcessDragging(self, movex, movey)
     
     # Refresh output element model
     def RefreshOutputModel(self, move=False):
-        if move:
+        if move and self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
             for output in self.Outputs:
                 wires = output.GetWires()
                 if len(wires) != 1:
@@ -962,7 +1013,11 @@
         self.Parent.RefreshDivergenceModel(self)
         # If divergence has moved, refresh the model of wires connected to outputs
         if move:
-            self.RefreshOutputModel()
+            if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
+                self.RefreshOutputModel()
+            else:
+                for output in self.Outputs:
+                    output.RefreshWires()
     
     # Draws divergence
     def Draw(self, dc):
@@ -974,8 +1029,8 @@
         elif self.Type in [SIMULTANEOUS_DIVERGENCE, SIMULTANEOUS_CONVERGENCE]:
             dc.DrawLine(self.Pos.x - SFC_SIMULTANEOUS_SEQUENCE_EXTRA, self.Pos.y, 
                         self.Pos.x + self.Size[0] + SFC_SIMULTANEOUS_SEQUENCE_EXTRA + 1, self.Pos.y)
-            dc.DrawLine(self.Pos.x - SFC_SIMULTANEOUS_SEQUENCE_EXTRA, self.Pos.y + 3, 
-                        self.Pos.x + self.Size[0] + SFC_SIMULTANEOUS_SEQUENCE_EXTRA + 1, self.Pos.y + 3)
+            dc.DrawLine(self.Pos.x - SFC_SIMULTANEOUS_SEQUENCE_EXTRA, self.Pos.y + self.Size[1], 
+                        self.Pos.x + self.Size[0] + SFC_SIMULTANEOUS_SEQUENCE_EXTRA + 1, self.Pos.y + self.Size[1])
         # Draw inputs and outputs connectors
         for input in self.Inputs:
             input.Draw(dc)
@@ -1004,15 +1059,17 @@
         
     # Destructor
     def __del__(self):
-        self.Inputs = None
+        self.Input = None
     
     # Forbids to change the jump size
     def SetSize(self, width, height):
-        pass
+        if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
+            Graphic_Element.SetSize(self, width, height)
     
     # Forbids to resize jump
     def Resize(self, x, y, width, height):
-        pass
+        if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
+            Graphic_Element.Resize(self, x, y, width, height)
     
     # Delete this jump by calling the appropriate method
     def Delete(self):
@@ -1020,8 +1077,7 @@
     
     # Unconnect input
     def Clean(self):
-        if self.Input:
-            self.Input.UnConnect()
+        self.Input.UnConnect()
     
     # Refresh the jump bounding box
     def RefreshBoundingBox(self):
@@ -1034,19 +1090,23 @@
     
     # Returns the connector connected to input
     def GetPreviousConnector(self):
-        if self.Input:
-            wires = self.Input.GetWires()
-            if len(wires) == 1:
-                return wires[0][0].EndConnected
+        wires = self.Input.GetWires()
+        if len(wires) == 1:
+            return wires[0][0].EndConnected
         return None
     
+    # Refresh the element connectors position
+    def RefreshConnectors(self):
+        self.Input.SetPosition(wxPoint(self.Size[0] / 2, 0))
+        self.RefreshConnected()
+    
     # Refresh the position of wires connected to jump
     def RefreshConnected(self, exclude = []):
         if self.Input:
             self.Input.MoveConnected(exclude)
     
     # Returns input jump connector 
-    def GetConnector(self, position = None):
+    def GetConnector(self, position = None, name = None):
         return self.Input
     
     # Test if point given is on jump input connector
@@ -1091,28 +1151,32 @@
         pass
     
     # Method called when a LeftDClick event have been generated
-    def OnLeftDClick(self, event, scaling):
+    def OnLeftDClick(self, event, dc, scaling):
         # Edit the jump properties
         self.Parent.EditJumpContent(self)
     
     # Method called when a RightUp event have been generated
-    def OnRightUp(self, event, scaling):
+    def OnRightUp(self, event, dc, scaling):
         # Popup the default menu
         self.Parent.PopupDefaultMenu()
     
     # Refreshes the jump state according to move defined and handle selected
     def ProcessDragging(self, movex, movey):
-        self.Move(movex, 0)
-        self.RefreshInputPosition()
+        if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
+            self.Move(movex, 0)
+            self.RefreshInputPosition()
+        else:
+            Graphic_Element.ProcessDragging(self, movex, movey)
     
     # Refresh input element model
     def RefreshInputModel(self):
-        input = self.GetPreviousConnector()
-        if input:
-            input_block = input.GetParentBlock()
-            input_block.RefreshModel(False)
-            if not isinstance(input_block, SFC_Divergence):
-                input_block.RefreshInputModel()
+        if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
+            input = self.GetPreviousConnector()
+            if input:
+                input_block = input.GetParentBlock()
+                input_block.RefreshModel(False)
+                if not isinstance(input_block, SFC_Divergence):
+                    input_block.RefreshInputModel()
     
     # Refresh output element model
     def RefreshOutputModel(self, move=False):
@@ -1122,7 +1186,8 @@
     def RefreshModel(self, move=True):
         self.Parent.RefreshJumpModel(self)
         if move:
-            self.RefreshInputModel()
+            if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
+                self.RefreshInputModel()
     
     # Draws divergence
     def Draw(self, dc):
@@ -1171,10 +1236,19 @@
     def GetLineNumber(self):
         return len(self.Actions)
     
+    def GetLineSize(self):
+        if len(self.Actions) > 1:
+            return self.Size[1] / len(self.Actions)
+        else:
+            return SFC_ACTION_MIN_SIZE[1]
+    
     # Forbids to resize the action block
     def Resize(self, x, y, width, height):
-        if x == 0:
-            self.SetSize(width, self.Size[1])
+        if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
+            if x == 0:
+                self.SetSize(width, self.Size[1])
+        else:
+            Graphic_Element.Resize(self, x, y, width, height)
     
     # Delete this action block by calling the appropriate method
     def Delete(self):
@@ -1193,7 +1267,7 @@
         self.Input.MoveConnected(exclude)
     
     # Returns input action block connector 
-    def GetConnector(self, position = None):
+    def GetConnector(self, position = None, name = None):
         return self.Input
     
     # Test if point given is on action block input connector
@@ -1219,8 +1293,12 @@
             if "indicator" in action and action["indicator"] != "":
                 width, height = dc.GetTextExtent(action["indicator"])
                 self.ColSize[2] = max(self.ColSize[2], width + 10)
-        self.Size = wxSize(max(self.ColSize[0] + self.ColSize[1] + self.ColSize[2],
-            SFC_ACTION_MIN_SIZE[0]), len(self.Actions) * SFC_ACTION_MIN_SIZE[1])
+        if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
+            line_size = self.GetLineSize()
+            self.Size = wxSize(self.ColSize[0] + self.ColSize[1] + self.ColSize[2], len(self.Actions) * line_size)
+        else:
+            self.Size = wxSize(max(self.ColSize[0] + self.ColSize[1] + self.ColSize[2],
+                SFC_ACTION_MIN_SIZE[0]), len(self.Actions) * SFC_ACTION_MIN_SIZE[1])
         self.RefreshBoundingBox()
         if self.Input:
             wires = self.Input.GetWires()
@@ -1239,21 +1317,25 @@
             SFC_ACTION_MIN_SIZE[0]), len(self.Actions) * SFC_ACTION_MIN_SIZE[1]
     
     # Method called when a LeftDClick event have been generated
-    def OnLeftDClick(self, event, scaling):
+    def OnLeftDClick(self, event, dc, scaling):
         # Edit the action block properties
         self.Parent.EditActionBlockContent(self)
     
     # Refreshes the action block state according to move defined and handle selected
     def ProcessDragging(self, movex, movey):
-        handle_type, handle = self.Handle
-        if handle_type == HANDLE_MOVE:
-            wires = self.Input.GetWires()
-            if len(wires) == 1:
-                input_pos = wires[0][0].EndConnected.GetPosition(False)
-                if self.Pos.x - input_pos.x + movex >= SFC_WIRE_MIN_SIZE:
-                    self.Move(movex, 0)
+        if self.Parent.GetDrawingMode() != FREEDRAWING_MODE:
+            handle_type, handle = self.Handle
+            if handle_type == HANDLE_MOVE:
+                wires = self.Input.GetWires()
+                if len(wires) == 1:
+                    input_pos = wires[0][0].EndConnected.GetPosition(False)
+                    if self.Pos.x - input_pos.x + movex >= SFC_WIRE_MIN_SIZE:
+                        self.Move(movex, 0)
+            else:
+                Graphic_Element.ProcessDragging(self, movex, movey)
         else:
             Graphic_Element.ProcessDragging(self, movex, movey)
+
     
    # Refreshes the action block model
     def RefreshModel(self, move=True):
@@ -1270,27 +1352,29 @@
                 self.Pos.x + colsize[0], self.Pos.y + self.Size[1])
         dc.DrawLine(self.Pos.x + colsize[0] + colsize[1], self.Pos.y, 
                 self.Pos.x + colsize[0] + colsize[1], self.Pos.y + self.Size[1])
+        line_size = self.GetLineSize()
         for i, action in enumerate(self.Actions):
             if i != 0:
-                dc.DrawLine(self.Pos.x, self.Pos.y + i * SFC_ACTION_MIN_SIZE[1], 
-                    self.Pos.x + self.Size[0], self.Pos.y + i * SFC_ACTION_MIN_SIZE[1])
+                dc.DrawLine(self.Pos.x, self.Pos.y + i * line_size, 
+                    self.Pos.x + self.Size[0], self.Pos.y + i * line_size)
             text_width, text_height = dc.GetTextExtent(action["qualifier"])
             if "duration" in action:
                 dc.DrawText(action["qualifier"], self.Pos.x + (colsize[0] - text_width) / 2,
-                    self.Pos.y + i * SFC_ACTION_MIN_SIZE[1] + SFC_ACTION_MIN_SIZE[1] / 2 - text_height)
+                    self.Pos.y + i * line_size + line_size / 2 - text_height)
                 text_width, text_height = dc.GetTextExtent(action["duration"])
                 dc.DrawText(action["duration"], self.Pos.x + (colsize[0] - text_width) / 2,
-                    self.Pos.y + i * SFC_ACTION_MIN_SIZE[1] + SFC_ACTION_MIN_SIZE[1] / 2)
+                    self.Pos.y + i * line_size + line_size / 2)
             else:
                 dc.DrawText(action["qualifier"], self.Pos.x + (colsize[0] - text_width) / 2,
-                        self.Pos.y + i * SFC_ACTION_MIN_SIZE[1] + (SFC_ACTION_MIN_SIZE[1] - text_height) / 2)
+                        self.Pos.y + i * line_size + (line_size - text_height) / 2)
             text_width, text_height = dc.GetTextExtent(action["value"])
             dc.DrawText(action["value"], self.Pos.x + colsize[0] + (colsize[1] - text_width) / 2,
-                    self.Pos.y + i * SFC_ACTION_MIN_SIZE[1] + (SFC_ACTION_MIN_SIZE[1] - text_height) / 2)
+                    self.Pos.y + i * line_size + (line_size - text_height) / 2)
             if "indicator" in action:
                 text_width, text_height = dc.GetTextExtent(action["indicator"])
                 dc.DrawText(action["indicator"], self.Pos.x + colsize[0] + colsize[1] + (colsize[2] - text_width) / 2,
-                        self.Pos.y + i * SFC_ACTION_MIN_SIZE[1] + (SFC_ACTION_MIN_SIZE[1] - text_height) / 2)
+                        self.Pos.y + i * line_size + (line_size - text_height) / 2)
         # Draw input connector
         self.Input.Draw(dc)
         Graphic_Element.Draw(self, dc)
+