graphics/GraphicCommons.py
changeset 27 dae55dd9ee14
parent 5 f8652b073e84
child 28 fc23e1f415d8
--- a/graphics/GraphicCommons.py	Sat Jul 07 11:35:17 2007 +0200
+++ b/graphics/GraphicCommons.py	Mon Jul 09 11:10:14 2007 +0200
@@ -55,7 +55,7 @@
 # SFC constants
 SFC_STEP_DEFAULT_SIZE = (40, 30)      # Default size of a SFC step
 SFC_TRANSITION_SIZE = (20, 2)         # Size of a SFC transition
-SFC_DEFAULT_SEQUENCE_INTERVAL = 80    # Default size of the interval between two divergence branches
+SFC_DEFAULT_SEQUENCE_INTERVAL = 40    # Default size of the interval between two divergence branches
 SFC_SIMULTANEOUS_SEQUENCE_EXTRA = 20  # Size of extra lines for simultaneous divergence and convergence
 SFC_JUMP_SIZE = (12, 13)              # Size of a SFC jump to step
 SFC_WIRE_MIN_SIZE = 25                # Size of a wire between two elements
@@ -80,7 +80,12 @@
 
 # Contants for defining which mode is selected for each view 
 [MODE_SELECTION, MODE_BLOCK, MODE_VARIABLE, MODE_CONNECTION, MODE_COMMENT, MODE_WIRE,
- MODE_INITIAL_STEP] = range(7)
+ MODE_COIL, MODE_CONTACT, MODE_POWERRAIL, MODE_INITIALSTEP, MODE_STEP, MODE_TRANSITION,
+ MODE_DIVERGENCE, MODE_JUMP, MODE_ACTION] = range(15)
+
+# Contants for defining which drawing mode is selected for app
+[FREEDRAWING_MODE, DRIVENDRAWING_MODE] = [1, 2]
+
 
 """
 Basic vector operations for calculate wire points
@@ -115,8 +120,8 @@
 Function that calculates the nearest point of the grid defined by scaling for the given point
 """
 
-def GetScaledEventPosition(event, scaling):
-    pos = event.GetPosition()
+def GetScaledEventPosition(event, dc, scaling):
+    pos = event.GetLogicalPosition(dc)
     if scaling:
         pos.x = round(float(pos.x) / float(scaling[0])) * scaling[0]
         pos.y = round(float(pos.y) / float(scaling[1])) * scaling[1]
@@ -166,8 +171,8 @@
         return self.currentBox
     
     # Method called when a new box starts to be edited
-    def OnLeftDown(self, event, scaling):
-        pos = GetScaledEventPosition(event, scaling)
+    def OnLeftDown(self, event, dc, scaling):
+        pos = GetScaledEventPosition(event, dc, scaling)
         # Save the point for calculate the box position and size
         self.startPoint = pos
         self.currentBox = wxRect(pos.x, pos.y, 0, 0)
@@ -175,8 +180,8 @@
         self.Redraw()
     
     # Method called when dragging with a box edited
-    def OnMotion(self, event, scaling):
-        pos = GetScaledEventPosition(event, scaling)
+    def OnMotion(self, event, dc, scaling):
+        pos = GetScaledEventPosition(event, dc, scaling)
         # Save the last position and size of the box for erasing it
         self.lastBox = wxRect(self.currentBox.x, self.currentBox.y, self.currentBox.width,
             self.currentBox.height)
@@ -196,7 +201,7 @@
         self.Redraw()
     
     # Method called when dragging is stopped
-    def OnLeftUp(self, event, scaling):
+    def OnLeftUp(self, event, dc, scaling):
         self.drawingSurface.SetCursor(wxNullCursor)
         self.lastBox = self.currentBox
         self.currentBox = None
@@ -204,7 +209,7 @@
 
     # Method that erase the last box and draw the new box
     def Redraw(self):
-        dc = wxClientDC(self.drawingSurface)
+        dc = self.drawingSurface.GetLogicalDC()
         dc.SetPen(wxPen(wxWHITE, 1, wxDOT))
         dc.SetBrush(wxTRANSPARENT_BRUSH)
         dc.SetLogicalFunction(wxXOR)
@@ -217,6 +222,27 @@
             dc.DrawRectangle(self.currentBox.x, self.currentBox.y, self.currentBox.width,
                 self.currentBox.height)
 
+    # Erase last box
+    def Erase(self):
+        dc = self.drawingSurface.GetLogicalDC()
+        dc.SetPen(wxPen(wxWHITE, 1, wxDOT))
+        dc.SetBrush(wxTRANSPARENT_BRUSH)
+        dc.SetLogicalFunction(wxXOR)
+        if self.lastBox:
+            dc.DrawRectangle(self.lastBox.x, self.lastBox.y, self.lastBox.width,
+                self.lastBox.height)
+        
+    # Draw current box
+    def Draw(self):
+        dc = self.drawingSurface.GetLogicalDC()
+        dc.SetPen(wxPen(wxWHITE, 1, wxDOT))
+        dc.SetBrush(wxTRANSPARENT_BRUSH)
+        dc.SetLogicalFunction(wxXOR)
+        if self.currentBox:
+            # Draw current box
+            dc.DrawRectangle(self.currentBox.x, self.currentBox.y, self.currentBox.width,
+                self.currentBox.height)
+
 
 #-------------------------------------------------------------------------------
 #                           Graphic element base class
@@ -335,8 +361,8 @@
         return 0, 0
     
     # Method called when a LeftDown event have been generated
-    def OnLeftDown(self, event, scaling):
-        pos = event.GetPosition()
+    def OnLeftDown(self, event, dc, scaling):
+        pos = event.GetLogicalPosition(dc)
         # Test if an handle have been clicked
         result = self.TestHandle(pos)
         # Find which type of handle have been clicked,
@@ -359,14 +385,14 @@
             self.Parent.SetCursor(wxStockCursor(wxCURSOR_HAND))
             self.SetSelected(False)
         # Initializes the last position
-        self.oldPos = GetScaledEventPosition(event, scaling)
+        self.oldPos = GetScaledEventPosition(event, dc, scaling)
     
     # Method called when a LeftUp event have been generated
-    def OnLeftUp(self, event, scaling):
+    def OnLeftUp(self, event, dc, scaling):
         # If a dragging have been initiated
         if self.Dragging and self.oldPos:
             # Calculate the movement of cursor and refreshes the element state
-            pos = GetScaledEventPosition(event, scaling)
+            pos = GetScaledEventPosition(event, dc, scaling)
             movex = pos.x - self.oldPos.x
             movey = pos.y - self.oldPos.y
             self.ProcessDragging(movex, movey)
@@ -375,20 +401,20 @@
         self.oldPos = None
 
     # Method called when a RightUp event have been generated
-    def OnRightUp(self, event, scaling):
+    def OnRightUp(self, event, dc, scaling):
         self.SetSelected(True)
         self.oldPos = None
 
     # Method called when a LeftDClick event have been generated
-    def OnLeftDClick(self, event, scaling):
+    def OnLeftDClick(self, event, dc, scaling):
         pass
     
     # Method called when a Motion event have been generated
-    def OnMotion(self, event, scaling):
+    def OnMotion(self, event, dc, scaling):
         # If the cursor is dragging and the element have been clicked
         if event.Dragging() and self.oldPos:
             # Calculate the movement of cursor
-            pos = GetScaledEventPosition(event, scaling)
+            pos = GetScaledEventPosition(event, dc, scaling)
             movex = pos.x - self.oldPos.x
             movey = pos.y - self.oldPos.y
             # If movement is greater than MIN_MOVE then a dragging is initiated
@@ -400,7 +426,7 @@
                 self.ProcessDragging(movex, movey)
         # If cursor just pass over the element, changes the cursor if it is on a handle
         else:
-            pos = event.GetPosition()
+            pos = event.GetLogicalPosition(dc)
             handle = self.TestHandle(pos)
             if handle == (1, 1) or handle == (3, 3):
                 wxCallAfter(self.Parent.SetCursor, wxStockCursor(wxCURSOR_SIZENWSE))
@@ -614,7 +640,7 @@
 class Connector:
     
     # Create a new connector
-    def __init__(self, parent, name, type, position, direction, negated = False, edge = "none"):
+    def __init__(self, parent, name, type, position, direction, negated = False, edge = "none", onlyone = False):
         self.ParentBlock = parent
         self.Name = name
         self.Type = type
@@ -623,6 +649,7 @@
         self.Wires = []
         self.Negated = negated
         self.Edge = edge
+        self.OneConnected = onlyone
         self.Pen = wxBLACK_PEN
     
     # Change the connector pen
@@ -758,6 +785,22 @@
     def RefreshParentBlock(self):
         self.ParentBlock.RefreshModel(False)
     
+    # Returns all the blocks connected to this connector
+    def GetConnectedBlocks(self):
+        blocks = []
+        for wire, handle in self.Wires:
+            # Get other connector connected to each wire
+            if handle == 0:
+                connector = blocks.GetEndConnected()
+            else:
+                connector = blocks.GetStartConnected()
+            # Get parent block for this connector
+            if connector:
+                block = connector.GetParentBlock()
+                if block not in blocks:
+                    blocks.append(block)
+        return blocks
+    
     # Returns the connector negated property
     def IsNegated(self):
         return self.Negated
@@ -779,7 +822,7 @@
     # Tests if the point given is near from the end point of this connector
     def TestPoint(self, pt, exclude = True):
         parent_pos = self.ParentBlock.GetPosition()
-        if not (len(self.Wires) > 0 and self.Direction == WEST and exclude):
+        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
@@ -872,6 +915,14 @@
     def SetSize(width, height):
         pass
     
+    # Returns connector to which start point is connected
+    def GetStartConnected(self):
+        return self.StartConnected
+    
+    # Returns connector to which end point is connected
+    def GetEndConnected(self):
+        return self.EndConnected
+    
     # Unconnect the start and end points
     def Clean(self):
         if self.StartConnected:
@@ -1084,11 +1135,11 @@
         return connected
     
     # Returns the id of the block connected to the first or the last wire point
-    def GetConnectedId(self, index):
+    def GetConnectedInfos(self, index):
         if index == 0 and self.StartConnected:
-            return self.StartConnected.GetBlockId()
+            return self.StartConnected.GetBlockId(), self.StartConnected.GetName()
         elif index == -1 and self.EndConnected:
-            return self.EndConnected.GetBlockId()
+            return self.EndConnected.GetBlockId(), self.StartConnected.GetName()
         return None
     
     # Update the wire points position by keeping at most possible the current positions
@@ -1423,8 +1474,8 @@
             self.RefreshModel()
             
     # 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 point have been handled
         #result = self.TestPoint(pos)
         #if result != None:
@@ -1441,12 +1492,12 @@
             self.Handle = (HANDLE_SEGMENT, result)
         # Execute the default method for a graphic element
         else:
-            Graphic_Element.OnLeftDown(self, event, scaling)
+            Graphic_Element.OnLeftDown(self, event, dc, scaling)
         self.oldPos = pos
     
     # 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)
         # Test if a segment has been handled
         result = self.TestSegment(pos)
         if result != None:
@@ -1455,16 +1506,16 @@
             self.Parent.PopupWireMenu()
         else:
             # Execute the default method for a graphic element
-            Graphic_Element.OnRightUp(self, event, scaling)
+            Graphic_Element.OnRightUp(self, event, dc, scaling)
     
     # Method called when a LeftDClick event have been generated
-    def OnLeftDClick(self, event, scaling):
+    def OnLeftDClick(self, event, dc, scaling):
         self.ResetPoints()
         self.GeneratePoints()
         
     # Method called when a Motion event have been generated
-    def OnMotion(self, event, scaling):
-        pos = GetScaledEventPosition(event, scaling)
+    def OnMotion(self, event, dc, scaling):
+        pos = GetScaledEventPosition(event, dc, scaling)
         if not event.Dragging():
             # Test if a segment has been handled
             result = self.TestSegment(pos)
@@ -1485,10 +1536,10 @@
                 #    self.OverStart = False
                 #    self.OverEnd = False
                 # Execute the default method for a graphic element
-                Graphic_Element.OnMotion(self, event, scaling)
+                Graphic_Element.OnMotion(self, event, dc, scaling)
         else:
             # Execute the default method for a graphic element
-            Graphic_Element.OnMotion(self, event, scaling)
+            Graphic_Element.OnMotion(self, event, dc, scaling)
     
     # Refreshes the wire state according to move defined and handle selected
     def ProcessDragging(self, movex, movey):
@@ -1648,7 +1699,7 @@
         self.SetSize(width, height)
     
     # 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()
     
@@ -1657,7 +1708,7 @@
         self.Parent.RefreshCommentModel(self)
     
     # Method called when a LeftDClick event have been generated
-    def OnLeftDClick(self, event, scaling):
+    def OnLeftDClick(self, event, dc, scaling):
         # Edit the comment content
         self.Parent.EditCommentContent(self)