/[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 882 - (show annotations)
Fri May 9 16:34:28 2003 UTC (21 years, 10 months ago) by jonathan
Original Path: trunk/thuban/Thuban/UI/legend.py
File MIME type: text/x-python
File size: 14927 byte(s)
Explicit imports.

1 # Copyright (c) 2001, 2002, 2003 by Intevation GmbH
2 # Authors:
3 # Jonathan Coles <[email protected]>
4 #
5 # This program is free software under the GPL (>=v2)
6 # Read the file COPYING coming with Thuban for details.
7
8 __version__ = "$Revision$"
9
10 from Thuban import _
11
12 import resource
13
14 from wxPython.wx import *
15
16 from Thuban.Model.layer import Layer
17 from Thuban.Model.map import Map
18 from Thuban.Model.classification import ClassGroup
19
20 from Thuban.Model.messages import \
21 MAP_STACKING_CHANGED, MAP_LAYERS_ADDED, MAP_LAYERS_REMOVED, LAYER_CHANGED,\
22 LAYER_VISIBILITY_CHANGED, TITLE_CHANGED
23
24 from Thuban.UI.messages import SCALE_CHANGED
25
26 from Thuban.UI.classifier import ClassDataPreviewer
27 from Thuban.UI.dock import DockPanel
28 from Thuban.UI.scalebar import ScaleBar
29
30 from Thuban.Lib.connector import ConnectorError
31
32 ID_LEGEND_RAISE = 4001
33 ID_LEGEND_LOWER = 4002
34 ID_LEGEND_TREE = 4003
35 ID_LEGEND_PROPS = 4004
36 ID_LEGEND_SHOWLAYER = 4005
37 ID_LEGEND_HIDELAYER = 4006
38
39 BMP_SIZE_W = 30
40 BMP_SIZE_H = 15
41
42 RAISE_BMP = "raise_layer"
43 LOWER_BMP = "lower_layer"
44 SHOW_BMP = "show_layer"
45 HIDE_BMP = "hide_layer"
46 PROPS_BMP = "layer_properties"
47
48
49 class LegendPanel(DockPanel):
50
51 def __init__(self, parent, map, mainWindow):
52 DockPanel.__init__(self, parent, -1)
53
54 self.mainWindow = mainWindow
55 self.parent = parent
56
57 self.buttons = []
58
59 panelBox = wxBoxSizer(wxVERTICAL)
60
61 self.toolBar = wxToolBar(self, -1)
62 self.toolBar.SetToolBitmapSize(wxSize(24, 24))
63
64 bmp = resource.GetBitmapResource(RAISE_BMP, wxBITMAP_TYPE_XPM)
65 self.toolBar.AddTool(ID_LEGEND_RAISE, bmp,
66 shortHelpString=_("Raise Layer"))
67
68 bmp = resource.GetBitmapResource(LOWER_BMP, wxBITMAP_TYPE_XPM)
69 self.toolBar.AddTool(ID_LEGEND_LOWER, bmp,
70 shortHelpString=_("Lower Layer"))
71
72 bmp = resource.GetBitmapResource(SHOW_BMP, wxBITMAP_TYPE_XPM)
73 self.toolBar.AddTool(ID_LEGEND_SHOWLAYER, bmp,
74 shortHelpString=_("Show Layer"))
75
76 bmp = resource.GetBitmapResource(HIDE_BMP, wxBITMAP_TYPE_XPM)
77 self.toolBar.AddTool(ID_LEGEND_HIDELAYER, bmp,
78 shortHelpString=_("Hide Layer"))
79
80 bmp = resource.GetBitmapResource(PROPS_BMP, wxBITMAP_TYPE_XPM)
81 self.toolBar.AddTool(ID_LEGEND_PROPS, bmp,
82 shortHelpString=_("Edit Layer Properties"))
83
84 self.toolBar.Realize()
85 panelBox.Add(self.toolBar, 0, wxGROW, 0)
86
87 EVT_TOOL(self, ID_LEGEND_RAISE, self._OnMoveUp)
88 EVT_TOOL(self, ID_LEGEND_LOWER, self._OnMoveDown)
89 EVT_TOOL(self, ID_LEGEND_PROPS, self._OnProperties)
90 EVT_TOOL(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)
91 EVT_TOOL(self, ID_LEGEND_HIDELAYER, self._OnHideLayer)
92
93 self.tree = LegendTree(self, ID_LEGEND_TREE, map, mainWindow)
94
95 panelBox.Add(self.tree, 1, wxGROW, 0)
96
97 self.scalebarbitmap = ScaleBarBitmap(self, map, mainWindow)
98 panelBox.Add(self.scalebarbitmap, 0, wxGROW, 0)
99
100 self.SetAutoLayout(True)
101 self.SetSizer(panelBox)
102 panelBox.SetSizeHints(self)
103
104
105 self.panelBox = panelBox
106
107 self.__EnableButtons(False)
108
109 self.Create()
110
111 EVT_CLOSE(self, self._OnClose)
112
113
114 def GetMap(self):
115 return self.tree.GetMap()
116
117 def SetMap(self, map):
118 self.tree.SetMap(map)
119 self.scalebarbitmap.SetCanvas(self.mainWindow.canvas)
120
121 def DoOnSelChanged(self, layer, group):
122
123 ok = isinstance(layer, Layer)
124 self.__EnableButtons(ok)
125
126 self.mainWindow.SelectLayer(layer)
127
128 def DoOnProperties(self):
129 list = self.tree.GetSelectedHierarchy()
130
131 ok = isinstance(list[0], Layer)
132 if ok:
133 self.mainWindow.OpenLayerProperties(list[0], list[1])
134
135 def Destroy(self):
136 self.__Close()
137
138 def _OnProperties(self, event):
139 self.DoOnProperties()
140
141 def _OnMoveUp(self, event):
142 self.tree.MoveCurrentItemUp()
143
144 def _OnMoveDown(self, event):
145 self.tree.MoveCurrentItemDown()
146
147 def _OnShowLayer(self, event):
148 self.tree.DoOnShowLayer()
149 pass
150
151 #def Close(self, force = False):
152 #DockPanel.Close(self, force)
153
154 def _OnClose(self, event):
155 self.__Close()
156
157 def _OnHideLayer(self, event):
158 self.tree.DoOnHideLayer()
159 pass
160
161 def __EnableButtons(self, on):
162 self.toolBar.EnableTool(ID_LEGEND_RAISE, on)
163 self.toolBar.EnableTool(ID_LEGEND_LOWER, on)
164 self.toolBar.EnableTool(ID_LEGEND_SHOWLAYER, on)
165 self.toolBar.EnableTool(ID_LEGEND_HIDELAYER, on)
166 self.toolBar.EnableTool(ID_LEGEND_PROPS, on)
167
168 def __Close(self):
169 self.tree.Close()
170
171 class LegendTree(wxTreeCtrl):
172
173 def __init__(self, parent, id, map, mainWindow):
174 wxTreeCtrl.__init__(self, parent, id,
175 style = wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT,
176 size = (200, 200))
177
178 self.mainWindow = mainWindow
179 self.map = None
180 self.parent = parent
181 self.layer2id = {}
182
183 self.image_list = None
184 self.emptyImageIndex = 0
185
186 self.previewer = ClassDataPreviewer()
187
188 EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)
189 EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)
190
191 EVT_CLOSE(self, self._OnClose)
192
193 self.SetMap(map)
194
195 def _OnClose(self, event):
196 self.SetMap(None)
197
198 def GetMap(self):
199 return self.map
200
201 def SetMap(self, map):
202
203 sub_list = [(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged),
204 (MAP_LAYERS_ADDED, self._OnMsgMapLayersAddedRemoved),
205 (MAP_LAYERS_REMOVED, self._OnMsgMapLayersAddedRemoved)]
206
207 if self.map is not None:
208 for msg, func in sub_list: self.map.Unsubscribe(msg, func)
209 #self.mainWindow.application.Unsubscribe(SESSION_REPLACED,
210 #self._OnMsgMapsChanged)
211 #try:
212 #self.mainWindow.application.session.Unsubscribe(MAPS_CHANGED,
213 #self._OnMsgMapsChanged)
214 #except ConnectorError:
215 #pass
216 self.__DeleteAllItems()
217
218 self.map = map
219
220 if self.map is not None:
221 for msg, func in sub_list: self.map.Subscribe(msg, func)
222 #self.mainWindow.application.session.Subscribe(MAPS_CHANGED,
223 #self._OnMsgMapsChanged)
224 #self.mainWindow.application.Subscribe(SESSION_REPLACED,
225 #self._OnMsgMapsChanged)
226 self.__FillTree(self.map)
227
228 def MoveCurrentItemUp(self):
229 layer, group = self.GetSelectedHierarchy()
230
231 if layer is not None:
232 self.map.RaiseLayer(layer)
233 else:
234 assert False, "Shouldn't be allowed."
235 pass
236
237 def MoveCurrentItemDown(self):
238 layer, group = self.GetSelectedHierarchy()
239
240 if layer is not None:
241 self.map.LowerLayer(layer)
242 else:
243 assert False, "Shouldn't be allowed."
244 pass
245
246 def OnCompareItems(self, item1, item2):
247
248 data1 = self.GetPyData(item1)
249 data2 = self.GetPyData(item2)
250
251 if isinstance(data1, Layer):
252 layers = self.map.Layers()
253 return layers.index(data2) - layers.index(data1)
254 else:
255 return wxTreeCtrl.OnCompareItems(self, item1, item2)
256
257 def DoOnShowLayer(self):
258 #self.__ShowHideLayer(True)
259 layer, group = self.GetSelectedHierarchy()
260 layer.SetVisible(True)
261
262 def DoOnHideLayer(self):
263 #self.__ShowHideLayer(False)
264 layer, group = self.GetSelectedHierarchy()
265 layer.SetVisible(False)
266
267 def Sort(self):
268 self.SortChildren(self.GetRootItem())
269
270 def GetSelectedHierarchy(self):
271 id = self.GetSelection()
272
273 if not id.IsOk():
274 return (None, None)
275
276 layer = self.GetPyData(id)
277 group = None
278
279 if isinstance(layer, ClassGroup):
280 id = self.GetItemParent(id)
281 assert id.IsOk()
282 group = layer
283 layer = self.GetPyData(id)
284
285 return (layer, group)
286
287 def _OnMsgMapsChanged(self):
288 #print self.map is self.mainWindow.Map()
289 self.SetMap(self.mainWindow.Map())
290
291 def _OnSelChanged(self, event):
292 self.__UpdateSelection()
293
294 def _OnItemActivated(self, event):
295 self.parent.DoOnProperties()
296
297 def _OnMsgLayerChanged(self, layer):
298 assert isinstance(layer, Layer)
299
300 id = self.layer2id[layer]
301 assert id.IsOk()
302
303 # XXX: yikes! this is so bad, we should be doing what is
304 # commented out, but there is a problem with keeping
305 # track of the images in the image list when we replace
306 # a layer. it ends up causing a seg fault.
307 self.__FillTree(self.map)
308 self.__UpdateSelection()
309 #self.__FillTreeLayer(id)
310
311 def _OnMsgMapStackingChanged(self, *args):
312 self.Sort()
313 id = self.GetSelection()
314
315 if id.IsOk():
316 self.EnsureVisible(id)
317 self.__UpdateSelection()
318
319 def _OnMsgMapLayersAddedRemoved(self, map):
320 assert map is self.map
321
322 self.__FillTree(self.map)
323 self.__UpdateSelection()
324
325 def _OnMsgLayerVisibilityChanged(self, layer):
326 assert isinstance(layer, Layer)
327
328 self.__ShowHideLayer(layer)
329 self.__UpdateSelection()
330
331 def _OnMsgLayerTitleChanged(self, layer):
332
333 id = self.layer2id[layer]
334 if id.IsOk():
335 self.SetItemText(id, layer.Title())
336 self.__UpdateSelection()
337
338 def __UpdateSelection(self):
339 layer, group = self.GetSelectedHierarchy()
340 self.parent.DoOnSelChanged(layer, group)
341
342 def __FillTree(self, map):
343
344 self.Freeze()
345
346 self.__DeleteAllItems()
347
348 if map.HasLayers():
349
350 self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)
351
352 bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
353 dc = wxMemoryDC()
354 dc.SelectObject(bmp)
355 dc.SetBrush(wxBLACK_BRUSH)
356 dc.Clear()
357 dc.SelectObject(wxNullBitmap)
358
359 self.emptyImageIndex = \
360 self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))
361
362 self.AssignImageList(self.image_list)
363
364 root = self.AddRoot("")
365
366 for l in map.Layers():
367 id = self.PrependItem(root, l.Title())
368 l.Subscribe(LAYER_CHANGED, self._OnMsgLayerChanged)
369 l.Subscribe(LAYER_VISIBILITY_CHANGED,
370 self._OnMsgLayerVisibilityChanged)
371 l.Subscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
372 self.SetPyData(id, l)
373 self.__SetVisibilityStyle(l.Visible(), id)
374
375 self.layer2id[l] = id
376
377 self.__FillTreeLayer(id)
378 self.Expand(id)
379
380 self.Thaw()
381
382 def __FillTreeLayer(self, pid):
383 layer = self.GetPyData(pid)
384
385 self.Freeze()
386
387 self.DeleteChildren(pid)
388
389 clazz = layer.GetClassification()
390
391 shapeType = layer.ShapeType()
392
393 show = layer.Visible()
394 for g in clazz:
395 if g.IsVisible():
396 id = self.AppendItem(pid, g.GetDisplayText())
397 self.SetPyData(id, g)
398 self.__SetVisibilityStyle(show, id)
399
400 bmp = self.__BuildGroupImage(g, shapeType)
401
402 if bmp is None:
403 self.SetItemImage(id, self.emptyImageIndex)
404 else:
405 i = self.image_list.Add(bmp)
406 self.SetItemImage(id, i)
407
408 self.Thaw()
409
410 def __BuildGroupImage(self, group, shapeType):
411
412 bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
413 #brush = wxBrush(Color2wxColour(item[1]), wxSOLID)
414 dc = wxMemoryDC()
415 dc.SelectObject(bmp)
416 dc.Clear()
417
418 self.previewer.Draw(dc, None, group.GetProperties(), shapeType)
419
420 return bmp
421
422 def __DeleteAllItems(self):
423
424 while len(self.layer2id) > 0:
425 layer, id = self.layer2id.popitem()
426 layer.Unsubscribe(LAYER_CHANGED,
427 self._OnMsgLayerChanged)
428 layer.Unsubscribe(LAYER_VISIBILITY_CHANGED,
429 self._OnMsgLayerVisibilityChanged)
430 layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
431
432 self.DeleteAllItems()
433
434 def __SetVisibilityStyle(self, visible, id):
435 font = self.GetItemFont(id)
436
437 if visible:
438 font.SetStyle(wxNORMAL)
439 color = wxBLACK
440 else:
441 font.SetStyle(wxITALIC)
442 color = wxLIGHT_GREY
443
444 self.SetItemTextColour(id, color)
445 self.SetItemFont(id, font)
446
447 def __ShowHideLayer(self, layer):
448 parent = self.layer2id[layer]
449 assert parent.IsOk()
450
451 visible = layer.Visible()
452
453 self.__SetVisibilityStyle(visible, parent)
454
455 id, cookie = self.GetFirstChild(parent, 123)
456
457 while id.IsOk():
458 self.__SetVisibilityStyle(visible, id)
459 id, cookie = self.GetNextChild(parent, cookie)
460
461 class ScaleBarBitmap(wxBoxSizer):
462
463 def __init__(self, parent, map, mainWindow):
464 # While the width is fixed, get the height _now_.
465 dc = wxMemoryDC()
466 textwidth, textheight = dc.GetTextExtent("%d"%0)
467 self.width = 200
468 self.height = textheight + 3*2 + 8
469
470 wxBoxSizer.__init__(self, wxVERTICAL)
471 bmp=wxEmptyBitmap(self.width, self.height)
472 self.scalebarBitmap = wxStaticBitmap(parent, -1, bmp)
473 self.Add(self.scalebarBitmap, 0, wxALIGN_CENTER|wxLEFT|wxTOP|wxRIGHT, 1)
474
475 self.mainWindow = mainWindow
476 self.parent = parent
477 self.canvas = None
478 self.SetCanvas(self.mainWindow.canvas)
479
480 def SetCanvas(self, canvas):
481 sub_list = [(SCALE_CHANGED, self._OnMsgScaleChanged)]
482
483 if self.canvas is not None:
484 for msg, func in sub_list: self.canvas.Unsubscribe(msg, func)
485
486 self.canvas = canvas
487 self.scalebar = ScaleBar(canvas.map)
488
489 if self.canvas is not None:
490 for msg, func in sub_list: self.canvas.Subscribe(msg, func)
491 self.__SetScale(self.canvas.scale)
492
493 def _OnMsgScaleChanged(self, scale):
494 self.__SetScale(scale)
495
496 def __SetScale(self, scale):
497 bmp = wxEmptyBitmap(self.width, self.height)
498 dc = wxMemoryDC()
499 dc.SelectObject(bmp)
500 dc.Clear()
501
502 self.scalebar.DrawScalebar(scale, dc)
503
504 self.scalebarBitmap.SetBitmap(bmp)
505

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26