Viewer.py
changeset 332 555124c752ec
parent 331 9106d66bd204
child 338 87e5015330ae
--- a/Viewer.py	Thu Mar 19 18:10:12 2009 +0100
+++ b/Viewer.py	Fri Mar 20 16:05:57 2009 +0100
@@ -22,6 +22,8 @@
 #License along with this library; if not, write to the Free Software
 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
+import math
+
 import wx
 if wx.VERSION >= (2, 8, 0):
     USE_AUI = True
@@ -60,6 +62,8 @@
               'size' : 20,
              }
 
+ZOOM_FACTORS = [math.sqrt(2) ** x for x in xrange(-6, 7)]
+
 #-------------------------------------------------------------------------------
 #                       Graphic elements Viewer base class
 #-------------------------------------------------------------------------------
@@ -350,7 +354,6 @@
         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
@@ -386,6 +389,8 @@
             width, height = dc.GetTextExtent("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
         self.SetFont(font)
         
+        self.SetScale(len(ZOOM_FACTORS) / 2)
+        
         self.ResetView()
         
         # Link Viewer event to corresponding methods
@@ -440,10 +445,14 @@
         self.Flush()
         self.ResetView()
     
-    def SetScale(self, scalex, scaley):
-        self.ViewScale = (scalex, scaley)
+    def SetScale(self, scale_number):
+        self.CurrentScale = max(0, min(scale_number, len(ZOOM_FACTORS) - 1))
+        self.ViewScale = (ZOOM_FACTORS[self.CurrentScale], ZOOM_FACTORS[self.CurrentScale])
         self.RefreshScaling()
 
+    def GetScale(self):
+        return self.CurrentScale
+
     def GetLogicalDC(self, buffered=False):
         if buffered:
             dc = wx.AutoBufferedPaintDC(self)
@@ -1661,12 +1670,17 @@
                 self.RefreshRect(self.GetScrolledRect(self.SelectedElement.GetRedrawRect(0, scaling[1])), False)
         elif not self.Debug and keycode == wx.WXK_SPACE and self.SelectedElement is not None and self.SelectedElement.Dragging:
             if self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement):
-                self.CopyBlock(self.SelectedElement, wx.Point(*self.SelectedElement.GetPosition()))
-                self.RefreshBuffer()
-                self.RefreshScrollBars()
+                block = self.CopyBlock(self.SelectedElement, wx.Point(*self.SelectedElement.GetPosition()))
+                event = wx.MouseEvent()
+                event.m_x, event.m_y = self.ScreenToClient(wx.GetMousePosition())
+                dc = self.GetLogicalDC()
+                self.SelectedElement.OnLeftUp(event, dc, self.Scaling)
+                self.SelectedElement.SetSelected(False)
+                block.OnLeftDown(event, dc, self.Scaling)
+                self.SelectedElement = block
+                self.SelectedElement.SetSelected(True)
                 self.ParentWindow.RefreshVariablePanel(self.TagName)
                 self.RefreshVisibleElements()
-                self.SelectedElement.Refresh()
             else:
                 event.Skip()
         else:
@@ -1681,7 +1695,7 @@
             width = round(float(width) / float(self.Scaling[0]) + 0.4) * self.Scaling[0]
             height = round(float(height) / float(self.Scaling[1]) + 0.4) * self.Scaling[1]
         return width, height
-
+    
     def AddNewBlock(self, bbox):
         dialog = BlockPropertiesDialog(self.ParentWindow, self.Controler)
         dialog.SetPreviewFont(self.GetFont())
@@ -2565,7 +2579,24 @@
     def Paste(self):
         element = self.ParentWindow.GetCopyBuffer()
         if not self.Debug and element is not None and self.CanAddElement(element):
-            block = self.CopyBlock(element, wx.Point(*self.CalcUnscrolledPosition(30, 30)))
+            mouse_pos = self.ScreenToClient(wx.GetMousePosition())
+            if wx.Rect(0, 0, *self.GetClientSize()).InsideXY(mouse_pos.x, mouse_pos.y):
+                x, y = self.CalcUnscrolledPosition(mouse_pos.x, mouse_pos.y)
+                block_size = element.GetSize()
+                x = int(float(x) / self.ViewScale[0]) - block_size[0] / 2
+                y = int(float(y) / self.ViewScale[1]) - block_size[1] / 2
+            else:
+                x, y = self.CalcUnscrolledPosition(0, 0)
+                x = int(x / self.ViewScale[0]) + 30
+                y = int(y / self.ViewScale[1]) + 30
+            if self.Scaling is not None:
+                new_pos = wx.Point(max(round_scaling(30, self.Scaling[0], 1), 
+                                       round_scaling(x, self.Scaling[0])),
+                                   max(round_scaling(30, self.Scaling[1], 1),
+                                       round_scaling(y, self.Scaling[1])))
+            else:
+                new_pos = wx.Point(max(30, x), max(30, y))
+            block = self.CopyBlock(element, new_pos)
             if self.SelectedElement is not None:
                 self.SelectedElement.SetSelected(False)
             self.SelectedElement = block
@@ -2707,15 +2738,13 @@
                 dc = self.GetLogicalDC()
                 pos = event.GetLogicalPosition(dc)
                 mouse_pos = event.GetPosition()
-                factor = 1.414 ** rotation
-                xscale = max(0.125, min(self.ViewScale[0] * factor, 8))
-                yscale = max(0.125, min(self.ViewScale[0] * factor, 8))
-                self.SetScale(xscale, yscale)
+                self.SetScale(self.CurrentScale + rotation)
                 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()
+                self.ParentWindow.RefreshDisplayMenu()
             else:
                 x, y = self.GetViewStart()
                 yp = max(0, min(y - rotation * 3, self.GetVirtualSize()[1] / self.GetScrollPixelsPerUnit()[1]))