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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1895 - (hide annotations)
Fri Oct 31 10:13:32 2003 UTC (21 years, 4 months ago) by frank
Original Path: trunk/thuban/Thuban/UI/legend.py
File MIME type: text/x-python
File size: 25094 byte(s)
Added two items to legend popup menu: Remove Layer and Show Layer Table

* Thuban/UI/legend.py
	(LegendPanel._OnRemoveLayer, LegendPanel._OnShowTable):
	New event handlers, call the corresponding mainwindow methods.
	(LegendTree._OnRightClick): Added items to popup menu.

1 jonathan 542 # Copyright (c) 2001, 2002, 2003 by Intevation GmbH
2     # Authors:
3     # Jonathan Coles <[email protected]>
4 frank 914 # Frank Koormann <[email protected]>
5 jonathan 542 #
6     # This program is free software under the GPL (>=v2)
7     # Read the file COPYING coming with Thuban for details.
8    
9     __version__ = "$Revision$"
10    
11 jonathan 1252 from math import fabs, cos, pi
12    
13 jonathan 542 from Thuban import _
14    
15 jonathan 652 import resource
16    
17 jonathan 542 from wxPython.wx import *
18    
19 jonathan 936 from Thuban.Model.layer import BaseLayer
20 jonathan 542 from Thuban.Model.map import Map
21     from Thuban.Model.classification import ClassGroup
22 jonathan 1252 from Thuban.Model.proj import PROJ_UNITS_DEGREES
23 jonathan 542
24 jonathan 882 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    
30 jonathan 542 from Thuban.UI.classifier import ClassDataPreviewer
31 jonathan 562 from Thuban.UI.dock import DockPanel
32 frank 864 from Thuban.UI.scalebar import ScaleBar
33 jonathan 542
34 jonathan 572 from Thuban.Lib.connector import ConnectorError
35    
36 frank 990 ID_LEGEND_TOP = 4001
37     ID_LEGEND_RAISE = 4002
38     ID_LEGEND_LOWER = 4003
39     ID_LEGEND_BOTTOM = 4004
40     ID_LEGEND_TREE = 4005
41     ID_LEGEND_PROPS = 4006
42     ID_LEGEND_SHOWLAYER = 4007
43     ID_LEGEND_HIDELAYER = 4008
44 jonathan 542
45 frank 1837 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 frank 1895 ID_POPUP_REMOVE = 4510
53     ID_POPUP_SHOWTABLE = 4511
54 frank 1837
55 frank 1050 BMP_SIZE_W = 15
56 jonathan 542 BMP_SIZE_H = 15
57    
58 frank 990 TOP_BMP = "top_layer"
59 jonathan 652 RAISE_BMP = "raise_layer"
60     LOWER_BMP = "lower_layer"
61 frank 990 BOTTOM_BMP = "bottom_layer"
62 jonathan 652 SHOW_BMP = "show_layer"
63     HIDE_BMP = "hide_layer"
64     PROPS_BMP = "layer_properties"
65    
66    
67 jonathan 562 class LegendPanel(DockPanel):
68    
69     def __init__(self, parent, map, mainWindow):
70     DockPanel.__init__(self, parent, -1)
71    
72     self.mainWindow = mainWindow
73     self.parent = parent
74    
75 jonathan 652 self.buttons = []
76    
77 jonathan 542 panelBox = wxBoxSizer(wxVERTICAL)
78    
79 jonathan 652 self.toolBar = wxToolBar(self, -1)
80 jonathan 658 self.toolBar.SetToolBitmapSize(wxSize(24, 24))
81 jonathan 542
82 frank 990 bmp = resource.GetBitmapResource(TOP_BMP, wxBITMAP_TYPE_XPM)
83     self.toolBar.AddTool(ID_LEGEND_TOP, bmp,
84     shortHelpString=_("Top Layer"))
85    
86 jonathan 652 bmp = resource.GetBitmapResource(RAISE_BMP, wxBITMAP_TYPE_XPM)
87     self.toolBar.AddTool(ID_LEGEND_RAISE, bmp,
88     shortHelpString=_("Raise Layer"))
89 jonathan 542
90 jonathan 652 bmp = resource.GetBitmapResource(LOWER_BMP, wxBITMAP_TYPE_XPM)
91     self.toolBar.AddTool(ID_LEGEND_LOWER, bmp,
92     shortHelpString=_("Lower Layer"))
93 jonathan 542
94 frank 990 bmp = resource.GetBitmapResource(BOTTOM_BMP, wxBITMAP_TYPE_XPM)
95     self.toolBar.AddTool(ID_LEGEND_BOTTOM, bmp,
96     shortHelpString=_("Bottom Layer"))
97    
98 jonathan 652 bmp = resource.GetBitmapResource(SHOW_BMP, wxBITMAP_TYPE_XPM)
99     self.toolBar.AddTool(ID_LEGEND_SHOWLAYER, bmp,
100     shortHelpString=_("Show Layer"))
101 jonathan 542
102 jonathan 652 bmp = resource.GetBitmapResource(HIDE_BMP, wxBITMAP_TYPE_XPM)
103     self.toolBar.AddTool(ID_LEGEND_HIDELAYER, bmp,
104     shortHelpString=_("Hide Layer"))
105 jonathan 542
106 jonathan 652 bmp = resource.GetBitmapResource(PROPS_BMP, wxBITMAP_TYPE_XPM)
107     self.toolBar.AddTool(ID_LEGEND_PROPS, bmp,
108     shortHelpString=_("Edit Layer Properties"))
109 jonathan 542
110 jonathan 652 self.toolBar.Realize()
111 jonathan 668 panelBox.Add(self.toolBar, 0, wxGROW, 0)
112 jonathan 542
113 frank 990 EVT_TOOL(self, ID_LEGEND_TOP, self._OnMoveTop)
114 jonathan 652 EVT_TOOL(self, ID_LEGEND_RAISE, self._OnMoveUp)
115     EVT_TOOL(self, ID_LEGEND_LOWER, self._OnMoveDown)
116 frank 990 EVT_TOOL(self, ID_LEGEND_BOTTOM, self._OnMoveBottom)
117 jonathan 652 EVT_TOOL(self, ID_LEGEND_PROPS, self._OnProperties)
118     EVT_TOOL(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)
119     EVT_TOOL(self, ID_LEGEND_HIDELAYER, self._OnHideLayer)
120 jonathan 542
121 frank 1837 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 frank 1895 EVT_MENU(self, ID_POPUP_REMOVE, self._OnRemoveLayer)
129     EVT_MENU(self, ID_POPUP_SHOWTABLE, self._OnShowTable)
130 frank 1837
131 jonathan 562 self.tree = LegendTree(self, ID_LEGEND_TREE, map, mainWindow)
132 jonathan 542
133 jonathan 658 panelBox.Add(self.tree, 1, wxGROW, 0)
134 jonathan 542
135 frank 854 self.scalebarbitmap = ScaleBarBitmap(self, map, mainWindow)
136     panelBox.Add(self.scalebarbitmap, 0, wxGROW, 0)
137    
138 jonathan 562 self.SetAutoLayout(True)
139     self.SetSizer(panelBox)
140 jonathan 542 panelBox.SetSizeHints(self)
141    
142 jonathan 658
143 jonathan 562 self.panelBox = panelBox
144 jonathan 542
145 jonathan 652 self.__EnableButtons(False)
146    
147 jonathan 658 self.Create()
148    
149 jonathan 572 EVT_CLOSE(self, self._OnClose)
150    
151    
152 jonathan 562 def GetMap(self):
153     return self.tree.GetMap()
154    
155     def SetMap(self, map):
156     self.tree.SetMap(map)
157 frank 854 self.scalebarbitmap.SetCanvas(self.mainWindow.canvas)
158 jonathan 562
159 jonathan 572 def DoOnSelChanged(self, layer, group):
160 jonathan 542
161 jonathan 936 ok = isinstance(layer, BaseLayer)
162 jonathan 572 self.__EnableButtons(ok)
163    
164 jonathan 655 self.mainWindow.SelectLayer(layer)
165 jonathan 568
166 jonathan 639 def DoOnProperties(self):
167 jonathan 572 list = self.tree.GetSelectedHierarchy()
168    
169 jonathan 936 ok = isinstance(list[0], BaseLayer)
170 jonathan 572 if ok:
171 jonathan 639 self.mainWindow.OpenLayerProperties(list[0], list[1])
172 jonathan 572
173 jonathan 578 def Destroy(self):
174     self.__Close()
175    
176 jonathan 639 def _OnProperties(self, event):
177     self.DoOnProperties()
178 jonathan 542
179 frank 990 def _OnMoveTop(self, event):
180     self.tree.MoveCurrentItemTop()
181    
182 jonathan 542 def _OnMoveUp(self, event):
183     self.tree.MoveCurrentItemUp()
184    
185     def _OnMoveDown(self, event):
186     self.tree.MoveCurrentItemDown()
187    
188 frank 990 def _OnMoveBottom(self, event):
189     self.tree.MoveCurrentItemBottom()
190    
191 jonathan 542 def _OnShowLayer(self, event):
192     self.tree.DoOnShowLayer()
193     pass
194    
195 jonathan 578 #def Close(self, force = False):
196     #DockPanel.Close(self, force)
197    
198 jonathan 572 def _OnClose(self, event):
199 jonathan 578 self.__Close()
200 jonathan 572
201 jonathan 542 def _OnHideLayer(self, event):
202     self.tree.DoOnHideLayer()
203     pass
204    
205 frank 1837 def _OnToggleVisibility(self, event):
206     self.tree.ToggleVisibility()
207    
208     def _OnProjection(self, event):
209     self.tree.LayerProjection()
210    
211 frank 1895 def _OnRemoveLayer(self, event):
212     self.mainWindow.RemoveLayer()
213    
214     def _OnShowTable(self, event):
215     self.mainWindow.LayerShowTable()
216    
217 jonathan 542 def __EnableButtons(self, on):
218 frank 990 self.toolBar.EnableTool(ID_LEGEND_TOP, on)
219 jonathan 652 self.toolBar.EnableTool(ID_LEGEND_RAISE, on)
220     self.toolBar.EnableTool(ID_LEGEND_LOWER, on)
221 frank 990 self.toolBar.EnableTool(ID_LEGEND_BOTTOM, on)
222 jonathan 652 self.toolBar.EnableTool(ID_LEGEND_SHOWLAYER, on)
223     self.toolBar.EnableTool(ID_LEGEND_HIDELAYER, on)
224     self.toolBar.EnableTool(ID_LEGEND_PROPS, on)
225 jonathan 542
226 jonathan 578 def __Close(self):
227     self.tree.Close()
228    
229 jonathan 542 class LegendTree(wxTreeCtrl):
230    
231 jonathan 562 def __init__(self, parent, id, map, mainWindow):
232 jonathan 542 wxTreeCtrl.__init__(self, parent, id,
233     style = wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT,
234     size = (200, 200))
235    
236 jonathan 572 self.mainWindow = mainWindow
237 jonathan 562 self.map = None
238 jonathan 542 self.parent = parent
239 bh 1113 self.changing_selection = 0
240 jonathan 542
241 jonathan 1102 #
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 jonathan 542 self.image_list = None
254     self.emptyImageIndex = 0
255    
256     self.previewer = ClassDataPreviewer()
257    
258 jonathan 1211 self.preventExpandCollapse = False
259 frank 1241 self.raiseProperties = False
260 jonathan 1211
261 jonathan 542 EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)
262     EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)
263 jonathan 1211 EVT_TREE_ITEM_EXPANDING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
264     EVT_TREE_ITEM_COLLAPSING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
265 frank 1837 EVT_TREE_ITEM_RIGHT_CLICK(self, ID_LEGEND_TREE, self._OnRightClick)
266 jonathan 542
267 jonathan 572 EVT_CLOSE(self, self._OnClose)
268    
269 jonathan 562 self.SetMap(map)
270 jonathan 542
271 frank 1895 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 bh 1129 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 jonathan 572 def _OnClose(self, event):
320     self.SetMap(None)
321    
322 jonathan 562 def GetMap(self):
323     return self.map
324 jonathan 542
325 jonathan 562 def SetMap(self, map):
326    
327     sub_list = [(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged),
328 jonathan 1102 (MAP_LAYERS_ADDED, self._OnMsgMapLayersAdded),
329     (MAP_LAYERS_REMOVED, self._OnMsgMapLayersRemoved)]
330 jonathan 562
331     if self.map is not None:
332     for msg, func in sub_list: self.map.Unsubscribe(msg, func)
333 jonathan 572 #self.mainWindow.application.Unsubscribe(SESSION_REPLACED,
334     #self._OnMsgMapsChanged)
335     #try:
336     #self.mainWindow.application.session.Unsubscribe(MAPS_CHANGED,
337     #self._OnMsgMapsChanged)
338     #except ConnectorError:
339     #pass
340 jonathan 1102 self.DeleteAllItems()
341 jonathan 562
342     self.map = map
343    
344     if self.map is not None:
345     for msg, func in sub_list: self.map.Subscribe(msg, func)
346 jonathan 572 #self.mainWindow.application.session.Subscribe(MAPS_CHANGED,
347     #self._OnMsgMapsChanged)
348     #self.mainWindow.application.Subscribe(SESSION_REPLACED,
349     #self._OnMsgMapsChanged)
350 jonathan 562 self.__FillTree(self.map)
351    
352 frank 990 def MoveCurrentItemTop(self):
353     layer, group = self.GetSelectedHierarchy()
354    
355     if layer is not None:
356 jonathan 1102 self.map.MoveLayerToTop(layer)
357 frank 990 else:
358     assert False, "Shouldn't be allowed."
359     pass
360    
361 jonathan 542 def MoveCurrentItemUp(self):
362 jonathan 795 layer, group = self.GetSelectedHierarchy()
363 jonathan 542
364 jonathan 795 if layer is not None:
365     self.map.RaiseLayer(layer)
366 jonathan 542 else:
367 jonathan 795 assert False, "Shouldn't be allowed."
368 jonathan 542 pass
369    
370     def MoveCurrentItemDown(self):
371 jonathan 795 layer, group = self.GetSelectedHierarchy()
372 jonathan 542
373 jonathan 795 if layer is not None:
374     self.map.LowerLayer(layer)
375 jonathan 542 else:
376 jonathan 795 assert False, "Shouldn't be allowed."
377 jonathan 542 pass
378    
379 frank 990 def MoveCurrentItemBottom(self):
380     layer, group = self.GetSelectedHierarchy()
381    
382     if layer is not None:
383 jonathan 1102 self.map.MoveLayerToBottom(layer)
384 frank 990 else:
385     assert False, "Shouldn't be allowed."
386     pass
387    
388 jonathan 542 def OnCompareItems(self, item1, item2):
389    
390     data1 = self.GetPyData(item1)
391     data2 = self.GetPyData(item2)
392    
393 jonathan 936 if isinstance(data1, BaseLayer):
394 jonathan 542 layers = self.map.Layers()
395     return layers.index(data2) - layers.index(data1)
396     else:
397     return wxTreeCtrl.OnCompareItems(self, item1, item2)
398    
399     def DoOnShowLayer(self):
400 jonathan 572 layer, group = self.GetSelectedHierarchy()
401     layer.SetVisible(True)
402 jonathan 542
403     def DoOnHideLayer(self):
404 jonathan 572 layer, group = self.GetSelectedHierarchy()
405     layer.SetVisible(False)
406 jonathan 542
407 frank 1837 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 jonathan 542 def Sort(self):
416     self.SortChildren(self.GetRootItem())
417    
418 jonathan 655 def GetSelectedHierarchy(self):
419     id = self.GetSelection()
420    
421     if not id.IsOk():
422     return (None, None)
423    
424     layer = self.GetPyData(id)
425     group = None
426    
427     if isinstance(layer, ClassGroup):
428     id = self.GetItemParent(id)
429     assert id.IsOk()
430     group = layer
431     layer = self.GetPyData(id)
432    
433     return (layer, group)
434    
435 jonathan 572 def _OnMsgMapsChanged(self):
436 jonathan 639 #print self.map is self.mainWindow.Map()
437 jonathan 572 self.SetMap(self.mainWindow.Map())
438    
439 jonathan 542 def _OnSelChanged(self, event):
440 bh 1113 # If we change the selection from normalize_selection do nothing.
441     if self.changing_selection:
442     return
443    
444     self.normalize_selection()
445 jonathan 655 self.__UpdateSelection()
446 jonathan 542
447 bh 1113 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 jonathan 1211 def OnItemExpandCollapse(self, event):
472     if self.preventExpandCollapse:
473     event.Veto()
474     self.preventExpandCollapse = False
475    
476 jonathan 542 def _OnItemActivated(self, event):
477 frank 1241 # 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 jonathan 542
492     def _OnMsgLayerChanged(self, layer):
493 jonathan 936 assert isinstance(layer, BaseLayer)
494 jonathan 542
495 bh 1129 id = self.find_layer(layer)
496     assert id is not None
497 jonathan 542
498 jonathan 1102 self.__FillTreeLayer(id)
499 jonathan 655 self.__UpdateSelection()
500 jonathan 542
501     def _OnMsgMapStackingChanged(self, *args):
502     self.Sort()
503 jonathan 562 id = self.GetSelection()
504 jonathan 542
505 jonathan 562 if id.IsOk():
506     self.EnsureVisible(id)
507 jonathan 655 self.__UpdateSelection()
508 jonathan 562
509 jonathan 1102 def _OnMsgMapLayersAdded(self, map):
510 jonathan 605 assert map is self.map
511 jonathan 542
512 bh 1129 # Build a dict with all layers known by the the tree as keys
513     layers = {}
514 jonathan 1102 root = self.GetRootItem()
515 bh 1129 id, cookie = self.GetFirstChild(root, 0)
516     while id.IsOk():
517     layers[self.GetPyData(id)] = 1
518     id, cookie = self.GetNextChild(root, cookie)
519 jonathan 1102
520 bh 1129 # Add layers in the map but not in the dict
521 jonathan 1102 i = 0
522     for l in map.Layers():
523 bh 1129 if not l in layers:
524 jonathan 1102 self.__AddLayer(i, l)
525    
526 jonathan 655 self.__UpdateSelection()
527 jonathan 542
528 jonathan 1102 def _OnMsgMapLayersRemoved(self, map):
529     assert map is self.map
530    
531     layers = map.Layers()
532    
533 bh 1129 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 jonathan 1102
540 bh 1129
541 jonathan 1102 self.__UpdateSelection()
542    
543 jonathan 572 def _OnMsgLayerVisibilityChanged(self, layer):
544 jonathan 936 assert isinstance(layer, BaseLayer)
545 jonathan 572
546     self.__ShowHideLayer(layer)
547 jonathan 655 self.__UpdateSelection()
548 jonathan 572
549 jonathan 652 def _OnMsgLayerTitleChanged(self, layer):
550    
551 bh 1129 id = self.find_layer(layer)
552 jonathan 652 if id.IsOk():
553     self.SetItemText(id, layer.Title())
554 jonathan 655 self.__UpdateSelection()
555 jonathan 652
556 jonathan 655 def __UpdateSelection(self):
557     layer, group = self.GetSelectedHierarchy()
558     self.parent.DoOnSelChanged(layer, group)
559    
560 jonathan 542 def __FillTree(self, map):
561    
562     self.Freeze()
563    
564 jonathan 1102 self.DeleteAllItems()
565 jonathan 542
566     if map.HasLayers():
567 jonathan 1102 root = self.GetRootItem()
568 jonathan 542 for l in map.Layers():
569 jonathan 1102 self.__AddLayer(0, l)
570 frank 1050
571 jonathan 542 self.Thaw()
572    
573     def __FillTreeLayer(self, pid):
574     layer = self.GetPyData(pid)
575    
576     self.Freeze()
577    
578     self.DeleteChildren(pid)
579    
580 jonathan 936 if layer.HasClassification():
581 jonathan 542
582 jonathan 936 clazz = layer.GetClassification()
583 jonathan 542
584 jonathan 936 shapeType = layer.ShapeType()
585 jonathan 542
586 jonathan 936 show = layer.Visible()
587     for g in clazz:
588     if g.IsVisible():
589     id = self.AppendItem(pid, g.GetDisplayText())
590     self.SetPyData(id, g)
591     self.__SetVisibilityStyle(show, id)
592 jonathan 542
593 jonathan 936 bmp = self.__BuildGroupImage(g, shapeType)
594 jonathan 542
595 jonathan 936 if bmp is None:
596 frank 1050 self.SetItemImage(id, -1)
597     self.SetItemSelectedImage(id, -1)
598 jonathan 936 else:
599 jonathan 1102 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 jonathan 936 self.SetItemImage(id, i)
606 frank 1050 self.SetItemSelectedImage(id, i)
607 jonathan 936
608 jonathan 542 self.Thaw()
609    
610     def __BuildGroupImage(self, group, shapeType):
611    
612     bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
613     #brush = wxBrush(Color2wxColour(item[1]), wxSOLID)
614     dc = wxMemoryDC()
615     dc.SelectObject(bmp)
616     dc.Clear()
617    
618     self.previewer.Draw(dc, None, group.GetProperties(), shapeType)
619    
620     return bmp
621    
622 jonathan 1102 def DeleteAllItems(self):
623 jonathan 542
624 jonathan 1102 pid = self.GetRootItem()
625 jonathan 542
626 jonathan 1102 id, cookie = self.GetFirstChild(pid, 123)
627     while id.IsOk():
628     self.__RemoveLayer(id)
629     id, cookie = self.GetNextChild(pid, cookie)
630 jonathan 578
631 jonathan 1102 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 bh 1115
676 jonathan 1102 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 bh 1115
683 jonathan 1102 self.emptyImageIndex = \
684     self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))
685 bh 1115
686 jonathan 1102 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 bh 1115 self.availImgListIndices = []
693 jonathan 1102
694     root = self.AddRoot("")
695    
696     return root
697    
698 jonathan 632 def __SetVisibilityStyle(self, visible, id):
699 jonathan 572 font = self.GetItemFont(id)
700 jonathan 542
701 jonathan 632 if visible:
702 jonathan 572 font.SetStyle(wxNORMAL)
703     color = wxBLACK
704     else:
705 frank 980 #font.SetStyle(wxITALIC)
706     font.SetStyle(wxNORMAL)
707 jonathan 572 color = wxLIGHT_GREY
708 jonathan 542
709 jonathan 572 self.SetItemTextColour(id, color)
710     self.SetItemFont(id, font)
711    
712     def __ShowHideLayer(self, layer):
713 bh 1129 parent = self.find_layer(layer)
714 jonathan 605 assert parent.IsOk()
715 jonathan 542
716 jonathan 632 visible = layer.Visible()
717 jonathan 542
718 jonathan 632 self.__SetVisibilityStyle(visible, parent)
719 jonathan 542
720 jonathan 572 id, cookie = self.GetFirstChild(parent, 123)
721 jonathan 542
722 jonathan 572 while id.IsOk():
723 jonathan 632 self.__SetVisibilityStyle(visible, id)
724 jonathan 572 id, cookie = self.GetNextChild(parent, cookie)
725    
726 frank 854 class ScaleBarBitmap(wxBoxSizer):
727    
728     def __init__(self, parent, map, mainWindow):
729     # While the width is fixed, get the height _now_.
730     dc = wxMemoryDC()
731     textwidth, textheight = dc.GetTextExtent("%d"%0)
732 frank 990 self.width = 210
733 frank 854 self.height = textheight + 3*2 + 8
734    
735     wxBoxSizer.__init__(self, wxVERTICAL)
736     bmp=wxEmptyBitmap(self.width, self.height)
737     self.scalebarBitmap = wxStaticBitmap(parent, -1, bmp)
738     self.Add(self.scalebarBitmap, 0, wxALIGN_CENTER|wxLEFT|wxTOP|wxRIGHT, 1)
739    
740     self.mainWindow = mainWindow
741     self.parent = parent
742     self.canvas = None
743     self.SetCanvas(self.mainWindow.canvas)
744    
745     def SetCanvas(self, canvas):
746     sub_list = [(SCALE_CHANGED, self._OnMsgScaleChanged)]
747    
748     if self.canvas is not None:
749     for msg, func in sub_list: self.canvas.Unsubscribe(msg, func)
750    
751     self.canvas = canvas
752 frank 858 self.scalebar = ScaleBar(canvas.map)
753 frank 854
754     if self.canvas is not None:
755     for msg, func in sub_list: self.canvas.Subscribe(msg, func)
756     self.__SetScale(self.canvas.scale)
757    
758     def _OnMsgScaleChanged(self, scale):
759     self.__SetScale(scale)
760    
761     def __SetScale(self, scale):
762     bmp = wxEmptyBitmap(self.width, self.height)
763     dc = wxMemoryDC()
764     dc.SelectObject(bmp)
765     dc.Clear()
766    
767 jonathan 1231 if self.canvas.map is not None \
768     and self.canvas.map.projection is not None:
769 jonathan 1252
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 jonathan 1180 self.scalebar.DrawScaleBar(scale, dc, (0,0), dc.GetSizeTuple())
795 frank 854
796     self.scalebarBitmap.SetBitmap(bmp)
797    

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26