GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gui_core/mapwindow.py
Go to the documentation of this file.
1 """!
2 @package gui_core.mapwindow
3 
4 @brief Map display canvas - base class for buffered window.
5 
6 Classes:
7  - mapwindow::MapWindow
8 
9 (C) 2006-2011 by the GRASS Development Team
10 
11 This program is free software under the GNU General Public License
12 (>=v2). Read the file COPYING that comes with GRASS for details.
13 
14 @author Martin Landa <landa.martin gmail.com>
15 @author Michael Barton
16 @author Jachym Cepicky
17 """
18 
19 import wx
20 
21 from core.settings import UserSettings
22 
23 class MapWindow(object):
24  """!Abstract map display window class
25 
26  Superclass for BufferedWindow class (2D display mode), and GLWindow
27  (3D display mode).
28 
29  Subclasses have to define
30  - _bindMouseEvents method which binds MouseEvent handlers
31  - Pixel2Cell
32  - Cell2Pixel (if it is possible)
33 
34  """
35  def __init__(self, parent, id = wx.ID_ANY,
36  Map = None, tree = None, lmgr = None, **kwargs):
37  self.parent = parent # MapFrame
38  self.Map = Map
39  self.tree = tree
40  self.lmgr = lmgr
41 
42  # mouse attributes -- position on the screen, begin and end of
43  # dragging, and type of drawing
44  self.mouse = {
45  'begin': [0, 0], # screen coordinates
46  'end' : [0, 0],
47  'use' : "pointer",
48  'box' : "point"
49  }
50  # last east, north coordinates, changes on mouse motion
51  self.lastEN = None
52 
53  # stores overridden cursor
54  self._overriddenCursor = None
55 
56  def RegisterMouseEventHandler(self, event, handler, cursor = None):
57  """!Binds event handler
58 
59  Call event.Skip() in handler to allow default processing in MapWindow.
60 
61  \code
62  # your class methods
63  def OnButton(self, event):
64  # current map display's map window
65  # expects LayerManager to be the parent
66  self.mapwin = self.parent.GetLayerTree().GetMapDisplay().GetWindow()
67  if self.mapwin.RegisterMouseEventHandler(wx.EVT_LEFT_DOWN, self.OnMouseAction,
68  wx.StockCursor(wx.CURSOR_CROSS)):
69  self.parent.GetLayerTree().GetMapDisplay().Raise()
70  else:
71  # handle that you cannot get coordinates
72 
73  def OnMouseAction(self, event):
74  # get real world coordinates of mouse click
75  coor = self.mapwin.Pixel2Cell(event.GetPositionTuple()[:])
76  self.text.SetLabel('Coor: ' + str(coor))
77  self.mapwin.UnregisterMouseEventHandler(wx.EVT_LEFT_DOWN)
78  event.Skip()
79  \endcode
80 
81  @param event one of mouse events
82  @param handler function to handle event
83  @param cursor cursor which temporary overrides current cursor
84 
85  @return True if successful
86  @return False if event cannot be bind
87  """
88 
89  # if it is a VDigitWindow it cannot be used
90  # hasattr is ugly
91  if hasattr(self, "digit"):
92  return False
93 
94  self.Bind(event, handler)
95  self.mouse['useBeforeGenericEvent'] = self.mouse['use']
96  self.mouse['use'] = 'genericEvent'
97 
98  if cursor:
99  self._overriddenCursor = self.GetCursor()
100  self.SetCursor(cursor)
101 
102  return True
103 
104 
105  def UnregisterMouseEventHandler(self, event):
106  """!Unbinds event handler a restores previous state
107 
108  You should unbind to restore normal MapWindow behaviour.
109  Note that this operation will unbind any other external (non-MapWindow) handlers.
110 
111  @param event event to unbind
112 
113  @return True if successful
114  @return False if event cannot be unbind
115  """
116  if hasattr(self, "digit"):
117  return False
118 
119  # it is not yet possible in wxPython to unbind exact event
120  ret = self.Unbind(event)
121 
122  # restore bind state
123  self._bindMouseEvents()
124 
125  # restore mouse use (previous state)
126  self.mouse['use'] = self.mouse['useBeforeGenericEvent']
127 
128  # restore overridden cursor
129  if self._overriddenCursor:
130  self.SetCursor(self._overriddenCursor)
131 
132  return ret
133 
134  def Pixel2Cell(self, (x, y)):
135  raise NotImplementedError()
136 
137  def Cell2Pixel(self, (east, north)):
138  raise NotImplementedError()
139 
140  def OnMotion(self, event):
141  """!Tracks mouse motion and update statusbar
142 
143  @see GetLastEN
144  """
145  try:
146  self.lastEN = self.Pixel2Cell(event.GetPositionTuple())
147  except (ValueError):
148  self.lastEN = None
149  # FIXME: special case for vdigit and access to statusbarManager
150  if self.parent.statusbarManager.GetMode() == 0: # Coordinates
151  updated = False
152  if hasattr(self, "digit"):
153  precision = int(UserSettings.Get(group = 'projection', key = 'format',
154  subkey = 'precision'))
155  updated = self._onMotion(self.lastEN, precision)
156 
157  if not updated:
158  self.parent.CoordinatesChanged()
159 
160  event.Skip()
161 
162  def GetLastEN(self):
163  """!Returns last coordinates of mouse cursor.
164 
165  @see OnMotion
166  """
167  return self.lastEN
168 
169  def GetLayerByName(self, name, mapType, dataType = 'layer'):
170  """!Get layer from layer tree by nam
171 
172  @param name layer name
173  @param type 'item' / 'layer' / 'nviz'
174 
175  @return layer / map layer properties / nviz properties
176  @return None
177  """
178  if not self.tree:
179  return None
180 
181  try:
182  mapLayer = self.Map.GetListOfLayers(l_type = mapType, l_name = name)[0]
183  except IndexError:
184  return None
185 
186  if dataType == 'layer':
187  return mapLayer
188  item = self.tree.FindItemByData('maplayer', mapLayer)
189  if not item:
190  return None
191  if dataType == 'nviz':
192  return self.tree.GetPyData(item)[0]['nviz']
193 
194  return item
195 
196  def GetSelectedLayer(self, type = 'layer', multi = False):
197  """!Get selected layer from layer tree
198 
199  @param type 'item' / 'layer' / 'nviz'
200  @param multi return first selected layer or all
201 
202  @return layer / map layer properties / nviz properties
203  @return None / [] on failure
204  """
205  ret = []
206  if not self.tree or \
207  not self.tree.GetSelection():
208  if multi:
209  return []
210  else:
211  return None
212 
213  if multi and \
214  type == 'item':
215  return self.tree.GetSelections()
216 
217  for item in self.tree.GetSelections():
218  if not item.IsChecked():
219  if multi:
220  continue
221  else:
222  return None
223 
224  if type == 'item': # -> multi = False
225  return item
226 
227  try:
228  if type == 'nviz':
229  layer = self.tree.GetPyData(item)[0]['nviz']
230  else:
231  layer = self.tree.GetPyData(item)[0]['maplayer']
232  except:
233  layer = None
234 
235  if multi:
236  ret.append(layer)
237  else:
238  return layer
239 
240  return ret
Abstract map display window class.
def GetSelectedLayer
Get selected layer from layer tree.
def OnMotion
Tracks mouse motion and update statusbar.
def RegisterMouseEventHandler
Binds event handler.
def UnregisterMouseEventHandler
Unbinds event handler a restores previous state.
def GetLastEN
Returns last coordinates of mouse cursor.
def GetLayerByName
Get layer from layer tree by nam.
Default GUI settings.