Viewer.py
changeset 332 555124c752ec
parent 331 9106d66bd204
child 338 87e5015330ae
equal deleted inserted replaced
331:9106d66bd204 332:555124c752ec
    20 #
    20 #
    21 #You should have received a copy of the GNU General Public
    21 #You should have received a copy of the GNU General Public
    22 #License along with this library; if not, write to the Free Software
    22 #License along with this library; if not, write to the Free Software
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24 
    24 
       
    25 import math
       
    26 
    25 import wx
    27 import wx
    26 if wx.VERSION >= (2, 8, 0):
    28 if wx.VERSION >= (2, 8, 0):
    27     USE_AUI = True
    29     USE_AUI = True
    28 else:
    30 else:
    29     USE_AUI = False
    31     USE_AUI = False
    57               'mono' : 'Courier',
    59               'mono' : 'Courier',
    58               'helv' : 'Helvetica',
    60               'helv' : 'Helvetica',
    59               'other': 'new century schoolbook',
    61               'other': 'new century schoolbook',
    60               'size' : 20,
    62               'size' : 20,
    61              }
    63              }
       
    64 
       
    65 ZOOM_FACTORS = [math.sqrt(2) ** x for x in xrange(-6, 7)]
    62 
    66 
    63 #-------------------------------------------------------------------------------
    67 #-------------------------------------------------------------------------------
    64 #                       Graphic elements Viewer base class
    68 #                       Graphic elements Viewer base class
    65 #-------------------------------------------------------------------------------
    69 #-------------------------------------------------------------------------------
    66 
    70 
   348         self.ResetView()
   352         self.ResetView()
   349         self.Scaling = None
   353         self.Scaling = None
   350         self.DrawGrid = True
   354         self.DrawGrid = True
   351         self.GridBrush = wx.TRANSPARENT_BRUSH
   355         self.GridBrush = wx.TRANSPARENT_BRUSH
   352         self.PageSize = None
   356         self.PageSize = None
   353         self.ViewScale = (1.0, 1.0)
       
   354         self.PagePen = wx.TRANSPARENT_PEN
   357         self.PagePen = wx.TRANSPARENT_PEN
   355         self.DrawingWire = False
   358         self.DrawingWire = False
   356         self.current_id = 0
   359         self.current_id = 0
   357         self.TagName = tagname
   360         self.TagName = tagname
   358         self.Errors = []
   361         self.Errors = []
   383             faces["size"] -= 1
   386             faces["size"] -= 1
   384             font = wx.Font(faces["size"], wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["mono"])
   387             font = wx.Font(faces["size"], wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["mono"])
   385             dc.SetFont(font)
   388             dc.SetFont(font)
   386             width, height = dc.GetTextExtent("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
   389             width, height = dc.GetTextExtent("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
   387         self.SetFont(font)
   390         self.SetFont(font)
       
   391         
       
   392         self.SetScale(len(ZOOM_FACTORS) / 2)
   388         
   393         
   389         self.ResetView()
   394         self.ResetView()
   390         
   395         
   391         # Link Viewer event to corresponding methods
   396         # Link Viewer event to corresponding methods
   392         self.Bind(wx.EVT_PAINT, self.OnPaint)
   397         self.Bind(wx.EVT_PAINT, self.OnPaint)
   438     # Destructor
   443     # Destructor
   439     def __del__(self):
   444     def __del__(self):
   440         self.Flush()
   445         self.Flush()
   441         self.ResetView()
   446         self.ResetView()
   442     
   447     
   443     def SetScale(self, scalex, scaley):
   448     def SetScale(self, scale_number):
   444         self.ViewScale = (scalex, scaley)
   449         self.CurrentScale = max(0, min(scale_number, len(ZOOM_FACTORS) - 1))
       
   450         self.ViewScale = (ZOOM_FACTORS[self.CurrentScale], ZOOM_FACTORS[self.CurrentScale])
   445         self.RefreshScaling()
   451         self.RefreshScaling()
       
   452 
       
   453     def GetScale(self):
       
   454         return self.CurrentScale
   446 
   455 
   447     def GetLogicalDC(self, buffered=False):
   456     def GetLogicalDC(self, buffered=False):
   448         if buffered:
   457         if buffered:
   449             dc = wx.AutoBufferedPaintDC(self)
   458             dc = wx.AutoBufferedPaintDC(self)
   450         else:
   459         else:
  1659                 self.RefreshBuffer()
  1668                 self.RefreshBuffer()
  1660                 self.RefreshScrollBars()
  1669                 self.RefreshScrollBars()
  1661                 self.RefreshRect(self.GetScrolledRect(self.SelectedElement.GetRedrawRect(0, scaling[1])), False)
  1670                 self.RefreshRect(self.GetScrolledRect(self.SelectedElement.GetRedrawRect(0, scaling[1])), False)
  1662         elif not self.Debug and keycode == wx.WXK_SPACE and self.SelectedElement is not None and self.SelectedElement.Dragging:
  1671         elif not self.Debug and keycode == wx.WXK_SPACE and self.SelectedElement is not None and self.SelectedElement.Dragging:
  1663             if self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement):
  1672             if self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement):
  1664                 self.CopyBlock(self.SelectedElement, wx.Point(*self.SelectedElement.GetPosition()))
  1673                 block = self.CopyBlock(self.SelectedElement, wx.Point(*self.SelectedElement.GetPosition()))
  1665                 self.RefreshBuffer()
  1674                 event = wx.MouseEvent()
  1666                 self.RefreshScrollBars()
  1675                 event.m_x, event.m_y = self.ScreenToClient(wx.GetMousePosition())
       
  1676                 dc = self.GetLogicalDC()
       
  1677                 self.SelectedElement.OnLeftUp(event, dc, self.Scaling)
       
  1678                 self.SelectedElement.SetSelected(False)
       
  1679                 block.OnLeftDown(event, dc, self.Scaling)
       
  1680                 self.SelectedElement = block
       
  1681                 self.SelectedElement.SetSelected(True)
  1667                 self.ParentWindow.RefreshVariablePanel(self.TagName)
  1682                 self.ParentWindow.RefreshVariablePanel(self.TagName)
  1668                 self.RefreshVisibleElements()
  1683                 self.RefreshVisibleElements()
  1669                 self.SelectedElement.Refresh()
       
  1670             else:
  1684             else:
  1671                 event.Skip()
  1685                 event.Skip()
  1672         else:
  1686         else:
  1673             event.Skip()
  1687             event.Skip()
  1674 
  1688 
  1679     def GetScaledSize(self, width, height):
  1693     def GetScaledSize(self, width, height):
  1680         if self.Scaling is not None:
  1694         if self.Scaling is not None:
  1681             width = round(float(width) / float(self.Scaling[0]) + 0.4) * self.Scaling[0]
  1695             width = round(float(width) / float(self.Scaling[0]) + 0.4) * self.Scaling[0]
  1682             height = round(float(height) / float(self.Scaling[1]) + 0.4) * self.Scaling[1]
  1696             height = round(float(height) / float(self.Scaling[1]) + 0.4) * self.Scaling[1]
  1683         return width, height
  1697         return width, height
  1684 
  1698     
  1685     def AddNewBlock(self, bbox):
  1699     def AddNewBlock(self, bbox):
  1686         dialog = BlockPropertiesDialog(self.ParentWindow, self.Controler)
  1700         dialog = BlockPropertiesDialog(self.ParentWindow, self.Controler)
  1687         dialog.SetPreviewFont(self.GetFont())
  1701         dialog.SetPreviewFont(self.GetFont())
  1688         dialog.SetBlockList(self.Controler.GetBlockTypes(self.TagName, self.Debug))
  1702         dialog.SetBlockList(self.Controler.GetBlockTypes(self.TagName, self.Debug))
  1689         dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
  1703         dialog.SetPouNames(self.Controler.GetProjectPouNames(self.Debug))
  2563             self.ParentWindow.SetCopyBuffer(self.SelectedElement.Clone(self))
  2577             self.ParentWindow.SetCopyBuffer(self.SelectedElement.Clone(self))
  2564             
  2578             
  2565     def Paste(self):
  2579     def Paste(self):
  2566         element = self.ParentWindow.GetCopyBuffer()
  2580         element = self.ParentWindow.GetCopyBuffer()
  2567         if not self.Debug and element is not None and self.CanAddElement(element):
  2581         if not self.Debug and element is not None and self.CanAddElement(element):
  2568             block = self.CopyBlock(element, wx.Point(*self.CalcUnscrolledPosition(30, 30)))
  2582             mouse_pos = self.ScreenToClient(wx.GetMousePosition())
       
  2583             if wx.Rect(0, 0, *self.GetClientSize()).InsideXY(mouse_pos.x, mouse_pos.y):
       
  2584                 x, y = self.CalcUnscrolledPosition(mouse_pos.x, mouse_pos.y)
       
  2585                 block_size = element.GetSize()
       
  2586                 x = int(float(x) / self.ViewScale[0]) - block_size[0] / 2
       
  2587                 y = int(float(y) / self.ViewScale[1]) - block_size[1] / 2
       
  2588             else:
       
  2589                 x, y = self.CalcUnscrolledPosition(0, 0)
       
  2590                 x = int(x / self.ViewScale[0]) + 30
       
  2591                 y = int(y / self.ViewScale[1]) + 30
       
  2592             if self.Scaling is not None:
       
  2593                 new_pos = wx.Point(max(round_scaling(30, self.Scaling[0], 1), 
       
  2594                                        round_scaling(x, self.Scaling[0])),
       
  2595                                    max(round_scaling(30, self.Scaling[1], 1),
       
  2596                                        round_scaling(y, self.Scaling[1])))
       
  2597             else:
       
  2598                 new_pos = wx.Point(max(30, x), max(30, y))
       
  2599             block = self.CopyBlock(element, new_pos)
  2569             if self.SelectedElement is not None:
  2600             if self.SelectedElement is not None:
  2570                 self.SelectedElement.SetSelected(False)
  2601                 self.SelectedElement.SetSelected(False)
  2571             self.SelectedElement = block
  2602             self.SelectedElement = block
  2572             self.SelectedElement.SetSelected(True)
  2603             self.SelectedElement.SetSelected(True)
  2573             self.RefreshBuffer()
  2604             self.RefreshBuffer()
  2705                 self.Scroll(xp, y)
  2736                 self.Scroll(xp, y)
  2706             elif event.ControlDown():
  2737             elif event.ControlDown():
  2707                 dc = self.GetLogicalDC()
  2738                 dc = self.GetLogicalDC()
  2708                 pos = event.GetLogicalPosition(dc)
  2739                 pos = event.GetLogicalPosition(dc)
  2709                 mouse_pos = event.GetPosition()
  2740                 mouse_pos = event.GetPosition()
  2710                 factor = 1.414 ** rotation
  2741                 self.SetScale(self.CurrentScale + rotation)
  2711                 xscale = max(0.125, min(self.ViewScale[0] * factor, 8))
       
  2712                 yscale = max(0.125, min(self.ViewScale[0] * factor, 8))
       
  2713                 self.SetScale(xscale, yscale)
       
  2714                 self.Scroll(round(pos.x * self.ViewScale[0] - mouse_pos.x) / SCROLLBAR_UNIT,
  2742                 self.Scroll(round(pos.x * self.ViewScale[0] - mouse_pos.x) / SCROLLBAR_UNIT,
  2715                             round(pos.y * self.ViewScale[1] - mouse_pos.y) / SCROLLBAR_UNIT)
  2743                             round(pos.y * self.ViewScale[1] - mouse_pos.y) / SCROLLBAR_UNIT)
  2716                 self.RefreshScrollBars()
  2744                 self.RefreshScrollBars()
  2717                 self.RefreshVisibleElements()
  2745                 self.RefreshVisibleElements()
  2718                 self.Refresh()
  2746                 self.Refresh()
       
  2747                 self.ParentWindow.RefreshDisplayMenu()
  2719             else:
  2748             else:
  2720                 x, y = self.GetViewStart()
  2749                 x, y = self.GetViewStart()
  2721                 yp = max(0, min(y - rotation * 3, self.GetVirtualSize()[1] / self.GetScrollPixelsPerUnit()[1]))
  2750                 yp = max(0, min(y - rotation * 3, self.GetVirtualSize()[1] / self.GetScrollPixelsPerUnit()[1]))
  2722                 self.RefreshVisibleElements(yp = yp)
  2751                 self.RefreshVisibleElements(yp = yp)
  2723                 self.Scroll(x, yp)
  2752                 self.Scroll(x, yp)