Viewer.py
changeset 319 efe0671df286
parent 302 43e10dccc16a
child 323 fd3a3a002bce
--- a/Viewer.py	Fri Mar 13 16:23:32 2009 +0100
+++ b/Viewer.py	Fri Mar 13 16:26:19 2009 +0100
@@ -337,7 +337,7 @@
     # Create a new Viewer
     def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""):
         wx.ScrolledWindow.__init__(self, parent, pos=wx.Point(0, 0), size=wx.Size(0, 0), 
-            style=wx.HSCROLL | wx.VSCROLL)
+            style=wx.HSCROLL | wx.VSCROLL | wx.ALWAYS_SHOW_SB)
         self._init_menus()
         # Adding a rubberband to Viewer
         self.rubberBand = RubberBand(drawingSurface=self)
@@ -355,6 +355,8 @@
         self.Errors = []
         self.Debug = debug
         self.InstancePath = instancepath
+        self.StartMousePos = None
+        self.StartScreenPos = None
         
         # Initialize Block, Wire and Comment numbers
         self.block_id = self.wire_id = self.comment_id = 0
@@ -390,10 +392,13 @@
         self.Bind(wx.EVT_LEFT_DCLICK, self.OnViewerLeftDClick)
         self.Bind(wx.EVT_RIGHT_DOWN, self.OnViewerRightDown)
         self.Bind(wx.EVT_RIGHT_UP, self.OnViewerRightUp)
+        self.Bind(wx.EVT_MIDDLE_DOWN, self.OnViewerMiddleDown)
+        self.Bind(wx.EVT_MIDDLE_UP, self.OnViewerMiddleUp)
         self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveViewer)
         self.Bind(wx.EVT_MOTION, self.OnViewerMotion)
         self.Bind(wx.EVT_CHAR, self.OnChar)
         self.Bind(wx.EVT_SCROLLWIN, self.OnScrollWindow)
+        self.Bind(wx.EVT_SCROLLWIN_THUMBRELEASE, self.OnScrollStop)
         self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheelWindow)
         self.Bind(wx.EVT_SIZE, self.OnMoveWindow)
     
@@ -693,7 +698,7 @@
             maxy = max(maxy, bbox.y + bbox.height)
         return maxx, maxy
     
-    def RefreshScrollBars(self):
+    def RefreshScrollBars(self, width_incr=0, height_incr=0):
         xstart, ystart = self.GetViewStart()
         window_size = self.GetClientSize()
         maxx, maxy = self.GetMaxSize()
@@ -704,7 +709,7 @@
             maxx = max(maxx, extent.x + extent.width)
             maxy = max(maxy, extent.y + extent.height)
         self.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT, 
-            round(maxx / SCROLLBAR_UNIT), round(maxy / SCROLLBAR_UNIT), 
+            round(maxx / SCROLLBAR_UNIT) + width_incr, round(maxy / SCROLLBAR_UNIT) + height_incr, 
             xstart, ystart, True)
         
     # Load instance from given informations
@@ -1226,13 +1231,11 @@
     def OnAddBranchMenu(self, event):
         if self.SelectedElement is not None and self.IsBlock(self.SelectedElement):
             self.AddDivergenceBranch(self.SelectedElement)
-            self.RefreshBuffer()
         event.Skip()
 
     def OnDeleteBranchMenu(self, event):
         if self.SelectedElement is not None and self.IsBlock(self.SelectedElement):
             self.RemoveDivergenceBranch(self.SelectedElement)
-            self.RefreshBuffer()
         event.Skip()
 
     def OnEditBlockMenu(self, event):
@@ -1425,6 +1428,16 @@
             wx.CallAfter(self.ParentWindow.ResetCurrentMode)
         event.Skip()
     
+    def OnViewerMiddleDown(self, event):
+        self.StartMousePos = event.GetPosition()
+        self.StartScreenPos = self.GetScrollPos(wx.HORIZONTAL), self.GetScrollPos(wx.VERTICAL)
+        event.Skip()
+        
+    def OnViewerMiddleUp(self, event):
+        self.StartMousePos = None
+        self.StartScreenPos = None
+        event.Skip()
+    
     def OnViewerRightDown(self, event):
         if self.Mode == MODE_SELECTION:
             dc = self.GetLogicalDC()
@@ -1468,30 +1481,45 @@
         refresh = False
         dc = self.GetLogicalDC()
         pos = GetScaledEventPosition(event, dc, self.Scaling)
-        if not event.Dragging():
-            highlighted = self.FindElement(pos) 
-            if self.HighlightedElement is not None and self.HighlightedElement != highlighted:
-                self.HighlightedElement.SetHighlighted(False)
-                self.HighlightedElement = None
-            if highlighted is not None and self.HighlightedElement != highlighted:
-                highlighted.SetHighlighted(True)
-            self.HighlightedElement = highlighted
-        if self.rubberBand.IsShown():
-            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)
-                if not connector or self.SelectedElement.EndConnected == None:
-                    self.SelectedElement.ResetPoints()
+        if event.LeftIsDown():
+            if not event.Dragging():
+                highlighted = self.FindElement(pos) 
+                if self.HighlightedElement is not None and self.HighlightedElement != highlighted:
+                    self.HighlightedElement.SetHighlighted(False)
+                    self.HighlightedElement = None
+                if highlighted is not None and self.HighlightedElement != highlighted:
+                    highlighted.SetHighlighted(True)
+                self.HighlightedElement = highlighted
+            if self.rubberBand.IsShown():
+                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)
+                    if not connector or self.SelectedElement.EndConnected == None:
+                        self.SelectedElement.ResetPoints()
+                        movex, movey = self.SelectedElement.OnMotion(event, dc, self.Scaling)
+                        self.SelectedElement.GeneratePoints()
+                        if movex != 0 or movey != 0:
+                            self.RefreshRect(self.GetScrolledRect(self.SelectedElement.GetRedrawRect(movex, movey)), False)
+                else:
                     movex, movey = self.SelectedElement.OnMotion(event, dc, self.Scaling)
-                    self.SelectedElement.GeneratePoints()
                     if movex != 0 or movey != 0:
                         self.RefreshRect(self.GetScrolledRect(self.SelectedElement.GetRedrawRect(movex, movey)), False)
-            else:
-                movex, movey = self.SelectedElement.OnMotion(event, dc, self.Scaling)
-                if movex != 0 or movey != 0:
-                    self.RefreshRect(self.GetScrolledRect(self.SelectedElement.GetRedrawRect(movex, movey)), False)
-        self.UpdateScrollPos(event)
+            self.UpdateScrollPos(event)
+        elif event.MiddleIsDown():
+            if self.StartMousePos is not None and self.StartScreenPos is not None:
+                new_pos = event.GetPosition()
+                xmax = self.GetScrollRange(wx.HORIZONTAL) - self.GetScrollThumb(wx.HORIZONTAL)
+                ymax = self.GetScrollRange(wx.VERTICAL) - self.GetScrollThumb(wx.VERTICAL)
+                scrollx = max(0, self.StartScreenPos[0] + (new_pos[0] - self.StartMousePos[0]) / SCROLLBAR_UNIT)
+                scrolly = max(0, self.StartScreenPos[1] + (new_pos[1] - self.StartMousePos[1]) / SCROLLBAR_UNIT)
+                if scrollx > xmax or scrolly > ymax:
+                    self.RefreshScrollBars(max(0, scrollx - xmax), max(0, scrolly - ymax))
+                    self.Scroll(scrollx, scrolly)
+                else:
+                    self.Scroll(scrollx, scrolly)
+                    self.RefreshScrollBars()
+                self.RefreshVisibleElements()
         event.Skip()
 
     def OnLeaveViewer(self, event):
@@ -1547,8 +1575,11 @@
         elif keycode == wx.WXK_LEFT:
             if event.ControlDown() and event.ShiftDown():
                 self.Scroll(0, ypos)
+                self.RefreshVisibleElements()
             elif event.ControlDown():
-                event.Skip()
+                self.Scroll(xpos - 1, ypos)
+                self.RefreshScrollBars()
+                self.RefreshVisibleElements()
             elif not self.Debug and self.SelectedElement is not None:
                 self.SelectedElement.Move(-scaling[0], 0)
                 self.SelectedElement.RefreshModel()
@@ -1558,8 +1589,11 @@
         elif keycode == wx.WXK_RIGHT:
             if event.ControlDown() and event.ShiftDown():
                 self.Scroll(xmax, ypos)
+                self.RefreshVisibleElements()
             elif event.ControlDown():
-                event.Skip()
+                self.RefreshScrollBars(width_incr=max(0, xpos + 1 - xmax))
+                self.Scroll(xpos + 1, ypos)
+                self.RefreshVisibleElements()
             elif not self.Debug and self.SelectedElement is not None:
                 self.SelectedElement.Move(scaling[0], 0)
                 self.SelectedElement.RefreshModel()
@@ -1569,8 +1603,11 @@
         elif keycode == wx.WXK_UP:
             if event.ControlDown() and event.ShiftDown():
                 self.Scroll(xpos, 0)
+                self.RefreshVisibleElements()
             elif event.ControlDown():
-                event.Skip()
+                self.Scroll(xpos, ypos - 1)
+                self.RefreshScrollBars()
+                self.RefreshVisibleElements()
             elif not self.Debug and self.SelectedElement is not None:
                 self.SelectedElement.Move(0, -scaling[1])
                 self.SelectedElement.RefreshModel()
@@ -1580,8 +1617,11 @@
         elif keycode == wx.WXK_DOWN:
             if event.ControlDown() and event.ShiftDown():
                 self.Scroll(xpos, ymax)
+                self.RefreshVisibleElements()
             elif event.ControlDown():
-                event.Skip()
+                self.RefreshScrollBars(height_incr=max(0, ypos + 1 - ymax))
+                self.Scroll(xpos, ypos + 1)
+                self.RefreshVisibleElements()
             elif not self.Debug and self.SelectedElement is not None:
                 self.SelectedElement.Move(0, scaling[1])
                 self.SelectedElement.RefreshModel()
@@ -2616,11 +2656,16 @@
             self.RefreshVisibleElements(yp = event.GetPosition())
         event.Skip()
 
+    def OnScrollStop(self, event):
+        self.RefreshScrollBars()
+        event.Skip()
+
     def OnMouseWheelWindow(self, event):
-        x, y = self.GetViewStart()
-        yp = max(0, min(y - event.GetWheelRotation() / event.GetWheelDelta() * 3, self.GetVirtualSize()[1] / self.GetScrollPixelsPerUnit()[1]))
-        self.RefreshVisibleElements(yp = yp)
-        self.Scroll(x, yp)
+        if self.StartMousePos is None or self.StartScreenPos is None:
+            x, y = self.GetViewStart()
+            yp = max(0, min(y - event.GetWheelRotation() / event.GetWheelDelta() * 3, self.GetVirtualSize()[1] / self.GetScrollPixelsPerUnit()[1]))
+            self.RefreshVisibleElements(yp = yp)
+            self.Scroll(x, yp)
         
     def OnMoveWindow(self, event):
         if not USE_AUI: