graphics/GraphicCommons.py
changeset 633 3536f4469cde
parent 628 edcd40605fff
child 634 cc3335911c01
--- a/graphics/GraphicCommons.py	Wed Jan 25 01:26:29 2012 +0100
+++ b/graphics/GraphicCommons.py	Mon Jan 30 16:12:19 2012 +0100
@@ -454,7 +454,7 @@
 
     # Method that erase the last box and draw the new box
     def Redraw(self, dc = None):
-        if not dc:
+        if dc is None:
             dc = self.Viewer.GetLogicalDC()
         scalex, scaley = dc.GetUserScale()
         dc.SetUserScale(1, 1)
@@ -473,7 +473,7 @@
     
     # Erase last box
     def Erase(self, dc = None):
-        if not dc:
+        if dc is None:
             dc = self.Viewer.GetLogicalDC()
         scalex, scaley = dc.GetUserScale()
         dc.SetUserScale(1, 1)
@@ -487,7 +487,7 @@
 
     # Draw current box
     def Draw(self, dc = None):
-        if not dc:
+        if dc is None:
             dc = self.Viewer.GetLogicalDC()
         scalex, scaley = dc.GetUserScale()
         dc.SetUserScale(1, 1)
@@ -523,6 +523,9 @@
               'size' : 12,
              }
 
+TOOLTIP_MAX_CHARACTERS = 30
+TOOLTIP_MAX_LINE = 5
+
 class ToolTip(wx.PopupWindow):
     
     def __init__(self, parent, tip):
@@ -536,7 +539,28 @@
         self.Bind(wx.EVT_PAINT, self.OnPaint)
         
     def SetTip(self, tip):
-        self.Tip = tip
+        lines = []
+        for line in tip.splitlines():
+            if line != "":
+                words = line.split()
+                new_line = words[0]
+                for word in words[1:]:
+                    if len(new_line + " " + word) <= TOOLTIP_MAX_CHARACTERS:
+                        new_line += " " + word
+                    else:
+                        lines.append(new_line)
+                        new_line = word
+                lines.append(new_line)
+            else:
+                lines.append(line)
+        if len(lines) > TOOLTIP_MAX_LINE:
+            self.Tip = lines[:TOOLTIP_MAX_LINE]
+            if len(self.Tip[-1]) < TOOLTIP_MAX_CHARACTERS - 3:
+                self.Tip[-1] += "..."
+            else:
+                self.Tip[-1] = self.Tip[-1][:TOOLTIP_MAX_CHARACTERS - 3] + "..."
+        else:
+            self.Tip = lines
         wx.CallAfter(self.RefreshTip)
     
     def MoveToolTip(self, pos):
@@ -546,7 +570,7 @@
     def GetTipExtent(self):
         max_width = 0
         max_height = 0
-        for line in self.Tip.splitlines():
+        for line in self.Tip:
             w, h = self.GetTextExtent(line)
             max_width = max(max_width, w)
             max_height += h
@@ -569,7 +593,7 @@
         w, h = self.GetTipExtent()
         dc.DrawRectangle(0, 0, w + 4, h + 4)
         offset = 0
-        for line in self.Tip.splitlines():
+        for line in self.Tip:
             dc.DrawText(line, 2, offset + 2)
             w, h = dc.GetTextExtent(line)
             offset += h
@@ -640,7 +664,7 @@
         self.Parent.Bind(wx.EVT_TIMER, self.OnToolTipTimer, self.ToolTipTimer)
     
     def __del__(self):
-        self
+        self.ToolTipTimer.Stop()
     
     def GetDefinition(self):
         return [self.Id], []
@@ -733,8 +757,11 @@
         return self.Id
     
     # Returns if the point given is in the bounding box
-    def HitTest(self, pt):
-        rect = self.BoundingBox
+    def HitTest(self, pt, connectors=True):
+        if connectors:
+            rect = self.BoundingBox
+        else:
+            rect = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0], self.Size[1])
         return rect.InsideXY(pt.x, pt.y)
     
     # Returns if the point given is in the bounding box
@@ -751,8 +778,7 @@
     
     # Returns the RedrawRect
     def GetRedrawRect(self, movex = 0, movey = 0):
-        dc = self.Parent.GetLogicalDC()
-        scalex, scaley = dc.GetUserScale()
+        scalex, scaley = self.Parent.GetViewScale()
         rect = wx.Rect()
         rect.x = self.BoundingBox.x - int(HANDLE_SIZE / scalex) - 3 - abs(movex)
         rect.y = self.BoundingBox.y - int(HANDLE_SIZE / scaley) - 3 - abs(movey)
@@ -1212,10 +1238,10 @@
         self.WireExcluded = []
     
     # Returns if the point given is in the bounding box of one of the elements of this group
-    def HitTest(self, pt):
+    def HitTest(self, pt, connectors=True):
         result = False
         for element in self.Elements:
-            result |= element.HitTest(pt)
+            result |= element.HitTest(pt, connectors)
         return result
     
     # Returns if the element given is in this group
@@ -1359,7 +1385,12 @@
     def SetHighlighted(self, highlighted):
         for element in self.Elements:
             element.SetHighlighted(highlighted)
-
+    
+    def HighlightPoint(self, pos):
+        for element in self.Elements:
+            if isinstance(element, Wire):
+                element.HighlightPoint(pos)
+    
     # Method called when a LeftDown event have been generated
     def OnLeftDown(self, event, dc, scaling):
         Graphic_Element.OnLeftDown(self, event, dc, scaling)
@@ -2181,12 +2212,20 @@
         return width + 1, height + 1
     
     # Returns if the point given is on one of the wire segments
-    def HitTest(self, pt):
+    def HitTest(self, pt, connectors=True):
         test = False
         for i in xrange(len(self.Points) - 1):
             rect = wx.Rect(0, 0, 0, 0)
-            x1, y1 = self.Points[i].x, self.Points[i].y
-            x2, y2 = self.Points[i + 1].x, self.Points[i + 1].y
+            if i == 0 and self.StartConnected is not None:
+                x1 = self.Points[i].x - self.Segments[0][0] * CONNECTOR_SIZE
+                y1 = self.Points[i].y - self.Segments[0][1] * CONNECTOR_SIZE
+            else:
+                x1, y1 = self.Points[i].x, self.Points[i].y    
+            if i == len(self.Points) - 2 and self.EndConnected is not None:
+                x2 = self.Points[i + 1].x + self.Segments[-1][0] * CONNECTOR_SIZE
+                y2 = self.Points[i + 1].y + self.Segments[-1][1] * CONNECTOR_SIZE
+            else:
+                x2, y2 = self.Points[i + 1].x, self.Points[i + 1].y
             # Calculate a rectangle around the segment
             rect = wx.Rect(min(x1, x2) - ANCHOR_DISTANCE, min(y1, y2) - ANCHOR_DISTANCE,
                 abs(x1 - x2) + 2 * ANCHOR_DISTANCE, abs(y1 - y2) + 2 * ANCHOR_DISTANCE)
@@ -2784,16 +2823,6 @@
                     wx.CallAfter(self.Parent.SetCurrentCursor, 5)
                 return 0, 0
             else:
-                # Test if a point has been handled
-                #result = self.TestPoint(pos)
-                #if result != None:
-                #    if result == 0 and self.StartConnected:
-                #        self.OverStart = True
-                #    elif result != 0 and self.EndConnected:
-                #        self.OverEnd = True
-                #else:
-                #    self.OverStart = False
-                #    self.OverEnd = False
                 # Execute the default method for a graphic element
                 return Graphic_Element.OnMotion(self, event, dc, scaling)
         else:
@@ -2868,6 +2897,29 @@
         if self.EndConnected and self.EndPoint[1] in [WEST, NORTH]:
             self.EndConnected.RefreshParentBlock()
     
+    # Change the variable that indicates if this element is highlighted
+    def SetHighlighted(self, highlighted):
+        self.Highlighted = highlighted
+        if not highlighted:
+            self.OverStart = False
+            self.OverEnd = False
+        self.Refresh()
+    
+    def HighlightPoint(self, pos):
+        refresh = False
+        start, end = self.OverStart, self.OverEnd
+        self.OverStart = False
+        self.OverEnd = False
+        # Test if a point has been handled
+        result = self.TestPoint(pos)
+        if result != None:
+            if result == 0 and self.StartConnected is not None:
+                self.OverStart = True
+            elif result != 0 and self.EndConnected is not None:
+                self.OverEnd = True
+        if start != self.OverStart or end != self.OverEnd:
+            self.Refresh()
+    
     # Draws the highlightment of this element if it is highlighted
     def DrawHighlightment(self, dc):
         scalex, scaley = dc.GetUserScale()