123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- """
- @package swipe.mapwindow
- @brief Map Swipe map window.
- Class _MouseEvent taken from wxPython FloatCanvas source code (Christopher Barker).
- Classes:
- - mapwindow::SwipeBufferedWindow
- - mapwindow::_MouseEvent
- (C) 2012 by the GRASS Development Team
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
- @author Anna Kratochvilova <kratochanna gmail.com>
- """
- import wx
- from core.debug import Debug
- from core.utils import _
- from core.settings import UserSettings
- from mapwin.buffered import BufferedMapWindow
- EVT_MY_MOUSE_EVENTS = wx.NewEventType()
- EVT_MY_MOTION = wx.NewEventType()
- EVT_MOUSE_EVENTS = wx.PyEventBinder(EVT_MY_MOUSE_EVENTS)
- EVT_MOTION = wx.PyEventBinder(EVT_MY_MOTION)
- class SwipeBufferedWindow(BufferedMapWindow):
- """A subclass of BufferedWindow class.
- Enables to draw the image translated.
- Special mouse events with changed coordinates are used.
- """
- def __init__(self, parent, giface, Map, properties, **kwargs):
- BufferedMapWindow.__init__(self, parent=parent, giface=giface, Map=Map,
- properties=properties, **kwargs)
- Debug.msg(2, "SwipeBufferedWindow.__init__()")
- self.specialSize = super(SwipeBufferedWindow, self).GetClientSize()
- self.specialCoords = [0, 0]
- self.imageId = 99
- self.movingSash = False
- self._mode = 'swipe'
- self.lineid = wx.NewId()
- def _bindMouseEvents(self):
- """Binds wx mouse events and custom mouse events"""
- wx.EVT_MOUSE_EVENTS(self, self._mouseActions)
- wx.EVT_MOTION(self, self._mouseMotion)
- self.Bind(EVT_MOTION, self.OnMotion)
- self.Bind(EVT_MOUSE_EVENTS, self.MouseActions)
- self.Bind(wx.EVT_CONTEXT_MENU, self.OnContextMenu)
- def _RaiseMouseEvent(self, Event, EventType):
- """This is called in various other places to raise a Mouse Event
- """
- Debug.msg(5, "SwipeBufferedWindow._RaiseMouseEvent()")
- # this computes the new coordinates from the mouse coords.
- x, y = Event.GetPosition()
- pt = x - self.GetImageCoords()[0], y - self.GetImageCoords()[1]
- evt = _MouseEvent(EventType, Event, self.GetId(), pt)
- self.GetEventHandler().ProcessEvent(evt)
- # this skip was not in the original code but is needed here
- Event.Skip()
- def _mouseActions(self, event):
- self._RaiseMouseEvent(event, EVT_MY_MOUSE_EVENTS)
- def _mouseMotion(self, event):
- self._RaiseMouseEvent(event, EVT_MY_MOTION)
- def GetClientSize(self):
- """Overriden method which returns simulated window size.
- """
- if self._mode == 'swipe':
- return self.specialSize
- else:
- return super(SwipeBufferedWindow, self).GetClientSize()
- def SetClientSize(self, size):
- """Overriden method which sets simulated window size.
- """
- Debug.msg(3, "SwipeBufferedWindow.SetClientSize(): size = %s" % size)
- self.specialSize = size
- def SetMode(self, mode):
- """Sets mode of the window.
- :param mode: mode can be 'swipe' or 'mirror'
- """
- self._mode = mode
- def GetImageCoords(self):
- """Returns coordinates of rendered image"""
- if self._mode == 'swipe':
- return self.specialCoords
- else:
- return (0, 0)
- def SetImageCoords(self, coords):
- """Sets coordinates of rendered image"""
- Debug.msg(
- 3, "SwipeBufferedWindow.SetImageCoords(): coords = %s, %s" %
- (coords[0], coords[1]))
- self.specialCoords = coords
- def OnSize(self, event):
- """Calls superclass's OnSize method only when needed"""
- Debug.msg(5, "SwipeBufferedWindow.OnSize()")
- if not self.movingSash:
- super(SwipeBufferedWindow, self).OnSize(event)
- def Draw(self, pdc, img=None, drawid=None, pdctype='image',
- coords=[0, 0, 0, 0], pen=None, brush=None):
- """Draws image (map) with translated coordinates.
- """
- Debug.msg(2, "SwipeBufferedWindow.Draw()")
- if pdctype == 'image':
- coords = self.GetImageCoords()
- return super(SwipeBufferedWindow, self).Draw(
- pdc, img, drawid, pdctype, coords, pen, brush)
- def OnLeftDown(self, event):
- """Left mouse button pressed.
- In case of 'pointer' mode, coordinates must be adjusted.
- """
- if self.mouse['use'] == 'pointer':
- evX, evY = event.GetPositionTuple()[:]
- imX, imY = self.GetImageCoords()
- self.lastpos = evX + imX, evY + imY
- # get decoration or text id
- self.dragid = None
- idlist = self.pdc.FindObjects(self.lastpos[0], self.lastpos[1],
- self.hitradius)
- if 99 in idlist:
- idlist.remove(99)
- if idlist:
- self.dragid = idlist[0] # drag whatever is on top
- else:
- super(SwipeBufferedWindow, self).OnLeftDown(event)
- def OnDragging(self, event):
- """Mouse dragging - overlay (text) is moving.
- Coordinates must be adjusted.
- """
- if (self.mouse['use'] == 'pointer' and self.dragid is not None):
- evX, evY = event.GetPositionTuple()
- imX, imY = self.GetImageCoords()
- self.DragItem(self.dragid, (evX + imX, evY + imY))
- else:
- super(SwipeBufferedWindow, self).OnDragging(event)
- def TranslateImage(self, dx, dy):
- """Translate image and redraw.
- """
- Debug.msg(
- 5, "SwipeBufferedWindow.TranslateImage(): dx = %s, dy = %s" %
- (dx, dy))
- self.pdc.TranslateId(self.imageId, dx, dy)
- self.Refresh()
- def SetRasterNameText(self, name, textId):
- """Sets text label with map name."""
- self.textdict[textId] = {'bbox': wx.Rect(), 'coords': [10, 10],
- 'font': self.GetFont(), 'color': wx.BLACK,
- 'background': wx.LIGHT_GREY,
- 'rotation': 0, 'text': name,
- 'active': True}
- def MouseDraw(self, pdc=None, begin=None, end=None):
- """Overriden method to recompute coordinates back to original values
- so that e.g. drawing of zoom box is done properly"""
- Debug.msg(5, "SwipeBufferedWindow.MouseDraw()")
- offsetX, offsetY = self.GetImageCoords()
- begin = (
- self.mouse['begin'][0] +
- offsetX,
- self.mouse['begin'][1] +
- offsetY)
- end = (self.mouse['end'][0] + offsetX, self.mouse['end'][1] + offsetY)
- super(SwipeBufferedWindow, self).MouseDraw(pdc, begin, end)
- def DrawMouseCursor(self, coords):
- """Draw moving cross."""
- self.pdcTmp.ClearId(self.lineid)
- color = UserSettings.Get(
- group='mapswipe',
- key='cursor',
- subkey='color')
- cursType = UserSettings.Get(
- group='mapswipe', key='cursor', subkey=[
- 'type', 'selection'])
- size = UserSettings.Get(group='mapswipe', key='cursor', subkey='size')
- width = UserSettings.Get(
- group='mapswipe',
- key='cursor',
- subkey='width')
- if cursType == 0:
- self.lineid = self.DrawCross(
- pdc=self.pdcTmp,
- coords=coords,
- size=size,
- pen=wx.Pen(
- wx.Colour(
- *color),
- width))
- elif cursType == 1:
- self.lineid = self.DrawRectangle(
- pdc=self.pdcTmp,
- point1=(
- coords[0] - size / 2,
- coords[1] - size / 2),
- point2=(
- coords[0] + size / 2,
- coords[1] + size / 2),
- pen=wx.Pen(
- wx.Colour(
- *color),
- width))
- elif cursType == 2:
- self.lineid = self.DrawCircle(pdc=self.pdcTmp,
- coords=coords, radius=size / 2,
- pen=wx.Pen(wx.Colour(*color), width))
- class _MouseEvent(wx.PyCommandEvent):
- """
- This event class takes a regular wxWindows mouse event as a parameter,
- and wraps it so that there is access to all the original methods. This
- is similar to subclassing, but you can't subclass a wxWindows event.
- The goal is to be able to it just like a regular mouse event.
- Difference is that it is a CommandEvent, which propagates up the
- window hierarchy until it is handled.
- """
- def __init__(self, EventType, NativeEvent, WinID, changed=None):
- Debug.msg(5, "_MouseEvent:__init__()")
- wx.PyCommandEvent.__init__(self)
- self.__dict__['_NativeEvent'] = NativeEvent
- self.__dict__['changed'] = changed
- self.SetEventType(EventType)
- def GetPosition(self):
- return wx.Point(*self.changed)
- def GetPositionTuple(self):
- return self.changed
- def GetX(self):
- return self.changed[0]
- def GetY(self):
- return self.changed[1]
- # this delegates all other attributes to the native event.
- def __getattr__(self, name):
- return getattr(self._NativeEvent, name)
|