Fix bug with two or more wires connected to one input. Now only one wire can be connected to one input, except BOOLean signals in LD and SFC. If user trying to connect wire with already connected input, wire highlight will become red.
authorSergey Surkov <surkovsv93@gmail.com>
Tue, 18 Oct 2016 17:44:08 +0300
changeset 1544 2969c2123105
parent 1543 61f0f31ef296
child 1545 d329cc88d307
Fix bug with two or more wires connected to one input. Now only one wire can be connected to one input, except BOOLean signals in LD and SFC. If user trying to connect wire with already connected input, wire highlight will become red.
Signed-off-by: Andrey Skvortsov <andrej.skvortzov@gmail.com>
editors/Viewer.py
graphics/GraphicCommons.py
--- a/editors/Viewer.py	Fri Oct 14 18:04:22 2016 +0300
+++ b/editors/Viewer.py	Tue Oct 18 17:44:08 2016 +0300
@@ -1462,12 +1462,20 @@
         return None
 
     def FindBlockConnector(self, pos, direction = None, exclude = None):
+        result, error = self.FindBlockConnectorWithError(pos, direction, exclude)
+        return result
+
+    def FindBlockConnectorWithError(self, pos, direction = None, exclude = None):
+        error = False        
         for block in self.Blocks.itervalues():
-            result = block.TestConnector(pos, direction, exclude)
-            if result:
-                return result
-        return None
-
+            connector = block.TestConnector(pos, direction, exclude)
+            if connector:
+                avail, error = connector.ConnectionAvailable(direction, exclude)
+                if not avail:
+                    connector = None
+                return connector, error
+        return None, error
+    
     def FindElementById(self, id):
         block = self.Blocks.get(id, None)
         if block is not None:
@@ -2273,7 +2281,8 @@
                 self.rubberBand.OnMotion(event, dc, self.Scaling)
             elif not self.Debug and self.Mode == MODE_SELECTION and self.SelectedElement is not None:
                 if self.DrawingWire:
-                    connector = self.FindBlockConnector(pos, self.SelectedElement.GetConnectionDirection(), self.SelectedElement.EndConnected)
+                    connector, errorHighlight = self.FindBlockConnectorWithError(pos, self.SelectedElement.GetConnectionDirection(), self.SelectedElement.EndConnected)
+                    self.SelectedElement.ErrHighlight = errorHighlight;
                     if not connector or self.SelectedElement.EndConnected == None:
                         self.SelectedElement.ResetPoints()
                         movex, movey = self.SelectedElement.OnMotion(event, dc, self.Scaling)
--- a/graphics/GraphicCommons.py	Fri Oct 14 18:04:22 2016 +0300
+++ b/graphics/GraphicCommons.py	Tue Oct 18 17:44:08 2016 +0300
@@ -1351,19 +1351,35 @@
             self.Edge = edge    
             self.Negated = False
     
+    # assume that pointer is already inside of this connector
+    def ConnectionAvailable(self, direction=None, exclude=True):
+        wire_nums = len(self.Wires)
+        
+        connector_free = (wire_nums<= 0)
+        connector_max_used = ((wire_nums > 0) and self.OneConnected)
+        if (self.Parent.CurrentLanguage in ["SFC", "LD"]) and (self.Type == "BOOL"):
+            connector_max_used = False;
+
+        # connector is available for new connection
+        connect  = connector_free or not connector_max_used
+        return connect, connector_max_used
+                           
     # Tests if the point given is near from the end point of this connector
-    def TestPoint(self, pt, direction = None, exclude = True):
-        parent_pos = self.ParentBlock.GetPosition()
-        if (not (len(self.Wires) > 0 and self.OneConnected and exclude) or self.Type == "BOOL")\
-            and direction is None or self.Direction == direction:
+    def TestPoint(self, pt, direction=None, exclude=True):
+        inside = False;
+        check_point = (not exclude) and (direction is None or self.Direction == direction);
+
+        if check_point:
             # Calculate a square around the end point of this connector
+            parent_pos = self.ParentBlock.GetPosition()
             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
+            inside = rect.InsideXY(pt.x, pt.y);
+                           
+        return inside
     
     # Draws the highlightment of this element if it is highlighted
     def DrawHighlightment(self, dc):
@@ -1551,6 +1567,7 @@
         self.OverEnd = False
         self.ComputingType = False
         self.Font = parent.GetMiniFont()
+        self.ErrHighlight = False
     
     def GetDefinition(self):
         if self.StartConnected is not None and self.EndConnected is not None:
@@ -2590,8 +2607,13 @@
     def DrawHighlightment(self, dc):
         scalex, scaley = dc.GetUserScale()
         dc.SetUserScale(1, 1)
-        dc.SetPen(MiterPen(HIGHLIGHTCOLOR, (2 * scalex + 5)))
-        dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR))
+        # If user trying to connect wire with wrong input, highlight will become red.
+        if self.ErrHighlight == True and not (self.EndConnected):
+            highlightcolor = wx.RED
+        else:
+            highlightcolor = HIGHLIGHTCOLOR
+        dc.SetPen(MiterPen(highlightcolor, (2 * scalex + 5)))
+        dc.SetBrush(wx.Brush(highlightcolor))
         dc.SetLogicalFunction(wx.AND)
         # Draw the start and end points if they are not connected or the mouse is over them
         if len(self.Points) > 0 and (not self.StartConnected or self.OverStart):