/[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 864 - (show annotations)
Thu May 8 12:29:23 2003 UTC (21 years, 10 months ago) by frank
Original Path: trunk/thuban/Thuban/UI/legend.py
File MIME type: text/x-python
File size: 14790 byte(s)
Import Thuban.UI.scalebar

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

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26