mapwindow.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. """!
  2. @package swipe.mapwindow
  3. @brief Map Swipe map window.
  4. Class _MouseEvent taken from wxPython FloatCanvas source code (Christopher Barker).
  5. Classes:
  6. - mapwindow::SwipeBufferedWindow
  7. - mapwindow::_MouseEvent
  8. (C) 2012 by the GRASS Development Team
  9. This program is free software under the GNU General Public License
  10. (>=v2). Read the file COPYING that comes with GRASS for details.
  11. @author Anna Kratochvilova <kratochanna gmail.com>
  12. """
  13. import wx
  14. from core.debug import Debug
  15. from mapdisp.mapwindow import BufferedWindow
  16. EVT_MY_MOUSE_EVENTS = wx.NewEventType()
  17. EVT_MY_MOTION = wx.NewEventType()
  18. EVT_MOUSE_EVENTS = wx.PyEventBinder(EVT_MY_MOUSE_EVENTS)
  19. EVT_MOTION = wx.PyEventBinder(EVT_MY_MOTION)
  20. class SwipeBufferedWindow(BufferedWindow):
  21. """!A subclass of BufferedWindow class.
  22. Enables to draw the image translated.
  23. Special mouse events with changed coordinates are used.
  24. """
  25. def __init__(self, parent, giface, Map, frame,
  26. tree = None, lmgr = None, **kwargs):
  27. BufferedWindow.__init__(self, parent = parent, giface = giface,
  28. Map = Map, frame = frame, tree = tree, lmgr = lmgr, **kwargs)
  29. Debug.msg(2, "SwipeBufferedWindow.__init__()")
  30. self.specialSize = super(SwipeBufferedWindow, self).GetClientSize()
  31. self.specialCoords = [0, 0]
  32. self.imageId = 99
  33. self.movingSash = False
  34. def _bindMouseEvents(self):
  35. """!Binds wx mouse events and custom mouse events"""
  36. wx.EVT_MOUSE_EVENTS(self, self._mouseActions)
  37. wx.EVT_MOTION(self, self._mouseMotion)
  38. self.Bind(EVT_MOTION, self.OnMotion)
  39. self.Bind(EVT_MOUSE_EVENTS, self.MouseActions)
  40. self.Bind(wx.EVT_CONTEXT_MENU, self.OnContextMenu)
  41. def _RaiseMouseEvent(self, Event, EventType):
  42. """!This is called in various other places to raise a Mouse Event
  43. """
  44. Debug.msg(5, "SwipeBufferedWindow._RaiseMouseEvent()")
  45. # this computes the new coordinates from the mouse coords.
  46. x, y = Event.GetPosition()
  47. pt = x - self.GetImageCoords()[0], y - self.GetImageCoords()[1]
  48. evt = _MouseEvent(EventType, Event, self.GetId(), pt)
  49. self.GetEventHandler().ProcessEvent(evt)
  50. # this skip was not in the original code but is needed here
  51. Event.Skip()
  52. def _mouseActions(self, event):
  53. self._RaiseMouseEvent(event, EVT_MY_MOUSE_EVENTS)
  54. def _mouseMotion(self, event):
  55. self._RaiseMouseEvent(event, EVT_MY_MOTION)
  56. def GetClientSize(self):
  57. """!Overriden method which returns simulated window size.
  58. """
  59. return self.specialSize
  60. def SetClientSize(self, size):
  61. """!Overriden method which sets simulated window size.
  62. """
  63. Debug.msg(3, "SwipeBufferedWindow.SetClientSize(): size = %s" % size)
  64. self.specialSize = size
  65. def GetImageCoords(self):
  66. """!Returns coordinates of rendered image"""
  67. return self.specialCoords
  68. def SetImageCoords(self, coords):
  69. """!Sets coordinates of rendered image"""
  70. Debug.msg(3, "SwipeBufferedWindow.SetImageCoords(): coords = %s, %s" % (coords[0], coords[1]))
  71. self.specialCoords = coords
  72. def OnSize(self, event):
  73. """!Calls superclass's OnSize method only when needed"""
  74. Debug.msg(5, "SwipeBufferedWindow.OnSize()")
  75. if not self.movingSash:
  76. super(SwipeBufferedWindow, self).OnSize(event)
  77. def ZoomToMap(self, layers = None, ignoreNulls = False, render = True):
  78. super(SwipeBufferedWindow, self).ZoomToMap(layers, ignoreNulls, render)
  79. self.frame.UpdateRegion()
  80. def ZoomBack(self):
  81. """!Zoom last (previously stored position)
  82. """
  83. super(SwipeBufferedWindow, self).ZoomBack()
  84. self.frame.UpdateRegion()
  85. def Draw(self, pdc, img = None, drawid = None, pdctype = 'image', coords = [0, 0, 0, 0]):
  86. """!Draws image (map) with translated coordinates.
  87. """
  88. Debug.msg(2, "SwipeBufferedWindow.Draw()")
  89. if pdctype == 'image':
  90. coords = self.GetImageCoords()
  91. return super(SwipeBufferedWindow, self).Draw(pdc, img, drawid, pdctype, coords)
  92. def TranslateImage(self, dx, dy):
  93. """!Translate image and redraw.
  94. """
  95. Debug.msg(5, "SwipeBufferedWindow.TranslateImage(): dx = %s, dy = %s" % (dx, dy))
  96. self.pdc.TranslateId(self.imageId, dx, dy)
  97. self.Refresh()
  98. def MouseActions(self, event):
  99. """!Handle mouse events and if needed let parent frame know"""
  100. super(SwipeBufferedWindow, self).MouseActions(event)
  101. if event.GetWheelRotation() != 0 or \
  102. event.LeftUp() or \
  103. event.MiddleUp():
  104. self.frame.UpdateRegion()
  105. event.Skip()
  106. def MouseDraw(self, pdc = None, begin = None, end = None):
  107. """!Overriden method to recompute coordinates back to original values
  108. so that e.g. drawing of zoom box is done properly"""
  109. Debug.msg(5, "SwipeBufferedWindow.MouseDraw()")
  110. offsetX, offsetY = self.GetImageCoords()
  111. begin = (self.mouse['begin'][0] + offsetX, self.mouse['begin'][1] + offsetY)
  112. end = (self.mouse['end'][0] + offsetX, self.mouse['end'][1] + offsetY)
  113. super(SwipeBufferedWindow, self).MouseDraw(pdc, begin, end)
  114. class _MouseEvent(wx.PyCommandEvent):
  115. """!
  116. This event class takes a regular wxWindows mouse event as a parameter,
  117. and wraps it so that there is access to all the original methods. This
  118. is similar to subclassing, but you can't subclass a wxWindows event.
  119. The goal is to be able to it just like a regular mouse event.
  120. Difference is that it is a CommandEvent, which propagates up the
  121. window hierarchy until it is handled.
  122. """
  123. def __init__(self, EventType, NativeEvent, WinID, changed = None):
  124. Debug.msg(5, "_MouseEvent:__init__()")
  125. wx.PyCommandEvent.__init__(self)
  126. self.SetEventType(EventType)
  127. self._NativeEvent = NativeEvent
  128. self.changed = changed
  129. def GetPosition(self):
  130. return wx.Point(*self.changed)
  131. def GetPositionTuple(self):
  132. return self.changed
  133. def GetX(self):
  134. return self.changed[0]
  135. def GetY(self):
  136. return self.changed[1]
  137. # this delegates all other attributes to the native event.
  138. def __getattr__(self, name):
  139. return getattr(self._NativeEvent, name)