Adding support for scaling
authorlbessard
Tue, 17 Mar 2009 16:14:13 +0100
changeset 323 fd3a3a002bce
parent 322 bf5a968bb7e0
child 324 9f240641e3f0
Adding support for scaling
Bug with MiddleButton fixed
Viewer.py
--- a/Viewer.py	Tue Mar 17 16:00:04 2009 +0100
+++ b/Viewer.py	Tue Mar 17 16:14:13 2009 +0100
@@ -89,6 +89,8 @@
     
     def OnDropText(self, x, y, data):
         x, y = self.ParentWindow.CalcUnscrolledPosition(x, y)
+        x = int(x / self.ParentWindow.ViewScale[0])
+        y = int(y / self.ParentWindow.ViewScale[1])
         scaling = self.ParentWindow.Scaling
         message = None
         try:
@@ -348,6 +350,7 @@
         self.DrawGrid = True
         self.GridBrush = wx.TRANSPARENT_BRUSH
         self.PageSize = None
+        self.ViewScale = (1.0, 1.0)
         self.PagePen = wx.TRANSPARENT_PEN
         self.DrawingWire = False
         self.current_id = 0
@@ -403,7 +406,10 @@
         self.Bind(wx.EVT_SIZE, self.OnMoveWindow)
     
     def GetScrolledRect(self, rect):
-        rect.x, rect.y = self.CalcScrolledPosition(rect.x, rect.y)
+        rect.x, rect.y = self.CalcScrolledPosition(int(rect.x * self.ViewScale[0]), 
+                                                   int(rect.y * self.ViewScale[1]))
+        rect.width = int(rect.width * self.ViewScale[0]) + 2
+        rect.height = int(rect.height * self.ViewScale[1]) + 2
         return rect
     
     def GetScaling(self):
@@ -433,6 +439,10 @@
     def __del__(self):
         self.Flush()
         self.ResetView()
+    
+    def SetScale(self, scalex, scaley):
+        self.ViewScale = (scalex, scaley)
+        self.RefreshScaling()
 
     def GetLogicalDC(self, buffered=False):
         if buffered:
@@ -444,6 +454,7 @@
             self.DoPrepareDC(dc)
         else:
             self.PrepareDC(dc)
+        dc.SetUserScale(self.ViewScale[0], self.ViewScale[1])
         return dc
 
     def GetMiniFont(self):
@@ -503,7 +514,8 @@
         if yp is not None:
             y = yp * self.GetScrollPixelsPerUnit()[1]
         width, height = self.GetClientSize()
-        screen = wx.Rect(x, y, width, height)
+        screen = wx.Rect(int(x / self.ViewScale[0]), int(y / self.ViewScale[1]),
+                         int(width / self.ViewScale[0]), int(height / self.ViewScale[1]))
         for comment in self.Comments:
             comment.TestVisible(screen)
         for wire in self.Wires:
@@ -565,7 +577,9 @@
         if scaling != (0, 0):
             self.Scaling = scaling
             if self.DrawGrid:
-                bitmap = wx.EmptyBitmap(*scaling)
+                width = max(2, int(scaling[0] * self.ViewScale[0]))
+                height = max(2, int(scaling[1] * self.ViewScale[1]))
+                bitmap = wx.EmptyBitmap(width, height)
                 dc = wx.MemoryDC(bitmap)
                 dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
                 dc.Clear()
@@ -702,12 +716,14 @@
         xstart, ystart = self.GetViewStart()
         window_size = self.GetClientSize()
         maxx, maxy = self.GetMaxSize()
-        maxx = max(maxx + WINDOW_BORDER, xstart * SCROLLBAR_UNIT + window_size[0])
-        maxy = max(maxy + WINDOW_BORDER, ystart * SCROLLBAR_UNIT + window_size[1])
+        maxx = max(maxx + WINDOW_BORDER, (xstart * SCROLLBAR_UNIT + window_size[0]) / self.ViewScale[0])
+        maxy = max(maxy + WINDOW_BORDER, (ystart * SCROLLBAR_UNIT + window_size[1]) / self.ViewScale[1])
         if self.rubberBand.IsShown():
             extent = self.rubberBand.GetCurrentExtent()
             maxx = max(maxx, extent.x + extent.width)
             maxy = max(maxy, extent.y + extent.height)
+        maxx = int(maxx * self.ViewScale[0])
+        maxy = int(maxy * self.ViewScale[1])
         self.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT, 
             round(maxx / SCROLLBAR_UNIT) + width_incr, round(maxy / SCROLLBAR_UNIT) + height_incr, 
             xstart, ystart, True)
@@ -1481,7 +1497,21 @@
         refresh = False
         dc = self.GetLogicalDC()
         pos = GetScaledEventPosition(event, dc, self.Scaling)
-        if event.LeftIsDown():
+        if 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]) * self.ViewScale[0] / SCROLLBAR_UNIT)
+                scrolly = max(0, self.StartScreenPos[1] + (new_pos[1] - self.StartMousePos[1]) * self.ViewScale[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()
+        else:
             if not event.Dragging():
                 highlighted = self.FindElement(pos) 
                 if self.HighlightedElement is not None and self.HighlightedElement != highlighted:
@@ -1506,20 +1536,6 @@
                     if movex != 0 or movey != 0:
                         self.RefreshRect(self.GetScrolledRect(self.SelectedElement.GetRedrawRect(movex, movey)), False)
             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):
@@ -2662,10 +2678,28 @@
 
     def OnMouseWheelWindow(self, event):
         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)
+            rotation = event.GetWheelRotation() / event.GetWheelDelta()
+            if event.ShiftDown():
+                x, y = self.GetViewStart()
+                xp = max(0, min(x - rotation * 3, self.GetVirtualSize()[0] / self.GetScrollPixelsPerUnit()[0]))
+                self.RefreshVisibleElements(xp = xp)
+                self.Scroll(xp, y)
+            elif event.ControlDown():
+                dc = self.GetLogicalDC()
+                pos = event.GetLogicalPosition(dc)
+                mouse_pos = event.GetPosition()
+                factor = 0.75 ** rotation
+                self.SetScale(self.ViewScale[0] * factor, self.ViewScale[1] * factor)
+                self.Scroll(round(pos.x * self.ViewScale[0] - mouse_pos.x) / SCROLLBAR_UNIT,
+                            round(pos.y * self.ViewScale[1] - mouse_pos.y) / SCROLLBAR_UNIT)
+                self.RefreshScrollBars()
+                self.RefreshVisibleElements()
+                self.Refresh()
+            else:
+                x, y = self.GetViewStart()
+                yp = max(0, min(y - rotation * 3, self.GetVirtualSize()[1] / self.GetScrollPixelsPerUnit()[1]))
+                self.RefreshVisibleElements(yp = yp)
+                self.Scroll(x, yp)
         
     def OnMoveWindow(self, event):
         if not USE_AUI:
@@ -2691,8 +2725,8 @@
             xstart, ystart = self.GetViewStart()
             window_size = self.GetClientSize()
             width, height = self.GetVirtualSize()
-            width = max(width, xstart * SCROLLBAR_UNIT + window_size[0])
-            height = max(height, ystart * SCROLLBAR_UNIT + window_size[1])
+            width = int(max(width, xstart * SCROLLBAR_UNIT + window_size[0]) / self.ViewScale[0])
+            height = int(max(height, ystart * SCROLLBAR_UNIT + window_size[1]) / self.ViewScale[1])
             dc.DrawRectangle(0, 0, width, height)
         if self.PageSize is not None and not printing:
             dc.SetPen(self.PagePen)