Adding support for allowing connections only between an input and an output connector
authorlbessard
Wed, 27 Aug 2008 16:56:25 +0200 (2008-08-27)
changeset 243 c5da8b706cde
parent 242 5b3e1c4569e6
child 244 05f6e0d7710c
Adding support for allowing connections only between an input and an output connector
Viewer.py
graphics/FBD_Objects.py
graphics/GraphicCommons.py
graphics/LD_Objects.py
graphics/SFC_Objects.py
--- a/Viewer.py	Wed Aug 27 16:55:16 2008 +0200
+++ b/Viewer.py	Wed Aug 27 16:56:25 2008 +0200
@@ -848,9 +848,9 @@
                 return element
         return None
     
-    def FindBlockConnector(self, pos, exclude = True):
+    def FindBlockConnector(self, pos, direction = None, exclude = True):
         for block in self.Blocks:
-            result = block.TestConnector(pos, exclude)
+            result = block.TestConnector(pos, direction, exclude)
             if result:
                 return result
         return None
@@ -1116,6 +1116,8 @@
                 if self.DrawingWire:
                     self.DrawingWire = False
                     if self.SelectedElement is not None:
+                        if element is None or element.TestHandle(pos) == (0, 0):
+                            connector = self.FindBlockConnector(pos, self.SelectedElement.GetConnectionDirection())
                         if connector:
                             event.Dragging = lambda : True
                             self.SelectedElement.OnMotion(event, self.GetLogicalDC(), self.Scaling)
@@ -1211,7 +1213,7 @@
             dc = self.GetLogicalDC()
             if self.DrawingWire:
                 pos = event.GetLogicalPosition(dc)
-                connector = self.FindBlockConnector(pos)
+                connector = self.FindBlockConnector(pos, self.SelectedElement.GetConnectionDirection())
                 if self.SelectedElement.EndConnected is not None:
                     self.DrawingWire = False
                     self.SelectedElement.StartConnected.HighlightParentBlock(False)
@@ -1287,7 +1289,7 @@
             self.rubberBand.OnMotion(event, dc, self.Scaling)
         elif self.Mode == MODE_SELECTION and self.SelectedElement:
             if self.DrawingWire:
-                connector = self.FindBlockConnector(pos, False)
+                connector = self.FindBlockConnector(pos, self.SelectedElement.GetConnectionDirection(), False)
                 if not connector or self.SelectedElement.EndConnected == None:
                     self.SelectedElement.ResetPoints()
                     movex, movey = self.SelectedElement.OnMotion(event, dc, self.Scaling)
--- a/graphics/FBD_Objects.py	Wed Aug 27 16:55:16 2008 +0200
+++ b/graphics/FBD_Objects.py	Wed Aug 27 16:56:25 2008 +0200
@@ -198,14 +198,14 @@
         return {"inputs" : self.Inputs, "outputs" : self.Outputs}
     
     # Test if point given is on one of the block connectors
-    def TestConnector(self, pt, exclude = True):
+    def TestConnector(self, pt, direction = None, exclude = True):
         # Test each input connector
         for input in self.Inputs:
-            if input.TestPoint(pt, exclude):
+            if input.TestPoint(pt, direction, exclude):
                 return input
         # Test each output connector
         for output in self.Outputs:
-            if output.TestPoint(pt, exclude):
+            if output.TestPoint(pt, direction, exclude):
                 return output
         return None
     
@@ -335,7 +335,7 @@
     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)
+        connector = self.TestConnector(pos, exclude=False)
         if connector:
             self.Handle = (HANDLE_CONNECTOR, connector)
             self.Parent.PopupBlockMenu(connector)
@@ -506,10 +506,10 @@
             self.Output.MoveConnected(exclude)
         
     # Test if point given is on the variable connector
-    def TestConnector(self, pt, exclude=True):
-        if self.Input and self.Input.TestPoint(pt, exclude):
+    def TestConnector(self, pt, direction = None, exclude=True):
+        if self.Input and self.Input.TestPoint(pt, direction, exclude):
             return self.Input
-        if self.Output and self.Output.TestPoint(pt, exclude):
+        if self.Output and self.Output.TestPoint(pt, direction, exclude):
             return self.Output
         return None
     
@@ -734,8 +734,8 @@
             self.Connector.MoveConnected(exclude)
     
     # Test if point given is on the connection connector
-    def TestConnector(self, pt, exclude=True):
-        if self.Connector and self.Connector.TestPoint(pt, exclude):
+    def TestConnector(self, pt, direction = None, exclude=True):
+        if self.Connector and self.Connector.TestPoint(pt, direction, exclude):
             return self.Connector
         return None
     
--- a/graphics/GraphicCommons.py	Wed Aug 27 16:55:16 2008 +0200
+++ b/graphics/GraphicCommons.py	Wed Aug 27 16:56:25 2008 +0200
@@ -1103,16 +1103,17 @@
             self.Negated = False
     
     # Tests if the point given is near from the end point of this connector
-    def TestPoint(self, pt, exclude = True):
+    def TestPoint(self, pt, direction = None, exclude = True):
         parent_pos = self.ParentBlock.GetPosition()
         if not (len(self.Wires) > 0 and self.OneConnected and exclude):
-            # Calculate a square around the end point of this connector
-            x = parent_pos[0] + self.Pos.x + self.Direction[0] * CONNECTOR_SIZE - ANCHOR_DISTANCE
-            y = parent_pos[1] + self.Pos.y + self.Direction[1] * CONNECTOR_SIZE - ANCHOR_DISTANCE
-            width = ANCHOR_DISTANCE * 2 + abs(self.Direction[0]) * CONNECTOR_SIZE
-            height = ANCHOR_DISTANCE * 2 + abs(self.Direction[1]) * CONNECTOR_SIZE
-            rect = wx.Rect(x, y, width, height)
-            return rect.InsideXY(pt.x, pt.y)
+            if direction is None or self.Direction == direction:
+                # Calculate a square around the end point of this connector
+                x = parent_pos[0] + self.Pos.x + self.Direction[0] * CONNECTOR_SIZE - ANCHOR_DISTANCE
+                y = parent_pos[1] + self.Pos.y + self.Direction[1] * CONNECTOR_SIZE - ANCHOR_DISTANCE
+                width = ANCHOR_DISTANCE * 2 + abs(self.Direction[0]) * CONNECTOR_SIZE
+                height = ANCHOR_DISTANCE * 2 + abs(self.Direction[1]) * CONNECTOR_SIZE
+                rect = wx.Rect(x, y, width, height)
+                return rect.InsideXY(pt.x, pt.y)
         return False
     
     # Draws the highlightment of this element if it is highlighted
@@ -1277,6 +1278,23 @@
             return computed_type
         return None
     
+    def GetConnectionDirection(self):
+        if self.StartConnected is None and self.EndConnected is None:
+            return None
+        elif self.StartConnected is not None and self.EndConnected is None:
+            return (-self.StartPoint[1][0], -self.StartPoint[1][1])
+        elif self.StartConnected is None and self.EndConnected is not None:
+            return self.EndPoint
+        elif self.Handle is not None:
+            handle_type, handle = self.Handle
+            # A point has been handled
+            if handle_type == HANDLE_POINT:
+                if handle == 0:
+                    return self.EndPoint
+                else:
+                    return (-self.StartPoint[1][0], -self.StartPoint[1][1])
+        return None
+    
     def GetOtherConnected(self, connector):
         if self.StartConnected == connector:
             return self.EndConnected
@@ -1998,7 +2016,7 @@
                 movey = round(float(self.Points[handle].y + movey) / float(scaling[1])) * scaling[1] - self.Points[handle].y
             # Try to connect point to a connector
             new_pos = wx.Point(self.Points[handle].x + movex, self.Points[handle].y + movey)
-            connector = self.Parent.FindBlockConnector(new_pos)
+            connector = self.Parent.FindBlockConnector(new_pos, self.GetConnectionDirection())
             if connector:
                 if handle == 0 and self.EndConnected != connector and connector.IsCompatible(self.GetEndConnectedType()):
                     connector.HighlightParentBlock(True)
--- a/graphics/LD_Objects.py	Wed Aug 27 16:55:16 2008 +0200
+++ b/graphics/LD_Objects.py	Wed Aug 27 16:56:25 2008 +0200
@@ -88,7 +88,7 @@
     # Forbids to select a power rail
     def HitTest(self, pt):
         if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
-            return Graphic_Element.HitTest(self, pt) or self.TestConnector(pt, False) != None
+            return Graphic_Element.HitTest(self, pt) or self.TestConnector(pt, exclude=False) != None
         return False
     
     # Forbids to select a power rail
@@ -241,9 +241,9 @@
         return [connector for connector in self.Connectors if connector]
     
     # Test if point given is on one of the power rail connectors
-    def TestConnector(self, pt, exclude=True):
+    def TestConnector(self, pt, direction = None, exclude = True):
         for connector in self.Connectors:
-            if connector and connector.TestPoint(pt, exclude):
+            if connector and connector.TestPoint(pt, direction, exclude):
                 return connector
         return None
     
@@ -281,7 +281,7 @@
     def OnRightDown(self, event, dc, scaling):
         pos = GetScaledEventPosition(event, dc, scaling)
         # Test if a connector have been handled
-        connector = self.TestConnector(pos, False)
+        connector = self.TestConnector(pos, exclude=False)
         if connector:
             self.Handle = (HANDLE_CONNECTOR, connector)
             self.Parent.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
@@ -495,12 +495,12 @@
         return {"input":self.Input,"output":self.Output}
     
     # Test if point given is on contact input or output connector
-    def TestConnector(self, pt, exclude=True):
+    def TestConnector(self, pt, direction = None, exclude=True):
         # Test input connector
-        if self.Input.TestPoint(pt, exclude):
+        if self.Input.TestPoint(pt, direction, exclude):
             return self.Input
         # Test output connector
-        if self.Output.TestPoint(pt, exclude):
+        if self.Output.TestPoint(pt, direction, exclude):
             return self.Output
         return None
 
@@ -747,12 +747,12 @@
         return {"input":self.Input,"output":self.Output}
     
     # Test if point given is on coil input or output connector
-    def TestConnector(self, pt, exclude=True):
+    def TestConnector(self, pt, direction = None, exclude=True):
         # Test input connector
-        if self.Input.TestPoint(pt, exclude):
+        if self.Input.TestPoint(pt, direction, exclude):
             return self.Input
         # Test output connector
-        if self.Output.TestPoint(pt, exclude):
+        if self.Output.TestPoint(pt, direction, exclude):
             return self.Output
         return None
     
--- a/graphics/SFC_Objects.py	Wed Aug 27 16:55:16 2008 +0200
+++ b/graphics/SFC_Objects.py	Wed Aug 27 16:56:25 2008 +0200
@@ -234,15 +234,15 @@
         return {"input":self.Input,"output":self.Output,"action":self.Action}
     
     # Test if point given is on step input or output connector
-    def TestConnector(self, pt, exclude=True):
+    def TestConnector(self, pt, direction = None, exclude=True):
         # Test input connector if it exists
-        if self.Input and self.Input.TestPoint(pt, exclude):
+        if self.Input and self.Input.TestPoint(pt, direction, exclude):
             return self.Input
         # Test output connector
-        if self.Output and self.Output.TestPoint(pt, exclude):
+        if self.Output and self.Output.TestPoint(pt, direction, exclude):
             return self.Output
         # Test action connector
-        if self.Action and self.Action.TestPoint(pt, exclude):
+        if self.Action and self.Action.TestPoint(pt, direction, exclude):
             return self.Action
         return None
 
@@ -676,15 +676,15 @@
         return connectors
     
     # Test if point given is on transition input or output connector
-    def TestConnector(self, pt, exclude=True):
+    def TestConnector(self, pt, direction = None, exclude=True):
         # Test input connector
-        if self.Input.TestPoint(pt, exclude):
+        if self.Input.TestPoint(pt, direction, exclude):
             return self.Input
         # Test output connector
-        if self.Output.TestPoint(pt, exclude):
+        if self.Output.TestPoint(pt, direction, exclude):
             return self.Output
         # Test condition connector
-        if self.Type == "connection" and self.Condition.TestPoint(pt, exclude):
+        if self.Type == "connection" and self.Condition.TestPoint(pt, direction, exclude):
             return self.Condition
         return None
 
@@ -1015,7 +1015,7 @@
     # Returns if the point given is in the bounding box
     def HitTest(self, pt):
         rect = self.BoundingBox
-        return rect.InsideXY(pt.x, pt.y) or self.TestConnector(pt, False) != None
+        return rect.InsideXY(pt.x, pt.y) or self.TestConnector(pt, exclude=False) != None
     
     # Refresh the divergence bounding box
     def RefreshBoundingBox(self):
@@ -1089,14 +1089,14 @@
         return {"inputs":self.Inputs,"outputs":self.Outputs}
     
     # Test if point given is on divergence input or output connector
-    def TestConnector(self, pt, exclude=True):
+    def TestConnector(self, pt, direction = None, exclude=True):
         # Test input connector
         for input in self.Inputs:
-            if input.TestPoint(pt, exclude):
+            if input.TestPoint(pt, direction, exclude):
                 return input
         # Test output connector
         for output in self.Outputs:
-            if output.TestPoint(pt, exclude):
+            if output.TestPoint(pt, direction, exclude):
                 return output
         return None
     
@@ -1209,7 +1209,7 @@
     def OnRightDown(self, event, dc, scaling):
         pos = GetScaledEventPosition(event, dc, scaling)
         # Test if a connector have been handled
-        connector = self.TestConnector(pos, False)
+        connector = self.TestConnector(pos, exclude=False)
         if connector:
             self.Handle = (HANDLE_CONNECTOR, connector)
             self.Parent.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
@@ -1237,7 +1237,7 @@
         else:
             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)
+            connector = self.TestConnector(pos, exclude=False)
             if connector:
                 self.Handle = (HANDLE_CONNECTOR, connector)
                 self.Parent.PopupDivergenceMenu(True)
@@ -1416,9 +1416,9 @@
         return self.Input
     
     # Test if point given is on jump input connector
-    def TestConnector(self, pt, exclude = True):
+    def TestConnector(self, pt, direction = None, exclude = True):
         # Test input connector
-        if self.Input and self.Input.TestPoint(pt, exclude):
+        if self.Input and self.Input.TestPoint(pt, direction, exclude):
             return self.Input
         return None
     
@@ -1626,9 +1626,9 @@
         return self.Input
     
     # Test if point given is on action block input connector
-    def TestConnector(self, pt, exclude = True):
+    def TestConnector(self, pt, direction = None, exclude = True):
         # Test input connector
-        if self.Input.TestPoint(pt, exclude):
+        if self.Input.TestPoint(pt, direction, exclude):
             return self.Input
         return None