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 |
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) |