/[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 980 by frank, Thu May 22 11:41:14 2003 UTC revision 1895 by frank, Fri Oct 31 10:13:32 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 30  from Thuban.UI.scalebar import ScaleBar Line 33  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    ID_POPUP_TOP = 4501
46    ID_POPUP_UP  = 4502
47    ID_POPUP_DOWN = 4503
48    ID_POPUP_BOTTOM = 4504
49    ID_POPUP_PROPS  = 4506
50    ID_POPUP_VISIBLE = 4507
51    ID_POPUP_PROJ = 4509
52    ID_POPUP_REMOVE = 4510
53    ID_POPUP_SHOWTABLE = 4511
54    
55  BMP_SIZE_W = 30  BMP_SIZE_W = 15
56  BMP_SIZE_H = 15  BMP_SIZE_H = 15
57    
58    TOP_BMP = "top_layer"
59  RAISE_BMP = "raise_layer"  RAISE_BMP = "raise_layer"
60  LOWER_BMP = "lower_layer"  LOWER_BMP = "lower_layer"
61    BOTTOM_BMP = "bottom_layer"
62  SHOW_BMP  = "show_layer"  SHOW_BMP  = "show_layer"
63  HIDE_BMP  = "hide_layer"  HIDE_BMP  = "hide_layer"
64  PROPS_BMP = "layer_properties"  PROPS_BMP = "layer_properties"
# Line 62  class LegendPanel(DockPanel): Line 79  class LegendPanel(DockPanel):
79          self.toolBar = wxToolBar(self, -1)          self.toolBar = wxToolBar(self, -1)
80          self.toolBar.SetToolBitmapSize(wxSize(24, 24))          self.toolBar.SetToolBitmapSize(wxSize(24, 24))
81    
82            bmp = resource.GetBitmapResource(TOP_BMP, wxBITMAP_TYPE_XPM)
83            self.toolBar.AddTool(ID_LEGEND_TOP, bmp,
84                shortHelpString=_("Top Layer"))
85    
86          bmp = resource.GetBitmapResource(RAISE_BMP, wxBITMAP_TYPE_XPM)          bmp = resource.GetBitmapResource(RAISE_BMP, wxBITMAP_TYPE_XPM)
87          self.toolBar.AddTool(ID_LEGEND_RAISE, bmp,          self.toolBar.AddTool(ID_LEGEND_RAISE, bmp,
88              shortHelpString=_("Raise Layer"))              shortHelpString=_("Raise Layer"))
# Line 70  class LegendPanel(DockPanel): Line 91  class LegendPanel(DockPanel):
91          self.toolBar.AddTool(ID_LEGEND_LOWER, bmp,          self.toolBar.AddTool(ID_LEGEND_LOWER, bmp,
92              shortHelpString=_("Lower Layer"))              shortHelpString=_("Lower Layer"))
93    
94            bmp = resource.GetBitmapResource(BOTTOM_BMP, wxBITMAP_TYPE_XPM)
95            self.toolBar.AddTool(ID_LEGEND_BOTTOM, bmp,
96                shortHelpString=_("Bottom Layer"))
97    
98          bmp = resource.GetBitmapResource(SHOW_BMP, wxBITMAP_TYPE_XPM)          bmp = resource.GetBitmapResource(SHOW_BMP, wxBITMAP_TYPE_XPM)
99          self.toolBar.AddTool(ID_LEGEND_SHOWLAYER, bmp,          self.toolBar.AddTool(ID_LEGEND_SHOWLAYER, bmp,
100              shortHelpString=_("Show Layer"))              shortHelpString=_("Show Layer"))
# Line 85  class LegendPanel(DockPanel): Line 110  class LegendPanel(DockPanel):
110          self.toolBar.Realize()          self.toolBar.Realize()
111          panelBox.Add(self.toolBar, 0, wxGROW, 0)          panelBox.Add(self.toolBar, 0, wxGROW, 0)
112    
113            EVT_TOOL(self, ID_LEGEND_TOP, self._OnMoveTop)
114          EVT_TOOL(self, ID_LEGEND_RAISE, self._OnMoveUp)          EVT_TOOL(self, ID_LEGEND_RAISE, self._OnMoveUp)
115          EVT_TOOL(self, ID_LEGEND_LOWER, self._OnMoveDown)          EVT_TOOL(self, ID_LEGEND_LOWER, self._OnMoveDown)
116            EVT_TOOL(self, ID_LEGEND_BOTTOM, self._OnMoveBottom)
117          EVT_TOOL(self, ID_LEGEND_PROPS, self._OnProperties)          EVT_TOOL(self, ID_LEGEND_PROPS, self._OnProperties)
118          EVT_TOOL(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)          EVT_TOOL(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)
119          EVT_TOOL(self, ID_LEGEND_HIDELAYER, self._OnHideLayer)          EVT_TOOL(self, ID_LEGEND_HIDELAYER, self._OnHideLayer)
120    
121            EVT_MENU(self, ID_POPUP_PROPS, self._OnProperties)
122            EVT_MENU(self, ID_POPUP_TOP, self._OnMoveTop)
123            EVT_MENU(self, ID_POPUP_UP, self._OnMoveUp)
124            EVT_MENU(self, ID_POPUP_DOWN, self._OnMoveDown)
125            EVT_MENU(self, ID_POPUP_BOTTOM, self._OnMoveBottom)
126            EVT_MENU(self, ID_POPUP_VISIBLE, self._OnToggleVisibility)
127            EVT_MENU(self, ID_POPUP_PROJ, self._OnProjection)
128            EVT_MENU(self, ID_POPUP_REMOVE, self._OnRemoveLayer)
129            EVT_MENU(self, ID_POPUP_SHOWTABLE, self._OnShowTable)
130            
131          self.tree = LegendTree(self, ID_LEGEND_TREE, map, mainWindow)          self.tree = LegendTree(self, ID_LEGEND_TREE, map, mainWindow)
132    
133          panelBox.Add(self.tree, 1, wxGROW, 0)          panelBox.Add(self.tree, 1, wxGROW, 0)
# Line 139  class LegendPanel(DockPanel): Line 176  class LegendPanel(DockPanel):
176      def _OnProperties(self, event):      def _OnProperties(self, event):
177          self.DoOnProperties()          self.DoOnProperties()
178    
179        def _OnMoveTop(self, event):
180            self.tree.MoveCurrentItemTop()
181            
182      def _OnMoveUp(self, event):      def _OnMoveUp(self, event):
183          self.tree.MoveCurrentItemUp()          self.tree.MoveCurrentItemUp()
184    
185      def _OnMoveDown(self, event):      def _OnMoveDown(self, event):
186          self.tree.MoveCurrentItemDown()          self.tree.MoveCurrentItemDown()
187    
188        def _OnMoveBottom(self, event):
189            self.tree.MoveCurrentItemBottom()
190    
191      def _OnShowLayer(self, event):      def _OnShowLayer(self, event):
192          self.tree.DoOnShowLayer()          self.tree.DoOnShowLayer()
193          pass          pass
# Line 159  class LegendPanel(DockPanel): Line 202  class LegendPanel(DockPanel):
202          self.tree.DoOnHideLayer()          self.tree.DoOnHideLayer()
203          pass          pass
204    
205        def _OnToggleVisibility(self, event):
206            self.tree.ToggleVisibility()
207    
208        def _OnProjection(self, event):
209            self.tree.LayerProjection()
210    
211        def _OnRemoveLayer(self, event):
212            self.mainWindow.RemoveLayer()
213    
214        def _OnShowTable(self, event):
215            self.mainWindow.LayerShowTable()
216    
217      def __EnableButtons(self, on):      def __EnableButtons(self, on):
218            self.toolBar.EnableTool(ID_LEGEND_TOP, on)
219          self.toolBar.EnableTool(ID_LEGEND_RAISE, on)          self.toolBar.EnableTool(ID_LEGEND_RAISE, on)
220          self.toolBar.EnableTool(ID_LEGEND_LOWER, on)          self.toolBar.EnableTool(ID_LEGEND_LOWER, on)
221            self.toolBar.EnableTool(ID_LEGEND_BOTTOM, on)
222          self.toolBar.EnableTool(ID_LEGEND_SHOWLAYER,  on)          self.toolBar.EnableTool(ID_LEGEND_SHOWLAYER,  on)
223          self.toolBar.EnableTool(ID_LEGEND_HIDELAYER,  on)          self.toolBar.EnableTool(ID_LEGEND_HIDELAYER,  on)
224          self.toolBar.EnableTool(ID_LEGEND_PROPS, on)          self.toolBar.EnableTool(ID_LEGEND_PROPS, on)
# Line 179  class LegendTree(wxTreeCtrl): Line 236  class LegendTree(wxTreeCtrl):
236          self.mainWindow = mainWindow          self.mainWindow = mainWindow
237          self.map = None          self.map = None
238          self.parent = parent          self.parent = parent
239          self.layer2id = {}          self.changing_selection = 0
240    
241            #
242            # The image list used by the wxTreeCtrl causes problems when
243            # we remove layers and/or change a classification because it
244            # changes the image indices if you remove images from the list.
245            # Rather than removing unused images we use this list to keep
246            # track of which indices are available in the image list
247            # (because of a previous removal) and then  replace those indices
248            # with new images rather than appending to the end of the image
249            # list (assuming there are any that are available).
250            #
251            self.availImgListIndices = []
252    
253          self.image_list = None          self.image_list = None
254          self.emptyImageIndex = 0          self.emptyImageIndex = 0
255    
256          self.previewer = ClassDataPreviewer()          self.previewer = ClassDataPreviewer()
257    
258            self.preventExpandCollapse = False
259            self.raiseProperties = False
260    
261          EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)          EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)
262          EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)          EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)
263            EVT_TREE_ITEM_EXPANDING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
264            EVT_TREE_ITEM_COLLAPSING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
265            EVT_TREE_ITEM_RIGHT_CLICK(self, ID_LEGEND_TREE, self._OnRightClick)
266    
267          EVT_CLOSE(self, self._OnClose)          EVT_CLOSE(self, self._OnClose)
268    
269          self.SetMap(map)          self.SetMap(map)
270    
271        def _OnRightClick(self, event):
272            """Select item and pop up a context menu"""
273    
274            # The pop up menu is related to the legend tree, so we have direct
275            # access on the tree items. The events issued by the menu are handled
276            # by the legend panel, since most of the handlers are already
277            # implemented there.
278    
279            # Update item selection to the right click
280            item = event.GetItem()
281            self.SelectItem(item)
282    
283            # Create the menu
284            menu = wxMenu("", 0)
285    
286            # The "Visible" item is a special ...
287            menuitem = wxMenuItem(menu, ID_POPUP_VISIBLE, _("Visible"),
288                                    "", wxITEM_CHECK)
289            menu.AppendItem(menuitem)
290            layer, group = self.GetSelectedHierarchy()
291            menuitem.Check(layer.Visible())
292    
293            menu.AppendSeparator()
294            menu.Append(ID_POPUP_PROPS, _("&Properties..."))
295            menu.Append(ID_POPUP_PROJ, _("Pro&jection..."))
296            menu.Append(ID_POPUP_REMOVE, _("&Remove Layer"))
297            menu.Append(ID_POPUP_SHOWTABLE, _("Show Ta&ble"))
298            menu.AppendSeparator()
299            menu.Append(ID_POPUP_TOP, _("Top Layer"))
300            menu.Append(ID_POPUP_UP, _("Raise Layer"))
301            menu.Append(ID_POPUP_DOWN, _("Lower Layer"))
302            menu.Append(ID_POPUP_BOTTOM, _("Bottom Layer"))
303    
304            # Display the menu
305            pos = event.GetPoint()
306            shift = self.ClientToScreen((0,0))
307            self.PopupMenu(menu, pos)
308    
309        def find_layer(self, layer):
310            """Return the tree item for the layer"""
311            root = self.GetRootItem()
312            id, cookie = self.GetFirstChild(root, 0)
313            while id.IsOk():
314                if self.GetPyData(id) is layer:
315                    return id
316                id, cookie = self.GetNextChild(root, cookie)
317            return None
318    
319      def _OnClose(self, event):      def _OnClose(self, event):
320          self.SetMap(None)          self.SetMap(None)
321    
# Line 202  class LegendTree(wxTreeCtrl): Line 325  class LegendTree(wxTreeCtrl):
325      def SetMap(self, map):      def SetMap(self, map):
326    
327          sub_list = [(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged),          sub_list = [(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged),
328                      (MAP_LAYERS_ADDED, self._OnMsgMapLayersAddedRemoved),                      (MAP_LAYERS_ADDED, self._OnMsgMapLayersAdded),
329                      (MAP_LAYERS_REMOVED, self._OnMsgMapLayersAddedRemoved)]                      (MAP_LAYERS_REMOVED, self._OnMsgMapLayersRemoved)]
330    
331          if self.map is not None:          if self.map is not None:
332              for msg, func in sub_list: self.map.Unsubscribe(msg, func)              for msg, func in sub_list: self.map.Unsubscribe(msg, func)
# Line 214  class LegendTree(wxTreeCtrl): Line 337  class LegendTree(wxTreeCtrl):
337                      #self._OnMsgMapsChanged)                      #self._OnMsgMapsChanged)
338              #except ConnectorError:              #except ConnectorError:
339                  #pass                  #pass
340              self.__DeleteAllItems()              self.DeleteAllItems()
341                    
342          self.map = map          self.map = map
343    
# Line 226  class LegendTree(wxTreeCtrl): Line 349  class LegendTree(wxTreeCtrl):
349                  #self._OnMsgMapsChanged)                  #self._OnMsgMapsChanged)
350              self.__FillTree(self.map)              self.__FillTree(self.map)
351    
352        def MoveCurrentItemTop(self):
353            layer, group = self.GetSelectedHierarchy()
354    
355            if layer is not None:
356                self.map.MoveLayerToTop(layer)
357            else:
358                assert False, "Shouldn't be allowed."
359                pass
360    
361      def MoveCurrentItemUp(self):      def MoveCurrentItemUp(self):
362          layer, group = self.GetSelectedHierarchy()          layer, group = self.GetSelectedHierarchy()
363    
# Line 244  class LegendTree(wxTreeCtrl): Line 376  class LegendTree(wxTreeCtrl):
376              assert False, "Shouldn't be allowed."              assert False, "Shouldn't be allowed."
377              pass              pass
378    
379        def MoveCurrentItemBottom(self):
380            layer, group = self.GetSelectedHierarchy()
381    
382            if layer is not None:
383                self.map.MoveLayerToBottom(layer)
384            else:
385                assert False, "Shouldn't be allowed."
386                pass
387    
388      def OnCompareItems(self, item1, item2):      def OnCompareItems(self, item1, item2):
389    
390          data1 = self.GetPyData(item1)          data1 = self.GetPyData(item1)
# Line 256  class LegendTree(wxTreeCtrl): Line 397  class LegendTree(wxTreeCtrl):
397              return wxTreeCtrl.OnCompareItems(self, item1, item2)              return wxTreeCtrl.OnCompareItems(self, item1, item2)
398    
399      def DoOnShowLayer(self):      def DoOnShowLayer(self):
         #self.__ShowHideLayer(True)  
400          layer, group = self.GetSelectedHierarchy()          layer, group = self.GetSelectedHierarchy()
401          layer.SetVisible(True)          layer.SetVisible(True)
402    
403      def DoOnHideLayer(self):      def DoOnHideLayer(self):
         #self.__ShowHideLayer(False)  
404          layer, group = self.GetSelectedHierarchy()          layer, group = self.GetSelectedHierarchy()
405          layer.SetVisible(False)          layer.SetVisible(False)
406    
407        def ToggleVisibility(self):
408            layer, group = self.GetSelectedHierarchy()
409    
410            layer.SetVisible(not layer.Visible())
411    
412        def LayerProjection(self):
413            self.parent.mainWindow.LayerProjection()
414    
415      def Sort(self):      def Sort(self):
416          self.SortChildren(self.GetRootItem())          self.SortChildren(self.GetRootItem())
417    
# Line 290  class LegendTree(wxTreeCtrl): Line 437  class LegendTree(wxTreeCtrl):
437          self.SetMap(self.mainWindow.Map())          self.SetMap(self.mainWindow.Map())
438                    
439      def _OnSelChanged(self, event):      def _OnSelChanged(self, event):
440            # If we change the selection from normalize_selection do nothing.
441            if self.changing_selection:
442                return
443    
444            self.normalize_selection()
445          self.__UpdateSelection()          self.__UpdateSelection()
446    
447        def normalize_selection(self):
448            """Select the layer containing currently selected item"""
449            # This is really a workaround for a bug in wx where deleting a
450            # subtree with DeleteChildren does not update the selection
451            # properly and can lead to segfaults later because the return
452            # value of GetSelection points to invalid data.
453            item = self.GetSelection()
454            while item.IsOk():
455                object = self.GetPyData(item)
456                if isinstance(object, BaseLayer):
457                    break
458                item = self.GetItemParent(item)
459            else:
460                # No layer was found in the chain of parents, so there's
461                # nothing we can do.
462                return
463    
464            self.changing_selection = 1
465            try:
466                self.SelectItem(item)
467            finally:
468                self.changing_selection = 0
469    
470    
471        def OnItemExpandCollapse(self, event):
472            if self.preventExpandCollapse:
473                event.Veto()
474                self.preventExpandCollapse = False
475    
476      def _OnItemActivated(self, event):      def _OnItemActivated(self, event):
477          self.parent.DoOnProperties()          # The following looks strange but is need under Windows to
478            # raise the Properties on double-click: The tree control
479            # always gets an Expanded / Collapsed event after the ItemActivated
480            # on double click, which raises the main window again. We add a second
481            # ItemActivated event to the queue, which simply raises the already
482            # displayed window.
483            if self.raiseProperties:
484                self.parent.DoOnProperties()
485                self.raiseProperties = False
486            else:
487                self.raiseProperties = True
488                self.preventExpandCollapse = True
489                self.parent.DoOnProperties()
490                self.AddPendingEvent(event)
491    
492      def _OnMsgLayerChanged(self, layer):      def _OnMsgLayerChanged(self, layer):
493          assert isinstance(layer, BaseLayer)          assert isinstance(layer, BaseLayer)
494    
495          id = self.layer2id[layer]          id = self.find_layer(layer)
496          assert id.IsOk()          assert id is not None
497    
498          # 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)  
499          self.__UpdateSelection()          self.__UpdateSelection()
         #self.__FillTreeLayer(id)  
500    
501      def _OnMsgMapStackingChanged(self, *args):      def _OnMsgMapStackingChanged(self, *args):
502          self.Sort()          self.Sort()
# Line 317  class LegendTree(wxTreeCtrl): Line 506  class LegendTree(wxTreeCtrl):
506              self.EnsureVisible(id)              self.EnsureVisible(id)
507          self.__UpdateSelection()          self.__UpdateSelection()
508    
509      def _OnMsgMapLayersAddedRemoved(self, map):      def _OnMsgMapLayersAdded(self, map):
510          assert map is self.map          assert map is self.map
511    
512          self.__FillTree(self.map)          # Build a dict with all layers known by the the tree as keys
513            layers = {}
514            root = self.GetRootItem()
515            id, cookie = self.GetFirstChild(root, 0)
516            while id.IsOk():
517                layers[self.GetPyData(id)] = 1
518                id, cookie = self.GetNextChild(root, cookie)
519    
520            # Add layers in the map but not in the dict
521            i = 0
522            for l in map.Layers():
523                if not l in layers:
524                    self.__AddLayer(i, l)
525    
526            self.__UpdateSelection()
527    
528        def _OnMsgMapLayersRemoved(self, map):
529            assert map is self.map
530    
531            layers = map.Layers()
532    
533            root = self.GetRootItem()
534            id, cookie = self.GetFirstChild(root, 0)
535            while id.IsOk():
536                if self.GetPyData(id) not in layers:
537                    self.__RemoveLayer(id)
538                id, cookie = self.GetNextChild(root, cookie)
539    
540    
541          self.__UpdateSelection()          self.__UpdateSelection()
542    
543      def _OnMsgLayerVisibilityChanged(self, layer):      def _OnMsgLayerVisibilityChanged(self, layer):
# Line 331  class LegendTree(wxTreeCtrl): Line 548  class LegendTree(wxTreeCtrl):
548    
549      def _OnMsgLayerTitleChanged(self, layer):      def _OnMsgLayerTitleChanged(self, layer):
550    
551          id = self.layer2id[layer]          id = self.find_layer(layer)
552          if id.IsOk():          if id.IsOk():
553              self.SetItemText(id, layer.Title())              self.SetItemText(id, layer.Title())
554          self.__UpdateSelection()          self.__UpdateSelection()
# Line 344  class LegendTree(wxTreeCtrl): Line 561  class LegendTree(wxTreeCtrl):
561    
562          self.Freeze()          self.Freeze()
563    
564          self.__DeleteAllItems()          self.DeleteAllItems()
565    
566          if map.HasLayers():          if map.HasLayers():
567                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("")  
   
568              for l in map.Layers():              for l in map.Layers():
569                  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)  
570    
571          self.Thaw()          self.Thaw()
572    
# Line 403  class LegendTree(wxTreeCtrl): Line 593  class LegendTree(wxTreeCtrl):
593                      bmp = self.__BuildGroupImage(g, shapeType)                      bmp = self.__BuildGroupImage(g, shapeType)
594    
595                      if bmp is None:                      if bmp is None:
596                          self.SetItemImage(id, self.emptyImageIndex)                          self.SetItemImage(id, -1)
597                            self.SetItemSelectedImage(id, -1)
598                      else:                      else:
599                          i = self.image_list.Add(bmp)                          if self.availImgListIndices:
600                                i = self.availImgListIndices.pop(0)
601                                self.image_list.Replace(i, bmp)
602                            else:
603                                i = self.image_list.Add(bmp)
604    
605                          self.SetItemImage(id, i)                          self.SetItemImage(id, i)
606                            self.SetItemSelectedImage(id, i)
607    
608          self.Thaw()          self.Thaw()
609    
# Line 422  class LegendTree(wxTreeCtrl): Line 619  class LegendTree(wxTreeCtrl):
619    
620          return bmp          return bmp
621    
622      def __DeleteAllItems(self):      def DeleteAllItems(self):
623    
624          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)  
625    
626          self.DeleteAllItems()          id, cookie = self.GetFirstChild(pid, 123)
627            while id.IsOk():
628                self.__RemoveLayer(id)
629                id, cookie = self.GetNextChild(pid, cookie)
630    
631            wxTreeCtrl.DeleteAllItems(self)
632    
633        def __AddLayer(self, before, l):
634            root = self.GetRootItem()
635            id = self.InsertItemBefore(root, before,
636                                l.Title(),
637                                self.mapImageIndex,
638                                self.mapImageIndex)
639    
640            self.SetPyData(id, l)
641            self.__SetVisibilityStyle(l.Visible(), id)
642    
643            self.__FillTreeLayer(id)
644            self.Expand(id)
645    
646            l.Subscribe(LAYER_CHANGED, self._OnMsgLayerChanged)
647            l.Subscribe(LAYER_VISIBILITY_CHANGED,
648                        self._OnMsgLayerVisibilityChanged)
649            l.Subscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
650    
651        def __RemoveLayer(self, id):
652            self.DeleteChildren(id)
653    
654            layer = self.GetPyData(id)
655            layer.Unsubscribe(LAYER_CHANGED,
656                              self._OnMsgLayerChanged)
657            layer.Unsubscribe(LAYER_VISIBILITY_CHANGED,
658                              self._OnMsgLayerVisibilityChanged)
659            layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
660    
661            self.Delete(id)
662    
663        def DeleteChildren(self, pid):
664            id, cookie = self.GetFirstChild(pid, 123)
665            while id.IsOk():
666                self.availImgListIndices.append(self.GetItemImage(id))
667                id, cookie = self.GetNextChild(pid, cookie)
668            wxTreeCtrl.DeleteChildren(self, pid)
669    
670        def GetRootItem(self):
671            root = wxTreeCtrl.GetRootItem(self)
672    
673            if not root.IsOk():
674                self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)
675    
676                bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
677                dc = wxMemoryDC()
678                dc.SelectObject(bmp)
679                dc.SetBrush(wxBLACK_BRUSH)
680                dc.Clear()
681                dc.SelectObject(wxNullBitmap)
682    
683                self.emptyImageIndex = \
684                    self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))
685    
686                bmp = resource.GetBitmapResource("legend_icon_layer",
687                                                  wxBITMAP_TYPE_XPM)
688                self.mapImageIndex = \
689                    self.image_list.Add(bmp)
690    
691                self.AssignImageList(self.image_list)
692                self.availImgListIndices = []
693    
694                root = self.AddRoot("")
695    
696            return root
697    
698      def __SetVisibilityStyle(self, visible, id):      def __SetVisibilityStyle(self, visible, id):
699          font = self.GetItemFont(id)          font = self.GetItemFont(id)
# Line 449  class LegendTree(wxTreeCtrl): Line 710  class LegendTree(wxTreeCtrl):
710          self.SetItemFont(id, font)          self.SetItemFont(id, font)
711                    
712      def __ShowHideLayer(self, layer):      def __ShowHideLayer(self, layer):
713          parent = self.layer2id[layer]          parent = self.find_layer(layer)
714          assert parent.IsOk()          assert parent.IsOk()
715    
716          visible = layer.Visible()          visible = layer.Visible()
# Line 468  class ScaleBarBitmap(wxBoxSizer): Line 729  class ScaleBarBitmap(wxBoxSizer):
729          # While the width is fixed, get the height _now_.          # While the width is fixed, get the height _now_.
730          dc = wxMemoryDC()          dc = wxMemoryDC()
731          textwidth, textheight = dc.GetTextExtent("%d"%0)          textwidth, textheight = dc.GetTextExtent("%d"%0)
732          self.width = 200          self.width = 210
733          self.height = textheight + 3*2 + 8          self.height = textheight + 3*2 + 8
734    
735          wxBoxSizer.__init__(self, wxVERTICAL)          wxBoxSizer.__init__(self, wxVERTICAL)
# Line 503  class ScaleBarBitmap(wxBoxSizer): Line 764  class ScaleBarBitmap(wxBoxSizer):
764          dc.SelectObject(bmp)          dc.SelectObject(bmp)
765          dc.Clear()          dc.Clear()
766    
767          self.scalebar.DrawScaleBar(scale, dc, (0,0), dc.GetSizeTuple())          if self.canvas.map is not None \
768                and self.canvas.map.projection is not None:
769    
770                # if we are using a projection with geographics coordinates
771                # we need to change the scale value based on where we are
772                # on the globe.
773                if self.canvas.map.projection.GetProjectedUnits() \
774                    == PROJ_UNITS_DEGREES:
775    
776                    width, height = self.canvas.GetSizeTuple()
777                    long, lat = self.canvas.win_to_proj(width/2, height/2)
778    
779                    # slightly inaccurate, but if we are looking at
780                    # the north/south pole we could end up dividing by zero
781                    #
782                    # it shouldn't matter for our purposes that we ignore
783                    # the original sign of lat.
784                    if fabs(lat) > 89.9: lat = 89.9
785    
786                    #
787                    # one degree is about 111,133m at the equator
788                    # we need to adjust that for latitude as
789                    # we move north/south. use the center of the map
790                    # as the point to scale the length to.
791                    #
792                    scale = scale / (111133.0 * fabs(cos(lat * pi/180)))
793    
794                self.scalebar.DrawScaleBar(scale, dc, (0,0), dc.GetSizeTuple())
795    
796          self.scalebarBitmap.SetBitmap(bmp)          self.scalebarBitmap.SetBitmap(bmp)
797    

Legend:
Removed from v.980  
changed lines
  Added in v.1895

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26