GRASS Programmer's Manual  6.4.3(2013)-r
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties 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.
int
Definition: y.tab.c:1344
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.