graphics/GraphicCommons.py
changeset 144 b67a5de5a24a
parent 140 06d28f03f6f4
child 145 4fb225afddf4
--- a/graphics/GraphicCommons.py	Fri Jan 04 17:47:58 2008 +0100
+++ b/graphics/GraphicCommons.py	Fri Jan 04 17:49:17 2008 +0100
@@ -48,6 +48,7 @@
 LD_ELEMENT_SIZE = (21, 15)              # Size (width, height) of a ladder element (contact or coil)
 LD_WIRE_SIZE = 30                       # Size of a wire between two contact
 LD_WIRECOIL_SIZE = 70                   # Size of a wire between a coil and a contact
+LD_POWERRAIL_WIDTH = 3                  # Width of a Powerrail
 LD_OFFSET = (10, 10)                    # Distance (x, y) between each comment and rung of the ladder
 LD_COMMENT_DEFAULTSIZE = (600, 40)      # Size (width, height) of a comment box
 
@@ -298,6 +299,9 @@
         self.CurrentCursor = 0
         ResetCursors()
     
+    def GetDragging(self):
+        return self.Dragging
+    
     # Make a clone of this element
     def Clone(self):
         return Graphic_Element(self.Parent, self.Id)
@@ -365,13 +369,27 @@
     def GetBoundingBox(self):
         return self.BoundingBox
     
+    # Returns the RedrawRect
+    def GetRedrawRect(self, movex = 0, movey = 0):
+        rect = wx.Rect()
+        rect.x = self.BoundingBox.x - HANDLE_SIZE - 2 - abs(movex)
+        rect.y = self.BoundingBox.y - HANDLE_SIZE - 2 - abs(movey)
+        rect.width = self.BoundingBox.width + 2 * (HANDLE_SIZE + abs(movex)) + 4
+        rect.height = self.BoundingBox.height + 2 * (HANDLE_SIZE + abs(movey)) + 4
+        return rect
+    
+    def Refresh(self, rect = None):
+        self.Parent.RefreshRect(self.Parent.GetScrolledRect(self.GetRedrawRect()))
+    
     # Change the variable that indicates if this element is selected
     def SetSelected(self, selected):
         self.Selected = selected
+        self.Refresh()
     
     # Change the variable that indicates if this element is highlighted
     def SetHighlighted(self, highlighted):
         self.Highlighted = highlighted
+        self.Refresh()
     
     # Test if the point is on a handle of this element
     def TestHandle(self, pt):
@@ -465,7 +483,8 @@
                 dragx, dragy = self.ProcessDragging(movex, movey)
                 self.oldPos.x += dragx
                 self.oldPos.y += dragy
-            return True
+                return dragx, dragy
+            return movex, movey
         # If cursor just pass over the element, changes the cursor if it is on a handle
         else:
             pos = event.GetLogicalPosition(dc)
@@ -476,7 +495,7 @@
             if cursor != self.CurrentCursor:
                 self.Parent.SetCursor(CURSORS[cursor])
                 self.CurrentCursor = cursor
-            return False
+            return 0, 0
 
     # Moves the element
     def Move(self, dx, dy, exclude = []):
@@ -536,13 +555,16 @@
     
     # Draws the highlightment of this element if it is highlighted (can be overwritten)
     def DrawHighlightment(self, dc):
-        if self.Highlighted:
-            dc.SetPen(wx.Pen(HIGHLIGHTCOLOR))
-            dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR))
-            dc.DrawRectangle(self.Pos.x - 2, self.Pos.y - 2, self.Size.width + 5, self.Size.height + 5)
+        dc.SetPen(wx.Pen(HIGHLIGHTCOLOR))
+        dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR))
+        dc.SetLogicalFunction(wx.AND)
+        dc.DrawRectangle(self.Pos.x - 2, self.Pos.y - 2, self.Size.width + 5, self.Size.height + 5)
+        dc.SetLogicalFunction(wx.COPY)
     
     # Draws the handles of this element if it is selected
     def Draw(self, dc):
+        if self.Highlighted:
+            self.DrawHighlightment(dc)
         if self.Selected:
             dc.SetPen(wx.BLACK_PEN)
             dc.SetBrush(wx.BLACK_BRUSH)
@@ -602,6 +624,16 @@
         clone.SetElements(elements)
         return clone
     
+    # Returns the RedrawRect
+    def GetRedrawRect(self, movex = 0, movey = 0):
+        rect = None
+        for element in self.Elements:
+            if rect is None:
+                rect = element.GetRedrawRect(movex, movey)
+            else:
+                rect = rect.Union(element.GetRedrawRect(movex, movey))
+        return rect
+    
     # Clean this group of elements
     def Clean(self):
         # Clean all the elements of the group
@@ -774,6 +806,21 @@
         self.Pen = wx.BLACK_PEN
         self.RefreshNameSize()
     
+    # Returns the RedrawRect
+    def GetRedrawRect(self, movex = 0, movey = 0):
+        parent_pos = self.ParentBlock.GetPosition()
+        x = min(parent_pos[0] + self.Pos.x, parent_pos[0] + self.Pos.x + self.Direction[0] * CONNECTOR_SIZE)
+        y = min(parent_pos[1] + self.Pos.y, parent_pos[1] + self.Pos.y + self.Direction[1] * CONNECTOR_SIZE)
+        if self.Direction[0] == 0:
+            width = 5
+        else:
+            width = CONNECTOR_SIZE
+        if self.Direction[1] == 0:
+            height = 5
+        else:
+            height = CONNECTOR_SIZE
+        return wx.Rect(x - abs(movex), y - abs(movey), width + 2 * abs(movex), height + 2 * abs(movey))
+    
     # Change the connector pen
     def SetPen(self, pen):
         self.Pen = pen
@@ -806,6 +853,16 @@
             return self.Wires[0][0].GetOtherConnectedType(self.Wires[0][1])
         return self.Type
     
+    # Returns the connector type
+    def GetConnectedRedrawRect(self, movex, movey):
+        rect = None
+        for wire, handle in self.Wires:
+            if rect is None:
+                rect = wire.GetRedrawRect()
+            else:
+                rect = rect.Union(wire.GetRedrawRect())
+        return rect
+    
     # Returns if connector type is compatible with type given
     def IsCompatible(self, type):
         reference = self.GetType()
@@ -947,6 +1004,7 @@
     # Highlight the parent block
     def HighlightParentBlock(self, highlight):
         self.ParentBlock.SetHighlighted(highlight)
+        self.ParentBlock.Refresh()
     
     # Returns all the blocks connected to this connector
     def GetConnectedBlocks(self):
@@ -1001,6 +1059,7 @@
     def DrawHighlightment(self, dc):
         dc.SetPen(wx.Pen(HIGHLIGHTCOLOR))
         dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR))
+        dc.SetLogicalFunction(wx.AND)
         parent_pos = self.ParentBlock.GetPosition()
         posx = parent_pos[0] + self.Pos.x
         posy = parent_pos[1] + self.Pos.y
@@ -1017,6 +1076,7 @@
             posy -= 2
             height = 5
         dc.DrawRectangle(posx, posy, width, height)
+        dc.SetLogicalFunction(wx.COPY)
     
     # Draws the connector
     def Draw(self, dc):
@@ -1092,6 +1152,15 @@
         self.StartConnected = None
         self.EndConnected = None
     
+    # Returns the RedrawRect
+    def GetRedrawRect(self, movex = 0, movey = 0):
+        rect = Graphic_Element.GetRedrawRect(self, movex, movey)
+        if self.StartConnected:
+            rect = rect.Union(self.StartConnected.GetRedrawRect(movex, movey))
+        if self.EndConnected:
+            rect = rect.Union(self.EndConnected.GetRedrawRect(movex, movey))
+        return rect
+    
     # Forbids to change the wire position
     def SetPosition(x, y):
         pass
@@ -1175,6 +1244,7 @@
             if self.EndConnected:
                 self.EndConnected.SetPen(wx.RED_PEN)
         self.SelectedSegment = segment
+        self.Refresh()
     
     # Reinitialize the wire points
     def ResetPoints(self):
@@ -1786,7 +1856,7 @@
                     if self.CurrentCursor != 5:
                         self.CurrentCursor = 5
                         wx.CallAfter(self.Parent.SetCursor, CURSORS[5])
-                return False
+                return 0, 0
             else:
                 # Test if a point has been handled
                 #result = self.TestPoint(pos)
@@ -1865,27 +1935,29 @@
     
     # Draws the highlightment of this element if it is highlighted
     def DrawHighlightment(self, dc):
-        if self.Highlighted:
-            dc.SetPen(wx.Pen(HIGHLIGHTCOLOR))
-            dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR))
-            # 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):
-                dc.DrawCircle(self.Points[0].x, self.Points[0].y, POINT_RADIUS + 2)
-            if len(self.Points) > 1 and (not self.EndConnected or self.OverEnd):
-                dc.DrawCircle(self.Points[-1].x, self.Points[-1].y, POINT_RADIUS + 2)
-            for i in xrange(len(self.Points) - 1):
-                posx = min(self.Points[i].x, self.Points[i + 1].x) - 2
-                posy = min(self.Points[i].y, self.Points[i + 1].y) - 2
-                width = abs(self.Points[i + 1].x - self.Points[i].x) + 5
-                height = abs(self.Points[i + 1].y - self.Points[i].y) + 5
-                dc.DrawRectangle(posx, posy, width, height)
-            if self.StartConnected is not None:
-                self.StartConnected.DrawHighlightment(dc)
-            if self.EndConnected is not None:
-                self.EndConnected.DrawHighlightment(dc)    
+        dc.SetPen(wx.Pen(HIGHLIGHTCOLOR))
+        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):
+            dc.DrawCircle(self.Points[0].x, self.Points[0].y, POINT_RADIUS + 2)
+        if len(self.Points) > 1 and (not self.EndConnected or self.OverEnd):
+            dc.DrawCircle(self.Points[-1].x, self.Points[-1].y, POINT_RADIUS + 2)
+        for i in xrange(len(self.Points) - 1):
+            posx = min(self.Points[i].x, self.Points[i + 1].x) - 2
+            posy = min(self.Points[i].y, self.Points[i + 1].y) - 2
+            width = abs(self.Points[i + 1].x - self.Points[i].x) + 5
+            height = abs(self.Points[i + 1].y - self.Points[i].y) + 5
+            dc.DrawRectangle(posx, posy, width, height)
+        if self.StartConnected is not None:
+            self.StartConnected.DrawHighlightment(dc)
+        if self.EndConnected is not None:
+            self.EndConnected.DrawHighlightment(dc)
+        dc.SetLogicalFunction(wx.COPY)
         
     # Draws the wire lines and points
     def Draw(self, dc):
+        Graphic_Element.Draw(self, dc)
         dc.SetPen(wx.BLACK_PEN)
         dc.SetBrush(wx.BLACK_BRUSH)
         # Draw the start and end points if they are not connected or the mouse is over them
@@ -1903,7 +1975,7 @@
                         self.Points[self.SelectedSegment + 1].x, self.Points[self.SelectedSegment + 1].y)
             if self.SelectedSegment == len(self.Segments) - 1:
                 dc.DrawPoint(self.Points[-1].x, self.Points[-1].y)
-        Graphic_Element.Draw(self, dc)
+
 
 #-------------------------------------------------------------------------------
 #                           Graphic comment element
@@ -2013,18 +2085,20 @@
     
     # Draws the highlightment of this element if it is highlighted
     def DrawHighlightment(self, dc):
-        if self.Highlighted:
-            dc.SetPen(wx.Pen(HIGHLIGHTCOLOR))
-            dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR))
-            polygon = [wx.Point(self.Pos.x - 2, self.Pos.y - 2), 
-                       wx.Point(self.Pos.x + self.Size[0] - 8, self.Pos.y - 2),
-                       wx.Point(self.Pos.x + self.Size[0] + 2, self.Pos.y + 8),
-                       wx.Point(self.Pos.x + self.Size[0] + 2, self.Pos.y + self.Size[1] + 2),
-                       wx.Point(self.Pos.x - 2, self.Pos.y + self.Size[1] + 2)]
-            dc.DrawPolygon(polygon)
+        dc.SetPen(wx.Pen(HIGHLIGHTCOLOR))
+        dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR))
+        dc.SetLogicalFunction(wx.AND)
+        polygon = [wx.Point(self.Pos.x - 2, self.Pos.y - 2), 
+                   wx.Point(self.Pos.x + self.Size[0] - 8, self.Pos.y - 2),
+                   wx.Point(self.Pos.x + self.Size[0] + 2, self.Pos.y + 8),
+                   wx.Point(self.Pos.x + self.Size[0] + 2, self.Pos.y + self.Size[1] + 2),
+                   wx.Point(self.Pos.x - 2, self.Pos.y + self.Size[1] + 2)]
+        dc.DrawPolygon(polygon)
+        dc.SetLogicalFunction(wx.COPY)
         
     # Draws the comment and its content
     def Draw(self, dc):
+        Graphic_Element.Draw(self, dc)
         dc.SetPen(wx.BLACK_PEN)
         dc.SetBrush(wx.WHITE_BRUSH)
         # Draws the comment shape
@@ -2069,4 +2143,3 @@
                     y += wordheight + 5
             if y + wordheight > self.Pos.y + self.Size[1] - 10:
                 break
-        Graphic_Element.Draw(self, dc)