/[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 1837 - (hide annotations)
Tue Oct 21 09:29:52 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: 24618 byte(s)
Popup menu for legend. Scheduled for the 1.2 release this was too
simple to implement: The popup menu is bound to the legend tree, while
the events are hanlded by its anchestor, the legend panel. This
allows reuse of all the event handlers already implemented for the
legend toolbar buttons.

* Thuban/UI/legend.py (LegendPanel.__init__): EVT_MENU macros
	to add handlers for the events issued by the popup menu.
 	(LegendPanel._OnToggleVisibility): Handler for toggling layer
	visibility event
    	(LegendPanel._OnProjection): Handler for layer projection event.
	(LegendTree.__init__): Added EVT_TREE_ITEM_RIGHT_CLICK
	(LegendTree._OnRightClick): Event handler for right click, select item
	and pop up menu.
	(LegendTree.ToggleVisibility): Toggle layer visibility
	(LegendTree.LayerProjection): Raise layer projection dialog for
	current layer.

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    
53 frank 1050 BMP_SIZE_W = 15
54 jonathan 542 BMP_SIZE_H = 15
55    
56 frank 990 TOP_BMP = "top_layer"
57 jonathan 652 RAISE_BMP = "raise_layer"
58     LOWER_BMP = "lower_layer"
59 frank 990 BOTTOM_BMP = "bottom_layer"
60 jonathan 652 SHOW_BMP = "show_layer"
61     HIDE_BMP = "hide_layer"
62     PROPS_BMP = "layer_properties"
63    
64    
65 jonathan 562 class LegendPanel(DockPanel):
66    
67     def __init__(self, parent, map, mainWindow):
68     DockPanel.__init__(self, parent, -1)
69    
70     self.mainWindow = mainWindow
71     self.parent = parent
72    
73 jonathan 652 self.buttons = []
74    
75 jonathan 542 panelBox = wxBoxSizer(wxVERTICAL)
76    
77 jonathan 652 self.toolBar = wxToolBar(self, -1)
78 jonathan 658 self.toolBar.SetToolBitmapSize(wxSize(24, 24))
79 jonathan 542
80 frank 990 bmp = resource.GetBitmapResource(TOP_BMP, wxBITMAP_TYPE_XPM)
81     self.toolBar.AddTool(ID_LEGEND_TOP, bmp,
82     shortHelpString=_("Top Layer"))
83    
84 jonathan 652 bmp = resource.GetBitmapResource(RAISE_BMP, wxBITMAP_TYPE_XPM)
85     self.toolBar.AddTool(ID_LEGEND_RAISE, bmp,
86     shortHelpString=_("Raise Layer"))
87 jonathan 542
88 jonathan 652 bmp = resource.GetBitmapResource(LOWER_BMP, wxBITMAP_TYPE_XPM)
89     self.toolBar.AddTool(ID_LEGEND_LOWER, bmp,
90     shortHelpString=_("Lower Layer"))
91 jonathan 542
92 frank 990 bmp = resource.GetBitmapResource(BOTTOM_BMP, wxBITMAP_TYPE_XPM)
93     self.toolBar.AddTool(ID_LEGEND_BOTTOM, bmp,
94     shortHelpString=_("Bottom Layer"))
95    
96 jonathan 652 bmp = resource.GetBitmapResource(SHOW_BMP, wxBITMAP_TYPE_XPM)
97     self.toolBar.AddTool(ID_LEGEND_SHOWLAYER, bmp,
98     shortHelpString=_("Show Layer"))
99 jonathan 542
100 jonathan 652 bmp = resource.GetBitmapResource(HIDE_BMP, wxBITMAP_TYPE_XPM)
101     self.toolBar.AddTool(ID_LEGEND_HIDELAYER, bmp,
102     shortHelpString=_("Hide Layer"))
103 jonathan 542
104 jonathan 652 bmp = resource.GetBitmapResource(PROPS_BMP, wxBITMAP_TYPE_XPM)
105     self.toolBar.AddTool(ID_LEGEND_PROPS, bmp,
106     shortHelpString=_("Edit Layer Properties"))
107 jonathan 542
108 jonathan 652 self.toolBar.Realize()
109 jonathan 668 panelBox.Add(self.toolBar, 0, wxGROW, 0)
110 jonathan 542
111 frank 990 EVT_TOOL(self, ID_LEGEND_TOP, self._OnMoveTop)
112 jonathan 652 EVT_TOOL(self, ID_LEGEND_RAISE, self._OnMoveUp)
113     EVT_TOOL(self, ID_LEGEND_LOWER, self._OnMoveDown)
114 frank 990 EVT_TOOL(self, ID_LEGEND_BOTTOM, self._OnMoveBottom)
115 jonathan 652 EVT_TOOL(self, ID_LEGEND_PROPS, self._OnProperties)
116     EVT_TOOL(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)
117     EVT_TOOL(self, ID_LEGEND_HIDELAYER, self._OnHideLayer)
118 jonathan 542
119 frank 1837 EVT_MENU(self, ID_POPUP_PROPS, self._OnProperties)
120     EVT_MENU(self, ID_POPUP_TOP, self._OnMoveTop)
121     EVT_MENU(self, ID_POPUP_UP, self._OnMoveUp)
122     EVT_MENU(self, ID_POPUP_DOWN, self._OnMoveDown)
123     EVT_MENU(self, ID_POPUP_BOTTOM, self._OnMoveBottom)
124     EVT_MENU(self, ID_POPUP_VISIBLE, self._OnToggleVisibility)
125     EVT_MENU(self, ID_POPUP_PROJ, self._OnProjection)
126    
127 jonathan 562 self.tree = LegendTree(self, ID_LEGEND_TREE, map, mainWindow)
128 jonathan 542
129 jonathan 658 panelBox.Add(self.tree, 1, wxGROW, 0)
130 jonathan 542
131 frank 854 self.scalebarbitmap = ScaleBarBitmap(self, map, mainWindow)
132     panelBox.Add(self.scalebarbitmap, 0, wxGROW, 0)
133    
134 jonathan 562 self.SetAutoLayout(True)
135     self.SetSizer(panelBox)
136 jonathan 542 panelBox.SetSizeHints(self)
137    
138 jonathan 658
139 jonathan 562 self.panelBox = panelBox
140 jonathan 542
141 jonathan 652 self.__EnableButtons(False)
142    
143 jonathan 658 self.Create()
144    
145 jonathan 572 EVT_CLOSE(self, self._OnClose)
146    
147    
148 jonathan 562 def GetMap(self):
149     return self.tree.GetMap()
150    
151     def SetMap(self, map):
152     self.tree.SetMap(map)
153 frank 854 self.scalebarbitmap.SetCanvas(self.mainWindow.canvas)
154 jonathan 562
155 jonathan 572 def DoOnSelChanged(self, layer, group):
156 jonathan 542
157 jonathan 936 ok = isinstance(layer, BaseLayer)
158 jonathan 572 self.__EnableButtons(ok)
159    
160 jonathan 655 self.mainWindow.SelectLayer(layer)
161 jonathan 568
162 jonathan 639 def DoOnProperties(self):
163 jonathan 572 list = self.tree.GetSelectedHierarchy()
164    
165 jonathan 936 ok = isinstance(list[0], BaseLayer)
166 jonathan 572 if ok:
167 jonathan 639 self.mainWindow.OpenLayerProperties(list[0], list[1])
168 jonathan 572
169 jonathan 578 def Destroy(self):
170     self.__Close()
171    
172 jonathan 639 def _OnProperties(self, event):
173     self.DoOnProperties()
174 jonathan 542
175 frank 990 def _OnMoveTop(self, event):
176     self.tree.MoveCurrentItemTop()
177    
178 jonathan 542 def _OnMoveUp(self, event):
179     self.tree.MoveCurrentItemUp()
180    
181     def _OnMoveDown(self, event):
182     self.tree.MoveCurrentItemDown()
183    
184 frank 990 def _OnMoveBottom(self, event):
185     self.tree.MoveCurrentItemBottom()
186    
187 jonathan 542 def _OnShowLayer(self, event):
188     self.tree.DoOnShowLayer()
189     pass
190    
191 jonathan 578 #def Close(self, force = False):
192     #DockPanel.Close(self, force)
193    
194 jonathan 572 def _OnClose(self, event):
195 jonathan 578 self.__Close()
196 jonathan 572
197 jonathan 542 def _OnHideLayer(self, event):
198     self.tree.DoOnHideLayer()
199     pass
200    
201 frank 1837 def _OnToggleVisibility(self, event):
202     self.tree.ToggleVisibility()
203    
204     def _OnProjection(self, event):
205     self.tree.LayerProjection()
206    
207 jonathan 542 def __EnableButtons(self, on):
208 frank 990 self.toolBar.EnableTool(ID_LEGEND_TOP, on)
209 jonathan 652 self.toolBar.EnableTool(ID_LEGEND_RAISE, on)
210     self.toolBar.EnableTool(ID_LEGEND_LOWER, on)
211 frank 990 self.toolBar.EnableTool(ID_LEGEND_BOTTOM, on)
212 jonathan 652 self.toolBar.EnableTool(ID_LEGEND_SHOWLAYER, on)
213     self.toolBar.EnableTool(ID_LEGEND_HIDELAYER, on)
214     self.toolBar.EnableTool(ID_LEGEND_PROPS, on)
215 jonathan 542
216 jonathan 578 def __Close(self):
217     self.tree.Close()
218    
219 jonathan 542 class LegendTree(wxTreeCtrl):
220    
221 jonathan 562 def __init__(self, parent, id, map, mainWindow):
222 jonathan 542 wxTreeCtrl.__init__(self, parent, id,
223     style = wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT,
224     size = (200, 200))
225    
226 jonathan 572 self.mainWindow = mainWindow
227 jonathan 562 self.map = None
228 jonathan 542 self.parent = parent
229 bh 1113 self.changing_selection = 0
230 jonathan 542
231 jonathan 1102 #
232     # The image list used by the wxTreeCtrl causes problems when
233     # we remove layers and/or change a classification because it
234     # changes the image indices if you remove images from the list.
235     # Rather than removing unused images we use this list to keep
236     # track of which indices are available in the image list
237     # (because of a previous removal) and then replace those indices
238     # with new images rather than appending to the end of the image
239     # list (assuming there are any that are available).
240     #
241     self.availImgListIndices = []
242    
243 jonathan 542 self.image_list = None
244     self.emptyImageIndex = 0
245    
246     self.previewer = ClassDataPreviewer()
247    
248 jonathan 1211 self.preventExpandCollapse = False
249 frank 1241 self.raiseProperties = False
250 jonathan 1211
251 jonathan 542 EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)
252     EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)
253 jonathan 1211 EVT_TREE_ITEM_EXPANDING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
254     EVT_TREE_ITEM_COLLAPSING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
255 frank 1837 EVT_TREE_ITEM_RIGHT_CLICK(self, ID_LEGEND_TREE, self._OnRightClick)
256 jonathan 542
257 jonathan 572 EVT_CLOSE(self, self._OnClose)
258    
259 jonathan 562 self.SetMap(map)
260 jonathan 542
261 bh 1129 def find_layer(self, layer):
262     """Return the tree item for the layer"""
263     root = self.GetRootItem()
264     id, cookie = self.GetFirstChild(root, 0)
265     while id.IsOk():
266     if self.GetPyData(id) is layer:
267     return id
268     id, cookie = self.GetNextChild(root, cookie)
269     return None
270    
271 jonathan 572 def _OnClose(self, event):
272     self.SetMap(None)
273    
274 jonathan 562 def GetMap(self):
275     return self.map
276 jonathan 542
277 jonathan 562 def SetMap(self, map):
278    
279     sub_list = [(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged),
280 jonathan 1102 (MAP_LAYERS_ADDED, self._OnMsgMapLayersAdded),
281     (MAP_LAYERS_REMOVED, self._OnMsgMapLayersRemoved)]
282 jonathan 562
283     if self.map is not None:
284     for msg, func in sub_list: self.map.Unsubscribe(msg, func)
285 jonathan 572 #self.mainWindow.application.Unsubscribe(SESSION_REPLACED,
286     #self._OnMsgMapsChanged)
287     #try:
288     #self.mainWindow.application.session.Unsubscribe(MAPS_CHANGED,
289     #self._OnMsgMapsChanged)
290     #except ConnectorError:
291     #pass
292 jonathan 1102 self.DeleteAllItems()
293 jonathan 562
294     self.map = map
295    
296     if self.map is not None:
297     for msg, func in sub_list: self.map.Subscribe(msg, func)
298 jonathan 572 #self.mainWindow.application.session.Subscribe(MAPS_CHANGED,
299     #self._OnMsgMapsChanged)
300     #self.mainWindow.application.Subscribe(SESSION_REPLACED,
301     #self._OnMsgMapsChanged)
302 jonathan 562 self.__FillTree(self.map)
303    
304 frank 990 def MoveCurrentItemTop(self):
305     layer, group = self.GetSelectedHierarchy()
306    
307     if layer is not None:
308 jonathan 1102 self.map.MoveLayerToTop(layer)
309 frank 990 else:
310     assert False, "Shouldn't be allowed."
311     pass
312    
313 jonathan 542 def MoveCurrentItemUp(self):
314 jonathan 795 layer, group = self.GetSelectedHierarchy()
315 jonathan 542
316 jonathan 795 if layer is not None:
317     self.map.RaiseLayer(layer)
318 jonathan 542 else:
319 jonathan 795 assert False, "Shouldn't be allowed."
320 jonathan 542 pass
321    
322     def MoveCurrentItemDown(self):
323 jonathan 795 layer, group = self.GetSelectedHierarchy()
324 jonathan 542
325 jonathan 795 if layer is not None:
326     self.map.LowerLayer(layer)
327 jonathan 542 else:
328 jonathan 795 assert False, "Shouldn't be allowed."
329 jonathan 542 pass
330    
331 frank 990 def MoveCurrentItemBottom(self):
332     layer, group = self.GetSelectedHierarchy()
333    
334     if layer is not None:
335 jonathan 1102 self.map.MoveLayerToBottom(layer)
336 frank 990 else:
337     assert False, "Shouldn't be allowed."
338     pass
339    
340 jonathan 542 def OnCompareItems(self, item1, item2):
341    
342     data1 = self.GetPyData(item1)
343     data2 = self.GetPyData(item2)
344    
345 jonathan 936 if isinstance(data1, BaseLayer):
346 jonathan 542 layers = self.map.Layers()
347     return layers.index(data2) - layers.index(data1)
348     else:
349     return wxTreeCtrl.OnCompareItems(self, item1, item2)
350    
351     def DoOnShowLayer(self):
352 jonathan 572 layer, group = self.GetSelectedHierarchy()
353     layer.SetVisible(True)
354 jonathan 542
355     def DoOnHideLayer(self):
356 jonathan 572 layer, group = self.GetSelectedHierarchy()
357     layer.SetVisible(False)
358 jonathan 542
359 frank 1837 def ToggleVisibility(self):
360     layer, group = self.GetSelectedHierarchy()
361    
362     layer.SetVisible(not layer.Visible())
363    
364     def LayerProjection(self):
365     self.parent.mainWindow.LayerProjection()
366    
367 jonathan 542 def Sort(self):
368     self.SortChildren(self.GetRootItem())
369    
370 jonathan 655 def GetSelectedHierarchy(self):
371     id = self.GetSelection()
372    
373     if not id.IsOk():
374     return (None, None)
375    
376     layer = self.GetPyData(id)
377     group = None
378    
379     if isinstance(layer, ClassGroup):
380     id = self.GetItemParent(id)
381     assert id.IsOk()
382     group = layer
383     layer = self.GetPyData(id)
384    
385     return (layer, group)
386    
387 jonathan 572 def _OnMsgMapsChanged(self):
388 jonathan 639 #print self.map is self.mainWindow.Map()
389 jonathan 572 self.SetMap(self.mainWindow.Map())
390    
391 jonathan 542 def _OnSelChanged(self, event):
392 bh 1113 # If we change the selection from normalize_selection do nothing.
393     if self.changing_selection:
394     return
395    
396     self.normalize_selection()
397 jonathan 655 self.__UpdateSelection()
398 jonathan 542
399 bh 1113 def normalize_selection(self):
400     """Select the layer containing currently selected item"""
401     # This is really a workaround for a bug in wx where deleting a
402     # subtree with DeleteChildren does not update the selection
403     # properly and can lead to segfaults later because the return
404     # value of GetSelection points to invalid data.
405     item = self.GetSelection()
406     while item.IsOk():
407     object = self.GetPyData(item)
408     if isinstance(object, BaseLayer):
409     break
410     item = self.GetItemParent(item)
411     else:
412     # No layer was found in the chain of parents, so there's
413     # nothing we can do.
414     return
415    
416     self.changing_selection = 1
417     try:
418     self.SelectItem(item)
419     finally:
420     self.changing_selection = 0
421    
422    
423 jonathan 1211 def OnItemExpandCollapse(self, event):
424     if self.preventExpandCollapse:
425     event.Veto()
426     self.preventExpandCollapse = False
427    
428 frank 1837 def _OnRightClick(self, event):
429     """Select item and pop up a context menu"""
430    
431     # The pop up menu is related to the legend tree, so we have direct
432     # access on the tree items. The events issued by the menu are handled
433     # by the legend panel, since most of the handlers are already
434     # implemented there.
435    
436     # Update item selection to the right click
437     item = event.GetItem()
438     self.SelectItem(item)
439    
440     # Create the menu
441     menu = wxMenu("", 0)
442    
443     # The "Visible" item is a special ...
444     menuitem = wxMenuItem(menu, ID_POPUP_VISIBLE, _("Visible"),
445     "", wxITEM_CHECK)
446     menu.AppendItem(menuitem)
447     layer, group = self.GetSelectedHierarchy()
448     menuitem.Check(layer.Visible())
449    
450     menu.AppendSeparator()
451     menu.Append(ID_POPUP_PROPS, _("Properties"))
452     menu.Append(ID_POPUP_PROJ, _("Projection"))
453     menu.AppendSeparator()
454     menu.Append(ID_POPUP_TOP, _("Top"))
455     menu.Append(ID_POPUP_UP, _("Up"))
456     menu.Append(ID_POPUP_DOWN, _("Down"))
457     menu.Append(ID_POPUP_BOTTOM, _("Bottom"))
458    
459     # Display the menu
460     pos = event.GetPoint()
461     shift = self.ClientToScreen((0,0))
462     self.PopupMenu(menu, pos)
463    
464 jonathan 542 def _OnItemActivated(self, event):
465 frank 1241 # The following looks strange but is need under Windows to
466     # raise the Properties on double-click: The tree control
467     # always gets an Expanded / Collapsed event after the ItemActivated
468     # on double click, which raises the main window again. We add a second
469     # ItemActivated event to the queue, which simply raises the already
470     # displayed window.
471     if self.raiseProperties:
472     self.parent.DoOnProperties()
473     self.raiseProperties = False
474     else:
475     self.raiseProperties = True
476     self.preventExpandCollapse = True
477     self.parent.DoOnProperties()
478     self.AddPendingEvent(event)
479 jonathan 542
480     def _OnMsgLayerChanged(self, layer):
481 jonathan 936 assert isinstance(layer, BaseLayer)
482 jonathan 542
483 bh 1129 id = self.find_layer(layer)
484     assert id is not None
485 jonathan 542
486 jonathan 1102 self.__FillTreeLayer(id)
487 jonathan 655 self.__UpdateSelection()
488 jonathan 542
489     def _OnMsgMapStackingChanged(self, *args):
490     self.Sort()
491 jonathan 562 id = self.GetSelection()
492 jonathan 542
493 jonathan 562 if id.IsOk():
494     self.EnsureVisible(id)
495 jonathan 655 self.__UpdateSelection()
496 jonathan 562
497 jonathan 1102 def _OnMsgMapLayersAdded(self, map):
498 jonathan 605 assert map is self.map
499 jonathan 542
500 bh 1129 # Build a dict with all layers known by the the tree as keys
501     layers = {}
502 jonathan 1102 root = self.GetRootItem()
503 bh 1129 id, cookie = self.GetFirstChild(root, 0)
504     while id.IsOk():
505     layers[self.GetPyData(id)] = 1
506     id, cookie = self.GetNextChild(root, cookie)
507 jonathan 1102
508 bh 1129 # Add layers in the map but not in the dict
509 jonathan 1102 i = 0
510     for l in map.Layers():
511 bh 1129 if not l in layers:
512 jonathan 1102 self.__AddLayer(i, l)
513    
514 jonathan 655 self.__UpdateSelection()
515 jonathan 542
516 jonathan 1102 def _OnMsgMapLayersRemoved(self, map):
517     assert map is self.map
518    
519     layers = map.Layers()
520    
521 bh 1129 root = self.GetRootItem()
522     id, cookie = self.GetFirstChild(root, 0)
523     while id.IsOk():
524     if self.GetPyData(id) not in layers:
525     self.__RemoveLayer(id)
526     id, cookie = self.GetNextChild(root, cookie)
527 jonathan 1102
528 bh 1129
529 jonathan 1102 self.__UpdateSelection()
530    
531 jonathan 572 def _OnMsgLayerVisibilityChanged(self, layer):
532 jonathan 936 assert isinstance(layer, BaseLayer)
533 jonathan 572
534     self.__ShowHideLayer(layer)
535 jonathan 655 self.__UpdateSelection()
536 jonathan 572
537 jonathan 652 def _OnMsgLayerTitleChanged(self, layer):
538    
539 bh 1129 id = self.find_layer(layer)
540 jonathan 652 if id.IsOk():
541     self.SetItemText(id, layer.Title())
542 jonathan 655 self.__UpdateSelection()
543 jonathan 652
544 jonathan 655 def __UpdateSelection(self):
545     layer, group = self.GetSelectedHierarchy()
546     self.parent.DoOnSelChanged(layer, group)
547    
548 jonathan 542 def __FillTree(self, map):
549    
550     self.Freeze()
551    
552 jonathan 1102 self.DeleteAllItems()
553 jonathan 542
554     if map.HasLayers():
555 jonathan 1102 root = self.GetRootItem()
556 jonathan 542 for l in map.Layers():
557 jonathan 1102 self.__AddLayer(0, l)
558 frank 1050
559 jonathan 542 self.Thaw()
560    
561     def __FillTreeLayer(self, pid):
562     layer = self.GetPyData(pid)
563    
564     self.Freeze()
565    
566     self.DeleteChildren(pid)
567    
568 jonathan 936 if layer.HasClassification():
569 jonathan 542
570 jonathan 936 clazz = layer.GetClassification()
571 jonathan 542
572 jonathan 936 shapeType = layer.ShapeType()
573 jonathan 542
574 jonathan 936 show = layer.Visible()
575     for g in clazz:
576     if g.IsVisible():
577     id = self.AppendItem(pid, g.GetDisplayText())
578     self.SetPyData(id, g)
579     self.__SetVisibilityStyle(show, id)
580 jonathan 542
581 jonathan 936 bmp = self.__BuildGroupImage(g, shapeType)
582 jonathan 542
583 jonathan 936 if bmp is None:
584 frank 1050 self.SetItemImage(id, -1)
585     self.SetItemSelectedImage(id, -1)
586 jonathan 936 else:
587 jonathan 1102 if self.availImgListIndices:
588     i = self.availImgListIndices.pop(0)
589     self.image_list.Replace(i, bmp)
590     else:
591     i = self.image_list.Add(bmp)
592    
593 jonathan 936 self.SetItemImage(id, i)
594 frank 1050 self.SetItemSelectedImage(id, i)
595 jonathan 936
596 jonathan 542 self.Thaw()
597    
598     def __BuildGroupImage(self, group, shapeType):
599    
600     bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
601     #brush = wxBrush(Color2wxColour(item[1]), wxSOLID)
602     dc = wxMemoryDC()
603     dc.SelectObject(bmp)
604     dc.Clear()
605    
606     self.previewer.Draw(dc, None, group.GetProperties(), shapeType)
607    
608     return bmp
609    
610 jonathan 1102 def DeleteAllItems(self):
611 jonathan 542
612 jonathan 1102 pid = self.GetRootItem()
613 jonathan 542
614 jonathan 1102 id, cookie = self.GetFirstChild(pid, 123)
615     while id.IsOk():
616     self.__RemoveLayer(id)
617     id, cookie = self.GetNextChild(pid, cookie)
618 jonathan 578
619 jonathan 1102 wxTreeCtrl.DeleteAllItems(self)
620    
621     def __AddLayer(self, before, l):
622     root = self.GetRootItem()
623     id = self.InsertItemBefore(root, before,
624     l.Title(),
625     self.mapImageIndex,
626     self.mapImageIndex)
627    
628     self.SetPyData(id, l)
629     self.__SetVisibilityStyle(l.Visible(), id)
630    
631     self.__FillTreeLayer(id)
632     self.Expand(id)
633    
634     l.Subscribe(LAYER_CHANGED, self._OnMsgLayerChanged)
635     l.Subscribe(LAYER_VISIBILITY_CHANGED,
636     self._OnMsgLayerVisibilityChanged)
637     l.Subscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
638    
639     def __RemoveLayer(self, id):
640     self.DeleteChildren(id)
641    
642     layer = self.GetPyData(id)
643     layer.Unsubscribe(LAYER_CHANGED,
644     self._OnMsgLayerChanged)
645     layer.Unsubscribe(LAYER_VISIBILITY_CHANGED,
646     self._OnMsgLayerVisibilityChanged)
647     layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
648    
649     self.Delete(id)
650    
651     def DeleteChildren(self, pid):
652     id, cookie = self.GetFirstChild(pid, 123)
653     while id.IsOk():
654     self.availImgListIndices.append(self.GetItemImage(id))
655     id, cookie = self.GetNextChild(pid, cookie)
656     wxTreeCtrl.DeleteChildren(self, pid)
657    
658     def GetRootItem(self):
659     root = wxTreeCtrl.GetRootItem(self)
660    
661     if not root.IsOk():
662     self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)
663 bh 1115
664 jonathan 1102 bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
665     dc = wxMemoryDC()
666     dc.SelectObject(bmp)
667     dc.SetBrush(wxBLACK_BRUSH)
668     dc.Clear()
669     dc.SelectObject(wxNullBitmap)
670 bh 1115
671 jonathan 1102 self.emptyImageIndex = \
672     self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))
673 bh 1115
674 jonathan 1102 bmp = resource.GetBitmapResource("legend_icon_layer",
675     wxBITMAP_TYPE_XPM)
676     self.mapImageIndex = \
677     self.image_list.Add(bmp)
678    
679     self.AssignImageList(self.image_list)
680 bh 1115 self.availImgListIndices = []
681 jonathan 1102
682     root = self.AddRoot("")
683    
684     return root
685    
686 jonathan 632 def __SetVisibilityStyle(self, visible, id):
687 jonathan 572 font = self.GetItemFont(id)
688 jonathan 542
689 jonathan 632 if visible:
690 jonathan 572 font.SetStyle(wxNORMAL)
691     color = wxBLACK
692     else:
693 frank 980 #font.SetStyle(wxITALIC)
694     font.SetStyle(wxNORMAL)
695 jonathan 572 color = wxLIGHT_GREY
696 jonathan 542
697 jonathan 572 self.SetItemTextColour(id, color)
698     self.SetItemFont(id, font)
699    
700     def __ShowHideLayer(self, layer):
701 bh 1129 parent = self.find_layer(layer)
702 jonathan 605 assert parent.IsOk()
703 jonathan 542
704 jonathan 632 visible = layer.Visible()
705 jonathan 542
706 jonathan 632 self.__SetVisibilityStyle(visible, parent)
707 jonathan 542
708 jonathan 572 id, cookie = self.GetFirstChild(parent, 123)
709 jonathan 542
710 jonathan 572 while id.IsOk():
711 jonathan 632 self.__SetVisibilityStyle(visible, id)
712 jonathan 572 id, cookie = self.GetNextChild(parent, cookie)
713    
714 frank 854 class ScaleBarBitmap(wxBoxSizer):
715    
716     def __init__(self, parent, map, mainWindow):
717     # While the width is fixed, get the height _now_.
718     dc = wxMemoryDC()
719     textwidth, textheight = dc.GetTextExtent("%d"%0)
720 frank 990 self.width = 210
721 frank 854 self.height = textheight + 3*2 + 8
722    
723     wxBoxSizer.__init__(self, wxVERTICAL)
724     bmp=wxEmptyBitmap(self.width, self.height)
725     self.scalebarBitmap = wxStaticBitmap(parent, -1, bmp)
726     self.Add(self.scalebarBitmap, 0, wxALIGN_CENTER|wxLEFT|wxTOP|wxRIGHT, 1)
727    
728     self.mainWindow = mainWindow
729     self.parent = parent
730     self.canvas = None
731     self.SetCanvas(self.mainWindow.canvas)
732    
733     def SetCanvas(self, canvas):
734     sub_list = [(SCALE_CHANGED, self._OnMsgScaleChanged)]
735    
736     if self.canvas is not None:
737     for msg, func in sub_list: self.canvas.Unsubscribe(msg, func)
738    
739     self.canvas = canvas
740 frank 858 self.scalebar = ScaleBar(canvas.map)
741 frank 854
742     if self.canvas is not None:
743     for msg, func in sub_list: self.canvas.Subscribe(msg, func)
744     self.__SetScale(self.canvas.scale)
745    
746     def _OnMsgScaleChanged(self, scale):
747     self.__SetScale(scale)
748    
749     def __SetScale(self, scale):
750     bmp = wxEmptyBitmap(self.width, self.height)
751     dc = wxMemoryDC()
752     dc.SelectObject(bmp)
753     dc.Clear()
754    
755 jonathan 1231 if self.canvas.map is not None \
756     and self.canvas.map.projection is not None:
757 jonathan 1252
758     # if we are using a projection with geographics coordinates
759     # we need to change the scale value based on where we are
760     # on the globe.
761     if self.canvas.map.projection.GetProjectedUnits() \
762     == PROJ_UNITS_DEGREES:
763    
764     width, height = self.canvas.GetSizeTuple()
765     long, lat = self.canvas.win_to_proj(width/2, height/2)
766    
767     # slightly inaccurate, but if we are looking at
768     # the north/south pole we could end up dividing by zero
769     #
770     # it shouldn't matter for our purposes that we ignore
771     # the original sign of lat.
772     if fabs(lat) > 89.9: lat = 89.9
773    
774     #
775     # one degree is about 111,133m at the equator
776     # we need to adjust that for latitude as
777     # we move north/south. use the center of the map
778     # as the point to scale the length to.
779     #
780     scale = scale / (111133.0 * fabs(cos(lat * pi/180)))
781    
782 jonathan 1180 self.scalebar.DrawScaleBar(scale, dc, (0,0), dc.GetSizeTuple())
783 frank 854
784     self.scalebarBitmap.SetBitmap(bmp)
785    

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26