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

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

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

revision 1102 by jonathan, Fri May 30 06:29:05 2003 UTC revision 1252 by jonathan, Fri Jun 20 09:28:08 2003 UTC
# Line 8  Line 8 
8    
9  __version__ = "$Revision$"  __version__ = "$Revision$"
10    
11    from  math import fabs, cos, pi
12    
13  from Thuban import _  from Thuban import _
14    
15  import resource  import resource
# Line 17  from wxPython.wx import * Line 19  from wxPython.wx import *
19  from Thuban.Model.layer import BaseLayer  from Thuban.Model.layer import BaseLayer
20  from Thuban.Model.map import Map  from Thuban.Model.map import Map
21  from Thuban.Model.classification import ClassGroup  from Thuban.Model.classification import ClassGroup
22    from Thuban.Model.proj import PROJ_UNITS_DEGREES
23    
24  from Thuban.Model.messages import \  from Thuban.Model.messages import \
25      MAP_STACKING_CHANGED, MAP_LAYERS_ADDED, MAP_LAYERS_REMOVED, LAYER_CHANGED,\      MAP_STACKING_CHANGED, MAP_LAYERS_ADDED, MAP_LAYERS_REMOVED, LAYER_CHANGED,\
# Line 201  class LegendTree(wxTreeCtrl): Line 204  class LegendTree(wxTreeCtrl):
204          self.mainWindow = mainWindow          self.mainWindow = mainWindow
205          self.map = None          self.map = None
206          self.parent = parent          self.parent = parent
207          self.layer2id = {}          self.changing_selection = 0
208    
209          #          #
210          # The image list used by the wxTreeCtrl causes problems when          # The image list used by the wxTreeCtrl causes problems when
# Line 220  class LegendTree(wxTreeCtrl): Line 223  class LegendTree(wxTreeCtrl):
223    
224          self.previewer = ClassDataPreviewer()          self.previewer = ClassDataPreviewer()
225    
226            self.preventExpandCollapse = False
227            self.raiseProperties = False
228    
229          EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)          EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)
230          EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)          EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)
231            EVT_TREE_ITEM_EXPANDING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
232            EVT_TREE_ITEM_COLLAPSING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
233    
234          EVT_CLOSE(self, self._OnClose)          EVT_CLOSE(self, self._OnClose)
235    
236          self.SetMap(map)          self.SetMap(map)
237    
238        def find_layer(self, layer):
239            """Return the tree item for the layer"""
240            root = self.GetRootItem()
241            id, cookie = self.GetFirstChild(root, 0)
242            while id.IsOk():
243                if self.GetPyData(id) is layer:
244                    return id
245                id, cookie = self.GetNextChild(root, cookie)
246            return None
247    
248      def _OnClose(self, event):      def _OnClose(self, event):
249          self.SetMap(None)          self.SetMap(None)
250    
# Line 340  class LegendTree(wxTreeCtrl): Line 358  class LegendTree(wxTreeCtrl):
358          self.SetMap(self.mainWindow.Map())          self.SetMap(self.mainWindow.Map())
359                    
360      def _OnSelChanged(self, event):      def _OnSelChanged(self, event):
361            # If we change the selection from normalize_selection do nothing.
362            if self.changing_selection:
363                return
364    
365            self.normalize_selection()
366          self.__UpdateSelection()          self.__UpdateSelection()
367    
368        def normalize_selection(self):
369            """Select the layer containing currently selected item"""
370            # This is really a workaround for a bug in wx where deleting a
371            # subtree with DeleteChildren does not update the selection
372            # properly and can lead to segfaults later because the return
373            # value of GetSelection points to invalid data.
374            item = self.GetSelection()
375            while item.IsOk():
376                object = self.GetPyData(item)
377                if isinstance(object, BaseLayer):
378                    break
379                item = self.GetItemParent(item)
380            else:
381                # No layer was found in the chain of parents, so there's
382                # nothing we can do.
383                return
384    
385            self.changing_selection = 1
386            try:
387                self.SelectItem(item)
388            finally:
389                self.changing_selection = 0
390    
391    
392        def OnItemExpandCollapse(self, event):
393            if self.preventExpandCollapse:
394                event.Veto()
395                self.preventExpandCollapse = False
396    
397      def _OnItemActivated(self, event):      def _OnItemActivated(self, event):
398          self.parent.DoOnProperties()          # The following looks strange but is need under Windows to
399            # raise the Properties on double-click: The tree control
400            # always gets an Expanded / Collapsed event after the ItemActivated
401            # on double click, which raises the main window again. We add a second
402            # ItemActivated event to the queue, which simply raises the already
403            # displayed window.
404            if self.raiseProperties:
405                self.parent.DoOnProperties()
406                self.raiseProperties = False
407            else:
408                self.raiseProperties = True
409                self.preventExpandCollapse = True
410                self.parent.DoOnProperties()
411                self.AddPendingEvent(event)
412    
413      def _OnMsgLayerChanged(self, layer):      def _OnMsgLayerChanged(self, layer):
414          assert isinstance(layer, BaseLayer)          assert isinstance(layer, BaseLayer)
415    
416          id = self.layer2id[layer]          id = self.find_layer(layer)
417          assert id.IsOk()          assert id is not None
418    
419          self.__FillTreeLayer(id)          self.__FillTreeLayer(id)
420          self.__UpdateSelection()          self.__UpdateSelection()
# Line 365  class LegendTree(wxTreeCtrl): Line 430  class LegendTree(wxTreeCtrl):
430      def _OnMsgMapLayersAdded(self, map):      def _OnMsgMapLayersAdded(self, map):
431          assert map is self.map          assert map is self.map
432    
433            # Build a dict with all layers known by the the tree as keys
434            layers = {}
435          root = self.GetRootItem()          root = self.GetRootItem()
436            id, cookie = self.GetFirstChild(root, 0)
437            while id.IsOk():
438                layers[self.GetPyData(id)] = 1
439                id, cookie = self.GetNextChild(root, cookie)
440    
441            # Add layers in the map but not in the dict
442          i = 0          i = 0
443          for l in map.Layers():          for l in map.Layers():
444              if not self.layer2id.has_key(l):              if not l in layers:
445                  self.__AddLayer(i, l)                  self.__AddLayer(i, l)
446    
447          self.__UpdateSelection()          self.__UpdateSelection()
# Line 377  class LegendTree(wxTreeCtrl): Line 449  class LegendTree(wxTreeCtrl):
449      def _OnMsgMapLayersRemoved(self, map):      def _OnMsgMapLayersRemoved(self, map):
450          assert map is self.map          assert map is self.map
451    
         layer, group = self.GetSelectedHierarchy()  
   
         if layer is None:  
             assert False, "Shouldn't be allowed."  
             return  
   
452          layers = map.Layers()          layers = map.Layers()
453    
454          for layer, id in self.layer2id.items():          root = self.GetRootItem()
455              if layer not in layers:          id, cookie = self.GetFirstChild(root, 0)
456                  if id.IsOk():          while id.IsOk():
457                      self.__RemoveLayer(id)              if self.GetPyData(id) not in layers:
458                    self.__RemoveLayer(id)
459                id, cookie = self.GetNextChild(root, cookie)
460    
461    
462          self.__UpdateSelection()          self.__UpdateSelection()
463    
# Line 400  class LegendTree(wxTreeCtrl): Line 469  class LegendTree(wxTreeCtrl):
469    
470      def _OnMsgLayerTitleChanged(self, layer):      def _OnMsgLayerTitleChanged(self, layer):
471    
472          id = self.layer2id[layer]          id = self.find_layer(layer)
473          if id.IsOk():          if id.IsOk():
474              self.SetItemText(id, layer.Title())              self.SetItemText(id, layer.Title())
475          self.__UpdateSelection()          self.__UpdateSelection()
# Line 492  class LegendTree(wxTreeCtrl): Line 561  class LegendTree(wxTreeCtrl):
561          self.SetPyData(id, l)          self.SetPyData(id, l)
562          self.__SetVisibilityStyle(l.Visible(), id)          self.__SetVisibilityStyle(l.Visible(), id)
563    
         self.layer2id[l] = id  
   
564          self.__FillTreeLayer(id)          self.__FillTreeLayer(id)
565          self.Expand(id)          self.Expand(id)
566    
# Line 513  class LegendTree(wxTreeCtrl): Line 580  class LegendTree(wxTreeCtrl):
580          layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)          layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
581    
582          self.Delete(id)          self.Delete(id)
         del self.layer2id[layer]  
583    
584      def DeleteChildren(self, pid):      def DeleteChildren(self, pid):
585          id, cookie = self.GetFirstChild(pid, 123)          id, cookie = self.GetFirstChild(pid, 123)
# Line 527  class LegendTree(wxTreeCtrl): Line 593  class LegendTree(wxTreeCtrl):
593    
594          if not root.IsOk():          if not root.IsOk():
595              self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)              self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)
596                                                                                    
597              bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)              bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
598              dc = wxMemoryDC()              dc = wxMemoryDC()
599              dc.SelectObject(bmp)              dc.SelectObject(bmp)
600              dc.SetBrush(wxBLACK_BRUSH)              dc.SetBrush(wxBLACK_BRUSH)
601              dc.Clear()              dc.Clear()
602              dc.SelectObject(wxNullBitmap)              dc.SelectObject(wxNullBitmap)
603                                                                                    
604              self.emptyImageIndex = \              self.emptyImageIndex = \
605                  self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))                  self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))
606                                                                                    
607              bmp = resource.GetBitmapResource("legend_icon_layer",              bmp = resource.GetBitmapResource("legend_icon_layer",
608                                                wxBITMAP_TYPE_XPM)                                                wxBITMAP_TYPE_XPM)
609              self.mapImageIndex = \              self.mapImageIndex = \
610                  self.image_list.Add(bmp)                  self.image_list.Add(bmp)
611    
612              self.AssignImageList(self.image_list)              self.AssignImageList(self.image_list)
613                self.availImgListIndices = []
614    
615              root = self.AddRoot("")              root = self.AddRoot("")
616    
# Line 564  class LegendTree(wxTreeCtrl): Line 631  class LegendTree(wxTreeCtrl):
631          self.SetItemFont(id, font)          self.SetItemFont(id, font)
632                    
633      def __ShowHideLayer(self, layer):      def __ShowHideLayer(self, layer):
634          parent = self.layer2id[layer]          parent = self.find_layer(layer)
635          assert parent.IsOk()          assert parent.IsOk()
636    
637          visible = layer.Visible()          visible = layer.Visible()
# Line 618  class ScaleBarBitmap(wxBoxSizer): Line 685  class ScaleBarBitmap(wxBoxSizer):
685          dc.SelectObject(bmp)          dc.SelectObject(bmp)
686          dc.Clear()          dc.Clear()
687    
688          self.scalebar.DrawScaleBar(scale, dc, (0,0), dc.GetSizeTuple())          if self.canvas.map is not None \
689                and self.canvas.map.projection is not None:
690    
691                # if we are using a projection with geographics coordinates
692                # we need to change the scale value based on where we are
693                # on the globe.
694                if self.canvas.map.projection.GetProjectedUnits() \
695                    == PROJ_UNITS_DEGREES:
696    
697                    width, height = self.canvas.GetSizeTuple()
698                    long, lat = self.canvas.win_to_proj(width/2, height/2)
699    
700                    # slightly inaccurate, but if we are looking at
701                    # the north/south pole we could end up dividing by zero
702                    #
703                    # it shouldn't matter for our purposes that we ignore
704                    # the original sign of lat.
705                    if fabs(lat) > 89.9: lat = 89.9
706    
707                    #
708                    # one degree is about 111,133m at the equator
709                    # we need to adjust that for latitude as
710                    # we move north/south. use the center of the map
711                    # as the point to scale the length to.
712                    #
713                    scale = scale / (111133.0 * fabs(cos(lat * pi/180)))
714    
715                self.scalebar.DrawScaleBar(scale, dc, (0,0), dc.GetSizeTuple())
716    
717          self.scalebarBitmap.SetBitmap(bmp)          self.scalebarBitmap.SetBitmap(bmp)
718    

Legend:
Removed from v.1102  
changed lines
  Added in v.1252

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26