/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/UI/view.py
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/Thuban/UI/view.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1865 by bh, Mon Aug 25 15:59:58 2003 UTC revision 1866 by bh, Mon Oct 27 13:01:58 2003 UTC
# Line 10  Line 10 
10  Classes for display of a map and interaction with it  Classes for display of a map and interaction with it
11  """  """
12    
13  __version__ = "$Revision$"  from __future__ import generators
14    
15  from Thuban import _  __version__ = "$Revision$"
16    # $Source$
17    # $Id$
18    
19  import os.path  import os.path
20    import time
21    import traceback
22    
23  from wxPython.wx import wxWindow, \  from wxPython.wx import wxWindow, \
24       wxPaintDC, wxColour, wxClientDC, wxINVERT, wxTRANSPARENT_BRUSH, wxFont,\       wxPaintDC, wxColour, wxClientDC, wxINVERT, wxTRANSPARENT_BRUSH, wxFont,\
# Line 28  if wxPlatform == '__WXMSW__': Line 32  if wxPlatform == '__WXMSW__':
32    
33  from wxPython import wx  from wxPython import wx
34    
35    from Thuban import _
36    
37  from Thuban.Model.messages import MAP_LAYERS_CHANGED, LAYER_CHANGED, \  from Thuban.Model.messages import MAP_LAYERS_CHANGED, LAYER_CHANGED, \
38       LAYER_VISIBILITY_CHANGED       LAYER_VISIBILITY_CHANGED
39    
# Line 49  class CanvasPanTool(PanTool): Line 55  class CanvasPanTool(PanTool):
55              width, height = self.view.GetSizeTuple()              width, height = self.view.GetSizeTuple()
56    
57              bitmapdc = wx.wxMemoryDC()              bitmapdc = wx.wxMemoryDC()
58              bitmapdc.SelectObject(self.view.bitmap)              bitmapdc.SelectObject(self.view.PreviewBitmap())
59    
60              dc = self.view.drag_dc              dc = self.view.drag_dc
61              dc.Blit(0, 0, width, height, bitmapdc, sx - x, sy - y)              dc.Blit(0, 0, width, height, bitmapdc, sx - x, sy - y)
# Line 85  class MapPrintout(wx.wxPrintout): Line 91  class MapPrintout(wx.wxPrintout):
91                                                      self.canvas.GetSizeTuple(),                                                      self.canvas.GetSizeTuple(),
92                                                      self.GetPageSizePixels())                                                      self.GetPageSizePixels())
93          resx, resy = self.GetPPIPrinter()          resx, resy = self.GetPPIPrinter()
         renderer = PrinterRenderer(dc, scale, offset, resolution = resy)  
         x, y, width, height = self.region  
94          canvas_scale = self.canvas.scale          canvas_scale = self.canvas.scale
95          renderer.RenderMap(self.map,          x, y, width, height = self.region
96                             (0,0,          renderer = PrinterRenderer(dc, self.map, scale, offset,
97                                  (width/canvas_scale)*scale,                                     region = (0, 0,
98                                  (height/canvas_scale)*scale),                                               (width/canvas_scale)*scale,
99                                  mapregion,                                               (height/canvas_scale)*scale),
100                             self.selected_layer, self.selected_shapes)                                     resolution = resy,
101                                       destination_region = mapregion)
102            renderer.RenderMap(self.selected_layer, self.selected_shapes)
103          return True          return True
104    
105    
106  class MapCanvas(wxWindow, ViewPort):  class MapCanvas(wxWindow, ViewPort):
107    
108      """A widget that displays a map and offers some interaction"""      """A widget that displays a map and offers some interaction"""
# Line 108  class MapCanvas(wxWindow, ViewPort): Line 115  class MapCanvas(wxWindow, ViewPort):
115    
116          # the bitmap serving as backing store          # the bitmap serving as backing store
117          self.bitmap = None          self.bitmap = None
118            # the monochrome bitmap with the selection if any
119            self.selection_bitmap = None
120    
121          self.backgroundColor = wx.wxWHITE_BRUSH          self.backgroundColor = wx.wxWHITE_BRUSH
122    
123          # Set to true if there ever is an error during redraw. There          # The rendering iterator object. Used when rendering
124          # should never be errors, but unfortunately bugs happen.          # incrementally
125          self.error_on_redraw = 0          self.render_iter = None
126    
127          # subscribe the WX events we're interested in          # subscribe the WX events we're interested in
128          EVT_PAINT(self, self.OnPaint)          EVT_PAINT(self, self.OnPaint)
# Line 128  class MapCanvas(wxWindow, ViewPort): Line 137  class MapCanvas(wxWindow, ViewPort):
137          wxWindow.__del__(self)          wxWindow.__del__(self)
138          ViewPort.__del__(self)          ViewPort.__del__(self)
139    
140        def PreviewBitmap(self):
141            return self.bitmap
142    
143      def PanTool(self):      def PanTool(self):
144          """Start the canvas pan tool"""          """Start the canvas pan tool"""
145          self.SelectTool(CanvasPanTool(self))          self.SelectTool(CanvasPanTool(self))
# Line 152  class MapCanvas(wxWindow, ViewPort): Line 164  class MapCanvas(wxWindow, ViewPort):
164    
165      def OnPaint(self, event):      def OnPaint(self, event):
166          dc = wxPaintDC(self)          dc = wxPaintDC(self)
   
167          if self.Map() is not None and self.Map().HasLayers():          if self.Map() is not None and self.Map().HasLayers():
168              if self.bitmap in (None, -1):              if self.bitmap is not None:
                 # set the flag that we should redraw the  
                 # bitmap in idle time  
                 self.bitmap = -1  
             else:  
                 # blit the bitmap to the screen  
169                  dc.BeginDrawing()                  dc.BeginDrawing()
170                  dc.DrawBitmap(self.bitmap, 0, 0)                  dc.DrawBitmap(self.bitmap, 0, 0)
171                    if self.selection_bitmap is not None:
172                        dc.DrawBitmap(self.selection_bitmap, 0, 0, True)
173                  dc.EndDrawing()                  dc.EndDrawing()
174          else:          else:
175              # If we've got no map or if the map is empty, simply clear              # If we've got no map or if the map is empty, simply clear
# Line 178  class MapCanvas(wxWindow, ViewPort): Line 186  class MapCanvas(wxWindow, ViewPort):
186    
187      def OnIdle(self, event):      def OnIdle(self, event):
188          """Idle handler. Redraw the bitmap if necessary"""          """Idle handler. Redraw the bitmap if necessary"""
189            if (self.bitmap is None
190                or self.render_iter is not None
191                or (self.HasSelectedShapes()
192                    and self.selection_bitmap is None)):
193                event.RequestMore(self._do_redraw())
194    
195          if self.bitmap != -1:      def _do_redraw(self):
196              return          """Redraw a bit and return whether this method has to be called again.
         if self.error_on_redraw:  
             return  
197    
198          wxBeginBusyCursor()          Called by OnIdle to handle the actual redraw. Redraw is
199          try:          incremental for both the bitmap with the normal layers and the
200            bitmap with the selection.
201            """
202            finished = False
203            if self.render_iter is not None:
204              try:              try:
205                  self._do_redraw()                  if self.render_iter.next():
206                        # Redraw if the last preview redraw was some time
207                        # ago and the user is not currently dragging the
208                        # mouse because redrawing would interfere with what
209                        # the current tool is drawing on the window.
210                        if not self.dragging \
211                               and time.time() - self.render_last_preview > 0.5:
212                            client_dc = wxClientDC(self)
213                            client_dc.BeginDrawing()
214                            client_dc.DrawBitmap(self.bitmap, 0, 0)
215                            client_dc.EndDrawing()
216                            self.render_last_preview = time.time()
217                    else:
218                        self.render_iter = None
219                        # Redraw if not dragging because redrawing would
220                        # interfere with what the current tool is drawing on
221                        # the window.
222                        if not self.dragging:
223                            self.redraw()
224                        finished = True
225                except StopIteration:
226                    finished = True
227                    self.render_iter = None
228              except:              except:
229                  self.error_on_redraw = True                  finished = True
230                  raise                  self.render_iter = None
231          finally:                  traceback.print_exc()
232              wxEndBusyCursor()          else:
233                self.render_iter = self._render_iterator()
234                self.render_last_preview = time.time()
235            return not finished
236    
237      def _do_redraw(self):      def _render_iterator(self):
         """Called by OnIdle to do the actual redraw.  
         """  
238          width, height = self.GetSizeTuple()          width, height = self.GetSizeTuple()
   
         bitmap = wx.wxEmptyBitmap(width, height)  
239          dc = wx.wxMemoryDC()          dc = wx.wxMemoryDC()
         dc.SelectObject(bitmap)  
         dc.BeginDrawing()  
240    
241          dc.SetBackground(self.backgroundColor)          render_start = time.time()
         dc.Clear()  
242    
243          selected_layer = self.selection.SelectedLayer()          if self.bitmap is None:
244          selected_shapes = self.selection.SelectedShapes()              self.bitmap = wx.wxEmptyBitmap(width, height)
245                dc.SelectObject(self.bitmap)
246                dc.BeginDrawing()
247    
248          # draw the map into the bitmap              dc.SetBackground(self.backgroundColor)
249          renderer = ScreenRenderer(dc, self.scale, self.offset)              dc.Clear()
250    
251          # Pass the entire bitmap as update region to the renderer.              # draw the map into the bitmap
252          # We're redrawing the whole bitmap, after all.              renderer = ScreenRenderer(dc, self.Map(), self.scale, self.offset,
253          renderer.RenderMap(self.Map(), (0, 0, width, height),                                        (0, 0, width, height))
254                             selected_layer, selected_shapes)              for cont in renderer.RenderMapIncrementally():
255                    yield True
256    
257          dc.EndDrawing()              dc.EndDrawing()
258          dc.SelectObject(wx.wxNullBitmap)              dc.SelectObject(wx.wxNullBitmap)
259    
260          self.bitmap = bitmap          if self.HasSelectedShapes() and self.selection_bitmap is None:
261          # This causes a paint event that then draws the bitmap              bitmap = wx.wxEmptyBitmap(width, height)
262          self.redraw()              dc.SelectObject(bitmap)
263                dc.BeginDrawing()
264                dc.SetBackground(wx.wxWHITE_BRUSH)
265                dc.Clear()
266    
267                renderer = ScreenRenderer(dc, self.Map(), self.scale, self.offset,
268                                          (0, 0, width, height))
269                layer = self.SelectedLayer()
270                shapes = self.selection.SelectedShapes()
271                for cont in renderer.draw_selection_incrementally(layer, shapes):
272                    yield True
273    
274                dc.EndDrawing()
275                dc.SelectObject(wx.wxNullBitmap)
276    
277                bitmap.SetMask(wx.wxMaskColour(bitmap, wx.wxWHITE))
278                self.selection_bitmap = bitmap
279    
280            yield False
281    
282      def Export(self):      def Export(self):
283    
# Line 246  class MapCanvas(wxWindow, ViewPort): Line 300  class MapCanvas(wxWindow, ViewPort):
300              selected_layer = self.selection.SelectedLayer()              selected_layer = self.selection.SelectedLayer()
301              selected_shapes = self.selection.SelectedShapes()              selected_shapes = self.selection.SelectedShapes()
302    
303              renderer = ExportRenderer(dc, scale, offset)              renderer = ExportRenderer(dc, self.Map(), scale, offset,
304                                          region = (0, 0,
305                                                    (width/self.scale)*scale,
306                                                    (height/self.scale)*scale),
307                                          destination_region = mapregion)
308    
309              # Pass the entire bitmap as update region to the renderer.              # Pass the entire bitmap as update region to the renderer.
310              # We're redrawing the whole bitmap, after all.              # We're redrawing the whole bitmap, after all.
311              width, height = self.GetSizeTuple()              width, height = self.GetSizeTuple()
312              renderer.RenderMap(self.Map(),              renderer.RenderMap(selected_layer, selected_shapes)
                                 (0,0,  
                                     (width/self.scale)*scale,  
                                     (height/self.scale)*scale),  
                                 mapregion,  
                                 selected_layer, selected_shapes)  
313              dc.EndDrawing()              dc.EndDrawing()
314              dc.Close()              dc.Close()
315          dlg.Destroy()          dlg.Destroy()
# Line 277  class MapCanvas(wxWindow, ViewPort): Line 330  class MapCanvas(wxWindow, ViewPort):
330    
331      def full_redraw(self, *args):      def full_redraw(self, *args):
332          self.bitmap = None          self.bitmap = None
333            self.selection_bitmap = None
334            self.render_iter = None
335            self.redraw()
336    
337        def redraw_selection(self, *args):
338            self.selection_bitmap = None
339            self.render_iter = None
340          self.redraw()          self.redraw()
341    
342      def map_projection_changed(self, map, old_proj):      def map_projection_changed(self, map, old_proj):
# Line 350  class MapCanvas(wxWindow, ViewPort): Line 410  class MapCanvas(wxWindow, ViewPort):
410          """Receiver for the SHAPES_SELECTED messages. Redraw the map."""          """Receiver for the SHAPES_SELECTED messages. Redraw the map."""
411          # The selection object takes care that it only issues          # The selection object takes care that it only issues
412          # SHAPES_SELECTED messages when the set of selected shapes has          # SHAPES_SELECTED messages when the set of selected shapes has
413          # actually changed, so we can do a full redraw unconditionally.          # actually changed, so we can do a full redraw of the
414          # FIXME: We should perhaps try to limit the redraw to the are          # selection_bitmap unconditionally.
         # actually covered by the shapes before and after the selection  
         # change.  
415          ViewPort.shape_selected(self, layer, shape)          ViewPort.shape_selected(self, layer, shape)
416          self.full_redraw()          self.redraw_selection()
417    
418      def GetTextExtent(self, text):      def GetTextExtent(self, text):
419          dc = wxClientDC(self)          dc = wxClientDC(self)

Legend:
Removed from v.1865  
changed lines
  Added in v.1866

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26