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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1063 - (show annotations)
Tue May 27 14:08:28 2003 UTC (21 years, 9 months ago) by frank
Original Path: trunk/thuban/Thuban/UI/legend.py
File MIME type: text/x-python
File size: 16877 byte(s)
(LegendTree.__FillTree): Use 'legend_icon_layer'

1 # Copyright (c) 2001, 2002, 2003 by Intevation GmbH
2 # Authors:
3 # Jonathan Coles <[email protected]>
4 # Frank Koormann <[email protected]>
5 #
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 from Thuban import _
12
13 import resource
14
15 from wxPython.wx import *
16
17 from Thuban.Model.layer import BaseLayer
18 from Thuban.Model.map import Map
19 from Thuban.Model.classification import ClassGroup
20
21 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.UI.messages import SCALE_CHANGED
26
27 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_TOP = 4001
34 ID_LEGEND_RAISE = 4002
35 ID_LEGEND_LOWER = 4003
36 ID_LEGEND_BOTTOM = 4004
37 ID_LEGEND_TREE = 4005
38 ID_LEGEND_PROPS = 4006
39 ID_LEGEND_SHOWLAYER = 4007
40 ID_LEGEND_HIDELAYER = 4008
41
42 BMP_SIZE_W = 15
43 BMP_SIZE_H = 15
44
45 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
53
54 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 self.buttons = []
63
64 panelBox = wxBoxSizer(wxVERTICAL)
65
66 self.toolBar = wxToolBar(self, -1)
67 self.toolBar.SetToolBitmapSize(wxSize(24, 24))
68
69 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 self.tree = LegendTree(self, ID_LEGEND_TREE, map, mainWindow)
109
110 panelBox.Add(self.tree, 1, wxGROW, 0)
111
112 self.scalebarbitmap = ScaleBarBitmap(self, map, mainWindow)
113 panelBox.Add(self.scalebarbitmap, 0, wxGROW, 0)
114
115 self.SetAutoLayout(True)
116 self.SetSizer(panelBox)
117 panelBox.SetSizeHints(self)
118
119
120 self.panelBox = panelBox
121
122 self.__EnableButtons(False)
123
124 self.Create()
125
126 EVT_CLOSE(self, self._OnClose)
127
128
129 def GetMap(self):
130 return self.tree.GetMap()
131
132 def SetMap(self, map):
133 self.tree.SetMap(map)
134 self.scalebarbitmap.SetCanvas(self.mainWindow.canvas)
135
136 def DoOnSelChanged(self, layer, group):
137
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 Destroy(self):
151 self.__Close()
152
153 def _OnProperties(self, event):
154 self.DoOnProperties()
155
156 def _OnMoveTop(self, event):
157 self.tree.MoveCurrentItemTop()
158
159 def _OnMoveUp(self, event):
160 self.tree.MoveCurrentItemUp()
161
162 def _OnMoveDown(self, event):
163 self.tree.MoveCurrentItemDown()
164
165 def _OnMoveBottom(self, event):
166 self.tree.MoveCurrentItemBottom()
167
168 def _OnShowLayer(self, event):
169 self.tree.DoOnShowLayer()
170 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):
179 self.tree.DoOnHideLayer()
180 pass
181
182 def __EnableButtons(self, on):
183 self.toolBar.EnableTool(ID_LEGEND_TOP, on)
184 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):
195
196 def __init__(self, parent, id, map, mainWindow):
197 wxTreeCtrl.__init__(self, parent, id,
198 style = wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT,
199 size = (200, 200))
200
201 self.mainWindow = mainWindow
202 self.map = None
203 self.parent = parent
204 self.layer2id = {}
205
206 self.image_list = None
207 self.emptyImageIndex = 0
208
209 self.previewer = ClassDataPreviewer()
210
211 EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)
212 EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)
213
214 EVT_CLOSE(self, self._OnClose)
215
216 self.SetMap(map)
217
218 def _OnClose(self, event):
219 self.SetMap(None)
220
221 def GetMap(self):
222 return self.map
223
224 def SetMap(self, map):
225
226 sub_list = [(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged),
227 (MAP_LAYERS_ADDED, self._OnMsgMapLayersAddedRemoved),
228 (MAP_LAYERS_REMOVED, self._OnMsgMapLayersAddedRemoved)]
229
230 if self.map is not None:
231 for msg, func in sub_list: self.map.Unsubscribe(msg, func)
232 #self.mainWindow.application.Unsubscribe(SESSION_REPLACED,
233 #self._OnMsgMapsChanged)
234 #try:
235 #self.mainWindow.application.session.Unsubscribe(MAPS_CHANGED,
236 #self._OnMsgMapsChanged)
237 #except ConnectorError:
238 #pass
239 self.__DeleteAllItems()
240
241 self.map = map
242
243 if self.map is not None:
244 for msg, func in sub_list: self.map.Subscribe(msg, func)
245 #self.mainWindow.application.session.Subscribe(MAPS_CHANGED,
246 #self._OnMsgMapsChanged)
247 #self.mainWindow.application.Subscribe(SESSION_REPLACED,
248 #self._OnMsgMapsChanged)
249 self.__FillTree(self.map)
250
251 def MoveCurrentItemTop(self):
252 layer, group = self.GetSelectedHierarchy()
253
254 if layer is not None:
255 self.map.TopLayer(layer)
256 else:
257 assert False, "Shouldn't be allowed."
258 pass
259
260 def MoveCurrentItemUp(self):
261 layer, group = self.GetSelectedHierarchy()
262
263 if layer is not None:
264 self.map.RaiseLayer(layer)
265 else:
266 assert False, "Shouldn't be allowed."
267 pass
268
269 def MoveCurrentItemDown(self):
270 layer, group = self.GetSelectedHierarchy()
271
272 if layer is not None:
273 self.map.LowerLayer(layer)
274 else:
275 assert False, "Shouldn't be allowed."
276 pass
277
278 def MoveCurrentItemBottom(self):
279 layer, group = self.GetSelectedHierarchy()
280
281 if layer is not None:
282 self.map.BottomLayer(layer)
283 else:
284 assert False, "Shouldn't be allowed."
285 pass
286
287 def OnCompareItems(self, item1, item2):
288
289 data1 = self.GetPyData(item1)
290 data2 = self.GetPyData(item2)
291
292 if isinstance(data1, BaseLayer):
293 layers = self.map.Layers()
294 return layers.index(data2) - layers.index(data1)
295 else:
296 return wxTreeCtrl.OnCompareItems(self, item1, item2)
297
298 def DoOnShowLayer(self):
299 #self.__ShowHideLayer(True)
300 layer, group = self.GetSelectedHierarchy()
301 layer.SetVisible(True)
302
303 def DoOnHideLayer(self):
304 #self.__ShowHideLayer(False)
305 layer, group = self.GetSelectedHierarchy()
306 layer.SetVisible(False)
307
308 def Sort(self):
309 self.SortChildren(self.GetRootItem())
310
311 def GetSelectedHierarchy(self):
312 id = self.GetSelection()
313
314 if not id.IsOk():
315 return (None, None)
316
317 layer = self.GetPyData(id)
318 group = None
319
320 if isinstance(layer, ClassGroup):
321 id = self.GetItemParent(id)
322 assert id.IsOk()
323 group = layer
324 layer = self.GetPyData(id)
325
326 return (layer, group)
327
328 def _OnMsgMapsChanged(self):
329 #print self.map is self.mainWindow.Map()
330 self.SetMap(self.mainWindow.Map())
331
332 def _OnSelChanged(self, event):
333 self.__UpdateSelection()
334
335 def _OnItemActivated(self, event):
336 self.parent.DoOnProperties()
337
338 def _OnMsgLayerChanged(self, layer):
339 assert isinstance(layer, BaseLayer)
340
341 id = self.layer2id[layer]
342 assert id.IsOk()
343
344 # XXX: yikes! this is so bad, we should be doing what is
345 # commented out, but there is a problem with keeping
346 # track of the images in the image list when we replace
347 # a layer. it ends up causing a seg fault.
348 self.__FillTree(self.map)
349 self.__UpdateSelection()
350 #self.__FillTreeLayer(id)
351
352 def _OnMsgMapStackingChanged(self, *args):
353 self.Sort()
354 id = self.GetSelection()
355
356 if id.IsOk():
357 self.EnsureVisible(id)
358 self.__UpdateSelection()
359
360 def _OnMsgMapLayersAddedRemoved(self, map):
361 assert map is self.map
362
363 self.__FillTree(self.map)
364 self.__UpdateSelection()
365
366 def _OnMsgLayerVisibilityChanged(self, layer):
367 assert isinstance(layer, BaseLayer)
368
369 self.__ShowHideLayer(layer)
370 self.__UpdateSelection()
371
372 def _OnMsgLayerTitleChanged(self, layer):
373
374 id = self.layer2id[layer]
375 if id.IsOk():
376 self.SetItemText(id, layer.Title())
377 self.__UpdateSelection()
378
379 def __UpdateSelection(self):
380 layer, group = self.GetSelectedHierarchy()
381 self.parent.DoOnSelChanged(layer, group)
382
383 def __FillTree(self, map):
384
385 self.Freeze()
386
387 self.__DeleteAllItems()
388
389 if map.HasLayers():
390
391 self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)
392
393 bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
394 dc = wxMemoryDC()
395 dc.SelectObject(bmp)
396 dc.SetBrush(wxBLACK_BRUSH)
397 dc.Clear()
398 dc.SelectObject(wxNullBitmap)
399
400 self.emptyImageIndex = \
401 self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))
402
403 bmp = resource.GetBitmapResource("legend_icon_layer",
404 wxBITMAP_TYPE_XPM)
405 self.mapImageIndex = \
406 self.image_list.Add(bmp)
407
408 self.AssignImageList(self.image_list)
409
410 root = self.AddRoot("")
411
412 for l in map.Layers():
413 id = self.PrependItem(root, l.Title())
414 self.SetItemImage(id, self.mapImageIndex)
415 self.SetItemSelectedImage(id, self.mapImageIndex)
416
417 l.Subscribe(LAYER_CHANGED, self._OnMsgLayerChanged)
418 l.Subscribe(LAYER_VISIBILITY_CHANGED,
419 self._OnMsgLayerVisibilityChanged)
420 l.Subscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
421 self.SetPyData(id, l)
422 self.__SetVisibilityStyle(l.Visible(), id)
423
424 self.layer2id[l] = id
425
426 self.__FillTreeLayer(id)
427 self.Expand(id)
428
429 self.Thaw()
430
431 def __FillTreeLayer(self, pid):
432 layer = self.GetPyData(pid)
433
434 self.Freeze()
435
436 self.DeleteChildren(pid)
437
438 if layer.HasClassification():
439
440 clazz = layer.GetClassification()
441
442 shapeType = layer.ShapeType()
443
444 show = layer.Visible()
445 for g in clazz:
446 if g.IsVisible():
447 id = self.AppendItem(pid, g.GetDisplayText())
448 self.SetPyData(id, g)
449 self.__SetVisibilityStyle(show, id)
450
451 bmp = self.__BuildGroupImage(g, shapeType)
452
453 if bmp is None:
454 self.SetItemImage(id, -1)
455 self.SetItemSelectedImage(id, -1)
456 else:
457 i = self.image_list.Add(bmp)
458 self.SetItemImage(id, i)
459 self.SetItemSelectedImage(id, i)
460
461 self.Thaw()
462
463 def __BuildGroupImage(self, group, shapeType):
464
465 bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
466 #brush = wxBrush(Color2wxColour(item[1]), wxSOLID)
467 dc = wxMemoryDC()
468 dc.SelectObject(bmp)
469 dc.Clear()
470
471 self.previewer.Draw(dc, None, group.GetProperties(), shapeType)
472
473 return bmp
474
475 def __DeleteAllItems(self):
476
477 while len(self.layer2id) > 0:
478 layer, id = self.layer2id.popitem()
479 layer.Unsubscribe(LAYER_CHANGED,
480 self._OnMsgLayerChanged)
481 layer.Unsubscribe(LAYER_VISIBILITY_CHANGED,
482 self._OnMsgLayerVisibilityChanged)
483 layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
484
485 self.DeleteAllItems()
486
487 def __SetVisibilityStyle(self, visible, id):
488 font = self.GetItemFont(id)
489
490 if visible:
491 font.SetStyle(wxNORMAL)
492 color = wxBLACK
493 else:
494 #font.SetStyle(wxITALIC)
495 font.SetStyle(wxNORMAL)
496 color = wxLIGHT_GREY
497
498 self.SetItemTextColour(id, color)
499 self.SetItemFont(id, font)
500
501 def __ShowHideLayer(self, layer):
502 parent = self.layer2id[layer]
503 assert parent.IsOk()
504
505 visible = layer.Visible()
506
507 self.__SetVisibilityStyle(visible, parent)
508
509 id, cookie = self.GetFirstChild(parent, 123)
510
511 while id.IsOk():
512 self.__SetVisibilityStyle(visible, id)
513 id, cookie = self.GetNextChild(parent, cookie)
514
515 class ScaleBarBitmap(wxBoxSizer):
516
517 def __init__(self, parent, map, mainWindow):
518 # While the width is fixed, get the height _now_.
519 dc = wxMemoryDC()
520 textwidth, textheight = dc.GetTextExtent("%d"%0)
521 self.width = 210
522 self.height = textheight + 3*2 + 8
523
524 wxBoxSizer.__init__(self, wxVERTICAL)
525 bmp=wxEmptyBitmap(self.width, self.height)
526 self.scalebarBitmap = wxStaticBitmap(parent, -1, bmp)
527 self.Add(self.scalebarBitmap, 0, wxALIGN_CENTER|wxLEFT|wxTOP|wxRIGHT, 1)
528
529 self.mainWindow = mainWindow
530 self.parent = parent
531 self.canvas = None
532 self.SetCanvas(self.mainWindow.canvas)
533
534 def SetCanvas(self, canvas):
535 sub_list = [(SCALE_CHANGED, self._OnMsgScaleChanged)]
536
537 if self.canvas is not None:
538 for msg, func in sub_list: self.canvas.Unsubscribe(msg, func)
539
540 self.canvas = canvas
541 self.scalebar = ScaleBar(canvas.map)
542
543 if self.canvas is not None:
544 for msg, func in sub_list: self.canvas.Subscribe(msg, func)
545 self.__SetScale(self.canvas.scale)
546
547 def _OnMsgScaleChanged(self, scale):
548 self.__SetScale(scale)
549
550 def __SetScale(self, scale):
551 bmp = wxEmptyBitmap(self.width, self.height)
552 dc = wxMemoryDC()
553 dc.SelectObject(bmp)
554 dc.Clear()
555
556 self.scalebar.DrawScaleBar(scale, dc, (0,0), dc.GetSizeTuple())
557
558 self.scalebarBitmap.SetBitmap(bmp)
559

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26