~ubuntu-branches/ubuntu/vivid/grass/vivid-proposed

« back to all changes in this revision

Viewing changes to gui/wxpython/gui_core/mapwindow.py

  • Committer: Package Import Robot
  • Author(s): Bas Couwenberg
  • Date: 2015-02-20 23:12:08 UTC
  • mfrom: (8.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20150220231208-1u6qvqm84v430b10
Tags: 7.0.0-1~exp1
* New upstream release.
* Update python-ctypes-ternary.patch to use if/else instead of and/or.
* Drop check4dev patch, rely on upstream check.
* Add build dependency on libpq-dev to grass-dev for libpq-fe.h.
* Drop patches applied upstream, refresh remaining patches.
* Update symlinks for images switched from jpg to png.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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