/[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 60 by bh, Thu Sep 13 14:47:39 2001 UTC revision 261 by bh, Thu Aug 15 17:44:33 2002 UTC
# Line 1  Line 1 
1  # Copyright (c) 2001 by Intevation GmbH  # Copyright (c) 2001, 2002 by Intevation GmbH
2  # Authors:  # Authors:
3  # Bernhard Herzog <[email protected]>  # Bernhard Herzog <[email protected]>
4  #  #
# Line 15  from math import hypot Line 15  from math import hypot
15    
16  from wxPython.wx import wxWindow,\  from wxPython.wx import wxWindow,\
17       wxPaintDC, wxColour, wxClientDC, wxINVERT, wxTRANSPARENT_BRUSH, wxFont,\       wxPaintDC, wxColour, wxClientDC, wxINVERT, wxTRANSPARENT_BRUSH, wxFont,\
18       EVT_PAINT, EVT_LEFT_DOWN, EVT_LEFT_UP, EVT_MOTION       EVT_PAINT, EVT_LEFT_DOWN, EVT_LEFT_UP, EVT_MOTION, EVT_LEAVE_WINDOW
19    
20    
21  from wxPython import wx  from wxPython import wx
# Line 29  from Thuban.Model.layer import SHAPETYPE Line 29  from Thuban.Model.layer import SHAPETYPE
29       SHAPETYPE_POINT       SHAPETYPE_POINT
30  from Thuban.Model.label import ALIGN_CENTER, ALIGN_TOP, ALIGN_BOTTOM, \  from Thuban.Model.label import ALIGN_CENTER, ALIGN_TOP, ALIGN_BOTTOM, \
31       ALIGN_LEFT, ALIGN_RIGHT       ALIGN_LEFT, ALIGN_RIGHT
32    from Thuban.Lib.connector import Publisher
33    
34  from renderer import ScreenRenderer, PrinterRender  from renderer import ScreenRenderer, PrinterRender
35    
36  import labeldialog  import labeldialog
37    
38  from messages import SELECTED_SHAPE  from messages import SELECTED_SHAPE, VIEW_POSITION
39    
40    
41  #  #
# Line 140  class ZoomInTool(RectTool): Line 140  class ZoomInTool(RectTool):
140  class ZoomOutTool(RectTool):  class ZoomOutTool(RectTool):
141    
142      """The Zoom-Out Tool"""      """The Zoom-Out Tool"""
143        
144      def Name(self):      def Name(self):
145          return "ZoomOutTool"          return "ZoomOutTool"
146    
# Line 151  class ZoomOutTool(RectTool): Line 151  class ZoomOutTool(RectTool):
151              cx, cy = self.current              cx, cy = self.current
152              if sx == cx and sy == cy:              if sx == cx and sy == cy:
153                  # Just a mouse click. Simply zoom out by a factor of two                  # Just a mouse click. Simply zoom out by a factor of two
154                  self.view.ZoomFactor(0.5, center = (cy, cy))                  self.view.ZoomFactor(0.5, center = (cx, cy))
155              else:              else:
156                  # A drag. Zoom out to the rectangle                  # A drag. Zoom out to the rectangle
157                  self.view.ZoomOutToRect((min(sx, cx), min(sy, cy),                  self.view.ZoomOutToRect((min(sx, cx), min(sy, cy),
# Line 167  class PanTool(Tool): Line 167  class PanTool(Tool):
167    
168      def MouseMove(self, event):      def MouseMove(self, event):
169          if self.dragging:          if self.dragging:
             x0, y0 = self.current  
170              Tool.MouseMove(self, event)              Tool.MouseMove(self, event)
171                sx, sy = self.start
172              x, y = self.current              x, y = self.current
173              width, height = self.view.GetSizeTuple()              width, height = self.view.GetSizeTuple()
174    
175                bitmapdc = wx.wxMemoryDC()
176                bitmapdc.SelectObject(self.view.bitmap)
177    
178              dc = self.view.drag_dc              dc = self.view.drag_dc
179              dc.Blit(0, 0, width, height, dc, x0 - x, y0 - y)              dc.Blit(0, 0, width, height, bitmapdc, sx - x, sy - y)
180    
181      def MouseUp(self, event):      def MouseUp(self, event):
182          if self.dragging:          if self.dragging:
# Line 180  class PanTool(Tool): Line 184  class PanTool(Tool):
184              sx, sy = self.start              sx, sy = self.start
185              cx, cy = self.current              cx, cy = self.current
186              self.view.Translate(cx - sx, cy - sy)              self.view.Translate(cx - sx, cy - sy)
187            
188  class IdentifyTool(Tool):  class IdentifyTool(Tool):
189    
190      """The "Identify" Tool"""      """The "Identify" Tool"""
191        
192      def Name(self):      def Name(self):
193          return "IdentifyTool"          return "IdentifyTool"
194    
# Line 238  class MapPrintout(wx.wxPrintout): Line 242  class MapPrintout(wx.wxPrintout):
242          renderer = PrinterRender(dc, scale, (offx, offy), resolution = resx)          renderer = PrinterRender(dc, scale, (offx, offy), resolution = resx)
243          renderer.RenderMap(self.map)          renderer.RenderMap(self.map)
244          return wx.true          return wx.true
           
245    
246  class MapCanvas(wxWindow):  
247    class MapCanvas(wxWindow, Publisher):
248    
249      """A widget that displays a map and offers some interaction"""      """A widget that displays a map and offers some interaction"""
250    
251      def __init__(self, parent, winid, interactor):      def __init__(self, parent, winid, interactor):
252          wxWindow.__init__(self, parent, winid)          wxWindow.__init__(self, parent, winid)
253          self.SetBackgroundColour(wxColour(255, 255, 255))          self.SetBackgroundColour(wxColour(255, 255, 255))
254    
255            # the map displayed in this canvas. Set with SetMap()
256          self.map = None          self.map = None
257    
258            # scale and offset describe the transformation from projected
259            # coordinates to window coordinates.
260          self.scale = 1.0          self.scale = 1.0
261          self.offset = (0, 0)          self.offset = (0, 0)
262    
263            # whether the user is currently dragging the mouse, i.e. moving
264            # the mouse while pressing a mouse button
265          self.dragging = 0          self.dragging = 0
266    
267            # the currently active tool
268          self.tool = None          self.tool = None
269    
270            # The current mouse position of the last OnMotion event or None
271            # if the mouse is outside the window.
272            self.current_position = None
273    
274            # If true, OnIdle will call do_redraw to do the actual
275            # redrawing. Set by OnPaint to avoid some unnecessary redraws.
276            # To force a redraw call full_redraw().
277          self.redraw_on_idle = 0          self.redraw_on_idle = 0
278    
279            # The region to update when idle
280            self.update_region = wx.wxRegion()
281    
282            # the bitmap serving as backing store
283            self.bitmap = None
284    
285            # the interactor
286            self.interactor = interactor
287            self.interactor.Subscribe(SELECTED_SHAPE, self.shape_selected)
288    
289            # keep track of which layers/shapes are selected to make sure we
290            # only redraw when necessary
291            self.last_selected_layer = None
292            self.last_selected_shape = None
293    
294            # subscribe the WX events we're interested in
295          EVT_PAINT(self, self.OnPaint)          EVT_PAINT(self, self.OnPaint)
296          EVT_LEFT_DOWN(self, self.OnLeftDown)          EVT_LEFT_DOWN(self, self.OnLeftDown)
297          EVT_LEFT_UP(self, self.OnLeftUp)          EVT_LEFT_UP(self, self.OnLeftUp)
298          EVT_MOTION(self, self.OnMotion)          EVT_MOTION(self, self.OnMotion)
299            EVT_LEAVE_WINDOW(self, self.OnLeaveWindow)
300            wx.EVT_SIZE(self, self.OnSize)
301          wx.EVT_IDLE(self, self.OnIdle)          wx.EVT_IDLE(self, self.OnIdle)
302          self.interactor = interactor  
303          self.interactor.Subscribe(SELECTED_SHAPE, self.shape_selected)      def __del__(self):
304            wxWindow.__del__(self)
305            Publisher.__del__(self)
306    
307      def OnPaint(self, event):      def OnPaint(self, event):
308          dc = wxPaintDC(self)          dc = wxPaintDC(self)
309          if self.map is not None and self.map.HasLayers():          if self.map is not None and self.map.HasLayers():
310              # We have a non-empty map. Redraw it in idle time              # We have a non-empty map. Redraw it in idle time
311              self.redraw_on_idle = 1              self.redraw_on_idle = 1
312                # update the region that has to be redrawn
313                self.update_region.UnionRegion(self.GetUpdateRegion())
314          else:          else:
315              # 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
316              # the screen.              # the screen.
317                
318              # XXX it's probably possible to get rid of this. The              # XXX it's probably possible to get rid of this. The
319              # background color of the window is already white and the              # background color of the window is already white and the
320              # only thing we may have to do is to call self.Refresh()              # only thing we may have to do is to call self.Refresh()
321              # with a true argument in the right places.              # with a true argument in the right places.
322              dc.BeginDrawing()              dc.BeginDrawing()
323              dc.Clear()                          dc.Clear()
324              dc.EndDrawing()              dc.EndDrawing()
325    
326                # clear the region
327                self.update_region = wx.wxRegion()
328    
329      def do_redraw(self):      def do_redraw(self):
330          # This should only be called if we have a non-empty map. We draw          # This should only be called if we have a non-empty map.
331          # it into a memory DC and then blit it to the screen.  
332            # get the update region and reset it. We're not actually using
333            # it anymore, though.
334            update_box = self.update_region.GetBox()
335            self.update_region = wx.wxRegion()
336    
337            # Get the window size.
338          width, height = self.GetSizeTuple()          width, height = self.GetSizeTuple()
         bitmap = wx.wxEmptyBitmap(width, height)  
         dc = wx.wxMemoryDC()  
         dc.SelectObject(bitmap)  
         dc.BeginDrawing()  
339    
340          # clear the background          # If self.bitmap's still there, reuse it. Otherwise redraw it
341          dc.SetBrush(wx.wxWHITE_BRUSH)          if self.bitmap is not None:
342          dc.SetPen(wx.wxTRANSPARENT_PEN)              bitmap = self.bitmap
         dc.DrawRectangle(0, 0, width, height)  
   
         if 1: #self.interactor.selected_map is self.map:  
             selected_layer = self.interactor.selected_layer  
             selected_shape = self.interactor.selected_shape  
343          else:          else:
344              selected_layer = None              bitmap = wx.wxEmptyBitmap(width, height)
345              selected_shape = None              dc = wx.wxMemoryDC()
346                dc.SelectObject(bitmap)
347                dc.BeginDrawing()
348    
349                # clear the background
350                dc.SetBrush(wx.wxWHITE_BRUSH)
351                dc.SetPen(wx.wxTRANSPARENT_PEN)
352                dc.DrawRectangle(0, 0, width, height)
353    
354                if 1: #self.interactor.selected_map is self.map:
355                    selected_layer = self.interactor.selected_layer
356                    selected_shape = self.interactor.selected_shape
357                else:
358                    selected_layer = None
359                    selected_shape = None
360    
361          # draw the map into the bitmap              # draw the map into the bitmap
362          renderer = ScreenRenderer(dc, self.scale, self.offset)              renderer = ScreenRenderer(dc, self.scale, self.offset)
         renderer.RenderMap(self.map, selected_layer, selected_shape)  
363    
364          dc.EndDrawing()              # Pass the entire bitmap as update_region to the renderer.
365                # We're redrawing the whole bitmap, after all.
366                renderer.RenderMap(self.map, (0, 0, width, height),
367                                   selected_layer, selected_shape)
368    
369                dc.EndDrawing()
370                dc.SelectObject(wx.wxNullBitmap)
371                self.bitmap = bitmap
372    
373          # blit the bitmap to the screen          # blit the bitmap to the screen
374            dc = wx.wxMemoryDC()
375            dc.SelectObject(bitmap)
376          clientdc = wxClientDC(self)          clientdc = wxClientDC(self)
377          clientdc.BeginDrawing()          clientdc.BeginDrawing()
378          clientdc.Blit(0, 0, width, height, dc, 0, 0)          clientdc.Blit(0, 0, width, height, dc, 0, 0)
# Line 316  class MapCanvas(wxWindow): Line 383  class MapCanvas(wxWindow):
383          printout = MapPrintout(self.map)          printout = MapPrintout(self.map)
384          printer.Print(self, printout, wx.true)          printer.Print(self, printout, wx.true)
385          printout.Destroy()          printout.Destroy()
386            
387      def SetMap(self, map):      def SetMap(self, map):
388          redraw_channels = (LAYERS_CHANGED, LAYER_LEGEND_CHANGED,          redraw_channels = (LAYERS_CHANGED, LAYER_LEGEND_CHANGED,
389                             LAYER_VISIBILITY_CHANGED)                             LAYER_VISIBILITY_CHANGED)
390          if self.map is not None:          if self.map is not None:
391              for channel in redraw_channels:              for channel in redraw_channels:
392                  self.map.Unsubscribe(channel, self.redraw)                  self.map.Unsubscribe(channel, self.full_redraw)
393              self.map.Unsubscribe(MAP_PROJECTION_CHANGED,              self.map.Unsubscribe(MAP_PROJECTION_CHANGED,
394                                   self.projection_changed)                                   self.projection_changed)
395          self.map = map          self.map = map
396          if self.map is not None:          if self.map is not None:
397              for channel in redraw_channels:              for channel in redraw_channels:
398                  self.map.Subscribe(channel, self.redraw)                  self.map.Subscribe(channel, self.full_redraw)
399              self.map.Subscribe(MAP_PROJECTION_CHANGED, self.projection_changed)              self.map.Subscribe(MAP_PROJECTION_CHANGED, self.projection_changed)
400          self.FitMapToWindow()          self.FitMapToWindow()
401          # force a redraw. If map is not empty, it's already been called          # force a redraw. If map is not empty, it's already been called
402          # by FitMapToWindow but if map is empty it hasn't been called          # by FitMapToWindow but if map is empty it hasn't been called
403          # yet so we have to explicitly call it.          # yet so we have to explicitly call it.
404          self.redraw()          self.full_redraw()
405    
406      def Map(self):      def Map(self):
407          return self.map          return self.map
# Line 342  class MapCanvas(wxWindow): Line 409  class MapCanvas(wxWindow):
409      def redraw(self, *args):      def redraw(self, *args):
410          self.Refresh(0)          self.Refresh(0)
411    
412        def full_redraw(self, *args):
413            self.bitmap = None
414            self.redraw()
415    
416      def projection_changed(self, *args):      def projection_changed(self, *args):
417          self.FitMapToWindow()          self.FitMapToWindow()
418          self.redraw()          self.full_redraw()
419    
420      def set_view_transform(self, scale, offset):      def set_view_transform(self, scale, offset):
421          self.scale = scale          self.scale = scale
422          self.offset = offset          self.offset = offset
423          self.redraw()          self.full_redraw()
424    
425      def proj_to_win(self, x, y):      def proj_to_win(self, x, y):
426          """\          """\
# Line 446  class MapCanvas(wxWindow): Line 517  class MapCanvas(wxWindow):
517      def CurrentTool(self):      def CurrentTool(self):
518          return self.tool and self.tool.Name() or None          return self.tool and self.tool.Name() or None
519    
520        def CurrentPosition(self):
521            """Return current position of the mouse in projected coordinates.
522    
523            The result is a 2-tuple of floats with the coordinates. If the
524            mouse is not in the window, the result is None.
525            """
526            if self.current_position is not None:
527                x, y = self.current_position
528                return self.win_to_proj(x, y)
529            else:
530                return None
531    
532        def set_current_position(self, event):
533            """Set the current position from event
534    
535            Should be called by all events that contain mouse positions
536            especially EVT_MOTION. The event paramete may be None to
537            indicate the the pointer left the window.
538            """
539            if event is not None:
540                self.current_position = (event.m_x, event.m_y)
541            else:
542                self.current_position = None
543            self.issue(VIEW_POSITION)
544    
545      def OnLeftDown(self, event):      def OnLeftDown(self, event):
546            self.set_current_position(event)
547          if self.tool is not None:          if self.tool is not None:
548              self.drag_dc = wxClientDC(self)              self.drag_dc = wxClientDC(self)
549              self.drag_dc.SetLogicalFunction(wxINVERT)              self.drag_dc.SetLogicalFunction(wxINVERT)
# Line 455  class MapCanvas(wxWindow): Line 552  class MapCanvas(wxWindow):
552              self.tool.MouseDown(event)              self.tool.MouseDown(event)
553              self.tool.Show(self.drag_dc)              self.tool.Show(self.drag_dc)
554              self.dragging = 1              self.dragging = 1
555            
556      def OnLeftUp(self, event):      def OnLeftUp(self, event):
557          self.ReleaseMouse()          self.set_current_position(event)
558          if self.dragging:          if self.dragging:
559                self.ReleaseMouse()
560              self.tool.Hide(self.drag_dc)              self.tool.Hide(self.drag_dc)
561              self.tool.MouseUp(event)              self.tool.MouseUp(event)
562              self.drag_dc = None              self.drag_dc = None
563          self.dragging = 0          self.dragging = 0
564    
565      def OnMotion(self, event):      def OnMotion(self, event):
566            self.set_current_position(event)
567          if self.dragging:          if self.dragging:
568              self.tool.Hide(self.drag_dc)              self.tool.Hide(self.drag_dc)
569              self.tool.MouseMove(event)              self.tool.MouseMove(event)
570              self.tool.Show(self.drag_dc)              self.tool.Show(self.drag_dc)
571    
572        def OnLeaveWindow(self, event):
573            self.set_current_position(None)
574    
575      def OnIdle(self, event):      def OnIdle(self, event):
576          if self.redraw_on_idle:          if self.redraw_on_idle:
577              self.do_redraw()              self.do_redraw()
578          self.redraw_on_idle = 0          self.redraw_on_idle = 0
579    
580        def OnSize(self, event):
581            # the window's size has changed. We have to get a new bitmap. If
582            # we want to be clever we could try to get by without throwing
583            # everything away. E.g. when the window gets smaller, we could
584            # either keep the bitmap or create the new one from the old one.
585            # Even when the window becomes larger some parts of the bitmap
586            # could be reused.
587            self.full_redraw()
588    
589      def shape_selected(self, layer, shape):      def shape_selected(self, layer, shape):
590          self.redraw()          """Redraw the map.
591    
592            Receiver for the SELECTED_SHAPE messages. Try to redraw only
593            when necessary.
594            """
595            # A redraw is necessary when the display has to change, which
596            # means that either the status changes from having no selection
597            # to having a selection shape or vice versa, or when the fact
598            # whether there is a selection at all doesn't change, when the
599            # shape which is selected has changed (which means that layer or
600            # shapeid changes).
601            if ((shape is not None or self.last_selected_shape is not None)
602                and (shape != self.last_selected_shape
603                     or layer != self.last_selected_layer)):
604                self.full_redraw()
605    
606            # remember the selection so we can compare when it changes again.
607            self.last_selected_layer = layer
608            self.last_selected_shape = shape
609    
610        def unprojected_rect_around_point(self, x, y):
611            """return a rect a few pixels around (x, y) in unprojected corrdinates
612    
613      def find_shape_at(self, px, py, select_labels = 0, selected_layer = 1):          The return value is a tuple (minx, miny, maxx, maxy) suitable a
614            parameter to a layer's ShapesInRegion method.
615            """
616            map_proj = self.map.projection
617            if map_proj is not None:
618                inverse = map_proj.Inverse
619            else:
620                inverse = None
621    
622            xs = []
623            ys = []
624            for dx, dy in ((-1, -1), (1, -1), (1, 1), (-1, 1)):
625                px, py = self.win_to_proj(x + dx, y + dy)
626                if inverse:
627                    px, py = inverse(px, py)
628                xs.append(px)
629                ys.append(py)
630            return (min(xs), min(ys), max(xs), max(ys))
631    
632        def find_shape_at(self, px, py, select_labels = 0, searched_layer = None):
633          """Determine the shape at point px, py in window coords          """Determine the shape at point px, py in window coords
634    
635          Return the shape and the corresponding layer as a tuple (layer,          Return the shape and the corresponding layer as a tuple (layer,
# Line 488  class MapCanvas(wxWindow): Line 639  class MapCanvas(wxWindow):
639          search through the labels. If a label is found return it's index          search through the labels. If a label is found return it's index
640          as the shape and None as the layer.          as the shape and None as the layer.
641    
642          If the optional parameter selected_layer is true (default), only          If the optional parameter searched_layer is given (or not None
643          search in the currently selected layer.          which it defaults to), only search in that layer.
644          """          """
645          map_proj = self.map.projection          map_proj = self.map.projection
646          if map_proj is not None:          if map_proj is not None:
# Line 500  class MapCanvas(wxWindow): Line 651  class MapCanvas(wxWindow):
651          scale = self.scale          scale = self.scale
652          offx, offy = self.offset          offx, offy = self.offset
653    
654            box = self.unprojected_rect_around_point(px, py)
655    
656          if select_labels:          if select_labels:
657              labels = self.map.LabelLayer().Labels()              labels = self.map.LabelLayer().Labels()
658                
659              if labels:              if labels:
660                  dc = wxClientDC(self)                  dc = wxClientDC(self)
661                  font = wxFont(10, wx.wxSWISS, wx.wxNORMAL, wx.wxNORMAL)                  font = wxFont(10, wx.wxSWISS, wx.wxNORMAL, wx.wxNORMAL)
# Line 534  class MapCanvas(wxWindow): Line 687  class MapCanvas(wxWindow):
687                      if x <= px < x + width and y <= py <= y + height:                      if x <= px < x + width and y <= py <= y + height:
688                          return None, i                          return None, i
689    
690          if selected_layer:          if searched_layer:
691              layer = self.interactor.SelectedLayer()              layers = [searched_layer]
             if layer is not None:  
                 layers = [layer]  
             else:  
                 # no layer selected. Use an empty list to effectively  
                 # ignore all layers.  
                 layers = []  
692          else:          else:
693              layers = self.map.Layers()              layers = self.map.Layers()
694    
# Line 554  class MapCanvas(wxWindow): Line 701  class MapCanvas(wxWindow):
701    
702              filled = layer.fill is not None              filled = layer.fill is not None
703              stroked = layer.stroke is not None              stroked = layer.stroke is not None
704                    
705              layer_proj = layer.projection              layer_proj = layer.projection
706              if layer_proj is not None:              if layer_proj is not None:
707                  inverse = layer_proj.Inverse                  inverse = layer_proj.Inverse
708              else:              else:
709                  inverse = None                  inverse = None
710                    
711              shapetype = layer.ShapeType()              shapetype = layer.ShapeType()
712    
713              select_shape = -1              select_shape = -1
714    
715                shape_ids = layer.ShapesInRegion(box)
716                shape_ids.reverse()
717    
718              if shapetype == SHAPETYPE_POLYGON:              if shapetype == SHAPETYPE_POLYGON:
719                  for i in range(layer.NumShapes() - 1, -1, -1):                  for i in shape_ids:
720                      result = point_in_polygon_shape(layer.shapefile.cobject(),                      result = point_in_polygon_shape(layer.shapefile.cobject(),
721                                                      i,                                                      i,
722                                                      filled, stroked,                                                      filled, stroked,
# Line 576  class MapCanvas(wxWindow): Line 727  class MapCanvas(wxWindow):
727                          select_shape = i                          select_shape = i
728                          break                          break
729              elif shapetype == SHAPETYPE_ARC:              elif shapetype == SHAPETYPE_ARC:
730                  for i in range(layer.NumShapes() - 1, -1, -1):                  for i in shape_ids:
731                      result = point_in_polygon_shape(layer.shapefile.cobject(),                      result = point_in_polygon_shape(layer.shapefile.cobject(),
732                                                      i, 0, 1,                                                      i, 0, 1,
733                                                      map_proj, layer_proj,                                                      map_proj, layer_proj,
# Line 586  class MapCanvas(wxWindow): Line 737  class MapCanvas(wxWindow):
737                          select_shape = i                          select_shape = i
738                          break                          break
739              elif shapetype == SHAPETYPE_POINT:              elif shapetype == SHAPETYPE_POINT:
740                  for i in range(layer.NumShapes() - 1, -1, -1):                  for i in shape_ids:
741                      shape = layer.Shape(i)                      shape = layer.Shape(i)
742                      x, y = shape.Points()[0]                      x, y = shape.Points()[0]
743                      if inverse:                      if inverse:
# Line 603  class MapCanvas(wxWindow): Line 754  class MapCanvas(wxWindow):
754                  return layer, select_shape                  return layer, select_shape
755          return None, None          return None, None
756    
757      def SelectShapeAt(self, x, y):      def SelectShapeAt(self, x, y, layer = None):
758          layer, shape = self.find_shape_at(x, y)          """\
759            Select and return the shape and its layer at window position (x, y)
760    
761            If layer is given, only search in that layer. If no layer is
762            given, search through all layers.
763    
764            Return a tuple (layer, shapeid). If no shape is found, return
765            (None, None).
766            """
767            layer, shape = result = self.find_shape_at(x, y, searched_layer=layer)
768          # If layer is None, then shape will also be None. We don't want          # If layer is None, then shape will also be None. We don't want
769          # to deselect the currently selected layer, so we simply select          # to deselect the currently selected layer, so we simply select
770          # the already selected layer again.          # the already selected layer again.
771          if layer is None:          if layer is None:
772              layer = self.interactor.SelectedLayer()              layer = self.interactor.SelectedLayer()
773          self.interactor.SelectLayerAndShape(layer, shape)          self.interactor.SelectLayerAndShape(layer, shape)
774            return result
775    
776      def LabelShapeAt(self, x, y):      def LabelShapeAt(self, x, y):
777          ox = x; oy = y          ox = x; oy = y

Legend:
Removed from v.60  
changed lines
  Added in v.261

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26