/[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 542 by jonathan, Thu Mar 20 09:43:16 2003 UTC revision 1231 by jonathan, Wed Jun 18 14:46:57 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.
# Line 9  __version__ = "$Revision$" Line 10  __version__ = "$Revision$"
10    
11  from Thuban import _  from Thuban import _
12    
13    import resource
14    
15  from wxPython.wx import *  from wxPython.wx import *
 from dialogs import NonModalDialog  
16    
17  from Thuban.Model.layer import Layer  from Thuban.Model.layer import BaseLayer
18  from Thuban.Model.map import Map  from Thuban.Model.map import Map
19    from Thuban.Model.classification import ClassGroup
20    
21  from Thuban.Model.messages import *  from Thuban.Model.messages import \
22        MAP_STACKING_CHANGED, MAP_LAYERS_ADDED, MAP_LAYERS_REMOVED, LAYER_CHANGED,\
23        LAYER_VISIBILITY_CHANGED, TITLE_CHANGED
24    
25  from Thuban.Model.classification import ClassGroup  from Thuban.UI.messages import SCALE_CHANGED
26    
27  from Thuban.UI.classifier import ClassDataPreviewer  from Thuban.UI.classifier import ClassDataPreviewer
28    from Thuban.UI.dock import DockPanel
29    from Thuban.UI.scalebar import ScaleBar
30    
31    from Thuban.Lib.connector import ConnectorError
32    
33  ID_LEGEND_MOVEUP = 4001  ID_LEGEND_TOP = 4001
34  ID_LEGEND_MOVEDOWN = 4002  ID_LEGEND_RAISE = 4002
35  ID_LEGEND_TREE = 4003  ID_LEGEND_LOWER = 4003
36  ID_LEGEND_CLASSIFY = 4004  ID_LEGEND_BOTTOM = 4004
37  ID_LEGEND_SHOWLAYER = 4005  ID_LEGEND_TREE = 4005
38  ID_LEGEND_HIDELAYER = 4006  ID_LEGEND_PROPS = 4006
39    ID_LEGEND_SHOWLAYER = 4007
40    ID_LEGEND_HIDELAYER = 4008
41    
42  BMP_SIZE_W = 30  BMP_SIZE_W = 15
43  BMP_SIZE_H = 15  BMP_SIZE_H = 15
44    
45  class Legend(NonModalDialog):  TOP_BMP = "top_layer"
46    RAISE_BMP = "raise_layer"
47    LOWER_BMP = "lower_layer"
48    BOTTOM_BMP = "bottom_layer"
49    SHOW_BMP  = "show_layer"
50    HIDE_BMP  = "hide_layer"
51    PROPS_BMP = "layer_properties"
52    
     def __init__(self, parent, name, map):  
         NonModalDialog.__init__(self, parent, name,  
                                 _("Legend: %s") % map.Title())  
53    
54          self.parent = parent  class LegendPanel(DockPanel):
55    
56        def __init__(self, parent, map, mainWindow):
57            DockPanel.__init__(self, parent, -1)
58    
59            self.mainWindow = mainWindow
60            self.parent = parent
61    
62          panel = wxPanel(self, -1)          self.buttons = []
63    
         topBox = wxBoxSizer(wxVERTICAL)  
64          panelBox = wxBoxSizer(wxVERTICAL)          panelBox = wxBoxSizer(wxVERTICAL)
65    
66          buttonBox = wxGridSizer(2, 3, 0, 0)          self.toolBar = wxToolBar(self, -1)
67            self.toolBar.SetToolBitmapSize(wxSize(24, 24))
68    
69          self.buttons = []          bmp = resource.GetBitmapResource(TOP_BMP, wxBITMAP_TYPE_XPM)
70            self.toolBar.AddTool(ID_LEGEND_TOP, bmp,
71                shortHelpString=_("Top Layer"))
72    
73            bmp = resource.GetBitmapResource(RAISE_BMP, wxBITMAP_TYPE_XPM)
74            self.toolBar.AddTool(ID_LEGEND_RAISE, bmp,
75                shortHelpString=_("Raise Layer"))
76    
77            bmp = resource.GetBitmapResource(LOWER_BMP, wxBITMAP_TYPE_XPM)
78            self.toolBar.AddTool(ID_LEGEND_LOWER, bmp,
79                shortHelpString=_("Lower Layer"))
80    
81            bmp = resource.GetBitmapResource(BOTTOM_BMP, wxBITMAP_TYPE_XPM)
82            self.toolBar.AddTool(ID_LEGEND_BOTTOM, bmp,
83                shortHelpString=_("Bottom Layer"))
84    
85            bmp = resource.GetBitmapResource(SHOW_BMP, wxBITMAP_TYPE_XPM)
86            self.toolBar.AddTool(ID_LEGEND_SHOWLAYER, bmp,
87                shortHelpString=_("Show Layer"))
88    
89            bmp = resource.GetBitmapResource(HIDE_BMP, wxBITMAP_TYPE_XPM)
90            self.toolBar.AddTool(ID_LEGEND_HIDELAYER, bmp,
91                shortHelpString=_("Hide Layer"))
92    
93            bmp = resource.GetBitmapResource(PROPS_BMP, wxBITMAP_TYPE_XPM)
94            self.toolBar.AddTool(ID_LEGEND_PROPS, bmp,
95                shortHelpString=_("Edit Layer Properties"))
96    
97            self.toolBar.Realize()
98            panelBox.Add(self.toolBar, 0, wxGROW, 0)
99    
100            EVT_TOOL(self, ID_LEGEND_TOP, self._OnMoveTop)
101            EVT_TOOL(self, ID_LEGEND_RAISE, self._OnMoveUp)
102            EVT_TOOL(self, ID_LEGEND_LOWER, self._OnMoveDown)
103            EVT_TOOL(self, ID_LEGEND_BOTTOM, self._OnMoveBottom)
104            EVT_TOOL(self, ID_LEGEND_PROPS, self._OnProperties)
105            EVT_TOOL(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)
106            EVT_TOOL(self, ID_LEGEND_HIDELAYER, self._OnHideLayer)
107    
108          button = wxButton(self, ID_LEGEND_MOVEUP, _("Move Up"))          self.tree = LegendTree(self, ID_LEGEND_TREE, map, mainWindow)
         buttonBox.Add(button, 0, wxGROW | wxLEFT | wxRIGHT, 0)  
         self.buttons.append(button)  
109    
110          button = wxButton(self, ID_LEGEND_SHOWLAYER, _("Show Layer"))          panelBox.Add(self.tree, 1, wxGROW, 0)
         buttonBox.Add(button, 0, wxGROW | wxLEFT | wxRIGHT, 0)  
         self.buttons.append(button)  
111    
112          button = wxButton(self, ID_LEGEND_CLASSIFY, _("Classify"))          self.scalebarbitmap = ScaleBarBitmap(self, map, mainWindow)
113          buttonBox.Add(button, 0, wxGROW | wxLEFT | wxRIGHT, 0)          panelBox.Add(self.scalebarbitmap, 0, wxGROW, 0)
         self.buttons.append(button)  
114    
115          button = wxButton(self, ID_LEGEND_MOVEDOWN, _("Move Down"))          self.SetAutoLayout(True)
116          buttonBox.Add(button, 0, wxGROW | wxLEFT | wxRIGHT, 0)          self.SetSizer(panelBox)
117          self.buttons.append(button)          panelBox.SetSizeHints(self)
118    
         button = wxButton(self, ID_LEGEND_HIDELAYER, _("Hide Layer"))  
         buttonBox.Add(button, 0, wxGROW | wxLEFT | wxRIGHT, 0)  
         self.buttons.append(button)  
119    
120            self.panelBox = panelBox
121    
122          EVT_BUTTON(self, ID_LEGEND_MOVEUP, self._OnMoveUp)          self.__EnableButtons(False)
         EVT_BUTTON(self, ID_LEGEND_MOVEDOWN, self._OnMoveDown)  
         EVT_BUTTON(self, ID_LEGEND_CLASSIFY, self._OnClassify)  
         EVT_BUTTON(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)  
         EVT_BUTTON(self, ID_LEGEND_HIDELAYER, self._OnHideLayer)  
123    
124          panelBox.Add(buttonBox, 0, 0, 4)          self.Create()
125    
126          self.tree = LegendTree(self, ID_LEGEND_TREE, map)          EVT_CLOSE(self, self._OnClose)
127    
         panelBox.Add(self.tree, 1, wxGROW, 4)  
128    
129          panel.SetAutoLayout(True)      def GetMap(self):
130          panel.SetSizer(panelBox)          return self.tree.GetMap()
         panelBox.SetSizeHints(panel)  
131    
132          topBox.Add(panel, 1, wxGROW, 0)      def SetMap(self, map):
133          panelBox.SetSizeHints(self)          self.tree.SetMap(map)
134            self.scalebarbitmap.SetCanvas(self.mainWindow.canvas)
135    
136          self.SetAutoLayout(True)      def DoOnSelChanged(self, layer, group):
137          self.SetSizer(topBox)  
138            ok = isinstance(layer, BaseLayer)
139            self.__EnableButtons(ok)
140    
141            self.mainWindow.SelectLayer(layer)
142    
143        def DoOnProperties(self):
144            list = self.tree.GetSelectedHierarchy()
145    
146            ok = isinstance(list[0], BaseLayer)
147            if ok:
148                self.mainWindow.OpenLayerProperties(list[0], list[1])
149    
150      def DoOnSelChanged(self):      def Destroy(self):
151          self.__EnableButtons(self.tree.GetSelection().IsOk())          self.__Close()
152    
153      def _OnClassify(self, event):      def _OnProperties(self, event):
154          self.tree.DoOnClassify()          self.DoOnProperties()
155    
156        def _OnMoveTop(self, event):
157            self.tree.MoveCurrentItemTop()
158            
159      def _OnMoveUp(self, event):      def _OnMoveUp(self, event):
160          self.tree.MoveCurrentItemUp()          self.tree.MoveCurrentItemUp()
161    
162      def _OnMoveDown(self, event):      def _OnMoveDown(self, event):
163          self.tree.MoveCurrentItemDown()          self.tree.MoveCurrentItemDown()
164    
165        def _OnMoveBottom(self, event):
166            self.tree.MoveCurrentItemBottom()
167    
168      def _OnShowLayer(self, event):      def _OnShowLayer(self, event):
169          self.tree.DoOnShowLayer()          self.tree.DoOnShowLayer()
170          pass          pass
171    
172        #def Close(self, force = False):
173            #DockPanel.Close(self, force)
174            
175        def _OnClose(self, event):
176            self.__Close()
177    
178      def _OnHideLayer(self, event):      def _OnHideLayer(self, event):
179          self.tree.DoOnHideLayer()          self.tree.DoOnHideLayer()
180          pass          pass
181    
   
182      def __EnableButtons(self, on):      def __EnableButtons(self, on):
183          for b in self.buttons:          self.toolBar.EnableTool(ID_LEGEND_TOP, on)
184              b.Enable(on)          self.toolBar.EnableTool(ID_LEGEND_RAISE, on)
185            self.toolBar.EnableTool(ID_LEGEND_LOWER, on)
186            self.toolBar.EnableTool(ID_LEGEND_BOTTOM, on)
187            self.toolBar.EnableTool(ID_LEGEND_SHOWLAYER,  on)
188            self.toolBar.EnableTool(ID_LEGEND_HIDELAYER,  on)
189            self.toolBar.EnableTool(ID_LEGEND_PROPS, on)
190    
191        def __Close(self):
192            self.tree.Close()
193    
194  class LegendTree(wxTreeCtrl):  class LegendTree(wxTreeCtrl):
195    
196      def __init__(self, parent, id, map):      def __init__(self, parent, id, map, mainWindow):
197          wxTreeCtrl.__init__(self, parent, id,          wxTreeCtrl.__init__(self, parent, id,
198                              style = wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT,                              style = wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT,
199                              size = (200, 200))                              size = (200, 200))
200    
201            self.mainWindow = mainWindow
202            self.map = None
203          self.parent = parent          self.parent = parent
204          self.map = map          self.changing_selection = 0
         self.layer2id = None  
205    
206            #
207            # The image list used by the wxTreeCtrl causes problems when
208            # we remove layers and/or change a classification because it
209            # changes the image indices if you remove images from the list.
210            # Rather than removing unused images we use this list to keep
211            # track of which indices are available in the image list
212            # (because of a previous removal) and then  replace those indices
213            # with new images rather than appending to the end of the image
214            # list (assuming there are any that are available).
215            #
216            self.availImgListIndices = []
217    
218          self.image_list = None          self.image_list = None
219          self.emptyImageIndex = 0          self.emptyImageIndex = 0
220    
221          self.previewer = ClassDataPreviewer()          self.previewer = ClassDataPreviewer()
222    
223            self.preventExpandCollapse = False
224    
225          EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)          EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)
226          EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)          EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)
227            EVT_TREE_ITEM_EXPANDING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
228            EVT_TREE_ITEM_COLLAPSING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
229    
230          map.Subscribe(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged)          EVT_CLOSE(self, self._OnClose)
         map.Subscribe(MAP_LAYERS_CHANGED, self._OnMsgMapLayersChanged)  
   
         self.__FillTree(map)  
231    
232      def MoveCurrentItemUp(self):          self.SetMap(map)
         cur_id = self.GetSelection()  
         assert(cur_id.IsOk())  
233    
234          cur_data = self.GetPyData(cur_id)      def find_layer(self, layer):
235            """Return the tree item for the layer"""
236            root = self.GetRootItem()
237            id, cookie = self.GetFirstChild(root, 0)
238            while id.IsOk():
239                if self.GetPyData(id) is layer:
240                    return id
241                id, cookie = self.GetNextChild(root, cookie)
242            return None
243    
244        def _OnClose(self, event):
245            self.SetMap(None)
246    
247        def GetMap(self):
248            return self.map
249    
250        def SetMap(self, map):
251    
252            sub_list = [(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged),
253                        (MAP_LAYERS_ADDED, self._OnMsgMapLayersAdded),
254                        (MAP_LAYERS_REMOVED, self._OnMsgMapLayersRemoved)]
255    
256            if self.map is not None:
257                for msg, func in sub_list: self.map.Unsubscribe(msg, func)
258                #self.mainWindow.application.Unsubscribe(SESSION_REPLACED,
259                    #self._OnMsgMapsChanged)
260                #try:
261                    #self.mainWindow.application.session.Unsubscribe(MAPS_CHANGED,
262                        #self._OnMsgMapsChanged)
263                #except ConnectorError:
264                    #pass
265                self.DeleteAllItems()
266            
267            self.map = map
268    
269          #prev_id = self.GetPrevSibling(cur_id)          if self.map is not None:
270                for msg, func in sub_list: self.map.Subscribe(msg, func)
271                #self.mainWindow.application.session.Subscribe(MAPS_CHANGED,
272                    #self._OnMsgMapsChanged)
273                #self.mainWindow.application.Subscribe(SESSION_REPLACED,
274                    #self._OnMsgMapsChanged)
275                self.__FillTree(self.map)
276    
277          #      def MoveCurrentItemTop(self):
278          # Get out if there's nowhere to go          layer, group = self.GetSelectedHierarchy()
         #  
         #if prev_id == INVALID_TREE_ID: return  
279    
280          if isinstance(cur_data, Layer):          if layer is not None:
281              self.map.RaiseLayer(cur_data)              self.map.MoveLayerToTop(layer)
282          elif isinstance(cur_data, ClassGroup):          else:
283                assert False, "Shouldn't be allowed."
284              pass              pass
285    
286        def MoveCurrentItemUp(self):
287            layer, group = self.GetSelectedHierarchy()
288    
289            if layer is not None:
290                self.map.RaiseLayer(layer)
291          else:          else:
292              assert(False, "Shouldn't be here.")              assert False, "Shouldn't be allowed."
293              pass              pass
294    
295      def MoveCurrentItemDown(self):      def MoveCurrentItemDown(self):
296          cur_id = self.GetSelection()          layer, group = self.GetSelectedHierarchy()
         assert(cur_id.IsOk())  
   
         cur_data = self.GetPyData(cur_id)  
297    
298          if isinstance(cur_data, Layer):          if layer is not None:
299              self.map.LowerLayer(cur_data)              self.map.LowerLayer(layer)
         elif isinstance(cur_data, ClassGroup):  
             pass  
300          else:          else:
301              assert(False, "Shouldn't be here.")              assert False, "Shouldn't be allowed."
302              pass              pass
303    
304        def MoveCurrentItemBottom(self):
305            layer, group = self.GetSelectedHierarchy()
306    
307            if layer is not None:
308                self.map.MoveLayerToBottom(layer)
309            else:
310                assert False, "Shouldn't be allowed."
311                pass
312    
313      def OnCompareItems(self, item1, item2):      def OnCompareItems(self, item1, item2):
314    
315          data1 = self.GetPyData(item1)          data1 = self.GetPyData(item1)
316          data2 = self.GetPyData(item2)          data2 = self.GetPyData(item2)
317    
318          if isinstance(data1, Layer):          if isinstance(data1, BaseLayer):
319              layers = self.map.Layers()              layers = self.map.Layers()
320              return layers.index(data2) - layers.index(data1)              return layers.index(data2) - layers.index(data1)
321          else:          else:
322              return wxTreeCtrl.OnCompareItems(self, item1, item2)              return wxTreeCtrl.OnCompareItems(self, item1, item2)
323    
   
324      def DoOnShowLayer(self):      def DoOnShowLayer(self):
325          self.__ShowHideLayer(True)          layer, group = self.GetSelectedHierarchy()
326            layer.SetVisible(True)
327    
328      def DoOnHideLayer(self):      def DoOnHideLayer(self):
329          self.__ShowHideLayer(False)          layer, group = self.GetSelectedHierarchy()
330            layer.SetVisible(False)
331    
332      def DoOnClassify(self):      def Sort(self):
333          id = self.GetSelection()          self.SortChildren(self.GetRootItem())
         assert(id.IsOk())  
334    
335          item = self.GetPyData(id)      def GetSelectedHierarchy(self):
336          if isinstance(item, ClassGroup):          id = self.GetSelection()
             id = self.GetItemParent(id)  
             assert(id.IsOk())  
             item = self.GetPyData(id)  
337    
338          self.parent.parent.OpenClassifier(item)          if not id.IsOk():
339                return (None, None)
340    
341      def Sort(self):          layer = self.GetPyData(id)
342          self.SortChildren(self.GetRootItem())          group = None
343    
344            if isinstance(layer, ClassGroup):
345                id = self.GetItemParent(id)
346                assert id.IsOk()
347                group = layer
348                layer = self.GetPyData(id)
349    
350            return (layer, group)
351    
352        def _OnMsgMapsChanged(self):
353            #print self.map is self.mainWindow.Map()
354            self.SetMap(self.mainWindow.Map())
355            
356      def _OnSelChanged(self, event):      def _OnSelChanged(self, event):
357          self.parent.DoOnSelChanged()          # If we change the selection from normalize_selection do nothing.
358            if self.changing_selection:
359                return
360    
361            self.normalize_selection()
362            self.__UpdateSelection()
363    
364        def normalize_selection(self):
365            """Select the layer containing currently selected item"""
366            # This is really a workaround for a bug in wx where deleting a
367            # subtree with DeleteChildren does not update the selection
368            # properly and can lead to segfaults later because the return
369            # value of GetSelection points to invalid data.
370            item = self.GetSelection()
371            while item.IsOk():
372                object = self.GetPyData(item)
373                if isinstance(object, BaseLayer):
374                    break
375                item = self.GetItemParent(item)
376            else:
377                # No layer was found in the chain of parents, so there's
378                # nothing we can do.
379                return
380    
381            self.changing_selection = 1
382            try:
383                self.SelectItem(item)
384            finally:
385                self.changing_selection = 0
386    
387    
388        def OnItemExpandCollapse(self, event):
389            if self.preventExpandCollapse:
390                event.Veto()
391                self.preventExpandCollapse = False
392    
393      def _OnItemActivated(self, event):      def _OnItemActivated(self, event):
394          self.DoOnClassify()          self.preventExpandCollapse = True
395            self.parent.DoOnProperties()
396    
397      def _OnMsgLayerChanged(self, layer):      def _OnMsgLayerChanged(self, layer):
398          assert(isinstance(layer, Layer))          assert isinstance(layer, BaseLayer)
399    
400          id = self.layer2id[layer]          id = self.find_layer(layer)
401            assert id is not None
402    
403          self.__FillTreeLayer(id)          self.__FillTreeLayer(id)
404            self.__UpdateSelection()
405    
406      def _OnMsgMapStackingChanged(self, *args):      def _OnMsgMapStackingChanged(self, *args):
407          self.Sort()          self.Sort()
408            id = self.GetSelection()
409    
410      def _OnMsgMapLayersChanged(self, map):          if id.IsOk():
411          assert(id(map) == id(self.map))              self.EnsureVisible(id)
412            self.__UpdateSelection()
413    
414          self.__FillTree(self.map)      def _OnMsgMapLayersAdded(self, map):
415            assert map is self.map
416    
417      def __FillTree(self, map):          # Build a dict with all layers known by the the tree as keys
418            layers = {}
419            root = self.GetRootItem()
420            id, cookie = self.GetFirstChild(root, 0)
421            while id.IsOk():
422                layers[self.GetPyData(id)] = 1
423                id, cookie = self.GetNextChild(root, cookie)
424    
425          assert(isinstance(map, Map))          # Add layers in the map but not in the dict
426            i = 0
427            for l in map.Layers():
428                if not l in layers:
429                    self.__AddLayer(i, l)
430    
431          self.Freeze()          self.__UpdateSelection()
432    
433          self.__DeleteAllItems()      def _OnMsgMapLayersRemoved(self, map):
434            assert map is self.map
435    
436          if map.HasLayers():          layers = map.Layers()
437    
438              self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)          root = self.GetRootItem()
439                                                                                            id, cookie = self.GetFirstChild(root, 0)
440              bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)          while id.IsOk():
441              dc = wxMemoryDC()              if self.GetPyData(id) not in layers:
442              dc.SelectObject(bmp)                  self.__RemoveLayer(id)
443              dc.SetBrush(wxBLACK_BRUSH)              id, cookie = self.GetNextChild(root, cookie)
             dc.Clear()  
             dc.SelectObject(wxNullBitmap)  
                                                                                   
             self.emptyImageIndex = \  
                 self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))  
                                                                                   
             self.AssignImageList(self.image_list)  
444    
             root = self.AddRoot("")  
445    
446              for l in map.Layers():          self.__UpdateSelection()
447                  id = self.PrependItem(root, l.Title())  
448                  l.Subscribe(LAYER_CHANGED, self._OnMsgLayerChanged)      def _OnMsgLayerVisibilityChanged(self, layer):
449                  self.SetPyData(id, l)          assert isinstance(layer, BaseLayer)
450                  font = self.GetItemFont(id)  
451                  if not l.Visible():          self.__ShowHideLayer(layer)
452                      font.SetStyle(wxITALIC)          self.__UpdateSelection()
                     self.SetItemFont(id, font)  
453    
454                  self.layer2id[l] = id      def _OnMsgLayerTitleChanged(self, layer):
455    
456                  self.__FillTreeLayer(id)          id = self.find_layer(layer)
457                  self.Expand(id)          if id.IsOk():
458                self.SetItemText(id, layer.Title())
459            self.__UpdateSelection()
460    
461        def __UpdateSelection(self):
462            layer, group = self.GetSelectedHierarchy()
463            self.parent.DoOnSelChanged(layer, group)
464            
465        def __FillTree(self, map):
466    
467            self.Freeze()
468    
469            self.DeleteAllItems()
470    
471            if map.HasLayers():
472                root = self.GetRootItem()
473                for l in map.Layers():
474                    self.__AddLayer(0, l)
475    
476          self.Thaw()          self.Thaw()
477    
# Line 283  class LegendTree(wxTreeCtrl): Line 482  class LegendTree(wxTreeCtrl):
482    
483          self.DeleteChildren(pid)          self.DeleteChildren(pid)
484    
485          clazz = layer.GetClassification()          if layer.HasClassification():
486    
487          shapeType = layer.ShapeType()              clazz = layer.GetClassification()
488    
489          for g in clazz:              shapeType = layer.ShapeType()
             id = self.AppendItem(pid, g.GetDisplayText())  
             self.SetPyData(id, g)  
490    
491              bmp = self.__BuildGroupImage(g, shapeType)              show = layer.Visible()
492                for g in clazz:
493                    if g.IsVisible():
494                        id = self.AppendItem(pid, g.GetDisplayText())
495                        self.SetPyData(id, g)
496                        self.__SetVisibilityStyle(show, id)
497    
498                        bmp = self.__BuildGroupImage(g, shapeType)
499    
500                        if bmp is None:
501                            self.SetItemImage(id, -1)
502                            self.SetItemSelectedImage(id, -1)
503                        else:
504                            if self.availImgListIndices:
505                                i = self.availImgListIndices.pop(0)
506                                self.image_list.Replace(i, bmp)
507                            else:
508                                i = self.image_list.Add(bmp)
509    
510              if bmp is None:                          self.SetItemImage(id, i)
511                  self.SetItemImage(id, self.emptyImageIndex)                          self.SetItemSelectedImage(id, i)
             else:  
                 i = self.image_list.Add(bmp)  
                 self.SetItemImage(id, i)  
   
             #self.layer2id[g] = id  
512    
513          self.Thaw()          self.Thaw()
514    
515      def __BuildGroupImage(self, group, shapeType):      def __BuildGroupImage(self, group, shapeType):
         assert(isinstance(group, ClassGroup))  
516    
517          bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)          bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
518          #brush = wxBrush(Color2wxColour(item[1]), wxSOLID)          #brush = wxBrush(Color2wxColour(item[1]), wxSOLID)
# Line 316  class LegendTree(wxTreeCtrl): Line 524  class LegendTree(wxTreeCtrl):
524    
525          return bmp          return bmp
526    
527      def __DeleteAllItems(self):      def DeleteAllItems(self):
         self.DeleteAllItems()  
         self.layer2id = {}  
528    
529            pid = self.GetRootItem()
530    
531      def __ShowHideLayer(self, show):          id, cookie = self.GetFirstChild(pid, 123)
532          id = self.GetSelection()          while id.IsOk():
533          assert(id.IsOk())              self.__RemoveLayer(id)
534                id, cookie = self.GetNextChild(pid, cookie)
535    
536            wxTreeCtrl.DeleteAllItems(self)
537    
538        def __AddLayer(self, before, l):
539            root = self.GetRootItem()
540            id = self.InsertItemBefore(root, before,
541                                l.Title(),
542                                self.mapImageIndex,
543                                self.mapImageIndex)
544    
545            self.SetPyData(id, l)
546            self.__SetVisibilityStyle(l.Visible(), id)
547    
548            self.__FillTreeLayer(id)
549            self.Expand(id)
550    
551            l.Subscribe(LAYER_CHANGED, self._OnMsgLayerChanged)
552            l.Subscribe(LAYER_VISIBILITY_CHANGED,
553                        self._OnMsgLayerVisibilityChanged)
554            l.Subscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
555    
556        def __RemoveLayer(self, id):
557            self.DeleteChildren(id)
558    
559            layer = self.GetPyData(id)
560            layer.Unsubscribe(LAYER_CHANGED,
561                              self._OnMsgLayerChanged)
562            layer.Unsubscribe(LAYER_VISIBILITY_CHANGED,
563                              self._OnMsgLayerVisibilityChanged)
564            layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
565    
566            self.Delete(id)
567    
568        def DeleteChildren(self, pid):
569            id, cookie = self.GetFirstChild(pid, 123)
570            while id.IsOk():
571                self.availImgListIndices.append(self.GetItemImage(id))
572                id, cookie = self.GetNextChild(pid, cookie)
573            wxTreeCtrl.DeleteChildren(self, pid)
574    
575        def GetRootItem(self):
576            root = wxTreeCtrl.GetRootItem(self)
577    
578            if not root.IsOk():
579                self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)
580    
581                bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
582                dc = wxMemoryDC()
583                dc.SelectObject(bmp)
584                dc.SetBrush(wxBLACK_BRUSH)
585                dc.Clear()
586                dc.SelectObject(wxNullBitmap)
587    
588                self.emptyImageIndex = \
589                    self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))
590    
591                bmp = resource.GetBitmapResource("legend_icon_layer",
592                                                  wxBITMAP_TYPE_XPM)
593                self.mapImageIndex = \
594                    self.image_list.Add(bmp)
595    
596                self.AssignImageList(self.image_list)
597                self.availImgListIndices = []
598    
599                root = self.AddRoot("")
600    
601            return root
602    
603        def __SetVisibilityStyle(self, visible, id):
604            font = self.GetItemFont(id)
605    
606            if visible:
607                font.SetStyle(wxNORMAL)
608                color = wxBLACK
609            else:
610                #font.SetStyle(wxITALIC)
611                font.SetStyle(wxNORMAL)
612                color = wxLIGHT_GREY
613    
614            self.SetItemTextColour(id, color)
615            self.SetItemFont(id, font)
616                    
617          item = self.GetPyData(id)      def __ShowHideLayer(self, layer):
618          if isinstance(item, ClassGroup):          parent = self.find_layer(layer)
619              id = self.GetItemParent(id)          assert parent.IsOk()
620              assert(id.IsOk())  
621              item = self.GetPyData(id)          visible = layer.Visible()
622    
623            self.__SetVisibilityStyle(visible, parent)
624    
625            id, cookie = self.GetFirstChild(parent, 123)
626    
627          if show != item.Visible():          while id.IsOk():
628                self.__SetVisibilityStyle(visible, id)
629                id, cookie = self.GetNextChild(parent, cookie)
630                
631    class ScaleBarBitmap(wxBoxSizer):
632    
633        def __init__(self, parent, map, mainWindow):
634            # While the width is fixed, get the height _now_.
635            dc = wxMemoryDC()
636            textwidth, textheight = dc.GetTextExtent("%d"%0)
637            self.width = 210
638            self.height = textheight + 3*2 + 8
639    
640            wxBoxSizer.__init__(self, wxVERTICAL)
641            bmp=wxEmptyBitmap(self.width, self.height)
642            self.scalebarBitmap = wxStaticBitmap(parent, -1, bmp)
643            self.Add(self.scalebarBitmap, 0, wxALIGN_CENTER|wxLEFT|wxTOP|wxRIGHT, 1)
644    
645            self.mainWindow = mainWindow
646            self.parent = parent
647            self.canvas = None
648            self.SetCanvas(self.mainWindow.canvas)
649    
650              item.SetVisible(show)      def SetCanvas(self, canvas):
651            sub_list = [(SCALE_CHANGED, self._OnMsgScaleChanged)]
652    
653              font = self.GetItemFont(id)          if self.canvas is not None:
654              if show:              for msg, func in sub_list: self.canvas.Unsubscribe(msg, func)
655                  font.SetStyle(wxNORMAL)          
656                  self.SetItemFont(id, font)          self.canvas = canvas
657              else:          self.scalebar = ScaleBar(canvas.map)
658                  font.SetStyle(wxITALIC)  
659                  self.SetItemFont(id, font)          if self.canvas is not None:
660                for msg, func in sub_list: self.canvas.Subscribe(msg, func)
661                self.__SetScale(self.canvas.scale)
662    
663        def _OnMsgScaleChanged(self, scale):
664            self.__SetScale(scale)
665    
666        def __SetScale(self, scale):
667            bmp = wxEmptyBitmap(self.width, self.height)
668            dc = wxMemoryDC()
669            dc.SelectObject(bmp)
670            dc.Clear()
671    
672            if self.canvas.map is not None \
673                and self.canvas.map.projection is not None:
674                self.scalebar.DrawScaleBar(scale, dc, (0,0), dc.GetSizeTuple())
675    
676            self.scalebarBitmap.SetBitmap(bmp)
677    

Legend:
Removed from v.542  
changed lines
  Added in v.1231

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26