/[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 795 by jonathan, Wed Apr 30 17:01:06 2003 UTC revision 1252 by jonathan, Fri Jun 20 09:28:08 2003 UTC
# Line 1  Line 1 
1  # Copyright (c) 2001, 2002, 2003 by Intevation GmbH  # Copyright (c) 2001, 2002, 2003 by Intevation GmbH
2  # Authors:  # Authors:
3  # Jonathan Coles <[email protected]>  # Jonathan Coles <[email protected]>
4    # Frank Koormann <[email protected]>
5  #  #
6  # This program is free software under the GPL (>=v2)  # This program is free software under the GPL (>=v2)
7  # Read the file COPYING coming with Thuban for details.  # Read the file COPYING coming with Thuban for details.
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
16    
17  from wxPython.wx import *  from wxPython.wx import *
18    
19  from Thuban.Model.layer import Layer  from Thuban.Model.layer import BaseLayer
20  from Thuban.Model.map import Map  from Thuban.Model.map import Map
 from Thuban.Model.messages import *  
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 \
25        MAP_STACKING_CHANGED, MAP_LAYERS_ADDED, MAP_LAYERS_REMOVED, LAYER_CHANGED,\
26        LAYER_VISIBILITY_CHANGED, TITLE_CHANGED
27    
28    from Thuban.UI.messages import SCALE_CHANGED
29    
 from Thuban.UI.messages import *  
30  from Thuban.UI.classifier import ClassDataPreviewer  from Thuban.UI.classifier import ClassDataPreviewer
31  from Thuban.UI.dock import DockPanel  from Thuban.UI.dock import DockPanel
32    from Thuban.UI.scalebar import ScaleBar
33    
34  from Thuban.Lib.connector import ConnectorError  from Thuban.Lib.connector import ConnectorError
35    
36  ID_LEGEND_RAISE = 4001  ID_LEGEND_TOP = 4001
37  ID_LEGEND_LOWER = 4002  ID_LEGEND_RAISE = 4002
38  ID_LEGEND_TREE = 4003  ID_LEGEND_LOWER = 4003
39  ID_LEGEND_PROPS = 4004  ID_LEGEND_BOTTOM = 4004
40  ID_LEGEND_SHOWLAYER = 4005  ID_LEGEND_TREE = 4005
41  ID_LEGEND_HIDELAYER = 4006  ID_LEGEND_PROPS = 4006
42    ID_LEGEND_SHOWLAYER = 4007
43    ID_LEGEND_HIDELAYER = 4008
44    
45  BMP_SIZE_W = 30  BMP_SIZE_W = 15
46  BMP_SIZE_H = 15  BMP_SIZE_H = 15
47    
48    TOP_BMP = "top_layer"
49  RAISE_BMP = "raise_layer"  RAISE_BMP = "raise_layer"
50  LOWER_BMP = "lower_layer"  LOWER_BMP = "lower_layer"
51    BOTTOM_BMP = "bottom_layer"
52  SHOW_BMP  = "show_layer"  SHOW_BMP  = "show_layer"
53  HIDE_BMP  = "hide_layer"  HIDE_BMP  = "hide_layer"
54  PROPS_BMP = "layer_properties"  PROPS_BMP = "layer_properties"
# Line 56  class LegendPanel(DockPanel): Line 69  class LegendPanel(DockPanel):
69          self.toolBar = wxToolBar(self, -1)          self.toolBar = wxToolBar(self, -1)
70          self.toolBar.SetToolBitmapSize(wxSize(24, 24))          self.toolBar.SetToolBitmapSize(wxSize(24, 24))
71    
72            bmp = resource.GetBitmapResource(TOP_BMP, wxBITMAP_TYPE_XPM)
73            self.toolBar.AddTool(ID_LEGEND_TOP, bmp,
74                shortHelpString=_("Top Layer"))
75    
76          bmp = resource.GetBitmapResource(RAISE_BMP, wxBITMAP_TYPE_XPM)          bmp = resource.GetBitmapResource(RAISE_BMP, wxBITMAP_TYPE_XPM)
77          self.toolBar.AddTool(ID_LEGEND_RAISE, bmp,          self.toolBar.AddTool(ID_LEGEND_RAISE, bmp,
78              shortHelpString=_("Raise Layer"))              shortHelpString=_("Raise Layer"))
# Line 64  class LegendPanel(DockPanel): Line 81  class LegendPanel(DockPanel):
81          self.toolBar.AddTool(ID_LEGEND_LOWER, bmp,          self.toolBar.AddTool(ID_LEGEND_LOWER, bmp,
82              shortHelpString=_("Lower Layer"))              shortHelpString=_("Lower Layer"))
83    
84            bmp = resource.GetBitmapResource(BOTTOM_BMP, wxBITMAP_TYPE_XPM)
85            self.toolBar.AddTool(ID_LEGEND_BOTTOM, bmp,
86                shortHelpString=_("Bottom Layer"))
87    
88          bmp = resource.GetBitmapResource(SHOW_BMP, wxBITMAP_TYPE_XPM)          bmp = resource.GetBitmapResource(SHOW_BMP, wxBITMAP_TYPE_XPM)
89          self.toolBar.AddTool(ID_LEGEND_SHOWLAYER, bmp,          self.toolBar.AddTool(ID_LEGEND_SHOWLAYER, bmp,
90              shortHelpString=_("Show Layer"))              shortHelpString=_("Show Layer"))
# Line 79  class LegendPanel(DockPanel): Line 100  class LegendPanel(DockPanel):
100          self.toolBar.Realize()          self.toolBar.Realize()
101          panelBox.Add(self.toolBar, 0, wxGROW, 0)          panelBox.Add(self.toolBar, 0, wxGROW, 0)
102    
103            EVT_TOOL(self, ID_LEGEND_TOP, self._OnMoveTop)
104          EVT_TOOL(self, ID_LEGEND_RAISE, self._OnMoveUp)          EVT_TOOL(self, ID_LEGEND_RAISE, self._OnMoveUp)
105          EVT_TOOL(self, ID_LEGEND_LOWER, self._OnMoveDown)          EVT_TOOL(self, ID_LEGEND_LOWER, self._OnMoveDown)
106            EVT_TOOL(self, ID_LEGEND_BOTTOM, self._OnMoveBottom)
107          EVT_TOOL(self, ID_LEGEND_PROPS, self._OnProperties)          EVT_TOOL(self, ID_LEGEND_PROPS, self._OnProperties)
108          EVT_TOOL(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)          EVT_TOOL(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)
109          EVT_TOOL(self, ID_LEGEND_HIDELAYER, self._OnHideLayer)          EVT_TOOL(self, ID_LEGEND_HIDELAYER, self._OnHideLayer)
# Line 89  class LegendPanel(DockPanel): Line 112  class LegendPanel(DockPanel):
112    
113          panelBox.Add(self.tree, 1, wxGROW, 0)          panelBox.Add(self.tree, 1, wxGROW, 0)
114    
115            self.scalebarbitmap = ScaleBarBitmap(self, map, mainWindow)
116            panelBox.Add(self.scalebarbitmap, 0, wxGROW, 0)
117    
118          self.SetAutoLayout(True)          self.SetAutoLayout(True)
119          self.SetSizer(panelBox)          self.SetSizer(panelBox)
120          panelBox.SetSizeHints(self)          panelBox.SetSizeHints(self)
# Line 108  class LegendPanel(DockPanel): Line 134  class LegendPanel(DockPanel):
134    
135      def SetMap(self, map):      def SetMap(self, map):
136          self.tree.SetMap(map)          self.tree.SetMap(map)
137            self.scalebarbitmap.SetCanvas(self.mainWindow.canvas)
138    
139      def DoOnSelChanged(self, layer, group):      def DoOnSelChanged(self, layer, group):
140    
141          ok = isinstance(layer, Layer)          ok = isinstance(layer, BaseLayer)
142          self.__EnableButtons(ok)          self.__EnableButtons(ok)
143    
144          self.mainWindow.SelectLayer(layer)          self.mainWindow.SelectLayer(layer)
# Line 119  class LegendPanel(DockPanel): Line 146  class LegendPanel(DockPanel):
146      def DoOnProperties(self):      def DoOnProperties(self):
147          list = self.tree.GetSelectedHierarchy()          list = self.tree.GetSelectedHierarchy()
148    
149          ok = isinstance(list[0], Layer)          ok = isinstance(list[0], BaseLayer)
150          if ok:          if ok:
151              self.mainWindow.OpenLayerProperties(list[0], list[1])              self.mainWindow.OpenLayerProperties(list[0], list[1])
152    
# Line 129  class LegendPanel(DockPanel): Line 156  class LegendPanel(DockPanel):
156      def _OnProperties(self, event):      def _OnProperties(self, event):
157          self.DoOnProperties()          self.DoOnProperties()
158    
159        def _OnMoveTop(self, event):
160            self.tree.MoveCurrentItemTop()
161            
162      def _OnMoveUp(self, event):      def _OnMoveUp(self, event):
163          self.tree.MoveCurrentItemUp()          self.tree.MoveCurrentItemUp()
164    
165      def _OnMoveDown(self, event):      def _OnMoveDown(self, event):
166          self.tree.MoveCurrentItemDown()          self.tree.MoveCurrentItemDown()
167    
168        def _OnMoveBottom(self, event):
169            self.tree.MoveCurrentItemBottom()
170    
171      def _OnShowLayer(self, event):      def _OnShowLayer(self, event):
172          self.tree.DoOnShowLayer()          self.tree.DoOnShowLayer()
173          pass          pass
# Line 150  class LegendPanel(DockPanel): Line 183  class LegendPanel(DockPanel):
183          pass          pass
184    
185      def __EnableButtons(self, on):      def __EnableButtons(self, on):
186            self.toolBar.EnableTool(ID_LEGEND_TOP, on)
187          self.toolBar.EnableTool(ID_LEGEND_RAISE, on)          self.toolBar.EnableTool(ID_LEGEND_RAISE, on)
188          self.toolBar.EnableTool(ID_LEGEND_LOWER, on)          self.toolBar.EnableTool(ID_LEGEND_LOWER, on)
189            self.toolBar.EnableTool(ID_LEGEND_BOTTOM, on)
190          self.toolBar.EnableTool(ID_LEGEND_SHOWLAYER,  on)          self.toolBar.EnableTool(ID_LEGEND_SHOWLAYER,  on)
191          self.toolBar.EnableTool(ID_LEGEND_HIDELAYER,  on)          self.toolBar.EnableTool(ID_LEGEND_HIDELAYER,  on)
192          self.toolBar.EnableTool(ID_LEGEND_PROPS, on)          self.toolBar.EnableTool(ID_LEGEND_PROPS, on)
# Line 169  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
211            # we remove layers and/or change a classification because it
212            # changes the image indices if you remove images from the list.
213            # Rather than removing unused images we use this list to keep
214            # track of which indices are available in the image list
215            # (because of a previous removal) and then  replace those indices
216            # with new images rather than appending to the end of the image
217            # list (assuming there are any that are available).
218            #
219            self.availImgListIndices = []
220    
221          self.image_list = None          self.image_list = None
222          self.emptyImageIndex = 0          self.emptyImageIndex = 0
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 192  class LegendTree(wxTreeCtrl): Line 254  class LegendTree(wxTreeCtrl):
254      def SetMap(self, map):      def SetMap(self, map):
255    
256          sub_list = [(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged),          sub_list = [(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged),
257                      (MAP_LAYERS_ADDED, self._OnMsgMapLayersAddedRemoved),                      (MAP_LAYERS_ADDED, self._OnMsgMapLayersAdded),
258                      (MAP_LAYERS_REMOVED, self._OnMsgMapLayersAddedRemoved)]                      (MAP_LAYERS_REMOVED, self._OnMsgMapLayersRemoved)]
259    
260          if self.map is not None:          if self.map is not None:
261              for msg, func in sub_list: self.map.Unsubscribe(msg, func)              for msg, func in sub_list: self.map.Unsubscribe(msg, func)
# Line 204  class LegendTree(wxTreeCtrl): Line 266  class LegendTree(wxTreeCtrl):
266                      #self._OnMsgMapsChanged)                      #self._OnMsgMapsChanged)
267              #except ConnectorError:              #except ConnectorError:
268                  #pass                  #pass
269              self.__DeleteAllItems()              self.DeleteAllItems()
270                    
271          self.map = map          self.map = map
272    
# Line 216  class LegendTree(wxTreeCtrl): Line 278  class LegendTree(wxTreeCtrl):
278                  #self._OnMsgMapsChanged)                  #self._OnMsgMapsChanged)
279              self.__FillTree(self.map)              self.__FillTree(self.map)
280    
281                    def MoveCurrentItemTop(self):
282            layer, group = self.GetSelectedHierarchy()
283    
284            if layer is not None:
285                self.map.MoveLayerToTop(layer)
286            else:
287                assert False, "Shouldn't be allowed."
288                pass
289    
290      def MoveCurrentItemUp(self):      def MoveCurrentItemUp(self):
291          layer, group = self.GetSelectedHierarchy()          layer, group = self.GetSelectedHierarchy()
292    
# Line 235  class LegendTree(wxTreeCtrl): Line 305  class LegendTree(wxTreeCtrl):
305              assert False, "Shouldn't be allowed."              assert False, "Shouldn't be allowed."
306              pass              pass
307    
308        def MoveCurrentItemBottom(self):
309            layer, group = self.GetSelectedHierarchy()
310    
311            if layer is not None:
312                self.map.MoveLayerToBottom(layer)
313            else:
314                assert False, "Shouldn't be allowed."
315                pass
316    
317      def OnCompareItems(self, item1, item2):      def OnCompareItems(self, item1, item2):
318    
319          data1 = self.GetPyData(item1)          data1 = self.GetPyData(item1)
320          data2 = self.GetPyData(item2)          data2 = self.GetPyData(item2)
321    
322          if isinstance(data1, Layer):          if isinstance(data1, BaseLayer):
323              layers = self.map.Layers()              layers = self.map.Layers()
324              return layers.index(data2) - layers.index(data1)              return layers.index(data2) - layers.index(data1)
325          else:          else:
326              return wxTreeCtrl.OnCompareItems(self, item1, item2)              return wxTreeCtrl.OnCompareItems(self, item1, item2)
327    
   
328      def DoOnShowLayer(self):      def DoOnShowLayer(self):
         #self.__ShowHideLayer(True)  
329          layer, group = self.GetSelectedHierarchy()          layer, group = self.GetSelectedHierarchy()
330          layer.SetVisible(True)          layer.SetVisible(True)
331    
332      def DoOnHideLayer(self):      def DoOnHideLayer(self):
         #self.__ShowHideLayer(False)  
333          layer, group = self.GetSelectedHierarchy()          layer, group = self.GetSelectedHierarchy()
334          layer.SetVisible(False)          layer.SetVisible(False)
335    
# Line 282  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, Layer)          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          # XXX: yikes! this is so bad, we should be doing what is          self.__FillTreeLayer(id)
         #      commented out, but there is a problem with keeping  
         #      track of the images in the image list when we replace  
         #      a layer. it ends up causing a seg fault.  
         self.__FillTree(self.map)  
420          self.__UpdateSelection()          self.__UpdateSelection()
         #self.__FillTreeLayer(id)  
421    
422      def _OnMsgMapStackingChanged(self, *args):      def _OnMsgMapStackingChanged(self, *args):
423          self.Sort()          self.Sort()
# Line 309  class LegendTree(wxTreeCtrl): Line 427  class LegendTree(wxTreeCtrl):
427              self.EnsureVisible(id)              self.EnsureVisible(id)
428          self.__UpdateSelection()          self.__UpdateSelection()
429    
430      def _OnMsgMapLayersAddedRemoved(self, map):      def _OnMsgMapLayersAdded(self, map):
431            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()
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
443            for l in map.Layers():
444                if not l in layers:
445                    self.__AddLayer(i, l)
446    
447            self.__UpdateSelection()
448    
449        def _OnMsgMapLayersRemoved(self, map):
450          assert map is self.map          assert map is self.map
451    
452          self.__FillTree(self.map)          layers = map.Layers()
453    
454            root = self.GetRootItem()
455            id, cookie = self.GetFirstChild(root, 0)
456            while id.IsOk():
457                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    
464      def _OnMsgLayerVisibilityChanged(self, layer):      def _OnMsgLayerVisibilityChanged(self, layer):
465          assert isinstance(layer, Layer)          assert isinstance(layer, BaseLayer)
466    
467          self.__ShowHideLayer(layer)          self.__ShowHideLayer(layer)
468          self.__UpdateSelection()          self.__UpdateSelection()
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 336  class LegendTree(wxTreeCtrl): Line 482  class LegendTree(wxTreeCtrl):
482    
483          self.Freeze()          self.Freeze()
484    
485          self.__DeleteAllItems()          self.DeleteAllItems()
486    
487          if map.HasLayers():          if map.HasLayers():
488                root = self.GetRootItem()
             self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)  
                                                                                   
             bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)  
             dc = wxMemoryDC()  
             dc.SelectObject(bmp)  
             dc.SetBrush(wxBLACK_BRUSH)  
             dc.Clear()  
             dc.SelectObject(wxNullBitmap)  
                                                                                   
             self.emptyImageIndex = \  
                 self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))  
                                                                                   
             self.AssignImageList(self.image_list)  
   
             root = self.AddRoot("")  
   
489              for l in map.Layers():              for l in map.Layers():
490                  id = self.PrependItem(root, l.Title())                  self.__AddLayer(0, l)
                 l.Subscribe(LAYER_CHANGED, self._OnMsgLayerChanged)  
                 l.Subscribe(LAYER_VISIBILITY_CHANGED,  
                             self._OnMsgLayerVisibilityChanged)  
                 l.Subscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)  
                 self.SetPyData(id, l)  
                 self.__SetVisibilityStyle(l.Visible(), id)  
   
                 self.layer2id[l] = id  
   
                 self.__FillTreeLayer(id)  
                 self.Expand(id)  
491    
492          self.Thaw()          self.Thaw()
493    
# Line 379  class LegendTree(wxTreeCtrl): Line 498  class LegendTree(wxTreeCtrl):
498    
499          self.DeleteChildren(pid)          self.DeleteChildren(pid)
500    
501          clazz = layer.GetClassification()          if layer.HasClassification():
502    
503                clazz = layer.GetClassification()
504    
505                shapeType = layer.ShapeType()
506    
507          shapeType = layer.ShapeType()              show = layer.Visible()
508                for g in clazz:
509                    if g.IsVisible():
510                        id = self.AppendItem(pid, g.GetDisplayText())
511                        self.SetPyData(id, g)
512                        self.__SetVisibilityStyle(show, id)
513    
514                        bmp = self.__BuildGroupImage(g, shapeType)
515    
516                        if bmp is None:
517                            self.SetItemImage(id, -1)
518                            self.SetItemSelectedImage(id, -1)
519                        else:
520                            if self.availImgListIndices:
521                                i = self.availImgListIndices.pop(0)
522                                self.image_list.Replace(i, bmp)
523                            else:
524                                i = self.image_list.Add(bmp)
525    
526          show = layer.Visible()                          self.SetItemImage(id, i)
527          for g in clazz:                          self.SetItemSelectedImage(id, i)
             if g.IsVisible():  
                 id = self.AppendItem(pid, g.GetDisplayText())  
                 self.SetPyData(id, g)  
                 self.__SetVisibilityStyle(show, id)  
   
                 bmp = self.__BuildGroupImage(g, shapeType)  
   
                 if bmp is None:  
                     self.SetItemImage(id, self.emptyImageIndex)  
                 else:  
                     i = self.image_list.Add(bmp)  
                     self.SetItemImage(id, i)  
528    
529          self.Thaw()          self.Thaw()
530    
# Line 412  class LegendTree(wxTreeCtrl): Line 540  class LegendTree(wxTreeCtrl):
540    
541          return bmp          return bmp
542    
543      def __DeleteAllItems(self):      def DeleteAllItems(self):
544    
545          while len(self.layer2id) > 0:          pid = self.GetRootItem()
             layer, id = self.layer2id.popitem()  
             layer.Unsubscribe(LAYER_CHANGED,  
                               self._OnMsgLayerChanged)  
             layer.Unsubscribe(LAYER_VISIBILITY_CHANGED,  
                               self._OnMsgLayerVisibilityChanged)  
             layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)  
546    
547          self.DeleteAllItems()          id, cookie = self.GetFirstChild(pid, 123)
548            while id.IsOk():
549                self.__RemoveLayer(id)
550                id, cookie = self.GetNextChild(pid, cookie)
551    
552            wxTreeCtrl.DeleteAllItems(self)
553    
554        def __AddLayer(self, before, l):
555            root = self.GetRootItem()
556            id = self.InsertItemBefore(root, before,
557                                l.Title(),
558                                self.mapImageIndex,
559                                self.mapImageIndex)
560    
561            self.SetPyData(id, l)
562            self.__SetVisibilityStyle(l.Visible(), id)
563    
564            self.__FillTreeLayer(id)
565            self.Expand(id)
566    
567            l.Subscribe(LAYER_CHANGED, self._OnMsgLayerChanged)
568            l.Subscribe(LAYER_VISIBILITY_CHANGED,
569                        self._OnMsgLayerVisibilityChanged)
570            l.Subscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
571    
572        def __RemoveLayer(self, id):
573            self.DeleteChildren(id)
574    
575            layer = self.GetPyData(id)
576            layer.Unsubscribe(LAYER_CHANGED,
577                              self._OnMsgLayerChanged)
578            layer.Unsubscribe(LAYER_VISIBILITY_CHANGED,
579                              self._OnMsgLayerVisibilityChanged)
580            layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
581    
582            self.Delete(id)
583    
584        def DeleteChildren(self, pid):
585            id, cookie = self.GetFirstChild(pid, 123)
586            while id.IsOk():
587                self.availImgListIndices.append(self.GetItemImage(id))
588                id, cookie = self.GetNextChild(pid, cookie)
589            wxTreeCtrl.DeleteChildren(self, pid)
590    
591        def GetRootItem(self):
592            root = wxTreeCtrl.GetRootItem(self)
593    
594            if not root.IsOk():
595                self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)
596    
597                bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
598                dc = wxMemoryDC()
599                dc.SelectObject(bmp)
600                dc.SetBrush(wxBLACK_BRUSH)
601                dc.Clear()
602                dc.SelectObject(wxNullBitmap)
603    
604                self.emptyImageIndex = \
605                    self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))
606    
607                bmp = resource.GetBitmapResource("legend_icon_layer",
608                                                  wxBITMAP_TYPE_XPM)
609                self.mapImageIndex = \
610                    self.image_list.Add(bmp)
611    
612                self.AssignImageList(self.image_list)
613                self.availImgListIndices = []
614    
615                root = self.AddRoot("")
616    
617            return root
618    
619      def __SetVisibilityStyle(self, visible, id):      def __SetVisibilityStyle(self, visible, id):
620          font = self.GetItemFont(id)          font = self.GetItemFont(id)
# Line 431  class LegendTree(wxTreeCtrl): Line 623  class LegendTree(wxTreeCtrl):
623              font.SetStyle(wxNORMAL)              font.SetStyle(wxNORMAL)
624              color = wxBLACK              color = wxBLACK
625          else:          else:
626              font.SetStyle(wxITALIC)              #font.SetStyle(wxITALIC)
627                font.SetStyle(wxNORMAL)
628              color = wxLIGHT_GREY              color = wxLIGHT_GREY
629    
630          self.SetItemTextColour(id, color)          self.SetItemTextColour(id, color)
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 451  class LegendTree(wxTreeCtrl): Line 644  class LegendTree(wxTreeCtrl):
644              self.__SetVisibilityStyle(visible, id)              self.__SetVisibilityStyle(visible, id)
645              id, cookie = self.GetNextChild(parent, cookie)              id, cookie = self.GetNextChild(parent, cookie)
646                            
647    class ScaleBarBitmap(wxBoxSizer):
648    
649        def __init__(self, parent, map, mainWindow):
650            # While the width is fixed, get the height _now_.
651            dc = wxMemoryDC()
652            textwidth, textheight = dc.GetTextExtent("%d"%0)
653            self.width = 210
654            self.height = textheight + 3*2 + 8
655    
656            wxBoxSizer.__init__(self, wxVERTICAL)
657            bmp=wxEmptyBitmap(self.width, self.height)
658            self.scalebarBitmap = wxStaticBitmap(parent, -1, bmp)
659            self.Add(self.scalebarBitmap, 0, wxALIGN_CENTER|wxLEFT|wxTOP|wxRIGHT, 1)
660    
661            self.mainWindow = mainWindow
662            self.parent = parent
663            self.canvas = None
664            self.SetCanvas(self.mainWindow.canvas)
665    
666        def SetCanvas(self, canvas):
667            sub_list = [(SCALE_CHANGED, self._OnMsgScaleChanged)]
668    
669            if self.canvas is not None:
670                for msg, func in sub_list: self.canvas.Unsubscribe(msg, func)
671            
672            self.canvas = canvas
673            self.scalebar = ScaleBar(canvas.map)
674    
675            if self.canvas is not None:
676                for msg, func in sub_list: self.canvas.Subscribe(msg, func)
677                self.__SetScale(self.canvas.scale)
678    
679        def _OnMsgScaleChanged(self, scale):
680            self.__SetScale(scale)
681    
682        def __SetScale(self, scale):
683            bmp = wxEmptyBitmap(self.width, self.height)
684            dc = wxMemoryDC()
685            dc.SelectObject(bmp)
686            dc.Clear()
687    
688            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)
718    

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26