GRASS Programmer's Manual  6.4.3(2013)-r
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Pages
tools.py
Go to the documentation of this file.
1 """!
2 @package nviz.tools
3 
4 @brief Nviz (3D view) tools window
5 
6 Classes:
7  - tools::NvizToolWindow
8  - tools::PositionWindow
9  - tools::ViewPositionWindow
10  - tools::LightPositionWindow
11 
12 (C) 2008-2011 by the GRASS Development Team
13 
14 This program is free software under the GNU General Public License
15 (>=v2). Read the file COPYING that comes with GRASS for details.
16 
17 @author Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
18 @author Enhancements by Michael Barton <michael.barton asu.edu>
19 @author Anna Kratochvilova <kratochanna gmail.com> (Google SoC 2011)
20 """
21 
22 import os
23 import sys
24 import copy
25 import types
26 
27 import wx
28 import wx.lib.colourselect as csel
29 import wx.lib.scrolledpanel as SP
30 import wx.lib.filebrowsebutton as filebrowse
31 try:
32  import wx.lib.agw.flatnotebook as FN
33 except ImportError:
34  import wx.lib.flatnotebook as FN
35 try:
36  from agw import foldpanelbar as fpb
37 except ImportError: # if it's not there locally, try the wxPython lib.
38  try:
39  import wx.lib.agw.foldpanelbar as fpb
40  except ImportError:
41  import wx.lib.foldpanelbar as fpb # versions <=2.5.5.1
42 
43 import grass.script as grass
44 
45 from core import globalvar
46 from core.gcmd import GMessage, RunCommand
47 from core.settings import UserSettings
48 from nviz.animation import EVT_ANIM_FIN, EVT_ANIM_UPDATE_IDX
49 from gui_core.widgets import ScrolledPanel, NumTextCtrl, FloatSlider, SymbolButton
50 from gui_core.gselect import Select
51 from core.debug import Debug
52 try:
53  from nviz.mapwindow import wxUpdateProperties, wxUpdateView,\
54  wxUpdateLight, wxUpdateCPlane
55  import wxnviz
56 except ImportError:
57  pass
58 
59 class NvizToolWindow(FN.FlatNotebook):
60  """!Nviz (3D view) tools panel
61  """
62  def __init__(self, parent, display, id = wx.ID_ANY,
63  style = globalvar.FNPageStyle|FN.FNB_NO_X_BUTTON,
64  **kwargs):
65  Debug.msg(5, "NvizToolWindow.__init__()")
66  self.parent = parent # GMFrame
67  self.mapDisplay = display
68  self.mapWindow = display.GetWindow()
69  self._display = self.mapWindow.GetDisplay()
70 
71  if globalvar.hasAgw:
72  kwargs['agwStyle'] = style
73  else:
74  kwargs['style'] = style
75  FN.FlatNotebook.__init__(self, parent, id, **kwargs)
76  self.SetTabAreaColour(globalvar.FNPageColor)
77 
78  self.win = {} # window ids
79  self.page = {} # page ids
80 
81  # view page
82  self.AddPage(page = self._createViewPage(),
83  text = " %s " % _("View"))
84 
85  # data page
86  self.AddPage(page = self._createDataPage(),
87  text = " %s " % _("Data"))
88 
89  # appearance page
90  self.AddPage(page = self._createAppearancePage(),
91  text = " %s " % _("Appearance"))
92 
93  # analysis page
94  self.AddPage(page = self._createAnalysisPage(),
95  text = " %s " % _("Analysis"))
96  # view page
97  self.AddPage(page = self._createAnimationPage(),
98  text = " %s " % _("Animation"))
99 
100  self.UpdateSettings()
101 
102  self.mapWindow.SetToolWin(self)
103 
104  self.pageChanging = False
105  self.vetoGSelectEvt = False #when setting map, event is invoked
106  self.mapWindow.render['quick'] = False
107  self.mapWindow.Refresh(False)
108 
109  # bindings
110  self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
111  self.Bind(wx.EVT_SIZE, self.OnSize)
112 
113  self.Bind(EVT_ANIM_FIN, self.OnAnimationFinished)
114  self.Bind(EVT_ANIM_UPDATE_IDX, self.OnAnimationUpdateIndex)
115 
116  Debug.msg(3, "NvizToolWindow.__init__()")
117 
118  self.Update()
119  wx.CallAfter(self.SetPage, 'view')
120  wx.CallAfter(self.UpdateScrolling, (self.foldpanelData, self.foldpanelAppear,
121  self.foldpanelAnalysis))
122  wx.CallAfter(self.SetInitialMaps)
123 
124  def SetInitialMaps(self):
125  """!Set initial raster and vector map"""
126  for l_type in ('raster', 'vector', '3d-raster'):
127  selectedLayer = self.mapWindow.GetSelectedLayer()
128  layers = self.mapWindow.Map.GetListOfLayers(l_type = l_type, l_active = True)
129  if selectedLayer in layers:
130  selection = selectedLayer.GetName()
131  else:
132  try:
133  selection = layers[0].GetName()
134  except:
135  continue
136  if l_type == 'raster':
137  self.FindWindowById(self.win['surface']['map']).SetValue(selection)
138  self.FindWindowById(self.win['fringe']['map']).SetValue(selection)
139  elif l_type == 'vector':
140  self.FindWindowById(self.win['vector']['map']).SetValue(selection)
141  elif l_type == '3d-raster':
142  self.FindWindowById(self.win['volume']['map']).SetValue(selection)
143 
144  def UpdateState(self, **kwargs):
145  if 'view' in kwargs:
146  self.mapWindow.view = kwargs['view']
147  self.FindWindowById(self.win['view']['position']).data = kwargs['view']
148  self.FindWindowById(self.win['view']['position']).PostDraw()
149  if 'iview' in kwargs:
150  self.mapWindow.iview = kwargs['iview']
151  if 'light' in kwargs:
152  self.mapWindow.light = kwargs['light']
153  self.FindWindowById(self.win['light']['position']).data = kwargs['light']
154  self.FindWindowById(self.win['light']['position']).PostDraw()
155  if 'fly' in kwargs:
156  self.mapWindow.fly['exag'] = kwargs['fly']['exag']
157 
158  def LoadSettings(self):
159  """!Load Nviz settings and apply to current session"""
160  view = copy.deepcopy(UserSettings.Get(group = 'nviz', key = 'view')) # copy
161  light = copy.deepcopy(UserSettings.Get(group = 'nviz', key = 'light')) # copy
162  fly = copy.deepcopy(UserSettings.Get(group = 'nviz', key = 'fly')) # copy
163  self.UpdateState(view = view, light = light, fly = fly)
164  self.PostViewEvent(zExag = True)
165  self.PostLightEvent()
166  self.UpdatePage('view')
167  self.UpdatePage('light')
168 
169  self.mapWindow.ReloadLayersData()
170  self.UpdatePage('surface')
171  self.UpdatePage('vector')
172  self.UpdateSettings()
173 
174  def OnPageChanged(self, event):
175  new = event.GetSelection()
176  # self.ChangeSelection(new)
177 
178  def PostViewEvent(self, zExag = False):
179  """!Change view settings"""
180  event = wxUpdateView(zExag = zExag)
181  wx.PostEvent(self.mapWindow, event)
182 
183  def PostLightEvent(self, refresh = False):
184  """!Change light settings"""
185  event = wxUpdateLight(refresh = refresh)
186  wx.PostEvent(self.mapWindow, event)
187 
188  def OnSize(self, event):
189  """!After window is resized, update scrolling"""
190  # workaround to resize captionbars of foldpanelbar
191  wx.CallAfter(self.UpdateScrolling, (self.foldpanelData, self.foldpanelAppear,
192  self.foldpanelAnalysis))
193  event.Skip()
194 
195  def OnPressCaption(self, event):
196  """!When foldpanel item collapsed/expanded, update scrollbars"""
197  foldpanel = event.GetBar().GetGrandParent().GetParent()
198  wx.CallAfter(self.UpdateScrolling, (foldpanel,))
199  event.Skip()
200 
201  def UpdateScrolling(self, foldpanels):
202  """!Update scrollbars in foldpanel"""
203  for foldpanel in foldpanels:
204  length = foldpanel.GetPanelsLength(collapsed = 0, expanded = 0)
205  # virtual width is set to fixed value to suppress GTK warning
206  foldpanel.GetParent().SetVirtualSize((100, length[2]))
207  foldpanel.GetParent().Layout()
208 
209  def _createViewPage(self):
210  """!Create view settings page"""
211  panel = SP.ScrolledPanel(parent = self, id = wx.ID_ANY)
212  panel.SetupScrolling(scroll_x = False)
213  self.page['view'] = { 'id' : 0,
214  'notebook' : self.GetId()}
215 
216  pageSizer = wx.BoxSizer(wx.VERTICAL)
217  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
218  label = " %s " % (_("Control View")))
219  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
220  gridSizer = wx.GridBagSizer(vgap = 5, hgap = 10)
221 
222  self.win['view'] = {}
223 
224  # position
225  posSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
226 
227  self._createCompass(panel = panel, sizer = posSizer, type = 'view')
228 
229  view = ViewPositionWindow(panel, size = (175, 175),
230  mapwindow = self.mapWindow)
231  self.win['view']['position'] = view.GetId()
232  posSizer.Add(item = view,
233  pos = (1, 1), flag = wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL)
234  gridSizer.Add(item = posSizer, pos = (0, 0))
235 
236  # perspective
237  # set initial defaults here (or perhaps in a default values file), not in user settings
238  #todo: consider setting an absolute max at 360 instead of undefined. (leave the default max value at pi)
239  tooltip = _("Adjusts the distance and angular perspective of the image viewpoint")
240  self._createControl(panel, data = self.win['view'], name = 'persp',
241  tooltip = tooltip, range = (1, 120),
242  bind = (self.OnViewChange, self.OnViewChanged, self.OnViewChangedText))
243 
244  gridSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Perspective:")),
245  pos = (1, 0), flag = wx.ALIGN_CENTER)
246  gridSizer.Add(item = self.FindWindowById(self.win['view']['persp']['slider']), pos = (2, 0),
247  flag = wx.ALIGN_CENTER)
248  gridSizer.Add(item = self.FindWindowById(self.win['view']['persp']['text']), pos = (3, 0),
249  flag = wx.ALIGN_CENTER)
250 
251  # twist
252  tooltip = _("Tilts the plane of the surface from the horizontal")
253  self._createControl(panel, data = self.win['view'], name = 'twist',
254  tooltip = tooltip, range = (-180,180),
255  bind = (self.OnViewChange, self.OnViewChanged, self.OnViewChangedText))
256  gridSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Tilt:")),
257  pos = (1, 1), flag = wx.ALIGN_CENTER)
258  gridSizer.Add(item = self.FindWindowById(self.win['view']['twist']['slider']), pos = (2, 1))
259  gridSizer.Add(item = self.FindWindowById(self.win['view']['twist']['text']), pos = (3, 1),
260  flag = wx.ALIGN_CENTER)
261 
262  # height + z-exag
263  tooltip = _("Adjusts the viewing height above the surface"
264  " (angle of view automatically adjusts to maintain the same center of view)")
265  self._createControl(panel, data = self.win['view'], name = 'height', sliderHor = False,
266  tooltip = tooltip, range = (0, 1),
267  bind = (self.OnViewChange, self.OnViewChanged, self.OnViewChangedText))
268  tooltip = _("Adjusts the relative height of features above the plane of the surface")
269  self._createControl(panel, data = self.win['view'], name = 'z-exag', sliderHor = False,
270  tooltip = tooltip, range = (0, 10), floatSlider = True,
271  bind = (self.OnViewChange, self.OnViewChanged, self.OnViewChangedText))
272  self.FindWindowById(self.win['view']['z-exag']['slider']).SetValue(1)
273  self.FindWindowById(self.win['view']['z-exag']['text']).SetValue(1)
274 
275  heightSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
276  heightSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Height:")),
277  pos = (0, 0), flag = wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL, span = (1, 2))
278  heightSizer.Add(item = self.FindWindowById(self.win['view']['height']['slider']),
279  flag = wx.ALIGN_RIGHT, pos = (1, 0))
280  heightSizer.Add(item = self.FindWindowById(self.win['view']['height']['text']),
281  flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT, pos = (1, 1))
282  heightSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Z-exag:")),
283  pos = (0, 2), flag = wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL, span = (1, 2))
284  heightSizer.Add(item = self.FindWindowById(self.win['view']['z-exag']['slider']),
285  flag = wx.ALIGN_RIGHT, pos = (1, 2))
286  heightSizer.Add(item = self.FindWindowById(self.win['view']['z-exag']['text']),
287  flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.TOP |
288  wx.BOTTOM | wx.RIGHT, pos = (1, 3))
289 
290  gridSizer.Add(item = heightSizer, pos = (0, 1), flag = wx.ALIGN_CENTER)
291 
292  # view setup + reset
293  viewSizer = wx.BoxSizer(wx.HORIZONTAL)
294  viewSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY,
295  label = _("Look:")),
296  flag = wx.ALL | wx.ALIGN_CENTER_VERTICAL,
297  border = 5)
298  here = wx.ToggleButton(panel, id = wx.ID_ANY, label = _("here"))
299  here.Bind(wx.EVT_TOGGLEBUTTON, self.OnLookAt)
300  here.SetName('here')
301  here.SetToolTipString(_("Allows you to select a point on the surface "
302  "that becomes the new center of view. "
303  "Click on the button and then on the surface."))
304  viewSizer.Add(item = here, flag = wx.TOP|wx.BOTTOM|wx.LEFT|wx.ALIGN_CENTER_VERTICAL,
305  border = 5)
306 
307  center = wx.Button(panel, id = wx.ID_ANY, label = _("center"))
308  center.Bind(wx.EVT_BUTTON, self.OnLookAt)
309  center.SetName('center')
310  center.SetToolTipString(_("Resets the view to the original default center of view"))
311  viewSizer.Add(item = center, flag = wx.TOP|wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL,
312  border = 5)
313 
314  top = wx.Button(panel, id = wx.ID_ANY, label = _("top"))
315  top.Bind(wx.EVT_BUTTON, self.OnLookAt)
316  top.SetName('top')
317  top.SetToolTipString(_("Sets the viewer directly over the scene's center position. This top view orients approximately north south."))
318  viewSizer.Add(item = top, flag = wx.TOP|wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL,
319  border = 5)
320 
321  reset = wx.Button(panel, id = wx.ID_ANY, label = _("reset"))
322  reset.SetToolTipString(_("Reset to default view"))
323  reset.Bind(wx.EVT_BUTTON, self.OnResetView)
324  viewSizer.Add(item = reset, proportion = 0,
325  flag = wx.TOP|wx.BOTTOM|wx.RIGHT| wx.ALIGN_RIGHT,
326  border = 5)
327 
328  gridSizer.AddGrowableCol(2)
329  gridSizer.Add(item = viewSizer, pos = (4, 0), span = (1, 3),
330  flag = wx.EXPAND)
331 
332  # body
333  boxSizer.Add(item = gridSizer, proportion = 1,
334  flag = wx.ALL | wx.EXPAND, border = 2)
335  pageSizer.Add(item = boxSizer, proportion = 0,
336  flag = wx.EXPAND | wx.ALL,
337  border = 3)
338 
339  box = wx.StaticBox(parent = panel, id = wx.ID_ANY,
340  label = " %s " % (_("Image Appearance")))
341  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
342  gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
343  gridSizer.AddGrowableCol(0)
344 
345  # background color
346  self.win['view']['background'] = {}
347  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
348  label = _("Background color:")),
349  pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
350 
351  color = csel.ColourSelect(panel, id = wx.ID_ANY,
352  colour = UserSettings.Get(group = 'nviz', key = 'view',
353  subkey = ['background', 'color']),
354  size = globalvar.DIALOG_COLOR_SIZE)
355  self.win['view']['background']['color'] = color.GetId()
356  color.Bind(csel.EVT_COLOURSELECT, self.OnBgColor)
357  gridSizer.Add(item = color, pos = (0, 1))
358 
359  boxSizer.Add(item = gridSizer, proportion = 1,
360  flag = wx.ALL | wx.EXPAND, border = 3)
361  pageSizer.Add(item = boxSizer, proportion = 0,
362  flag = wx.EXPAND | wx.LEFT | wx.RIGHT,
363  border = 3)
364 
365  panel.SetSizer(pageSizer)
366 
367  return panel
368 
369  def _createAnimationPage(self):
370  """!Create view settings page"""
371  panel = SP.ScrolledPanel(parent = self, id = wx.ID_ANY)
372  panel.SetupScrolling(scroll_x = False)
373  self.page['animation'] = { 'id' : 0,
374  'notebook' : self.GetId()}
375 
376  pageSizer = wx.BoxSizer(wx.VERTICAL)
377  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
378  label = " %s " % (_("Animation")))
379  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
380  hSizer = wx.BoxSizer(wx.HORIZONTAL)
381 
382  self.win['anim'] = {}
383  # animation help text
384  help = wx.StaticText(parent = panel, id = wx.ID_ANY,
385  label = _("Press 'Record' button and start changing the view. "
386  "It is recommended to use fly-through mode "
387  "(Map Display toolbar) to achieve smooth motion."))
388  self.win['anim']['help'] = help.GetId()
389  hSizer.Add(item = help, proportion = 0)
390  boxSizer.Add(item = hSizer, proportion = 1,
391  flag = wx.ALL | wx.EXPAND, border = 5)
392 
393  # animation controls
394  hSizer = wx.BoxSizer(wx.HORIZONTAL)
395  record = SymbolButton(parent = panel, id = wx.ID_ANY,
396  usage = "record", label = _("Record"))
397  play = SymbolButton(parent = panel, id = wx.ID_ANY,
398  usage = "play", label = _("Play"))
399  pause = SymbolButton(parent = panel, id = wx.ID_ANY,
400  usage = "pause", label = _("Pause"))
401  stop = SymbolButton(parent = panel, id = wx.ID_ANY,
402  usage = "stop", label = _("Stop"))
403 
404  self.win['anim']['record'] = record.GetId()
405  self.win['anim']['play'] = play.GetId()
406  self.win['anim']['pause'] = pause.GetId()
407  self.win['anim']['stop'] = stop.GetId()
408 
409  self._createControl(panel, data = self.win['anim'], name = 'frameIndex',
410  range = (0, 1), floatSlider = False,
411  bind = (self.OnFrameIndex, None, self.OnFrameIndexText))
412  frameSlider = self.FindWindowById(self.win['anim']['frameIndex']['slider'])
413  frameText = self.FindWindowById(self.win['anim']['frameIndex']['text'])
414  infoLabel = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("Total number of frames :"))
415  info = wx.StaticText(parent = panel, id = wx.ID_ANY)
416  self.win['anim']['info'] = info.GetId()
417 
418  fpsLabel = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("Frame rate (FPS):"))
419  fps = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
420  initial = UserSettings.Get(group = 'nviz', key = 'animation', subkey = 'fps'),
421  min = 1,
422  max = 50)
423  self.win['anim']['fps'] = fps.GetId()
424  fps.SetToolTipString(_("Frames are recorded with given frequency (FPS). "))
425 
426  record.Bind(wx.EVT_BUTTON, self.OnRecord)
427  play.Bind(wx.EVT_BUTTON, self.OnPlay)
428  stop.Bind(wx.EVT_BUTTON, self.OnStop)
429  pause.Bind(wx.EVT_BUTTON, self.OnPause)
430  fps.Bind(wx.EVT_SPINCTRL, self.OnFPS)
431 
432  hSizer.Add(item = record, proportion = 0)
433  hSizer.Add(item = play, proportion = 0)
434  hSizer.Add(item = pause, proportion = 0)
435  hSizer.Add(item = stop, proportion = 0)
436  boxSizer.Add(item = hSizer, proportion = 0,
437  flag = wx.ALL | wx.EXPAND, border = 3)
438 
439  sliderBox = wx.BoxSizer(wx.HORIZONTAL)
440  sliderBox.Add(item = frameSlider, proportion = 1, border = 5, flag = wx.EXPAND | wx.RIGHT)
441  sliderBox.Add(item = frameText, proportion = 0, border = 5, flag = wx.EXPAND| wx.RIGHT | wx.LEFT)
442  boxSizer.Add(item = sliderBox, proportion = 0, flag = wx.EXPAND)
443 
444  # total number of frames
445  hSizer = wx.BoxSizer(wx.HORIZONTAL)
446  hSizer.Add(item = infoLabel, proportion = 0, flag = wx.RIGHT, border = 5)
447  hSizer.Add(item = info, proportion = 0, flag = wx.LEFT, border = 5)
448 
449  boxSizer.Add(item = hSizer, proportion = 0,
450  flag = wx.ALL | wx.EXPAND, border = 5)
451 
452  # frames per second
453  hSizer = wx.BoxSizer(wx.HORIZONTAL)
454  hSizer.Add(item = fpsLabel, proportion = 0, flag = wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, border = 5)
455  hSizer.Add(item = fps, proportion = 0, flag = wx.LEFT | wx.ALIGN_CENTER_VERTICAL, border = 5)
456 
457  boxSizer.Add(item = hSizer, proportion = 0,
458  flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 5)
459  pageSizer.Add(item = boxSizer, proportion = 0,
460  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
461  border = 3)
462 
463  # save animation
464  self.win['anim']['save'] = {}
465  self.win['anim']['save']['image'] = {}
466  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
467  label = " %s " % (_("Save image sequence")))
468  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
469  vSizer = wx.BoxSizer(wx.VERTICAL)
470  gridSizer = wx.GridBagSizer(vgap = 5, hgap = 10)
471 
472  pwd = os.getcwd()
473  dir = filebrowse.DirBrowseButton(parent = panel, id = wx.ID_ANY,
474  labelText = _("Choose a directory:"),
475  dialogTitle = _("Choose a directory for images"),
476  buttonText = _('Browse'),
477  startDirectory = pwd)
478  dir.SetValue(pwd)
479  prefixLabel = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("File prefix:"))
480  prefixCtrl = wx.TextCtrl(parent = panel, id = wx.ID_ANY, size = (100, -1),
481  value = UserSettings.Get(group = 'nviz',
482  key = 'animation', subkey = 'prefix'))
483  prefixCtrl.SetToolTipString(_("Generated files names will look like this: prefix_1.ppm, prefix_2.ppm, ..."))
484  fileTypeLabel = wx.StaticText(parent = panel, id = wx.ID_ANY, label = _("File format:"))
485  fileTypeCtrl = wx.Choice(parent = panel, id = wx.ID_ANY, choices = ["TIF", "PPM"])
486 
487  save = wx.Button(parent = panel, id = wx.ID_ANY,
488  label = "Save")
489 
490  self.win['anim']['save']['image']['dir'] = dir.GetId()
491  self.win['anim']['save']['image']['prefix'] = prefixCtrl.GetId()
492  self.win['anim']['save']['image']['format'] = fileTypeCtrl.GetId()
493  self.win['anim']['save']['image']['confirm'] = save.GetId()
494 
495  boxSizer.Add(item = dir, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 3)
496 
497  gridSizer.Add(item = prefixLabel, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
498  gridSizer.Add(item = prefixCtrl, pos = (0, 1), flag = wx.EXPAND )
499  gridSizer.Add(item = fileTypeLabel, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
500  gridSizer.Add(item = fileTypeCtrl, pos = (1, 1), flag = wx.EXPAND )
501 
502  boxSizer.Add(item = gridSizer, proportion = 1,
503  flag = wx.ALL | wx.EXPAND, border = 5)
504  boxSizer.Add(item = save, proportion = 0, flag = wx.ALL | wx.ALIGN_RIGHT, border = 5)
505 
506  save.Bind(wx.EVT_BUTTON, self.OnSaveAnimation)
507 
508  pageSizer.Add(item = boxSizer, proportion = 0,
509  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
510  border = 3)
511 
512  panel.SetSizer(pageSizer)
513 
514  return panel
515 
516  def _createDataPage(self):
517  """!Create data (surface, vector, volume) settings page"""
518 
519  self.mainPanelData = ScrolledPanel(parent = self)
520  self.mainPanelData.SetupScrolling(scroll_x = False)
521 ## style = fpb.CaptionBarStyle()
522 ## style.SetCaptionStyle(fpb.CAPTIONBAR_FILLED_RECTANGLE)
523 ## style.SetFirstColour(wx.Color(250,250,250))
524  try:# wxpython <= 2.8.10
525  self.foldpanelData = fpb.FoldPanelBar(parent = self.mainPanelData, id = wx.ID_ANY,
526  style = fpb.FPB_DEFAULT_STYLE,
527  extraStyle = fpb.FPB_SINGLE_FOLD)
528  except:
529  try:# wxpython >= 2.8.11
530  self.foldpanelData = fpb.FoldPanelBar(parent = self.mainPanelData, id = wx.ID_ANY,
531  agwStyle = fpb.FPB_SINGLE_FOLD)
532  except: # to be sure
533  self.foldpanelData = fpb.FoldPanelBar(parent = self.mainPanelData, id = wx.ID_ANY,
534  style = fpb.FPB_SINGLE_FOLD)
535 
536 
537  self.foldpanelData.Bind(fpb.EVT_CAPTIONBAR, self.OnPressCaption)
538 
539 
540 
541  # surface page
542  surfacePanel = self.foldpanelData.AddFoldPanel(_("Surface"), collapsed = False)
543  self.foldpanelData.AddFoldPanelWindow(surfacePanel,
544  window = self._createSurfacePage(parent = surfacePanel), flags = fpb.FPB_ALIGN_WIDTH)
545  self.EnablePage("surface", enabled = False)
546 
547  # constant page
548  constantPanel = self.foldpanelData.AddFoldPanel(_("Constant surface"), collapsed = True)
549  self.foldpanelData.AddFoldPanelWindow(constantPanel,
550  window = self._createConstantPage(parent = constantPanel), flags = fpb.FPB_ALIGN_WIDTH)
551  self.EnablePage("constant", enabled = False)
552  # vector page
553  vectorPanel = self.foldpanelData.AddFoldPanel(_("Vector"), collapsed = True)
554  self.foldpanelData.AddFoldPanelWindow(vectorPanel,
555  window = self._createVectorPage(parent = vectorPanel), flags = fpb.FPB_ALIGN_WIDTH)
556  self.EnablePage("vector", enabled = False)
557 
558  # volume page
559  volumePanel = self.foldpanelData.AddFoldPanel(_("Volume"), collapsed = True)
560  self.foldpanelData.AddFoldPanelWindow(volumePanel,
561  window = self._createVolumePage(parent = volumePanel), flags = fpb.FPB_ALIGN_WIDTH)
562  self.EnablePage("volume", enabled = False)
563 
564 ## self.foldpanelData.ApplyCaptionStyleAll(style)
565 
566  sizer = wx.BoxSizer(wx.VERTICAL)
567  sizer.Add(self.foldpanelData, proportion = 1, flag = wx.EXPAND)
568  self.mainPanelData.SetSizer(sizer)
569  self.mainPanelData.Layout()
570  self.mainPanelData.Fit()
571 
572  return self.mainPanelData
573 
574 
575  def _createAppearancePage(self):
576  """!Create data (surface, vector, volume) settings page"""
577  self.mainPanelAppear = ScrolledPanel(parent = self)
578  self.mainPanelAppear.SetupScrolling(scroll_x = False)
579 
580  try:# wxpython <= 2.8.10
581  self.foldpanelAppear = fpb.FoldPanelBar(parent = self.mainPanelAppear, id = wx.ID_ANY,
582  style = fpb.FPB_DEFAULT_STYLE,
583  extraStyle = fpb.FPB_SINGLE_FOLD)
584  except:
585  try:# wxpython >= 2.8.11
586  self.foldpanelAppear = fpb.FoldPanelBar(parent = self.mainPanelAppear, id = wx.ID_ANY,
587  agwStyle = fpb.FPB_SINGLE_FOLD)
588  except: # to be sure
589  self.foldpanelAppear = fpb.FoldPanelBar(parent = self.mainPanelAppear, id = wx.ID_ANY,
590  style = fpb.FPB_SINGLE_FOLD)
591 
592  self.foldpanelAppear.Bind(fpb.EVT_CAPTIONBAR, self.OnPressCaption)
593  # light page
594  lightPanel = self.foldpanelAppear.AddFoldPanel(_("Lighting"), collapsed = False)
595  self.foldpanelAppear.AddFoldPanelWindow(lightPanel,
596  window = self._createLightPage(parent = lightPanel), flags = fpb.FPB_ALIGN_WIDTH)
597 
598  # fringe page
599  fringePanel = self.foldpanelAppear.AddFoldPanel(_("Fringe"), collapsed = True)
600  self.foldpanelAppear.AddFoldPanelWindow(fringePanel,
601  window = self._createFringePage(parent = fringePanel), flags = fpb.FPB_ALIGN_WIDTH)
602 
603  self.EnablePage('fringe', False)
604 
605  # decoration page
606  decorationPanel = self.foldpanelAppear.AddFoldPanel(_("Decorations"), collapsed = True)
607  self.foldpanelAppear.AddFoldPanelWindow(decorationPanel,
608  window = self._createDecorationPage(parent = decorationPanel), flags = fpb.FPB_ALIGN_WIDTH)
609 
610 
611  sizer = wx.BoxSizer(wx.VERTICAL)
612  sizer.Add(self.foldpanelAppear, proportion = 1, flag = wx.EXPAND)
613  self.mainPanelAppear.SetSizer(sizer)
614  self.mainPanelAppear.Layout()
615  self.mainPanelAppear.Fit()
616  return self.mainPanelAppear
617 
618  def _createAnalysisPage(self):
619  """!Create data analysis (cutting planes, ...) page"""
620  self.mainPanelAnalysis = ScrolledPanel(parent = self)
621  self.mainPanelAnalysis.SetupScrolling(scroll_x = False)
622  self.foldpanelAnalysis = fpb.FoldPanelBar(parent = self.mainPanelAnalysis, id = wx.ID_ANY,
623  style = fpb.FPB_SINGLE_FOLD)
624  self.foldpanelAnalysis.Bind(fpb.EVT_CAPTIONBAR, self.OnPressCaption)
625  # cutting planes page
626  cplanePanel = self.foldpanelAnalysis.AddFoldPanel(_("Cutting planes"), collapsed = False)
627  self.foldpanelAnalysis.AddFoldPanelWindow(cplanePanel,
628  window = self._createCPlanePage(parent = cplanePanel), flags = fpb.FPB_ALIGN_WIDTH)
629 
630  sizer = wx.BoxSizer(wx.VERTICAL)
631  sizer.Add(self.foldpanelAnalysis, proportion = 1, flag = wx.EXPAND)
632  self.mainPanelAnalysis.SetSizer(sizer)
633  self.mainPanelAnalysis.Layout()
634  self.mainPanelAnalysis.Fit()
635  return self.mainPanelAnalysis
636 
637  def _createSurfacePage(self, parent):
638  """!Create view settings page"""
639  panel = wx.Panel(parent = parent, id = wx.ID_ANY)
640  self.page['surface'] = { 'id' : 0,
641  'notebook' : self.foldpanelData.GetId() }
642  pageSizer = wx.BoxSizer(wx.VERTICAL)
643 
644  self.win['surface'] = {}
645 
646  # selection
647  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
648  label = " %s " % (_("Raster map")))
649  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
650  rmaps = Select(parent = panel, type = 'raster',
651  onPopup = self.GselectOnPopup)
652  rmaps.GetChildren()[0].Bind(wx.EVT_TEXT, self.OnSetRaster)
653  self.win['surface']['map'] = rmaps.GetId()
654  desc = wx.StaticText(parent = panel, id = wx.ID_ANY)
655  self.win['surface']['desc'] = desc.GetId()
656  boxSizer.Add(item = rmaps, proportion = 0,
657  flag = wx.ALL,
658  border = 3)
659  boxSizer.Add(item = desc, proportion = 0,
660  flag = wx.ALL,
661  border = 3)
662  pageSizer.Add(item = boxSizer, proportion = 0,
663  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
664  border = 3)
665 
666  #
667  # draw
668  #
669  self.win['surface']['draw'] = {}
670  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
671  label = " %s " % (_("Draw")))
672  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
673  gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
674  gridSizer.AddGrowableCol(3)
675 
676  # mode
677  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
678  label = _("Mode:")),
679  pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
680  mode = wx.Choice (parent = panel, id = wx.ID_ANY, size = (-1, -1),
681  choices = [_("coarse"),
682  _("fine"),
683  _("both")])
684  mode.SetName("selection")
685  mode.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
686  self.win['surface']['draw']['mode'] = mode.GetId()
687  gridSizer.Add(item = mode, flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND,
688  pos = (0, 1),span = (1, 2))
689 
690  # shading
691  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
692  label = _("Shading:")),
693  pos = (0, 3), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
694  shade = wx.Choice (parent = panel, id = wx.ID_ANY, size = (-1, -1),
695  choices = [_("flat"),
696  _("gouraud")])
697  shade.SetName("selection")
698  self.win['surface']['draw']['shading'] = shade.GetId()
699  shade.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
700  gridSizer.Add(item = shade, flag = wx.ALIGN_CENTER_VERTICAL,
701  pos = (0, 4))
702 
703  # set to all
704  all = wx.Button(panel, id = wx.ID_ANY, label = _("Set to all"))
705  all.SetToolTipString(_("Use draw settings for all loaded surfaces"))
706  all.Bind(wx.EVT_BUTTON, self.OnSurfaceModeAll)
707  gridSizer.Add(item = all, flag = wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
708  pos = (3, 4))
709  self.win['surface']['all'] = all.GetId()
710 
711  # resolution coarse
712  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
713  label = _("Coarse mode:")),
714  pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL)
715  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
716  label = _("resolution:")),
717  pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL)
718  resC = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
719  initial = 6,
720  min = 1,
721  max = 100)
722  resC.SetName("value")
723  self.win['surface']['draw']['res-coarse'] = resC.GetId()
724  resC.Bind(wx.EVT_SPINCTRL, self.OnSurfaceResolution)
725  gridSizer.Add(item = resC, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
726 
727  # Coarse style
728  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
729  label = _("style:")),
730  pos = (3, 1), flag = wx.ALIGN_CENTER_VERTICAL)
731  style = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
732  choices = [_("wire"),
733  _("surface")])
734  style.SetName("selection")
735  self.win['surface']['draw']['style'] = style.GetId()
736  style.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
737  gridSizer.Add(item = style, flag = wx.ALIGN_CENTER_VERTICAL,
738  pos = (3, 2))
739 
740  # color
741  color = csel.ColourSelect(panel, id = wx.ID_ANY,
742  size = globalvar.DIALOG_COLOR_SIZE)
743  color.SetName("colour")
744  color.Bind(csel.EVT_COLOURSELECT, self.OnSurfaceWireColor)
745  color.SetToolTipString(_("Change wire color"))
746  self.win['surface']['draw']['wire-color'] = color.GetId()
747  gridSizer.Add(item = color, flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
748  pos = (3, 3))
749 
750  # resolution fine
751  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
752  label = _("Fine mode:")),
753  pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL)
754 
755  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
756  label = _("resolution:")),
757  pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL)
758  resF = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
759  initial = 3,
760  min = 1,
761  max = 100)
762  resF.SetName("value")
763  self.win['surface']['draw']['res-fine'] = resF.GetId()
764  resF.Bind(wx.EVT_SPINCTRL, self.OnSurfaceResolution)
765  gridSizer.Add(item = resF, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
766 
767  boxSizer.Add(item = gridSizer, proportion = 1,
768  flag = wx.ALL | wx.EXPAND, border = 3)
769  pageSizer.Add(item = boxSizer, proportion = 0,
770  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
771  border = 3)
772 
773  #
774  # surface attributes
775  #
776  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
777  label = " %s " % (_("Surface attributes")))
778  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
779  gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
780  gridSizer.AddGrowableCol(2)
781 
782  # type
783  self.win['surface']['attr'] = {}
784  row = 0
785  for code, attrb in (('color', _("Color")),
786  ('mask', _("Mask")),
787  ('transp', _("Transparency")),
788  ('shine', _("Shininess"))):
789  self.win['surface'][code] = {}
790  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
791  label = attrb + ':'),
792  pos = (row, 0), flag = wx.ALIGN_CENTER_VERTICAL)
793  use = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
794  choices = [_("map")])
795 
796  if code not in ('color', 'shine'):
797  use.Insert(item = _("unset"), pos = 0)
798  self.win['surface'][code]['required'] = False
799  else:
800  self.win['surface'][code]['required'] = True
801  if code != 'mask':
802  use.Append(item = _('constant'))
803  self.win['surface'][code]['use'] = use.GetId()
804  use.Bind(wx.EVT_CHOICE, self.OnMapObjUse)
805  gridSizer.Add(item = use, flag = wx.ALIGN_CENTER_VERTICAL,
806  pos = (row, 1))
807 
808  map = Select(parent = panel, id = wx.ID_ANY,
809  # size = globalvar.DIALOG_GSELECT_SIZE,
810  size = (-1, -1),
811  type = "raster")
812  self.win['surface'][code]['map'] = map.GetId() - 1 # FIXME
813  map.Bind(wx.EVT_TEXT, self.OnSurfaceMap)
814  gridSizer.Add(item = map, flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND,
815  pos = (row, 2))
816 
817  if code == 'color':
818  color = UserSettings.Get(group = 'nviz', key = 'surface', subkey = ['color', 'value'])
819  value = csel.ColourSelect(panel, id = wx.ID_ANY,
820  colour = color,
821  size = globalvar.DIALOG_COLOR_SIZE)
822  value.Bind(csel.EVT_COLOURSELECT, self.OnSurfaceMap)
823  elif code == 'mask':
824  value = None
825  else:
826  value = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
827  initial = 0)
828  value.SetRange(minVal = 0, maxVal = 100)
829  value.Bind(wx.EVT_TEXT, self.OnSurfaceMap)
830 
831  if value:
832  self.win['surface'][code]['const'] = value.GetId()
833  value.Enable(False)
834  gridSizer.Add(item = value, flag = wx.ALIGN_CENTER_VERTICAL,
835  pos = (row, 3))
836  else:
837  self.win['surface'][code]['const'] = None
838 
839  self.SetMapObjUseMap(nvizType = 'surface',
840  attrb = code) # -> enable map / disable constant
841 
842  row += 1
843  boxSizer.Add(item = gridSizer, proportion = 0,
844  flag = wx.ALL | wx.EXPAND, border = 3)
845  pageSizer.Add(item = boxSizer, proportion = 0,
846  flag = wx.EXPAND | wx.ALL,
847  border = 3)
848  #
849  # position
850  #
851  self.win['surface']['position'] = {}
852  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
853  label = " %s " % (_("Position")))
854  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
855  gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
856  gridSizer.AddGrowableCol(3)
857 
858  # position
859  tooltip = _("Changes the x, y, and z position of the current surface")
860  self._createControl(panel, data = self.win['surface'], name = 'position',
861  tooltip = tooltip, range = (-10000, 10000), floatSlider = True,
862  bind = (self.OnSurfacePosition, self.OnSurfacePositionChanged, self.OnSurfacePositionText))
863 
864  axis = wx.Choice (parent = panel, id = wx.ID_ANY, size = (75, -1),
865  choices = ["X",
866  "Y",
867  "Z"])
868 
869  reset = wx.Button(panel, id = wx.ID_ANY, label = _("Reset"))
870  reset.SetToolTipString(_("Reset to default position"))
871  reset.Bind(wx.EVT_BUTTON, self.OnResetSurfacePosition)
872  self.win['surface']['position']['reset'] = reset.GetId()
873 
874  self.win['surface']['position']['axis'] = axis.GetId()
875  axis.SetSelection(2)
876  axis.Bind(wx.EVT_CHOICE, self.OnSurfaceAxis)
877 
878  pslide = self.FindWindowById(self.win['surface']['position']['slider'])
879  ptext = self.FindWindowById(self.win['surface']['position']['text'])
880  ptext.SetValue('0')
881 
882  gridSizer.Add(item = axis, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
883  gridSizer.Add(item = pslide, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 1))
884  gridSizer.Add(item = ptext, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 2))
885  gridSizer.Add(item = reset, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, pos = (0, 3))
886 
887  boxSizer.Add(item = gridSizer, proportion = 1,
888  flag = wx.ALL | wx.EXPAND, border = 3)
889 
890  pageSizer.Add(item = boxSizer, proportion = 1,
891  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
892  border = 3)
893  #
894  # mask
895  #
896 ## box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
897 ## label = " %s " % (_("Mask")))
898 ## boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
899 ## gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
900 ##
901 ## gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
902 ## label = _("Mask zeros:")),
903 ## pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
904 ##
905 ## elev = wx.CheckBox(parent = panel, id = wx.ID_ANY,
906 ## label = _("by elevation"))
907 ## elev.Enable(False) # TODO: not implemented yet
908 ## gridSizer.Add(item = elev, pos = (0, 1))
909 ##
910 ## color = wx.CheckBox(parent = panel, id = wx.ID_ANY,
911 ## label = _("by color"))
912 ## color.Enable(False) # TODO: not implemented yet
913 ## gridSizer.Add(item = color, pos = (0, 2))
914 ##
915 ## boxSizer.Add(item = gridSizer, proportion = 1,
916 ## flag = wx.ALL | wx.EXPAND, border = 3)
917 ## pageSizer.Add(item = boxSizer, proportion = 0,
918 ## flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
919 ## border = 3)
920 
921 
922  panel.SetSizer(pageSizer)
923 
924  panel.Layout()
925  panel.Fit()
926 
927  return panel
928  def _createCPlanePage(self, parent):
929  """!Create cutting planes page"""
930  panel = wx.Panel(parent = parent, id = wx.ID_ANY)
931  self.page['cplane'] = { 'id' : 4,
932  'notebook' : self.foldpanelData.GetId() }
933  self.win['cplane'] = {}
934 
935  pageSizer = wx.BoxSizer(wx.VERTICAL)
936  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
937  label = " %s " % (_("Cutting planes")))
938  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
939  horSizer = wx.BoxSizer(wx.HORIZONTAL)
940 
941  # planes
942  horSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
943  label = _("Active cutting plane:")),
944  flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
945  choice = wx.Choice(parent = panel, id = wx.ID_ANY, choices = [])
946  self.win['cplane']['planes'] = choice.GetId()
947  choice.Bind(wx.EVT_CHOICE, self.OnCPlaneSelection)
948  horSizer.Add(item = choice, flag = wx.ALL, border = 5)
949 
950  # shading
951  horSizer.Add(item = wx.Size(-1, -1), proportion = 1)
952  horSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
953  label = _("Shading:")),
954  flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
955  choices = [_("clear"),
956  _("top color"),
957  _("bottom color"),
958  _("blend"),
959  _("shaded")]
960  choice = wx.Choice(parent = panel, id = wx.ID_ANY, choices = choices)
961  self.win['cplane']['shading'] = choice.GetId()
962  choice.Bind(wx.EVT_CHOICE, self.OnCPlaneShading)
963  horSizer.Add(item = choice, flag = wx.ALL, border = 5)
964  boxSizer.Add(item = horSizer, flag = wx.EXPAND)
965 
966  gridSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
967 
968  # cutting plane horizontal x position
969  self.win['cplane']['position'] = {}
970  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
971  label = _("Horizontal X:")),
972  pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
973  tooltip = _("Sets the X coordinate of the current cutting plane")
974  self._createControl(panel, data = self.win['cplane']['position'], name = 'x', size = 250,
975  range = (-1000, 1000), sliderHor = True, floatSlider = True, tooltip = tooltip,
976  bind = (self.OnCPlaneChanging, self.OnCPlaneChangeDone, self.OnCPlaneChangeText))
977  self.FindWindowById(self.win['cplane']['position']['x']['slider']).SetValue(0)
978  self.FindWindowById(self.win['cplane']['position']['x']['text']).SetValue(0)
979  gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['x']['slider']),
980  pos = (0, 1), flag = wx.EXPAND|wx.ALIGN_RIGHT)
981  gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['x']['text']),
982  pos = (0, 2),
983  flag = wx.ALIGN_CENTER)
984 
985  # cutting plane horizontal y position
986  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
987  label = _("Horizontal Y:")),
988  pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL)
989  tooltip = _("Sets the Y coordinate of the current cutting plane")
990  self._createControl(panel, data = self.win['cplane']['position'], name = 'y', size = 250,
991  range = (-1000, 1000), sliderHor = True, floatSlider = True, tooltip = tooltip,
992  bind = (self.OnCPlaneChanging, self.OnCPlaneChangeDone, self.OnCPlaneChangeText))
993  self.FindWindowById(self.win['cplane']['position']['y']['slider']).SetValue(0)
994  self.FindWindowById(self.win['cplane']['position']['y']['text']).SetValue(0)
995  gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['y']['slider']),
996  pos = (1, 1), flag = wx.EXPAND|wx.ALIGN_RIGHT)
997  gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['y']['text']),
998  pos = (1, 2),
999  flag = wx.ALIGN_CENTER)
1000 
1001  # cutting plane rotation
1002  self.win['cplane']['rotation'] = {}
1003  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1004  label = _("Rotation:")),
1005  pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL)
1006  tooltip = _("Rotates the current cutting plane about vertical axis")
1007  self._createControl(panel, data = self.win['cplane']['rotation'], name = 'rot', size = 250,
1008  range = (0, 360), sliderHor = True, tooltip = tooltip,
1009  bind = (self.OnCPlaneChanging, self.OnCPlaneChangeDone, self.OnCPlaneChangeText))
1010  self.FindWindowById(self.win['cplane']['rotation']['rot']['slider']).SetValue(180)
1011  self.FindWindowById(self.win['cplane']['rotation']['rot']['text']).SetValue(180)
1012  gridSizer.Add(item = self.FindWindowById(self.win['cplane']['rotation']['rot']['slider']),
1013  pos = (2, 1), flag = wx.EXPAND|wx.ALIGN_RIGHT)
1014  gridSizer.Add(item = self.FindWindowById(self.win['cplane']['rotation']['rot']['text']),
1015  pos = (2, 2),
1016  flag = wx.ALIGN_CENTER)
1017 
1018  # cutting plane tilt
1019  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1020  label = _("Tilt:")),
1021  pos = (3, 0), flag = wx.ALIGN_CENTER_VERTICAL)
1022  tooltip = _("Rotates the current cutting plane about horizontal axis")
1023  self._createControl(panel, data = self.win['cplane']['rotation'], name = 'tilt', size = 250,
1024  range = (0, 360), sliderHor = True, tooltip = tooltip,
1025  bind = (self.OnCPlaneChanging, self.OnCPlaneChangeDone, self.OnCPlaneChangeText))
1026  self.FindWindowById(self.win['cplane']['rotation']['tilt']['slider']).SetValue(0)
1027  self.FindWindowById(self.win['cplane']['rotation']['tilt']['text']).SetValue(0)
1028  gridSizer.Add(item = self.FindWindowById(self.win['cplane']['rotation']['tilt']['slider']),
1029  pos = (3, 1), flag = wx.EXPAND|wx.ALIGN_RIGHT)
1030  gridSizer.Add(item = self.FindWindowById(self.win['cplane']['rotation']['tilt']['text']),
1031  pos = (3, 2),
1032  flag = wx.ALIGN_CENTER)
1033 
1034  # cutting pland height
1035  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1036  label = _("Height:")),
1037  pos = (4, 0), flag = wx.ALIGN_CENTER_VERTICAL)
1038  tooltip = _("Sets the Z coordinate of the current cutting plane (only meaningful when tilt is not 0)")
1039  self._createControl(panel, data = self.win['cplane']['position'], name = 'z', size = 250,
1040  range = (-1000, 1000), sliderHor = True, tooltip = tooltip,
1041  bind = (self.OnCPlaneChanging, self.OnCPlaneChangeDone, self.OnCPlaneChangeText))
1042  self.FindWindowById(self.win['cplane']['position']['z']['slider']).SetValue(0)
1043  self.FindWindowById(self.win['cplane']['position']['z']['text']).SetValue(0)
1044  gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['z']['slider']),
1045  pos = (4, 1), flag = wx.EXPAND|wx.ALIGN_RIGHT)
1046  gridSizer.Add(item = self.FindWindowById(self.win['cplane']['position']['z']['text']),
1047  pos = (4, 2),
1048  flag = wx.ALIGN_CENTER)
1049 
1050  boxSizer.Add(gridSizer, proportion = 0, flag = wx.EXPAND|wx.ALL, border = 5)
1051 
1052  horSizer = wx.BoxSizer(wx.HORIZONTAL)
1053  horSizer.Add(item = wx.Size(-1, -1), proportion = 1, flag = wx.ALL, border = 5)
1054  # reset
1055  reset = wx.Button(parent = panel, id = wx.ID_ANY, label = _("Reset"))
1056  self.win['cplane']['reset'] = reset.GetId()
1057  reset.Bind(wx.EVT_BUTTON, self.OnCPlaneReset)
1058  horSizer.Add(item = reset, flag = wx.ALL, border = 5)
1059  boxSizer.Add(horSizer, proportion = 0, flag = wx.EXPAND)
1060 
1061 
1062  pageSizer.Add(boxSizer, proportion = 0, flag = wx.EXPAND)
1063 
1064  panel.SetSizer(pageSizer)
1065  panel.Fit()
1066 
1067  return panel
1068 
1069  def _createConstantPage(self, parent):
1070  """!Create constant page"""
1071  panel = wx.Panel(parent = parent, id = wx.ID_ANY)
1072  self.page['constant'] = { 'id' : 1,
1073  'notebook' : self.foldpanelData.GetId() }
1074  self.win['constant'] = {}
1075 
1076  pageSizer = wx.BoxSizer(wx.VERTICAL)
1077 
1078  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
1079  label = " %s " % (_("Constant surface")))
1080  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
1081  horsizer = wx.BoxSizer(wx.HORIZONTAL)
1082 
1083  surface = wx.ComboBox(parent = panel, id = wx.ID_ANY,
1084  style = wx.CB_SIMPLE | wx.CB_READONLY,
1085  choices = [])
1086  self.win['constant']['surface'] = surface.GetId()
1087  surface.Bind(wx.EVT_COMBOBOX, self.OnConstantSelection)
1088  horsizer.Add(surface, proportion = 1, flag = wx.EXPAND|wx.RIGHT, border = 20)
1089 
1090  addNew = wx.Button(panel, id = wx.ID_ANY, label = _("New"))
1091  addNew.Bind(wx.EVT_BUTTON, self.OnNewConstant)
1092  self.win['constant']['new'] = addNew.GetId()
1093 
1094  delete = wx.Button(panel, id = wx.ID_ANY, label = _("Delete"))
1095  delete.Bind(wx.EVT_BUTTON, self.OnDeleteConstant)
1096  self.win['constant']['delete'] = delete.GetId()
1097 
1098  horsizer.Add(item = addNew, proportion = 0, flag = wx.RIGHT|wx.LEFT, border = 3)
1099  horsizer.Add(item = delete, proportion = 0, flag = wx.RIGHT|wx.LEFT, border = 3)
1100 
1101  boxSizer.Add(item = horsizer, proportion = 0, flag = wx.ALL|wx.EXPAND,
1102  border = 5)
1103 
1104  gridSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
1105  # fine resolution
1106  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1107  label = _("Fine resolution:")),
1108  pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
1109  resF = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
1110  initial = 3,
1111  min = 1,
1112  max = 100)
1113  resF.SetName("value")
1114  self.win['constant']['resolution'] = resF.GetId()
1115  resF.Bind(wx.EVT_SPINCTRL, self.OnSetConstantProp)
1116  gridSizer.Add(item = resF, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT)
1117  # value
1118  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1119  label = _("Value:")), pos = (1, 0),
1120  flag = wx.ALIGN_CENTER_VERTICAL)
1121 
1122  value = wx.SpinCtrl(panel, id = wx.ID_ANY,
1123  min = -1e9, max = 1e9,
1124  size = (65, -1))
1125  self.win['constant']['value'] = value.GetId()
1126  value.Bind(wx.EVT_SPINCTRL, self.OnSetConstantProp)
1127  gridSizer.Add(item = value, pos = (1, 1))
1128 
1129  # transparency
1130  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1131  label = _("Transparency:")), pos = (2, 0),
1132  flag = wx.ALIGN_CENTER_VERTICAL)
1133 
1134  transp = wx.SpinCtrl(panel, id = wx.ID_ANY,
1135  min = 0, max = 100,
1136  size = (65, -1))
1137  self.win['constant']['transp'] = transp.GetId()
1138  transp.Bind(wx.EVT_SPINCTRL, self.OnSetConstantProp)
1139  gridSizer.Add(item = transp, pos = (2, 1))
1140 
1141  # color
1142  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1143  label = _("Color:")), pos = (3, 0),
1144  flag = wx.ALIGN_CENTER_VERTICAL)
1145  color = csel.ColourSelect(panel, id = wx.ID_ANY,
1146  colour = (0,0,0),
1147  size = globalvar.DIALOG_COLOR_SIZE)
1148  self.win['constant']['color'] = color.GetId()
1149  color.Bind(csel.EVT_COLOURSELECT, self.OnSetConstantProp)
1150  gridSizer.Add(item = color, pos = (3, 1))
1151  boxSizer.Add(item = gridSizer, proportion = 0, flag = wx.ALL,
1152  border = 5)
1153  pageSizer.Add(item = boxSizer, proportion = 0,
1154  flag = wx.EXPAND | wx.ALL,
1155  border = 3)
1156 
1157  panel.SetSizer(pageSizer)
1158  panel.Fit()
1159 
1160  return panel
1161 
1162  def _createVectorPage(self, parent):
1163  """!Create view settings page"""
1164  panel = wx.Panel(parent = parent, id = wx.ID_ANY)
1165  self.page['vector'] = { 'id' : 2,
1166  'notebook' : self.foldpanelData.GetId() }
1167  pageSizer = wx.BoxSizer(wx.VERTICAL)
1168 
1169  self.win['vector'] = {}
1170 
1171  # selection
1172  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
1173  label = " %s " % (_("Vector map")))
1174  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
1175  vmaps = Select(parent = panel, type = 'vector',
1176  onPopup = self.GselectOnPopup)
1177  vmaps.GetChildren()[0].Bind(wx.EVT_TEXT, self.OnSetVector)
1178  self.win['vector']['map'] = vmaps.GetId()
1179  desc = wx.StaticText(parent = panel, id = wx.ID_ANY)
1180  self.win['vector']['desc'] = desc.GetId()
1181  boxSizer.Add(item = vmaps, proportion = 0,
1182  flag = wx.ALL,
1183  border = 3)
1184  boxSizer.Add(item = desc, proportion = 0,
1185  flag = wx.ALL,
1186  border = 3)
1187  pageSizer.Add(item = boxSizer, proportion = 0,
1188  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
1189  border = 3)
1190 
1191  #
1192  # vector lines
1193  #
1194  self.win['vector']['lines'] = {}
1195 
1196  showLines = wx.CheckBox(parent = panel, id = wx.ID_ANY,
1197  label = _("Show vector lines"))
1198  showLines.SetValue(True)
1199 
1200  self.win['vector']['lines']['show'] = showLines.GetId()
1201  showLines.Bind(wx.EVT_CHECKBOX, self.OnVectorShow)
1202 
1203  pageSizer.Add(item = showLines, proportion = 0,
1204  flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 5)
1205 
1206  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
1207  label = " %s " % (_("Vector lines")))
1208  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
1209  gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
1210  gridSizer.AddGrowableCol(5)
1211 
1212  # width
1213  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1214  label = _("Line:")),
1215  pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
1216  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1217  label = _("width:")),
1218  pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL |
1219  wx.ALIGN_RIGHT)
1220 
1221  width = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
1222  initial = 1,
1223  min = 1,
1224  max = 100)
1225  width.SetValue(1)
1226  self.win['vector']['lines']['width'] = width.GetId()
1227  width.Bind(wx.EVT_SPINCTRL, self.OnVectorLines)
1228  gridSizer.Add(item = width, pos = (0, 2),
1229  flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
1230 
1231  # color
1232  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1233  label = _("color:")),
1234  pos = (0, 3), flag = wx.ALIGN_CENTER_VERTICAL |
1235  wx.ALIGN_RIGHT)
1236 
1237  color = csel.ColourSelect(panel, id = wx.ID_ANY,
1238  colour = (0,0,0),
1239  size = globalvar.DIALOG_COLOR_SIZE)
1240  self.win['vector']['lines']['color'] = color.GetId()
1241  color.Bind(csel.EVT_COLOURSELECT, self.OnVectorLines)
1242 
1243  gridSizer.Add(item = color, pos = (0, 4), flag = wx.ALIGN_CENTER_VERTICAL |
1244  wx.ALIGN_LEFT)
1245 
1246  # display
1247  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1248  label = _("Display")),
1249  pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL |
1250  wx.ALIGN_LEFT)
1251 
1252  display = wx.Choice (parent = panel, id = wx.ID_ANY, size = (-1, -1),
1253  choices = [_("on surface(s):"),
1254  _("flat")])
1255  self.win['vector']['lines']['flat'] = display.GetId()
1256  display.Bind(wx.EVT_CHOICE, self.OnVectorDisplay)
1257 
1258  gridSizer.Add(item = display, flag = wx.ALIGN_CENTER_VERTICAL |
1259  wx.ALIGN_LEFT|wx.EXPAND, pos = (1, 1), span = (1,4))
1260 
1261  # height
1262  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1263  label = _("Height above surface:")),
1264  pos = (2, 5), flag = wx.ALIGN_BOTTOM|wx.EXPAND)
1265 
1266  surface = wx.CheckListBox(parent = panel, id = wx.ID_ANY, size = (-1, 60),
1267  choices = [], style = wx.LB_NEEDED_SB)
1268  surface.Bind(wx.EVT_CHECKLISTBOX, self.OnVectorSurface)
1269 
1270  self.win['vector']['lines']['surface'] = surface.GetId()
1271  gridSizer.Add(item = surface,
1272  pos = (2, 0), span = (3, 5),
1273  flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
1274 
1275  self._createControl(panel, data = self.win['vector']['lines'], name = 'height', size = -1,
1276  range = (0, 500), sliderHor = True,
1277  bind = (self.OnVectorHeight, self.OnVectorHeightFull, self.OnVectorHeightText))
1278  self.FindWindowById(self.win['vector']['lines']['height']['slider']).SetValue(0)
1279  self.FindWindowById(self.win['vector']['lines']['height']['text']).SetValue(0)
1280  gridSizer.Add(item = self.FindWindowById(self.win['vector']['lines']['height']['slider']),
1281  pos = (3, 5), flag = wx.EXPAND|wx.ALIGN_RIGHT)
1282  gridSizer.Add(item = self.FindWindowById(self.win['vector']['lines']['height']['text']),
1283  pos = (4, 5),
1284  flag = wx.ALIGN_CENTER)
1285 
1286  boxSizer.Add(item = gridSizer, proportion = 1,
1287  flag = wx.ALL | wx.EXPAND, border = 3)
1288  pageSizer.Add(item = boxSizer, proportion = 0,
1289  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
1290  border = 3)
1291 
1292  #
1293  # vector points
1294  #
1295  self.win['vector']['points'] = {}
1296 
1297  showPoints = wx.CheckBox(parent = panel, id = wx.ID_ANY,
1298  label = _("Show vector points"))
1299  showPoints.SetValue(True)
1300  self.win['vector']['points']['show'] = showPoints.GetId()
1301  showPoints.Bind(wx.EVT_CHECKBOX, self.OnVectorShow)
1302 
1303  pageSizer.Add(item = showPoints, proportion = 0,
1304  flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 5)
1305 
1306  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
1307  label = " %s " % (_("Vector points")))
1308  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
1309  vertSizer = wx.BoxSizer(wx.VERTICAL)
1310  gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
1311  gridSizer.AddGrowableCol(0)
1312  gridSizer.AddGrowableCol(2)
1313  gridSizer.AddGrowableCol(4)
1314  gridSizer.AddGrowableCol(6)
1315 
1316  # icon size
1317  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1318  label = _("Icon:")),
1319  pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
1320  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1321  label = _("size:")),
1322  pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL |
1323  wx.ALIGN_RIGHT)
1324 
1325  isize = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
1326  initial = 1,
1327  min = 1,
1328  max = 1e6)
1329  isize.SetName('value')
1330  isize.SetValue(100)
1331  self.win['vector']['points']['size'] = isize.GetId()
1332  isize.Bind(wx.EVT_SPINCTRL, self.OnVectorPoints)
1333  isize.Bind(wx.EVT_TEXT, self.OnVectorPoints)
1334  gridSizer.Add(item = isize, pos = (0, 2),
1335  flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
1336 
1337  # icon color
1338  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1339  label = _("color:")),
1340  pos = (0, 3), flag = wx.ALIGN_CENTER_VERTICAL |
1341  wx.ALIGN_RIGHT)
1342  icolor = csel.ColourSelect(panel, id = wx.ID_ANY,
1343  size = globalvar.DIALOG_COLOR_SIZE)
1344  icolor.SetName("color")
1345  icolor.SetColour((0,0,255))
1346  self.win['vector']['points']['color'] = icolor.GetId()
1347  icolor.Bind(csel.EVT_COLOURSELECT, self.OnVectorPoints)
1348  gridSizer.Add(item = icolor, flag = wx.ALIGN_CENTER_VERTICAL |
1349  wx.ALIGN_LEFT,
1350  pos = (0, 4))
1351 
1352  # icon width - seems to do nothing
1353 ## gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1354 ## label = _("width")),
1355 ## pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL |
1356 ## wx.ALIGN_RIGHT)
1357 ##
1358 ## iwidth = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
1359 ## initial = 1,
1360 ## min = 1,
1361 ## max = 1e6)
1362 ## iwidth.SetName('value')
1363 ## iwidth.SetValue(100)
1364 ## self.win['vector']['points']['width'] = iwidth.GetId()
1365 ## iwidth.Bind(wx.EVT_SPINCTRL, self.OnVectorPoints)
1366 ## iwidth.Bind(wx.EVT_TEXT, self.OnVectorPoints)
1367 ## gridSizer.Add(item = iwidth, pos = (1, 2),
1368 ## flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT)
1369  # icon symbol
1370  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1371  label = _("symbol:")),
1372  pos = (0, 5), flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
1373  isym = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
1374  choices = UserSettings.Get(group = 'nviz', key = 'vector',
1375  subkey = ['points', 'marker'], internal = True))
1376  isym.SetName("selection")
1377  self.win['vector']['points']['marker'] = isym.GetId()
1378  isym.Bind(wx.EVT_CHOICE, self.OnVectorPoints)
1379  gridSizer.Add(item = isym, flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
1380  pos = (0, 6))
1381 
1382  vertSizer.Add(gridSizer, proportion = 0, flag = wx.EXPAND, border = 0)
1383  # high
1384  gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
1385  gridSizer.AddGrowableCol(1)
1386  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1387  label = _("Display on surface(s):")),
1388  pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
1389  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1390  label = _("Height above surface:")),
1391  pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL)
1392 
1393  surface = wx.CheckListBox(parent = panel, id = wx.ID_ANY, size = (-1, 60),
1394  choices = [], style = wx.LB_NEEDED_SB)
1395  surface.Bind(wx.EVT_CHECKLISTBOX, self.OnVectorSurface)
1396  self.win['vector']['points']['surface'] = surface.GetId()
1397  gridSizer.Add(item = surface,
1398  pos = (1, 0), span = (3, 1),
1399  flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
1400 
1401  self._createControl(panel, data = self.win['vector']['points'], name = 'height', size = -1,
1402  range = (0, 500),
1403  bind = (self.OnVectorHeight, self.OnVectorHeightFull, self.OnVectorHeightText))
1404 
1405  self.FindWindowById(self.win['vector']['points']['height']['slider']).SetValue(0)
1406  self.FindWindowById(self.win['vector']['points']['height']['text']).SetValue(0)
1407 
1408  gridSizer.Add(item = self.FindWindowById(self.win['vector']['points']['height']['slider']),
1409  pos = (2, 1),flag = wx.EXPAND|wx.ALIGN_CENTER_VERTICAL)
1410  gridSizer.Add(item = self.FindWindowById(self.win['vector']['points']['height']['text']),
1411  pos = (3, 1),
1412  flag = wx.ALIGN_CENTER)
1413 
1414  vertSizer.Add(gridSizer, proportion = 0, flag = wx.EXPAND, border = 0)
1415  boxSizer.Add(item = vertSizer, proportion = 1,
1416  flag = wx.ALL | wx.EXPAND, border = 3)
1417  pageSizer.Add(item = boxSizer, proportion = 0,
1418  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
1419  border = 3)
1420 
1421  panel.SetSizer(pageSizer)
1422  panel.Fit()
1423 
1424  return panel
1425 
1426  def GselectOnPopup(self, ltype, exclude = False):
1427  """Update gselect.Select() items"""
1428  maps = list()
1429  for layer in self.mapWindow.Map.GetListOfLayers(l_type = ltype, l_active = True):
1430  maps.append(layer.GetName())
1431  return maps, exclude
1432 
1433  def _createVolumePage(self, parent):
1434  """!Create view settings page"""
1435  panel = wx.Panel(parent = parent, id = wx.ID_ANY)
1436  self.page['volume'] = { 'id' : 3,
1437  'notebook' : self.foldpanelData.GetId() }
1438  pageSizer = wx.BoxSizer(wx.VERTICAL)
1439 
1440  self.win['volume'] = {}
1441 
1442  # selection
1443  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
1444  label = " %s " % (_("3D raster map")))
1445  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
1446  rmaps = Select(parent = panel, type = '3d-raster',
1447  onPopup = self.GselectOnPopup)
1448  rmaps.GetChildren()[0].Bind(wx.EVT_TEXT, self.OnSetRaster3D)
1449  self.win['volume']['map'] = rmaps.GetId()
1450  desc = wx.StaticText(parent = panel, id = wx.ID_ANY)
1451  self.win['volume']['desc'] = desc.GetId()
1452  boxSizer.Add(item = rmaps, proportion = 0,
1453  flag = wx.ALL,
1454  border = 3)
1455  boxSizer.Add(item = desc, proportion = 0,
1456  flag = wx.ALL,
1457  border = 3)
1458  pageSizer.Add(item = boxSizer, proportion = 0,
1459  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
1460  border = 3)
1461 
1462  #
1463  # draw
1464  #
1465  self.win['volume']['draw'] = {}
1466  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
1467  label = " %s " % (_("Draw")))
1468  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
1469  gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
1470 ## gridSizer.AddGrowableCol(4)
1471 
1472  # mode
1473  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1474  label = _("Mode:")),
1475  pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
1476  mode = wx.Choice (parent = panel, id = wx.ID_ANY, size = (-1, -1),
1477  choices = [_("isosurfaces"),
1478  _("slices")])
1479  mode.SetSelection(0)
1480  mode.SetName("selection")
1481  mode.Bind(wx.EVT_CHOICE, self.OnVolumeMode)
1482  self.win['volume']['draw']['mode'] = mode.GetId()
1483  gridSizer.Add(item = mode, flag = wx.ALIGN_CENTER_VERTICAL,
1484  pos = (0, 1))
1485 
1486  # shading
1487  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1488  label = _("Shading:")),
1489  pos = (0, 2), flag = wx.ALIGN_CENTER_VERTICAL)
1490  shade = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
1491  choices = [_("flat"),
1492  _("gouraud")])
1493  shade.SetName("selection")
1494  self.win['volume']['draw']['shading'] = shade.GetId()
1495  shade.Bind(wx.EVT_CHOICE, self.OnVolumeDrawMode)
1496  gridSizer.Add(item = shade, flag = wx.ALIGN_CENTER_VERTICAL,
1497  pos = (0, 3))
1498 
1499  # resolution (mode)
1500  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1501  label = _("Resolution:")),
1502  pos = (0, 4), flag = wx.ALIGN_CENTER_VERTICAL)
1503  resol = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
1504  initial = 1,
1505  min = 1,
1506  max = 100)
1507  resol.SetName("value")
1508  self.win['volume']['draw']['resolution'] = resol.GetId()
1509  resol.Bind(wx.EVT_SPINCTRL, self.OnVolumeResolution)
1510  resol.Bind(wx.EVT_TEXT, self.OnVolumeResolution)
1511  gridSizer.Add(item = resol, pos = (0, 5))
1512 
1513  boxSizer.Add(item = gridSizer, proportion = 0,
1514  flag = wx.ALL | wx.EXPAND, border = 3)
1515  pageSizer.Add(item = boxSizer, proportion = 0,
1516  flag = wx.EXPAND | wx.ALL,
1517  border = 3)
1518 
1519  #
1520  # manage isosurfaces
1521  #
1522  box = wx.StaticBox(parent = panel, id = wx.ID_ANY,
1523  label = " %s " % (_("List of isosurfaces")))
1524  box.SetName('listStaticBox')
1525  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
1526  gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
1527 
1528  # list
1529  isolevel = wx.CheckListBox(parent = panel, id = wx.ID_ANY,
1530  size = (300, 150))
1531  self.Bind(wx.EVT_CHECKLISTBOX, self.OnVolumeCheck, isolevel)
1532  self.Bind(wx.EVT_LISTBOX, self.OnVolumeSelect, isolevel)
1533 
1534  self.win['volume']['isosurfs'] = isolevel.GetId()
1535  self.win['volume']['slices'] = isolevel.GetId()
1536  gridSizer.Add(item = isolevel, pos = (0, 0), span = (4, 1))
1537 
1538  # buttons (add, delete, move up, move down)
1539  btnAdd = wx.Button(parent = panel, id = wx.ID_ADD)
1540  self.win['volume']['btnAdd'] = btnAdd.GetId()
1541  btnAdd.Bind(wx.EVT_BUTTON, self.OnVolumeAdd)
1542  gridSizer.Add(item = btnAdd,
1543  pos = (0, 1))
1544  btnDelete = wx.Button(parent = panel, id = wx.ID_DELETE)
1545  self.win['volume']['btnDelete'] = btnDelete.GetId()
1546  btnDelete.Bind(wx.EVT_BUTTON, self.OnVolumeDelete)
1547  btnDelete.Enable(False)
1548  gridSizer.Add(item = btnDelete,
1549  pos = (1, 1))
1550  btnMoveUp = wx.Button(parent = panel, id = wx.ID_UP)
1551  self.win['volume']['btnMoveUp'] = btnMoveUp.GetId()
1552  btnMoveUp.Bind(wx.EVT_BUTTON, self.OnVolumeMoveUp)
1553  btnMoveUp.Enable(False)
1554  gridSizer.Add(item = btnMoveUp,
1555  pos = (2, 1))
1556  btnMoveDown = wx.Button(parent = panel, id = wx.ID_DOWN)
1557  self.win['volume']['btnMoveDown'] = btnMoveDown.GetId()
1558  btnMoveDown.Bind(wx.EVT_BUTTON, self.OnVolumeMoveDown)
1559  btnMoveDown.Enable(False)
1560  gridSizer.Add(item = btnMoveDown,
1561  pos = (3, 1))
1562 
1563  boxSizer.Add(item = gridSizer, proportion = 1,
1564  flag = wx.ALL | wx.EXPAND, border = 3)
1565  pageSizer.Add(item = boxSizer, proportion = 0,
1566  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
1567  border = 3)
1568  # isosurface/slice
1569  sizer = wx.BoxSizer()
1570  self.isoPanel = self._createIsosurfacePanel(panel)
1571  self.slicePanel = self._createSlicePanel(panel)
1572  sizer.Add(self.isoPanel, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 0)
1573  sizer.Add(self.slicePanel, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 0)
1574  sizer.Hide(self.slicePanel)
1575  pageSizer.Add(item = sizer, proportion = 0,
1576  flag = wx.EXPAND | wx.ALL,
1577  border = 3)
1578  #
1579  # position
1580  #
1581  self.win['volume']['position'] = {}
1582  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
1583  label = " %s " % (_("Position")))
1584  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
1585  gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
1586  gridSizer.AddGrowableCol(3)
1587 
1588  # position
1589  self._createControl(panel, data = self.win['volume'], name = 'position',
1590  range = (-10000, 10000), floatSlider = True,
1591  bind = (self.OnVolumePosition, self.OnVolumePositionChanged, self.OnVolumePositionText))
1592 
1593  axis = wx.Choice (parent = panel, id = wx.ID_ANY, size = (75, -1),
1594  choices = ["X",
1595  "Y",
1596  "Z"])
1597 
1598  reset = wx.Button(panel, id = wx.ID_ANY, label = _("Reset"))
1599  reset.SetToolTipString(_("Reset to default position"))
1600  reset.Bind(wx.EVT_BUTTON, self.OnResetVolumePosition)
1601  self.win['volume']['position']['reset'] = reset.GetId()
1602 
1603  self.win['volume']['position']['axis'] = axis.GetId()
1604  axis.SetSelection(2) # Z
1605  axis.Bind(wx.EVT_CHOICE, self.OnVolumeAxis)
1606 
1607  pslide = self.FindWindowById(self.win['volume']['position']['slider'])
1608  ptext = self.FindWindowById(self.win['volume']['position']['text'])
1609  ptext.SetValue('0')
1610 
1611  gridSizer.Add(item = axis, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
1612  gridSizer.Add(item = pslide, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 1))
1613  gridSizer.Add(item = ptext, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 2))
1614  gridSizer.Add(item = reset, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, pos = (0, 3))
1615 
1616  boxSizer.Add(item = gridSizer, proportion = 1,
1617  flag = wx.ALL | wx.EXPAND, border = 3)
1618 
1619  pageSizer.Add(item = boxSizer, proportion = 0,
1620  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
1621  border = 3)
1622  panel.SetSizer(pageSizer)
1623  panel.Fit()
1624 
1625  return panel
1626 
1627 
1628  def _createLightPage(self, parent):
1629  """!Create light page"""
1630  panel = wx.Panel(parent = parent, id = wx.ID_ANY)
1631 
1632  self.page['light'] = { 'id' : 0,
1633  'notebook' : self.foldpanelAppear.GetId() }
1634  self.win['light'] = {}
1635 
1636  pageSizer = wx.BoxSizer(wx.VERTICAL)
1637 
1638  show = wx.CheckBox(parent = panel, id = wx.ID_ANY,
1639  label = _("Show light model"))
1640  show.Bind(wx.EVT_CHECKBOX, self.OnShowLightModel)
1641  show.SetValue(True)
1642  self._display.showLight = True
1643  pageSizer.Add(item = show, proportion = 0,
1644  flag = wx.ALL, border = 3)
1645 ## surface = wx.CheckBox(parent = panel, id = wx.ID_ANY,
1646 ## label = _("Follow source viewpoint"))
1647 ## pageSizer.Add(item = surface, proportion = 0,
1648 ## flag = wx.ALL, border = 3)
1649 
1650  # position
1651  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
1652  label = " %s " % (_("Light source position")))
1653  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
1654 
1655  gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
1656  posSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
1657 
1658  self._createCompass(panel = panel, sizer = posSizer, type = 'light')
1659 
1660  pos = LightPositionWindow(panel, id = wx.ID_ANY, size = (175, 175),
1661  mapwindow = self.mapWindow)
1662  self.win['light']['position'] = pos.GetId()
1663  posSizer.Add(item = pos,
1664  pos = (1, 1), flag = wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL)
1665  gridSizer.Add(item = posSizer, pos = (0, 0))
1666 
1667  # height
1668  tooltip = _("Adjusts the light height")
1669  self._createControl(panel, data = self.win['light'], name = 'z', sliderHor = False,
1670  range = (0, 100), tooltip = tooltip,
1671  bind = (self.OnLightChange, self.OnLightChanged, self.OnLightChange))
1672 
1673  heightSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
1674  heightSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Height:")),
1675  pos = (0, 0), flag = wx.ALIGN_LEFT, span = (1, 2))
1676  heightSizer.Add(item = self.FindWindowById(self.win['light']['z']['slider']),
1677  flag = wx.ALIGN_RIGHT, pos = (1, 0))
1678  heightSizer.Add(item = self.FindWindowById(self.win['light']['z']['text']),
1679  flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.TOP |
1680  wx.BOTTOM | wx.RIGHT, pos = (1, 1))
1681 
1682  gridSizer.Add(item = heightSizer, pos = (0, 2), flag = wx.ALIGN_RIGHT)
1683 
1684  boxSizer.Add(item = gridSizer, proportion = 1,
1685  flag = wx.ALL | wx.EXPAND, border = 2)
1686  pageSizer.Add(item = boxSizer, proportion = 0,
1687  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
1688  border = 3)
1689 
1690  # position
1691  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
1692  label = " %s " % (_("Light color and intensity")))
1693  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
1694  gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
1695 
1696  gridSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Color:")),
1697  pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL)
1698  color = csel.ColourSelect(panel, id = wx.ID_ANY,
1699  colour = UserSettings.Get(group = 'nviz', key = 'light',
1700  subkey = 'color'),
1701  size = globalvar.DIALOG_COLOR_SIZE)
1702  self.win['light']['color'] = color.GetId()
1703  color.Bind(csel.EVT_COLOURSELECT, self.OnLightColor)
1704  gridSizer.Add(item = color, pos = (0, 2))
1705 
1706  gridSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Brightness:")),
1707  pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL)
1708  tooltip = _("Adjusts the brightness of the light")
1709  self._createControl(panel, data = self.win['light'], name = 'bright', size = 300,
1710  range = (0, 100), tooltip = tooltip,
1711  bind = (self.OnLightValue, self.OnLightChanged, self.OnLightValue))
1712  gridSizer.Add(item = self.FindWindowById(self.win['light']['bright']['slider']),
1713  pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL)
1714  gridSizer.Add(item = self.FindWindowById(self.win['light']['bright']['text']),
1715  pos = (1, 2),
1716  flag = wx.ALIGN_CENTER)
1717  gridSizer.Add(item = wx.StaticText(panel, id = wx.ID_ANY, label = _("Ambient:")),
1718  pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL)
1719  tooltip = _("Adjusts the ambient light")
1720  self._createControl(panel, data = self.win['light'], name = 'ambient', size = 300,
1721  range = (0, 100), tooltip = tooltip,
1722  bind = (self.OnLightValue, self.OnLightChanged, self.OnLightValue))
1723  gridSizer.Add(item = self.FindWindowById(self.win['light']['ambient']['slider']),
1724  pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL)
1725  gridSizer.Add(item = self.FindWindowById(self.win['light']['ambient']['text']),
1726  pos = (2, 2),
1727  flag = wx.ALIGN_CENTER)
1728 
1729  boxSizer.Add(item = gridSizer, proportion = 1,
1730  flag = wx.ALL | wx.EXPAND, border = 2)
1731  pageSizer.Add(item = boxSizer, proportion = 0,
1732  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
1733  border = 3)
1734 
1735  # reset = wx.Button(panel, id = wx.ID_ANY, label = _("Reset"))
1736  # reset.SetToolTipString(_("Reset to default view"))
1737  # # self.win['reset'] = reset.GetId()
1738  # reset.Bind(wx.EVT_BUTTON, self.OnResetView)
1739 
1740  # viewSizer.Add(item = reset, proportion = 1,
1741  # flag = wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT,
1742  # border = 5)
1743 
1744  # gridSizer.AddGrowableCol(3)
1745  # gridSizer.Add(item = viewSizer, pos = (4, 0), span = (1, 2),
1746  # flag = wx.EXPAND)
1747 
1748  panel.SetSizer(pageSizer)
1749  panel.Layout()
1750  panel.Fit()
1751 
1752  return panel
1753 
1754  def _createFringePage(self, parent):
1755  """!Create fringe page"""
1756  panel = wx.Panel(parent = parent, id = wx.ID_ANY)
1757 
1758  self.page['fringe'] = { 'id' : 1,
1759  'notebook' : self.foldpanelAppear.GetId() }
1760  self.win['fringe'] = {}
1761 
1762  pageSizer = wx.BoxSizer(wx.VERTICAL)
1763 
1764  # selection
1765  rbox = wx.StaticBox (parent = panel, id = wx.ID_ANY,
1766  label = " %s " % (_("Surface")))
1767  rboxSizer = wx.StaticBoxSizer(rbox, wx.VERTICAL)
1768  rmaps = Select(parent = panel, type = 'raster',
1769  onPopup = self.GselectOnPopup)
1770  rmaps.GetChildren()[0].Bind(wx.EVT_TEXT, self.OnSetSurface)
1771  self.win['fringe']['map'] = rmaps.GetId()
1772  rboxSizer.Add(item = rmaps, proportion = 0,
1773  flag = wx.ALL,
1774  border = 3)
1775  pageSizer.Add(item = rboxSizer, proportion = 0,
1776  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
1777  border = 3)
1778 
1779  ebox = wx.StaticBox (parent = panel, id = wx.ID_ANY,
1780  label = " %s " % (_("Edges with fringe")))
1781  eboxSizer = wx.StaticBoxSizer(ebox, wx.HORIZONTAL)
1782  for edge in [(_("N && W"), "nw"),
1783  (_("N && E"), "ne"),
1784  (_("S && W"), "sw"),
1785  (_("S && E"), "se")]:
1786  chkbox = wx.CheckBox(parent = panel,
1787  label = edge[0],
1788  name = edge[1])
1789  self.win['fringe'][edge[1]] = chkbox.GetId()
1790  eboxSizer.Add(item = chkbox, proportion = 0,
1791  flag = wx.ADJUST_MINSIZE | wx.LEFT | wx.RIGHT, border = 5)
1792  chkbox.Bind(wx.EVT_CHECKBOX, self.OnFringe)
1793 
1794  pageSizer.Add(item = eboxSizer, proportion = 0,
1795  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
1796  border = 3)
1797 
1798  sbox = wx.StaticBox (parent = panel, id = wx.ID_ANY,
1799  label = " %s " % (_("Settings")))
1800  sboxSizer = wx.StaticBoxSizer(sbox, wx.HORIZONTAL)
1801  gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
1802 
1803  # elevation
1804  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1805  label = _("Elevation of fringe from bottom:")),
1806  pos = (0, 0),
1807  flag = wx.ALIGN_CENTER_VERTICAL)
1808  spin = wx.SpinCtrl(parent = panel, id = wx.ID_ANY,
1809  size = (65, -1), min = -1e6, max = 1e6)
1810  spin.SetValue(UserSettings.Get(group = 'nviz', key = 'fringe', subkey = 'elev'))
1811  spin.Bind(wx.EVT_SPINCTRL, self.OnFringe)
1812  self.win['fringe']['elev'] = spin.GetId()
1813  gridSizer.Add(item = spin, pos = (0, 1))
1814 
1815  # color
1816  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1817  label = _("Color:")),
1818  pos = (1, 0),
1819  flag = wx.ALIGN_CENTER_VERTICAL)
1820  color = csel.ColourSelect(parent = panel, id = wx.ID_ANY,
1821  size = globalvar.DIALOG_COLOR_SIZE)
1822  color.SetColour(UserSettings.Get(group = 'nviz', key = 'fringe',
1823  subkey = 'color'))
1824  color.Bind(csel.EVT_COLOURSELECT, self.OnFringe)
1825  self.win['fringe']['color'] = color.GetId()
1826  gridSizer.Add(item = color, pos = (1, 1))
1827 
1828  sboxSizer.Add(item = gridSizer, proportion = 1,
1829  flag = wx.ALL | wx.EXPAND, border = 3)
1830  pageSizer.Add(item = sboxSizer, proportion = 0,
1831  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
1832  border = 3)
1833 
1834  panel.SetSizer(pageSizer)
1835  panel.Layout()
1836  panel.Fit()
1837 
1838  return panel
1839 
1840  def _createDecorationPage(self, parent):
1841  """!Create decoration (north arrow, scalebar, legend) page"""
1842  panel = wx.Panel(parent = parent, id = wx.ID_ANY)
1843 
1844  self.page['decoration'] = { 'id' : 2,
1845  'notebook' : self.foldpanelAppear.GetId()}
1846  self.win['decoration'] = {}
1847 
1848  pageSizer = wx.BoxSizer(wx.VERTICAL)
1849 
1850  # north arrow
1851  self.win['decoration']['arrow'] = {}
1852  nabox = wx.StaticBox (parent = panel, id = wx.ID_ANY,
1853  label = " %s " % (_("North Arrow")))
1854  naboxSizer = wx.StaticBoxSizer(nabox, wx.VERTICAL)
1855  gridSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
1856  # size
1857  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1858  label = _("Arrow length (in map units):")),
1859  pos = (0,0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL)
1860  sizeCtrl = NumTextCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1), style = wx.TE_PROCESS_ENTER)
1861  gridSizer.Add(sizeCtrl, pos = (0, 2))
1862  self.win['decoration']['arrow']['size'] = sizeCtrl.GetId()
1863  sizeCtrl.Bind(wx.EVT_TEXT_ENTER, self.OnDecorationProp)
1864  sizeCtrl.Bind(wx.EVT_KILL_FOCUS, self.OnDecorationProp)
1865 
1866  # color
1867  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1868  label = _("Arrow color:")),
1869  pos = (1,0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL)
1870  color = csel.ColourSelect(parent = panel, id = wx.ID_ANY,
1871  size = globalvar.DIALOG_COLOR_SIZE)
1872  gridSizer.Add(color, pos = (1, 2))
1873  self.win['decoration']['arrow']['color'] = color.GetId()
1874  color.Bind(csel.EVT_COLOURSELECT, self.OnDecorationProp)
1875 
1876  # control
1877  toggle = wx.ToggleButton(parent = panel, id = wx.ID_ANY, label = _("Place arrow"))
1878  gridSizer.Add(item = toggle, pos = (2, 0))
1879  toggle.Bind(wx.EVT_TOGGLEBUTTON, self.OnDecorationPlacement)
1880  self.win['decoration']['arrow']['place'] = toggle.GetId()
1881  toggle.SetName('placeArrow')
1882 
1883  delete = wx.Button(parent = panel, id = wx.ID_ANY, label = _("Delete"))
1884  gridSizer.Add(item = delete, pos = (2, 1))
1885  delete.Bind(wx.EVT_BUTTON, self.OnArrowDelete)
1886  naboxSizer.Add(item = gridSizer, proportion = 0, flag = wx.EXPAND, border = 3)
1887  pageSizer.Add(item = naboxSizer, proportion = 0,
1888  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
1889  border = 3)
1890 
1891 
1892  # north arrow
1893  self.win['decoration']['scalebar'] = {}
1894  nabox = wx.StaticBox (parent = panel, id = wx.ID_ANY,
1895  label = " %s " % (_("Scale bar")))
1896  naboxSizer = wx.StaticBoxSizer(nabox, wx.VERTICAL)
1897  gridSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
1898  # size
1899  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1900  label = _("Scale bar length (in map units):")),
1901  pos = (0,0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL)
1902  sizeCtrl = NumTextCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1), style = wx.TE_PROCESS_ENTER)
1903  gridSizer.Add(sizeCtrl, pos = (0, 2))
1904  self.win['decoration']['scalebar']['size'] = sizeCtrl.GetId()
1905  sizeCtrl.Bind(wx.EVT_TEXT_ENTER, self.OnDecorationProp)
1906  sizeCtrl.Bind(wx.EVT_KILL_FOCUS, self.OnDecorationProp)
1907 
1908  # color
1909  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
1910  label = _("Scale bar color:")),
1911  pos = (1,0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL)
1912  color = csel.ColourSelect(parent = panel, id = wx.ID_ANY,
1913  size = globalvar.DIALOG_COLOR_SIZE)
1914  gridSizer.Add(color, pos = (1, 2))
1915  self.win['decoration']['scalebar']['color'] = color.GetId()
1916  color.Bind(csel.EVT_COLOURSELECT, self.OnDecorationProp)
1917 
1918  # control
1919  toggle = wx.ToggleButton(parent = panel, id = wx.ID_ANY, label = _("Place scalebar"))
1920  gridSizer.Add(item = toggle, pos = (2, 0))
1921  toggle.Bind(wx.EVT_TOGGLEBUTTON, self.OnDecorationPlacement)
1922  self.win['decoration']['scalebar']['place'] = toggle.GetId()
1923  toggle.SetName('placeScalebar')
1924 
1925  delete = wx.Button(parent = panel, id = wx.ID_ANY, label = _("Delete last"))
1926  gridSizer.Add(item = delete, pos = (2, 1))
1927  delete.Bind(wx.EVT_BUTTON, self.OnScalebarDelete)
1928  naboxSizer.Add(item = gridSizer, proportion = 0, flag = wx.EXPAND, border = 3)
1929  pageSizer.Add(item = naboxSizer, proportion = 0,
1930  flag = wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
1931  border = 3)
1932  panel.SetSizer(pageSizer)
1933  panel.Layout()
1934  panel.Fit()
1935 
1936  return panel
1937 
1938  def GetLayerData(self, nvizType, nameOnly = False):
1939  """!Get nviz data"""
1940  name = self.FindWindowById(self.win[nvizType]['map']).GetValue()
1941  if nameOnly:
1942  return name
1943 
1944  if nvizType == 'surface' or nvizType == 'fringe':
1945  return self.mapWindow.GetLayerByName(name, mapType = 'raster', dataType = 'nviz')
1946  elif nvizType == 'vector':
1947  return self.mapWindow.GetLayerByName(name, mapType = 'vector', dataType = 'nviz')
1948  elif nvizType == 'volume':
1949  return self.mapWindow.GetLayerByName(name, mapType = '3d-raster', dataType = 'nviz')
1950 
1951  return None
1952 
1953  def OnRecord(self, event):
1954  """!Animation: start recording"""
1955  anim = self.mapWindow.GetAnimation()
1956  if not anim.IsPaused():
1957  if anim.Exists() and not anim.IsSaved():
1958  msg = _("Do you want to record new animation without saving the previous one?")
1959  dlg = wx.MessageDialog(parent = self,
1960  message = msg,
1961  caption =_("Animation already axists"),
1962  style = wx.YES_NO | wx.CENTRE)
1963  if dlg.ShowModal() == wx.ID_NO:
1964  dlg.Destroy()
1965  return
1966 
1967 
1968  anim.Clear()
1969  self.UpdateFrameIndex(0)
1970  self.UpdateFrameCount()
1971 
1972  anim.SetPause(False)
1973  anim.SetMode(mode = 'record')
1974  anim.Start()
1975 
1976  self.FindWindowById(self.win['anim']['play']).Disable()
1977  self.FindWindowById(self.win['anim']['record']).Disable()
1978  self.FindWindowById(self.win['anim']['pause']).Enable()
1979  self.FindWindowById(self.win['anim']['stop']).Enable()
1980  self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
1981  self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
1982 
1983  def OnPlay(self, event):
1984  """!Animation: replay"""
1985  anim = self.mapWindow.GetAnimation()
1986  anim.SetPause(False)
1987  anim.SetMode(mode = 'play')
1988  anim.Start()
1989 
1990  self.FindWindowById(self.win['anim']['play']).Disable()
1991  self.FindWindowById(self.win['anim']['record']).Disable()
1992  self.FindWindowById(self.win['anim']['pause']).Enable()
1993  self.FindWindowById(self.win['anim']['stop']).Enable()
1994  self.FindWindowById(self.win['anim']['frameIndex']['slider']).Enable()
1995  self.FindWindowById(self.win['anim']['frameIndex']['text']).Enable()
1996 
1997  def OnStop(self, event):
1998  """!Animation: stop recording/replaying"""
1999  anim = self.mapWindow.GetAnimation()
2000  anim.SetPause(False)
2001  if anim.GetMode() == 'save':
2002  anim.StopSaving()
2003  if anim.IsRunning():
2004  anim.Stop()
2005 
2006  self.UpdateFrameIndex(0)
2007 
2008  self.FindWindowById(self.win['anim']['play']).Enable()
2009  self.FindWindowById(self.win['anim']['record']).Enable()
2010  self.FindWindowById(self.win['anim']['pause']).Disable()
2011  self.FindWindowById(self.win['anim']['stop']).Disable()
2012  self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
2013  self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
2014 
2015  def OnPause(self, event):
2016  """!Pause animation"""
2017  anim = self.mapWindow.GetAnimation()
2018 
2019  anim.SetPause(True)
2020  mode = anim.GetMode()
2021  if anim.IsRunning():
2022  anim.Pause()
2023 
2024  if mode == "record":
2025  self.FindWindowById(self.win['anim']['play']).Disable()
2026  self.FindWindowById(self.win['anim']['record']).Enable()
2027  self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
2028  self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
2029  elif mode == 'play':
2030  self.FindWindowById(self.win['anim']['record']).Disable()
2031  self.FindWindowById(self.win['anim']['play']).Enable()
2032  self.FindWindowById(self.win['anim']['frameIndex']['slider']).Enable()
2033  self.FindWindowById(self.win['anim']['frameIndex']['text']).Enable()
2034 
2035  self.FindWindowById(self.win['anim']['pause']).Disable()
2036  self.FindWindowById(self.win['anim']['stop']).Enable()
2037 
2038 
2039  def OnFrameIndex(self, event):
2040  """!Frame index changed (by slider)"""
2041  index = event.GetInt()
2042  self.UpdateFrameIndex(index = index, sliderWidget = False)
2043 
2044  def OnFrameIndexText(self, event):
2045  """!Frame index changed by (textCtrl)"""
2046  index = event.GetValue()
2047  self.UpdateFrameIndex(index = index, textWidget = False)
2048 
2049  def OnFPS(self, event):
2050  """!Frames per second changed"""
2051  anim = self.mapWindow.GetAnimation()
2052  anim.SetFPS(event.GetInt())
2053 
2054  def UpdateFrameIndex(self, index, sliderWidget = True, textWidget = True, goToFrame = True):
2055  """!Update frame index"""
2056  anim = self.mapWindow.GetAnimation()
2057 
2058  # check index
2059  frameCount = anim.GetFrameCount()
2060  if index >= frameCount:
2061  index = frameCount - 1
2062  if index < 0:
2063  index = 0
2064 
2065  if sliderWidget:
2066  slider = self.FindWindowById(self.win['anim']['frameIndex']['slider'])
2067  slider.SetValue(index)
2068  if textWidget:
2069  text = self.FindWindowById(self.win['anim']['frameIndex']['text'])
2070  text.SetValue(int(index))
2071 
2072  # if called from tool window, update frame
2073  if goToFrame:
2074  anim.GoToFrame(int(index))
2075 
2076  def UpdateFrameCount(self):
2077  """!Update frame count label"""
2078  anim = self.mapWindow.GetAnimation()
2079  count = anim.GetFrameCount()
2080  self.FindWindowById(self.win['anim']['info']).SetLabel(str(count))
2081 
2082  def OnAnimationFinished(self, event):
2083  """!Animation finished"""
2084  anim = self.mapWindow.GetAnimation()
2085  self.UpdateFrameIndex(index = 0)
2086 
2087  slider = self.FindWindowById(self.win['anim']['frameIndex']['slider'])
2088  text = self.FindWindowById(self.win['anim']['frameIndex']['text'])
2089 
2090  if event.mode == 'record':
2091  count = anim.GetFrameCount()
2092  slider.SetMax(count)
2093  self.UpdateFrameCount()
2094 
2095  self.FindWindowById(self.win['anim']['pause']).Disable()
2096  self.FindWindowById(self.win['anim']['stop']).Disable()
2097  self.FindWindowById(self.win['anim']['record']).Enable()
2098  self.FindWindowById(self.win['anim']['play']).Enable()
2099  self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
2100  self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
2101  self.FindWindowById(self.win['anim']['save']['image']['confirm']).Enable()
2102 
2103  self.mapWindow.render['quick'] = False
2104  self.mapWindow.Refresh(False)
2105 
2106  def OnAnimationUpdateIndex(self, event):
2107  """!Animation: frame index changed"""
2108  if event.mode == 'record':
2109  self.UpdateFrameCount()
2110  elif event.mode == 'play':
2111  self.UpdateFrameIndex(index = event.index, goToFrame = False)
2112 
2113  def OnSaveAnimation(self, event):
2114  """!Save animation as a sequence of images"""
2115  anim = self.mapWindow.GetAnimation()
2116 
2117  prefix = self.FindWindowById(self.win['anim']['save']['image']['prefix']).GetValue()
2118  format = self.FindWindowById(self.win['anim']['save']['image']['format']).GetSelection()
2119  dir = self.FindWindowById(self.win['anim']['save']['image']['dir']).GetValue()
2120 
2121  if not prefix:
2122  GMessage(parent = self,
2123  message = _("No file prefix given."))
2124  return
2125  elif not os.path.exists(dir):
2126  GMessage(parent = self,
2127  message = _("Directory %s does not exist.") % dir)
2128  return
2129 
2130  self.FindWindowById(self.win['anim']['pause']).Disable()
2131  self.FindWindowById(self.win['anim']['stop']).Enable()
2132  self.FindWindowById(self.win['anim']['record']).Disable()
2133  self.FindWindowById(self.win['anim']['play']).Disable()
2134  self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
2135  self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
2136 
2137  self.FindWindowById(self.win['anim']['save']['image']['confirm']).Disable()
2138 
2139  anim.SaveAnimationFile(path = dir, prefix = prefix, format = format)
2140 
2141  def OnNewConstant(self, event):
2142  """!Create new surface with constant value"""
2143  #TODO settings
2144  name = self.mapWindow.NewConstant()
2145  win = self.FindWindowById(self.win['constant']['surface'])
2146  name = _("constant#") + str(name)
2147  win.Append(name)
2148  win.SetStringSelection(name)
2149  self.OnConstantSelection(None)
2150  self.EnablePage(name = 'constant', enabled = True)
2151 
2152  self.mapWindow.Refresh(eraseBackground = False)
2153 
2154  # need to update list of surfaces in vector page
2155  for vtype in ('points', 'lines'):
2156  checklist = self.FindWindowById(self.win['vector'][vtype]['surface'])
2157  checklist.Append(name)
2158  win = self.FindWindowById(self.win['vector']['map'])
2159  win.SetValue(win.GetValue())
2160 
2161 
2162  def OnDeleteConstant(self, event):
2163  """!Delete selected constant surface"""
2164  layerIdx = self.FindWindowById(self.win['constant']['surface']).GetSelection()
2165  if layerIdx == wx.NOT_FOUND:
2166  return
2167  name = self.FindWindowById(self.win['constant']['surface']).GetStringSelection()
2168  self.mapWindow.DeleteConstant(layerIdx)
2169  win = self.FindWindowById(self.win['constant']['surface'])
2170  win.Delete(layerIdx)
2171  if win.IsEmpty():
2172  win.SetValue("")
2173  self.EnablePage(name = 'constant', enabled = False)
2174  else:
2175  win.SetSelection(0)
2176  self.OnConstantSelection(None)
2177 
2178  # need to update list of surfaces in vector page
2179  for vtype in ('points', 'lines'):
2180  checklist = self.FindWindowById(self.win['vector'][vtype]['surface'])
2181  checklist.Delete(checklist.FindString(name))
2182 
2183  if self.mapDisplay.IsAutoRendered():
2184  self.mapWindow.Refresh(False)
2185 
2186  def OnConstantSelection(self, event):
2187  """!Constant selected"""
2188  layerIdx = self.FindWindowById(self.win['constant']['surface']).GetSelection()
2189  if layerIdx == wx.NOT_FOUND:
2190  return
2191  name = _("constant#") + str(layerIdx + 1)
2192  data = self.mapWindow.constants[layerIdx]
2193  for attr, value in data['constant'].iteritems():
2194  if attr == 'color':
2195  value = self._getColorFromString(value)
2196  if attr in ('color', 'value', 'resolution', 'transp'):
2197  if attr == 'transp':
2198  self.FindWindowById(self.win['constant'][attr]).SetValue(self._getPercent(value))
2199  self.FindWindowById(self.win['constant'][attr]).SetValue(value)
2200 
2201  def OnSetConstantProp(self, event):
2202  """!Change properties (color, value, resolution)
2203  of currently selected constant surface"""
2204  layerIdx = self.FindWindowById(self.win['constant']['surface']).GetSelection()
2205  if layerIdx == wx.NOT_FOUND:
2206  return
2207  data = self.mapWindow.constants[layerIdx]
2208  for attr in ('resolution', 'value', 'transp'):
2209  data['constant'][attr] = self.FindWindowById(self.win['constant'][attr]).GetValue()
2210  data['constant']['color'] = self._getColorString(
2211  self.FindWindowById(self.win['constant']['color']).GetValue())
2212  data['constant']['transp'] = self._getPercent(data['constant']['transp'], toPercent = False)
2213 
2214  # update properties
2215  event = wxUpdateProperties(data = data)
2216  wx.PostEvent(self.mapWindow, event)
2217  if self.mapDisplay.IsAutoRendered():
2218  self.mapWindow.Refresh(False)
2219 
2220  def OnFringe(self, event):
2221  """!Show/hide fringe"""
2222  data = self.GetLayerData('fringe')['surface']
2223 
2224  sid = data['object']['id']
2225  elev = self.FindWindowById(self.win['fringe']['elev']).GetValue()
2226  color = self.FindWindowById(self.win['fringe']['color']).GetValue()
2227 
2228  self._display.SetFringe(sid, color, elev,
2229  self.FindWindowById(self.win['fringe']['nw']).IsChecked(),
2230  self.FindWindowById(self.win['fringe']['ne']).IsChecked(),
2231  self.FindWindowById(self.win['fringe']['sw']).IsChecked(),
2232  self.FindWindowById(self.win['fringe']['se']).IsChecked())
2233  self.mapWindow.Refresh(False)
2234 
2235  def OnScroll(self, event, win, data):
2236  """!Generic scrolling handler"""
2237  winName = self.__GetWindowName(win, event.GetId())
2238  if not winName:
2239  return
2240  data[winName] = self.FindWindowById(event.GetId()).GetValue()
2241  for w in win[winName].itervalues():
2242  self.FindWindowById(w).SetValue(data[winName])
2243 
2244  event.Skip()
2245 
2246  def AdjustSliderRange(self, slider, value):
2247  minim, maxim = slider.GetRange()
2248  if not (minim <= value <= maxim):
2249  slider.SetRange(min(minim, value), max(maxim, value))
2250 
2251  def _createIsosurfacePanel(self, parent):
2252  panel = wx.Panel(parent = parent, id = wx.ID_ANY)
2253 
2254  vSizer = wx.BoxSizer(wx.HORIZONTAL)
2255 
2256  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
2257  label = " %s " % (_("Isosurface attributes")))
2258  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
2259  gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
2260 
2261  self.win['volume']['attr'] = {}
2262  inout = wx.CheckBox(parent = panel, id = wx.ID_ANY,
2263  label = _("toggle normal direction"))
2264  gridSizer.Add(item = inout, pos = (0,0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL)
2265  inout.Bind(wx.EVT_CHECKBOX, self.OnInOutMode)
2266  self.win['volume']['inout'] = inout.GetId()
2267 
2268  row = 1
2269  for code, attrb in (('topo', _("Isosurface value")),
2270  ('color', _("Color")),
2271  ('mask', _("Mask")),
2272  ('transp', _("Transparency")),
2273  ('shine', _("Shininess"))):
2274  self.win['volume'][code] = {}
2275  # label
2276  colspan = 1
2277  if code == 'topo':
2278  colspan = 2
2279  gridSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
2280  label = attrb + ':'),
2281  pos = (row, 0), span = (1, colspan),flag = wx.ALIGN_CENTER_VERTICAL)
2282  if code != 'topo':
2283  use = wx.Choice (parent = panel, id = wx.ID_ANY, size = (100, -1),
2284  choices = [_("map")])
2285  else:
2286  use = None
2287  # check for required properties
2288  if code not in ('topo', 'color', 'shine'):
2289  use.Insert(item = _("unset"), pos = 0)
2290  self.win['volume'][code]['required'] = False
2291  else:
2292  self.win['volume'][code]['required'] = True
2293  if use and code != 'mask':
2294  use.Append(item = _('constant'))
2295  if use:
2296  self.win['volume'][code]['use'] = use.GetId()
2297  use.Bind(wx.EVT_CHOICE, self.OnMapObjUse)
2298  gridSizer.Add(item = use, flag = wx.ALIGN_CENTER_VERTICAL,
2299  pos = (row, 1))
2300 
2301  if code != 'topo':
2302  map = Select(parent = panel, id = wx.ID_ANY,
2303  # size = globalvar.DIALOG_GSELECT_SIZE,
2304  size = (200, -1),
2305  type = "grid3")
2306  self.win['volume'][code]['map'] = map.GetId() - 1 # FIXME
2307  map.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
2308  gridSizer.Add(item = map, flag = wx.ALIGN_CENTER_VERTICAL,
2309  pos = (row, 2))
2310  else:
2311  map = None
2312 
2313  if code == 'color':
2314  color = UserSettings.Get(group = 'nviz', key = 'volume', subkey = ['color', 'value'])
2315  value = csel.ColourSelect(panel, id = wx.ID_ANY,
2316  colour = color,
2317  size = globalvar.DIALOG_COLOR_SIZE)
2318  value.Bind(csel.EVT_COLOURSELECT, self.OnVolumeIsosurfMap)
2319  value.SetName('color')
2320  elif code == 'mask':
2321  value = None
2322  elif code == 'topo':
2323  value = NumTextCtrl(parent = panel, id = wx.ID_ANY, size = (200, -1),
2324  style = wx.TE_PROCESS_ENTER)
2325  value.Bind(wx.EVT_TEXT_ENTER, self.OnVolumeIsosurfMap)
2326  value.Bind(wx.EVT_KILL_FOCUS, self.OnVolumeIsosurfMap)
2327 ## value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
2328  else:
2329  size = (65, -1)
2330  value = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = size,
2331  initial = 0)
2332  if code == 'topo':
2333  value.SetRange(minVal = -1e9, maxVal = 1e9)
2334  elif code in ('shine', 'transp'):
2335  value.SetRange(minVal = 0, maxVal = 100)
2336 
2337  value.Bind(wx.EVT_SPINCTRL, self.OnVolumeIsosurfMap)
2338  value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
2339 
2340  if value:
2341  self.win['volume'][code]['const'] = value.GetId()
2342  if code == 'topo':
2343  gridSizer.Add(item = value, flag = wx.ALIGN_CENTER_VERTICAL,
2344  pos = (row, 2))
2345  else:
2346  value.Enable(False)
2347  gridSizer.Add(item = value, flag = wx.ALIGN_CENTER_VERTICAL,
2348  pos = (row, 3))
2349  else:
2350  self.win['volume'][code]['const'] = None
2351 
2352  if code != 'topo':
2353  self.SetMapObjUseMap(nvizType = 'volume',
2354  attrb = code) # -> enable map / disable constant
2355 
2356  row += 1
2357 
2358  boxSizer.Add(item = gridSizer, proportion = 1,
2359  flag = wx.ALL | wx.EXPAND, border = 3)
2360  vSizer.Add(item = boxSizer, proportion = 1,
2361  flag = wx.EXPAND, border = 0)
2362  panel.SetSizer(vSizer)
2363 
2364  return panel
2365 
2366  def _createSlicePanel(self, parent):
2367  panel = wx.Panel(parent = parent, id = wx.ID_ANY)
2368 
2369  vSizer = wx.BoxSizer(wx.HORIZONTAL)
2370 
2371  box = wx.StaticBox (parent = panel, id = wx.ID_ANY,
2372  label = " %s " % (_("Slice attributes")))
2373  boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
2374  hSizer = wx.BoxSizer()
2375 
2376  self.win['volume']['slice'] = {}
2377  hSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
2378  label = _("Slice parallel to axis:")), proportion = 0,
2379  flag = wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, border = 3)
2380  axes = wx.Choice(parent = panel, id = wx.ID_ANY, size = (65, -1), choices = ("X", "Y", "Z"))
2381  hSizer.Add(axes, proportion = 0, flag = wx.ALIGN_LEFT|wx.LEFT, border = 3)
2382  self.win['volume']['slice']['axes'] = axes.GetId()
2383  axes.Bind(wx.EVT_CHOICE, self.OnVolumeSliceAxes)
2384  boxSizer.Add(hSizer, proportion = 0, flag = wx.ALL|wx.EXPAND, border = 3)
2385 
2386  gridSizer = wx.GridBagSizer(vgap = 3, hgap = 3)
2387  gridSizer.AddGrowableCol(0,1)
2388  gridSizer.AddGrowableCol(1,2)
2389  gridSizer.AddGrowableCol(2,2)
2390 
2391  # text labels
2392  for i in range(2):
2393  label = wx.StaticText(parent = panel, id = wx.ID_ANY)
2394  label.SetName('label_edge_' + str(i))
2395  gridSizer.Add(item = label, pos = (0, i + 1),
2396  flag = wx.ALIGN_CENTER)
2397  for i in range(2,4):
2398  label = wx.StaticText(parent = panel, id = wx.ID_ANY)
2399  label.SetName('label_edge_' + str(i))
2400  gridSizer.Add(item = label, pos = (3, i -1),
2401  flag = wx.ALIGN_CENTER)
2402  for i in range(2):
2403  label = wx.StaticText(parent = panel, id = wx.ID_ANY)
2404  label.SetName('label_coord_' + str(i))
2405  gridSizer.Add(item = label, pos = (i + 1, 0),
2406  flag = wx.ALIGN_CENTER_VERTICAL)
2407  label = wx.StaticText(parent = panel, id = wx.ID_ANY)
2408  label.SetName('label_coord_2')
2409  gridSizer.Add(item = label, pos = (4, 0),
2410  flag = wx.ALIGN_CENTER_VERTICAL)
2411  # sliders
2412  for i, coord in enumerate(('x1', 'x2')):
2413  slider = wx.Slider(parent = panel, id = wx.ID_ANY, minValue = 0, maxValue = 100, value = 0)
2414  self.win['volume']['slice']['slider_' + coord] = slider.GetId()
2415  slider.Bind(wx.EVT_SPIN, self.OnSlicePositionChange)
2416  slider.Bind(wx.EVT_SCROLL_THUMBRELEASE, self.OnSlicePositionChanged)
2417  gridSizer.Add(item = slider, pos = (1, i + 1),
2418  flag = wx.ALIGN_CENTER|wx.EXPAND)
2419 
2420  for i, coord in enumerate(('y1', 'y2')):
2421  slider = wx.Slider(parent = panel, id = wx.ID_ANY, minValue = 0, maxValue = 100, value = 0)
2422  self.win['volume']['slice']['slider_' + coord] = slider.GetId()
2423  slider.Bind(wx.EVT_SPIN, self.OnSlicePositionChange)
2424  slider.Bind(wx.EVT_SCROLL_THUMBRELEASE, self.OnSlicePositionChanged)
2425  gridSizer.Add(item = slider, pos = (2, i + 1),
2426  flag = wx.ALIGN_CENTER|wx.EXPAND)
2427 
2428  for i, coord in enumerate(('z1', 'z2')):
2429  slider = wx.Slider(parent = panel, id = wx.ID_ANY, minValue = 0, maxValue = 100, value = 0)
2430  self.win['volume']['slice']['slider_' + coord] = slider.GetId()
2431  slider.Bind(wx.EVT_SPIN, self.OnSlicePositionChange)
2432  slider.Bind(wx.EVT_SCROLL_THUMBRELEASE, self.OnSlicePositionChanged)
2433  gridSizer.Add(item = slider, pos = (4,i+1),
2434  flag = wx.ALIGN_CENTER|wx.EXPAND)
2435 
2436 
2437  boxSizer.Add(item = gridSizer, proportion = 1,
2438  flag = wx.ALL | wx.EXPAND, border = 3)
2439 
2440  # transparency, reset
2441  hSizer = wx.BoxSizer()
2442  hSizer.Add(item = wx.StaticText(parent = panel, id = wx.ID_ANY,
2443  label = _("Transparency:")), proportion = 0,
2444  flag = wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, border = 7)
2445  spin = wx.SpinCtrl(parent = panel, id = wx.ID_ANY, size = (65, -1),
2446  min = 0, max = 100, initial = 0)
2447  spin.Bind(wx.EVT_SPINCTRL, self.OnSliceTransparency)
2448  self.win['volume']['slice']['transp'] = spin.GetId()
2449  hSizer.Add(item = spin, proportion = 0,
2450  flag = wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.TOP, border = 7)
2451 
2452  hSizer.Add(item = wx.Size(-1, -1), proportion = 1,
2453  flag = wx.EXPAND)
2454  reset = wx.Button(parent = panel, id = wx.ID_ANY, label = _("Reset"))
2455  reset.Bind(wx.EVT_BUTTON, self.OnSliceReset)
2456  self.win['volume']['slice']['reset'] = reset.GetId()
2457  hSizer.Add(item = reset, proportion = 0,
2458  flag = wx.ALIGN_CENTER_VERTICAL|wx.TOP, border = 7)
2459 
2460  boxSizer.Add(hSizer, proportion = 0, flag = wx.ALL|wx.EXPAND, border = 3)
2461  panel.SetSizer(boxSizer)
2462 
2463  return panel
2464 
2465  def _createControl(self, parent, data, name, range, tooltip = None, bind = (None, None, None),
2466  sliderHor = True, size = 200, floatSlider = False):
2467  """!Add control (Slider + TextCtrl)"""
2468  data[name] = dict()
2469  if sliderHor:
2470  style = wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | \
2471  wx.SL_BOTTOM
2472  sizeW = (size, -1)
2473  else:
2474  style = wx.SL_VERTICAL | wx.SL_AUTOTICKS | \
2475  wx.SL_INVERSE
2476  sizeW = (-1, size)
2477 
2478  kwargs = dict(parent = parent, id = wx.ID_ANY,
2479  minValue = range[0],
2480  maxValue = range[1],
2481  style = style,
2482  size = sizeW)
2483  if floatSlider:
2484  slider = FloatSlider(**kwargs)
2485  else:
2486  slider = wx.Slider(**kwargs)
2487 
2488  slider.SetName('slider')
2489  if bind[0]:
2490  #EVT_SCROLL emits event after slider is released, EVT_SPIN not
2491  slider.Bind(wx.EVT_SPIN, bind[0])
2492 
2493  if bind[1]:
2494  slider.Bind(wx.EVT_SCROLL_THUMBRELEASE, bind[1])
2495  data[name]['slider'] = slider.GetId()
2496 
2497  text = NumTextCtrl(parent = parent, id = wx.ID_ANY, size = (65, -1),
2498  style = wx.TE_PROCESS_ENTER)
2499 
2500  text.SetName('text')
2501  if tooltip:
2502  text.SetToolTipString(tooltip)
2503  if bind[2]:
2504  text.Bind(wx.EVT_TEXT_ENTER, bind[2])
2505  text.Bind(wx.EVT_KILL_FOCUS, bind[2])
2506 
2507  data[name]['text'] = text.GetId()
2508 
2509  def _createCompass(self, panel, sizer, type):
2510  """!Create 'compass' widget for light and view page"""
2511  w = wx.Button(panel, id = wx.ID_ANY, label = _("W"))
2512  n = wx.Button(panel, id = wx.ID_ANY, label = _("N"))
2513  s = wx.Button(panel, id = wx.ID_ANY, label = _("S"))
2514  e = wx.Button(panel, id = wx.ID_ANY, label = _("E"))
2515  nw = wx.Button(panel, id = wx.ID_ANY, label = _("NW"))
2516  ne = wx.Button(panel, id = wx.ID_ANY, label = _("NE"))
2517  se = wx.Button(panel, id = wx.ID_ANY, label = _("SE"))
2518  sw = wx.Button(panel, id = wx.ID_ANY, label = _("SW"))
2519  padding = 15
2520  if sys.platform == 'darwin':
2521  padding = 20
2522  minWidth = sw.GetTextExtent(sw.GetLabel())[0] + padding
2523  for win, name in zip((w, n, s, e, nw, ne, se, sw),
2524  ('w', 'n', 's', 'e', 'nw', 'ne', 'se', 'sw')):
2525  win.SetMinSize((minWidth, -1))
2526  win.Bind(wx.EVT_BUTTON, self.OnLookFrom)
2527  win.SetName(type + '_' + name)
2528  sizer.Add(item = nw, pos = (0, 0), flag = wx.ALIGN_CENTER)
2529  sizer.Add(item = n, pos = (0, 1), flag = wx.ALIGN_CENTER)
2530  sizer.Add(item = ne, pos = (0, 2), flag = wx.ALIGN_CENTER)
2531  sizer.Add(item = e, pos = (1, 2), flag = wx.ALIGN_CENTER)
2532  sizer.Add(item = se, pos = (2, 2), flag = wx.ALIGN_CENTER)
2533  sizer.Add(item = s, pos = (2, 1), flag = wx.ALIGN_CENTER)
2534  sizer.Add(item = sw, pos = (2, 0), flag = wx.ALIGN_CENTER)
2535  sizer.Add(item = w, pos = (1, 0), flag = wx.ALIGN_CENTER)
2536 
2537 
2538 
2539  def __GetWindowName(self, data, id):
2540  for name in data.iterkeys():
2541  if type(data[name]) is type({}):
2542  for win in data[name].itervalues():
2543  if win == id:
2544  return name
2545  else:
2546  if data[name] == id:
2547  return name
2548 
2549  return None
2550 
2551  def UpdateSettings(self):
2552  """!Update view from settings values
2553  stored in self.mapWindow.view dictionary"""
2554  for control in ('height',
2555  'persp',
2556  'twist',
2557  'z-exag'):
2558  for win in self.win['view'][control].itervalues():
2559  try:
2560  if control == 'height':
2561  value = int(self.mapWindow.iview[control]['value'])
2562  else:
2563  value = self.mapWindow.view[control]['value']
2564  except KeyError:
2565  value = -1
2566 
2567  self.FindWindowById(win).SetValue(value)
2568 
2569  viewWin = self.FindWindowById(self.win['view']['position'])
2570  x, y = viewWin.UpdatePos(self.mapWindow.view['position']['x'],
2571  self.mapWindow.view['position']['y'])
2572  viewWin.Draw(pos = (x, y), scale = True)
2573  viewWin.Refresh(False)
2574 
2575  color = self._getColorString(self.mapWindow.view['background']['color'])
2576  self._display.SetBgColor(str(color))
2577 
2578  self.Update()
2579 
2580  self.mapWindow.Refresh(eraseBackground = False)
2581  self.mapWindow.render['quick'] = False
2582  self.mapWindow.Refresh(True)
2583 
2584  def OnShowLightModel(self, event):
2585  """!Show light model"""
2586  self._display.showLight = event.IsChecked()
2587  self._display.DrawLightingModel()
2588 
2589  def OnLightChange(self, event):
2590  """!Position of the light changing"""
2591  winName = self.__GetWindowName(self.win['light'], event.GetId())
2592  if not winName:
2593  return
2594 
2595  value = self.FindWindowById(event.GetId()).GetValue()
2596 
2597  self.mapWindow.light['position']['z'] = value
2598  for win in self.win['light'][winName].itervalues():
2599  self.FindWindowById(win).SetValue(value)
2600 
2601  self.PostLightEvent()
2602 
2603  event.Skip()
2604 
2605  def OnLightChanged(self, event):
2606  """!Light changed"""
2607  self.PostLightEvent(refresh = True)
2608 
2609  def OnLightColor(self, event):
2610  """!Color of the light changed"""
2611  self.mapWindow.light['color'] = tuple(event.GetValue())
2612 
2613  self.PostLightEvent(refresh = True)
2614 
2615  event.Skip()
2616 
2617  def OnLightValue(self, event):
2618  """!Light brightness/ambient changing"""
2619  data = self.mapWindow.light
2620  self.OnScroll(event, self.win['light'], data)
2621 
2622  self.PostLightEvent()
2623  event.Skip()
2624 
2625  def OnBgColor(self, event):
2626  """!Background color changed"""
2627  color = event.GetValue()
2628  self.mapWindow.view['background']['color'] = tuple(color)
2629  color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
2630  self._display.SetBgColor(str(color))
2631 
2632  if self.mapDisplay.IsAutoRendered():
2633  self.mapWindow.Refresh(False)
2634 
2635  def OnSetSurface(self, event):
2636  """!Surface selected, currently used for fringes"""
2637  name = event.GetString()
2638  try:
2639  data = self.mapWindow.GetLayerByName(name, mapType = 'raster', dataType = 'nviz')['surface']
2640  except:
2641  self.EnablePage('fringe', False)
2642  return
2643 
2644  layer = self.mapWindow.GetLayerByName(name, mapType = 'raster')
2645  self.EnablePage('fringe', True)
2646 
2647  def OnSetRaster(self, event):
2648  """!Raster map selected, update surface page"""
2649  name = event.GetString()
2650  try:
2651  data = self.mapWindow.GetLayerByName(name, mapType = 'raster', dataType = 'nviz')['surface']
2652  except:
2653  self.EnablePage('surface', False)
2654  return
2655 
2656  layer = self.mapWindow.GetLayerByName(name, mapType = 'raster')
2657  self.EnablePage('surface', True)
2658  self.UpdateSurfacePage(layer, data, updateName = False)
2659 
2660  def OnSetVector(self, event):
2661  """!Vector map selected, update properties page"""
2662  name = event.GetString()
2663  try:
2664  data = self.mapWindow.GetLayerByName(name, mapType = 'vector', dataType = 'nviz')['vector']
2665  except:
2666  self.EnablePage('vector', False)
2667  return
2668  layer = self.mapWindow.GetLayerByName(name, mapType = 'vector')
2669  self.EnablePage('vector', True)
2670  self.UpdateVectorPage(layer, data, updateName = False)
2671 
2672  def OnSetRaster3D(self, event):
2673  """!3D Raster map selected, update surface page"""
2674  name = event.GetString()
2675  try:
2676  data = self.mapWindow.GetLayerByName(name, mapType = '3d-raster', dataType = 'nviz')['volume']
2677  except:
2678  self.EnablePage('volume', False)
2679  return
2680 
2681  layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
2682  self.EnablePage('volume', True)
2683  self.UpdateVolumePage(layer, data, updateName = False)
2684 
2685  def OnViewChange(self, event):
2686  """!Change view, render in quick mode"""
2687  # find control
2688  winName = self.__GetWindowName(self.win['view'], event.GetId())
2689  if not winName:
2690  return
2691 
2692  value = self.FindWindowById(event.GetId()).GetValue()
2693  slider = self.FindWindowById(self.win['view'][winName]['slider'])
2694 
2695  if winName == 'persp' and not (0 <= value <= 180):
2696  return
2697 
2698  self.AdjustSliderRange(slider = slider, value = value)
2699 
2700  if winName == 'height':
2701  view = self.mapWindow.iview # internal
2702  else:
2703  view = self.mapWindow.view
2704 
2705  if winName == 'z-exag' and value >= 0:
2706  self.PostViewEvent(zExag = True)
2707  else:
2708  self.PostViewEvent(zExag = False)
2709 
2710  if winName in ('persp', 'twist'):
2711  convert = int
2712  else:
2713  convert = float
2714 
2715  view[winName]['value'] = convert(value)
2716 
2717  for win in self.win['view'][winName].itervalues():
2718  self.FindWindowById(win).SetValue(value)
2719 
2720  self.mapWindow.iview['dir']['use'] = False
2721  self.mapWindow.render['quick'] = True
2722  if self.mapDisplay.IsAutoRendered():
2723  self.mapWindow.Refresh(False)
2724 
2725  event.Skip()
2726 
2727  def OnViewChanged(self, event):
2728  """!View changed, render in full resolution"""
2729  self.mapWindow.render['quick'] = False
2730  self.mapWindow.Refresh(False)
2731  self.UpdateSettings()
2732  try:# when calling event = None
2733  event.Skip()
2734  except AttributeError:
2735  pass
2736 
2737  def OnViewChangedText(self, event):
2738  """!View changed, render in full resolution"""
2739  self.mapWindow.render['quick'] = False
2740  self.OnViewChange(event)
2741  self.OnViewChanged(None)
2742  self.Update()
2743 
2744  event.Skip()
2745 
2746  def OnLookAt(self, event):
2747  """!Look here/center"""
2748  name = self.FindWindowById(event.GetId()).GetName()
2749  if name == 'center':
2750  self._display.LookAtCenter()
2751  focus = self.mapWindow.iview['focus']
2752  focus['x'], focus['y'], focus['z'] = self._display.GetFocus()
2753  self.mapWindow.saveHistory = True
2754  self.mapWindow.Refresh(False)
2755  elif name == 'top':
2756  self.mapWindow.view['position']['x'] = 0.5
2757  self.mapWindow.view['position']['y'] = 0.5
2758  self.PostViewEvent(zExag = True)
2759  self.UpdateSettings()
2760  self.mapWindow.Refresh(False)
2761  else: # here
2762  if self.FindWindowById(event.GetId()).GetValue():
2763  self.mapDisplay.Raise()
2764  self.mapWindow.mouse['use'] = 'lookHere'
2765  self.mapWindow.SetCursor(self.mapWindow.cursors["cross"])
2766  else:
2767  self.mapWindow.mouse['use'] = 'default'
2768  self.mapWindow.SetCursor(self.mapWindow.cursors['default'])
2769 
2770  def OnResetView(self, event):
2771  """!Reset to default view (view page)"""
2772  self.mapWindow.ResetView()
2773  self.UpdateSettings()
2774  self.mapWindow.Refresh(False)
2775 
2776  def OnResetSurfacePosition(self, event):
2777  """!Reset position of surface"""
2778 
2779  for win in self.win['surface']['position'].itervalues():
2780  if win == self.win['surface']['position']['axis']:
2781  self.FindWindowById(win).SetSelection(2) # Z
2782  elif win == self.win['surface']['position']['reset']:
2783  continue
2784  else:
2785  self.FindWindowById(win).SetValue(0)
2786 
2787  data = self.GetLayerData('surface')
2788  data['surface']['position']['x'] = 0
2789  data['surface']['position']['y'] = 0
2790  data['surface']['position']['z'] = 0
2791  data['surface']['position']['update'] = None
2792  # update properties
2793  event = wxUpdateProperties(data = data)
2794  wx.PostEvent(self.mapWindow, event)
2795 
2796  if self.mapDisplay.IsAutoRendered():
2797  self.mapWindow.Refresh(False)
2798 
2799  def OnLookFrom(self, event):
2800  """!Position of view/light changed by buttons"""
2801  name = self.FindWindowById(event.GetId()).GetName()
2802  buttonName = name.split('_')[1]
2803  if name.split('_')[0] == 'view':
2804  type = 'view'
2805  data = self.mapWindow.view
2806  else:
2807  type = 'light'
2808  data = self.mapWindow.light
2809  if buttonName == 'n': # north
2810  data['position']['x'] = 0.5
2811  data['position']['y'] = 0.0
2812  elif buttonName == 's': # south
2813  data['position']['x'] = 0.5
2814  data['position']['y'] = 1.0
2815  elif buttonName == 'e': # east
2816  data['position']['x'] = 1.0
2817  data['position']['y'] = 0.5
2818  elif buttonName =='w': # west
2819  data['position']['x'] = 0.0
2820  data['position']['y'] = 0.5
2821  elif buttonName == 'nw': # north-west
2822  data['position']['x'] = 0.0
2823  data['position']['y'] = 0.0
2824  elif buttonName == 'ne': # north-east
2825  data['position']['x'] = 1.0
2826  data['position']['y'] = 0.0
2827  elif buttonName == 'se': # south-east
2828  data['position']['x'] = 1.0
2829  data['position']['y'] = 1.0
2830  elif buttonName == 'sw': # south-west
2831  data['position']['x'] = 0.0
2832  data['position']['y'] = 1.0
2833  if type == 'view':
2834  self.PostViewEvent(zExag = True)
2835 
2836  self.UpdateSettings()
2837  else:
2838  self.PostLightEvent()
2839  lightWin = self.FindWindowById(self.win['light']['position'])
2840  x, y = lightWin.UpdatePos(self.mapWindow.light['position']['x'],
2841  self.mapWindow.light['position']['y'])
2842  lightWin.Draw(pos = (x, y), scale = True)
2843  lightWin.Refresh(False)
2844  self.mapWindow.render['quick'] = False
2845  self.mapWindow.Refresh(False)
2846 
2847  def OnMapObjUse(self, event):
2848  """!Set surface attribute -- use -- map/constant"""
2849  if not self.mapWindow.init:
2850  return
2851 
2852  wx.Yield()
2853 
2854  # find attribute row
2855  attrb = self.__GetWindowName(self.win['surface'], event.GetId())
2856  if not attrb:
2857  attrb = self.__GetWindowName(self.win['volume'], event.GetId())
2858  nvizType = 'volume'
2859  else:
2860  nvizType = 'surface'
2861 
2862  selection = event.GetSelection()
2863  if self.win[nvizType][attrb]['required']: # no 'unset'
2864  selection += 1
2865  if selection == 0: # unset
2866  useMap = None
2867  value = ''
2868  elif selection == 1: # map
2869  useMap = True
2870  value = self.FindWindowById(self.win[nvizType][attrb]['map']).GetValue()
2871  elif selection == 2: # constant
2872  useMap = False
2873  if attrb == 'color':
2874  value = self.FindWindowById(self.win[nvizType][attrb]['const']).GetColour()
2875  value = self._getColorString(value)
2876  else:
2877  value = self._getPercent(self.FindWindowById(self.win[nvizType][attrb]['const']).GetValue(), toPercent = False)
2878 
2879  self.SetMapObjUseMap(nvizType = nvizType,
2880  attrb = attrb, map = useMap)
2881 
2882  name = self.FindWindowById(self.win[nvizType]['map']).GetValue()
2883  if nvizType == 'surface':
2884  data = self.mapWindow.GetLayerByName(name, mapType = 'raster', dataType = 'nviz')
2885  data[nvizType]['attribute'][attrb] = { 'map' : useMap,
2886  'value' : str(value),
2887  'update' : None }
2888  else: # volume / isosurface
2889  data = self.mapWindow.GetLayerByName(name, mapType = '3d-raster', dataType = 'nviz')
2890  list = self.FindWindowById(self.win['volume']['isosurfs'])
2891  id = list.GetSelection()
2892  if id != -1:
2893  data[nvizType]['isosurface'][id][attrb] = { 'map' : useMap,
2894  'value' : str(value),
2895  'update' : None }
2896 
2897  # update properties
2898  event = wxUpdateProperties(data = data)
2899  wx.PostEvent(self.mapWindow, event)
2900 
2901  if self.mapDisplay.IsAutoRendered():
2902  self.mapWindow.Refresh(False)
2903 
2904  def EnablePage(self, name, enabled = True):
2905  """!Enable/disable all widgets on page"""
2906  for key, item in self.win[name].iteritems():
2907  if key in ('map', 'surface', 'new','planes'):
2908  continue
2909  if type(item) == types.DictType:
2910  for skey, sitem in self.win[name][key].iteritems():
2911  if type(sitem) == types.DictType:
2912  for ssitem in self.win[name][key][skey].itervalues():
2913  if type(ssitem) == types.IntType:
2914  self.FindWindowById(ssitem).Enable(enabled)
2915  else:
2916  if type(sitem) == types.IntType:
2917  self.FindWindowById(sitem).Enable(enabled)
2918  else:
2919  if type(item) == types.IntType:
2920  self.FindWindowById(item).Enable(enabled)
2921 
2922  def SetMapObjUseMap(self, nvizType, attrb, map = None):
2923  """!Update dialog widgets when attribute type changed"""
2924  if attrb in ('topo', 'color', 'shine'):
2925  incSel = -1 # decrement selection (no 'unset')
2926  else:
2927  incSel = 0
2928  if nvizType == 'volume' and attrb == 'topo':
2929  return
2930  if map is True: # map
2931  if attrb != 'topo': # changing map topography not allowed
2932  # not sure why, but here must be disabled both ids, should be fixed!
2933  self.FindWindowById(self.win[nvizType][attrb]['map'] + 1).Enable(True)
2934  if self.win[nvizType][attrb]['const']:
2935  self.FindWindowById(self.win[nvizType][attrb]['const']).Enable(False)
2936  self.FindWindowById(self.win[nvizType][attrb]['use']).SetSelection(1 + incSel)
2937  elif map is False: # const
2938  self.FindWindowById(self.win[nvizType][attrb]['map'] + 1).Enable(False)
2939  if self.win[nvizType][attrb]['const']:
2940  self.FindWindowById(self.win[nvizType][attrb]['const']).Enable(True)
2941  self.FindWindowById(self.win[nvizType][attrb]['use']).SetSelection(2 + incSel)
2942  else: # unset
2943  self.FindWindowById(self.win[nvizType][attrb]['use']).SetSelection(0)
2944  self.FindWindowById(self.win[nvizType][attrb]['map'] + 1).Enable(False)
2945  if self.win[nvizType][attrb]['const']:
2946  self.FindWindowById(self.win[nvizType][attrb]['const']).Enable(False)
2947 
2948 
2949  def OnSurfaceMap(self, event):
2950  """!Set surface attribute"""
2951  if self.vetoGSelectEvt:
2952  self.vetoGSelectEvt = False
2953  return
2954  self.SetMapObjAttrb(nvizType = 'surface', winId = event.GetId())
2955 
2956  def SetMapObjAttrb(self, nvizType, winId):
2957  """!Set map object (surface/isosurface) attribute (map/constant)"""
2958  if not self.mapWindow.init:
2959  return
2960 
2961  attrb = self.__GetWindowName(self.win[nvizType], winId)
2962  if not attrb:
2963  return
2964 
2965  if not (nvizType == 'volume' and attrb == 'topo'):
2966  selection = self.FindWindowById(self.win[nvizType][attrb]['use']).GetSelection()
2967  if self.win[nvizType][attrb]['required']:
2968  selection += 1
2969 
2970  if selection == 0: # unset
2971  useMap = None
2972  value = ''
2973  elif selection == 1: # map
2974  value = self.FindWindowById(self.win[nvizType][attrb]['map']).GetValue()
2975  useMap = True
2976  else: # constant
2977  if attrb == 'color':
2978  value = self.FindWindowById(self.win[nvizType][attrb]['const']).GetColour()
2979  # tuple to string
2980  value = self._getColorString(value)
2981  else:
2982  value = self._getPercent(
2983  self.FindWindowById(self.win[nvizType][attrb]['const']).GetValue(), toPercent = False)
2984 
2985  useMap = False
2986  else:
2987  useMap = None
2988  value = self.FindWindowById(self.win[nvizType][attrb]['const']).GetValue()
2989  if not self.pageChanging:
2990  name = self.FindWindowById(self.win[nvizType]['map']).GetValue()
2991  if nvizType == 'surface':
2992  data = self.mapWindow.GetLayerByName(name, mapType = 'raster', dataType = 'nviz')
2993  data[nvizType]['attribute'][attrb] = { 'map' : useMap,
2994  'value' : str(value),
2995  'update' : None }
2996  else:
2997  data = self.mapWindow.GetLayerByName(name, mapType = '3d-raster', dataType = 'nviz')
2998  list = self.FindWindowById(self.win['volume']['isosurfs'])
2999  id = list.GetSelection()
3000  if id > -1:
3001  data[nvizType]['isosurface'][id][attrb] = { 'map' : useMap,
3002  'value' : str(value),
3003  'update' : None }
3004  if attrb == 'topo':
3005  list = self.FindWindowById(self.win['volume']['isosurfs'])
3006  sel = list.GetSelection()
3007  list.SetString(sel, "%s %s" % (_("Level"), str(value)))
3008  list.Check(sel)
3009 
3010  # update properties
3011  event = wxUpdateProperties(data = data)
3012  wx.PostEvent(self.mapWindow, event)
3013 
3014  if self.mapDisplay.IsAutoRendered():
3015  self.mapWindow.Refresh(False)
3016 
3017  def OnSurfaceResolution(self, event):
3018  """!Draw resolution changed"""
3019  self.SetSurfaceResolution()
3020 
3021  if self.mapDisplay.IsAutoRendered():
3022  self.mapWindow.Refresh(False)
3023 
3024 
3026  """!Set draw resolution"""
3027  coarse = self.FindWindowById(self.win['surface']['draw']['res-coarse']).GetValue()
3028  fine = self.FindWindowById(self.win['surface']['draw']['res-fine']).GetValue()
3029 
3030  data = self.GetLayerData('surface')
3031  data['surface']['draw']['resolution'] = { 'coarse' : coarse,
3032  'fine' : fine,
3033  'update' : None }
3034 
3035  # update properties
3036  event = wxUpdateProperties(data = data)
3037  wx.PostEvent(self.mapWindow, event)
3038 
3039  def SetSurfaceMode(self):
3040  """!Set draw mode"""
3041  mode = self.FindWindowById(self.win['surface']['draw']['mode']).GetSelection()
3042  style = self.FindWindowById(self.win['surface']['draw']['style']).GetSelection()
3043  if style == 0: # wire
3044  self.FindWindowById(self.win['surface']['draw']['wire-color']).Enable(True)
3045  elif style == 1: # surface
3046  self.FindWindowById(self.win['surface']['draw']['wire-color']).Enable(False)
3047 
3048  shade = self.FindWindowById(self.win['surface']['draw']['shading']).GetSelection()
3049 
3050  value, desc = self.mapWindow.nvizDefault.GetDrawMode(mode, style, shade)
3051 
3052  return value, desc
3053 
3054  def OnSurfaceMode(self, event):
3055  """!Set draw mode"""
3056  value, desc = self.SetSurfaceMode()
3057 
3058  data = self.GetLayerData('surface')
3059  data['surface']['draw']['mode'] = { 'value' : value,
3060  'desc' : desc,
3061  'update' : None }
3062 
3063  # update properties
3064  event = wxUpdateProperties(data = data)
3065  wx.PostEvent(self.mapWindow, event)
3066 
3067  if self.mapDisplay.IsAutoRendered():
3068  self.mapWindow.Refresh(False)
3069 
3070  def OnSurfaceModeAll(self, event):
3071  """!Set draw mode (including wire color) for all loaded surfaces"""
3072  value, desc = self.SetSurfaceMode()
3073  coarse = self.FindWindowById(self.win['surface']['draw']['res-coarse']).GetValue()
3074  fine = self.FindWindowById(self.win['surface']['draw']['res-fine']).GetValue()
3075  color = self.FindWindowById(self.win['surface']['draw']['wire-color']).GetColour()
3076  cvalue = self._getColorString(color)
3077 
3078  for name in self.mapWindow.GetLayerNames(type = 'raster'):
3079 
3080  data = self.mapWindow.GetLayerByName(name, mapType = 'raster', dataType = 'nviz')
3081  if not data:
3082  continue # shouldy no happen
3083 
3084  data['surface']['draw']['all'] = True
3085  data['surface']['draw']['mode'] = { 'value' : value,
3086  'desc' : desc,
3087  'update' : None }
3088  data['surface']['draw']['resolution'] = { 'coarse' : coarse,
3089  'fine' : fine,
3090  'update' : None }
3091  data['surface']['draw']['wire-color'] = { 'value' : cvalue,
3092  'update' : None }
3093 
3094  # update properties
3095  event = wxUpdateProperties(data = data)
3096  wx.PostEvent(self.mapWindow, event)
3097 
3098  if self.mapDisplay.IsAutoRendered():
3099  self.mapWindow.Refresh(False)
3100 
3101  def _getColorString(self, color):
3102  """!Convert color tuple to R:G:B format
3103 
3104  @param color tuple
3105 
3106  @return string R:G:B
3107  """
3108  return str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
3109 
3110  def _getColorFromString(self, color, delim = ':'):
3111  """!Convert color string (R:G:B) to wx.Color
3112 
3113  @param color string
3114  @param delim delimiter
3115 
3116  @return wx.Color instance
3117  """
3118  return wx.Color(*map(int, color.split(delim)))
3119 
3120  def _get3dRange(self, name):
3121  """!Gelper func for getting range of 3d map"""
3122  ret = RunCommand('r3.info', read = True, flags = 'r', map = name)
3123  if ret:
3124  range = []
3125  for value in ret.strip('\n').split('\n'):
3126  range.append(float(value.split('=')[1]))
3127  return range
3128 
3129  return -1e6, 1e6
3130 
3131  def _getPercent(self, value, toPercent = True):
3132  """!Convert values 0 - 255 to percents and vice versa"""
3133  value = int(value)
3134  if toPercent:
3135  value = int(value/255. * 100)
3136  else:
3137  value = int(value/100. * 255)
3138  return value
3139 
3140  def OnSurfaceWireColor(self, event):
3141  """!Set wire color"""
3142  data = self.GetLayerData('surface')
3143  value = self._getColorString(event.GetValue())
3144  data['surface']['draw']['wire-color'] = { 'value' : value,
3145  'update' : None }
3146 
3147  # update properties
3148  event = wxUpdateProperties(data = data)
3149  wx.PostEvent(self.mapWindow, event)
3150 
3151  if self.mapDisplay.IsAutoRendered():
3152  self.mapWindow.Refresh(False)
3153 
3154  def OnSurfaceAxis(self, event):
3155  """!Surface position, axis changed"""
3156  data = self.GetLayerData('surface')
3157  id = data['surface']['object']['id']
3158 
3159  axis = self.FindWindowById(self.win['surface']['position']['axis']).GetSelection()
3160  slider = self.FindWindowById(self.win['surface']['position']['slider'])
3161  text = self.FindWindowById(self.win['surface']['position']['text'])
3162  xydim = self._display.GetLongDim()
3163  zdim = self._display.GetZRange()
3164  zdim = zdim[1] - zdim[0]
3165 
3166  x, y, z = self._display.GetSurfacePosition(id)
3167 
3168  if axis == 0: # x
3169  slider.SetRange(-3 * xydim, 3 * xydim)
3170  slider.SetValue(x)
3171  text.SetValue(x)
3172  elif axis == 1: # y
3173  slider.SetRange(-3 * xydim, 3 * xydim)
3174  slider.SetValue(y)
3175  text.SetValue(y)
3176  else: # z
3177  slider.SetRange(-3 * zdim, 3 * zdim)
3178  slider.SetValue(z)
3179  text.SetValue(z)
3180 
3181  def OnSurfacePosition(self, event):
3182  """!Surface position"""
3183  winName = self.__GetWindowName(self.win['surface'], event.GetId())
3184  if not winName:
3185  return
3186  axis = self.FindWindowById(self.win['surface']['position']['axis']).GetSelection()
3187 
3188  value = self.FindWindowById(event.GetId()).GetValue()
3189  slider = self.FindWindowById(self.win['surface'][winName]['slider'])
3190  self.AdjustSliderRange(slider = slider, value = value)
3191 
3192  for win in self.win['surface']['position'].itervalues():
3193  if win in (self.win['surface']['position']['axis'],
3194  self.win['surface']['position']['reset']):
3195  continue
3196  else:
3197  self.FindWindowById(win).SetValue(value)
3198 
3199  data = self.GetLayerData('surface')
3200  id = data['surface']['object']['id']
3201  x, y, z = self._display.GetSurfacePosition(id)
3202 
3203  if axis == 0: # x
3204  x = value
3205  elif axis == 1: # y
3206  y = value
3207  else: # z
3208  z = value
3209 
3210  data['surface']['position']['x'] = x
3211  data['surface']['position']['y'] = y
3212  data['surface']['position']['z'] = z
3213  data['surface']['position']['update'] = None
3214  # update properties
3215 
3216  event = wxUpdateProperties(data = data)
3217  wx.PostEvent(self.mapWindow, event)
3218 
3219  self.mapWindow.render['quick'] = True
3220  if self.mapDisplay.IsAutoRendered():
3221  self.mapWindow.Refresh(False)
3222  # self.UpdatePage('surface')
3223 
3224  def OnSurfacePositionChanged(self, event):
3225  """!Surface position changed"""
3226  self.mapWindow.render['quick'] = False
3227  self.mapWindow.Refresh(False)
3228 
3229  def OnSurfacePositionText(self, event):
3230  """!Surface position changed by textctrl"""
3231  self.OnSurfacePosition(event)
3232  self.OnSurfacePositionChanged(None)
3233 
3234  def UpdateVectorShow(self, vecType, enabled):
3235  """!Enable/disable lines/points widgets
3236 
3237  @param vecType vector type (lines, points)
3238  """
3239  if vecType != 'lines' and vecType != 'points':
3240  return False
3241 
3242  for win in self.win['vector'][vecType].keys():
3243  if win == 'show':
3244  continue
3245  if type(self.win['vector'][vecType][win]) == type({}):
3246  for swin in self.win['vector'][vecType][win].keys():
3247  if enabled:
3248  self.FindWindowById(self.win['vector'][vecType][win][swin]).Enable(True)
3249  else:
3250  self.FindWindowById(self.win['vector'][vecType][win][swin]).Enable(False)
3251  else:
3252  if enabled:
3253  self.FindWindowById(self.win['vector'][vecType][win]).Enable(True)
3254  else:
3255  self.FindWindowById(self.win['vector'][vecType][win]).Enable(False)
3256 
3257  return True
3258 
3259  def OnVectorShow(self, event):
3260  """!Show vector lines/points"""
3261  winId = event.GetId()
3262  if winId == self.win['vector']['lines']['show']:
3263  vecType = 'lines'
3264  points = False
3265  else: # points
3266  vecType = 'points'
3267  points = True
3268 
3269  checked = event.IsChecked()
3270  name = self.FindWindowById(self.win['vector']['map']).GetValue()
3271  item = self.mapWindow.GetLayerByName(name, mapType = 'vector', dataType = 'item')
3272  data = self.GetLayerData('vector')['vector']
3273 
3274  if checked:
3275  self.mapWindow.LoadVector(item, points = points, append = False)
3276  else:
3277  self.mapWindow.UnloadVector(item, points = points, remove = False)
3278 
3279  self.UpdateVectorShow(vecType, checked)
3280 
3281  if checked:
3282  try:
3283  id = data[vecType]['object']['id']
3284  except KeyError:
3285  id = -1
3286 
3287  if id > 0:
3288  self.mapWindow.SetMapObjProperties(item, id, vecType)
3289 
3290  # update properties
3291  event = wxUpdateProperties(data = data)
3292  wx.PostEvent(self.mapWindow, event)
3293 
3294  if self.mapDisplay.IsAutoRendered():
3295  self.mapWindow.Refresh(False)
3296 
3297  event.Skip()
3298 
3299  def OnVectorDisplay(self, event):
3300  """!Display vector lines on surface/flat"""
3301  rasters = self.mapWindow.GetLayerNames('raster')
3302  if event.GetSelection() == 0: # surface
3303  if len(rasters) < 1:
3304  self.FindWindowById(self.win['vector']['lines']['surface']).Enable(False)
3305  self.FindWindowById(self.win['vector']['lines']['flat']).SetSelection(1)
3306  return
3307 
3308  self.FindWindowById(self.win['vector']['lines']['surface']).Enable(True)
3309  # set first found surface
3310  data = self.GetLayerData('vector')
3311  data['vector']['lines']['mode']['surface'] = rasters[0]
3312  self.FindWindowById(self.win['vector']['lines']['surface']).SetStringSelection( \
3313  rasters[0])
3314  else: # flat
3315  self.FindWindowById(self.win['vector']['lines']['surface']).Enable(False)
3316 
3317  self.OnVectorLines(event)
3318 
3319  event.Skip()
3320 
3321  def OnVectorLines(self, event):
3322  """!Set vector lines mode, apply changes if auto-rendering is enabled"""
3323  data = self.GetLayerData('vector')
3324  width = self.FindWindowById(self.win['vector']['lines']['width']).GetValue()
3325 
3326  mode = {}
3327  if self.FindWindowById(self.win['vector']['lines']['flat']).GetSelection() == 0:
3328  mode['type'] = 'surface'
3329  mode['surface'] = {}
3330  checklist = self.FindWindowById(self.win['vector']['lines']['surface'])
3331  value = list()
3332  checked = list()
3333  for surface in range(checklist.GetCount()):
3334  value.append(checklist.GetString(surface))
3335  checked.append(checklist.IsChecked(surface))
3336 
3337  mode['surface']['value'] = value
3338  mode['surface']['show'] = checked
3339  else:
3340  mode['type'] = 'flat'
3341 
3342  for attrb in ('width', 'mode'):
3343  data['vector']['lines'][attrb]['update'] = None
3344  data['vector']['lines']['width']['value'] = width
3345  data['vector']['lines']['mode'] = mode
3346 
3347  color = self.FindWindowById(self.win['vector']['lines']['color']).GetColour()
3348 
3349  if isinstance(color, csel.ColourSelect):
3350  pass #color picker not yet instantiated
3351  else:
3352  color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
3353  data['vector']['lines']['color']['update'] = None
3354  data['vector']['lines']['color']['value'] = color
3355 
3356  # update properties
3357  event = wxUpdateProperties(data = data)
3358  wx.PostEvent(self.mapWindow, event)
3359 
3360  if self.mapDisplay.IsAutoRendered():
3361  self.mapWindow.Refresh(False)
3362 
3363  def OnVectorHeight(self, event):
3364  id = event.GetId()
3365  if id in self.win['vector']['lines']['height'].values():
3366  vtype = 'lines'
3367  else:
3368  vtype = 'points'
3369 
3370  value = self.FindWindowById(id).GetValue()
3371  slider = self.FindWindowById(self.win['vector'][vtype]['height']['slider'])
3372  self.AdjustSliderRange(slider = slider, value = value)
3373 
3374  for win in self.win['vector'][vtype]['height'].itervalues():
3375  self.FindWindowById(win).SetValue(value)
3376 
3377  data = self.GetLayerData('vector')
3378  data['vector'][vtype]['height'] = { 'value' : value,
3379  'update' : None }
3380 
3381  # update properties
3382 
3383  event = wxUpdateProperties(data = data)
3384  wx.PostEvent(self.mapWindow, event)
3385 
3386  self.mapWindow.render['quick'] = True
3387  self.mapWindow.render['v' + vtype] = True
3388  self.mapWindow.Refresh(False)
3389 
3390  event.Skip()
3391 
3392  def OnVectorHeightFull(self, event):
3393  """!Vector height changed, render in full resolution"""
3394  self.OnVectorHeight(event)
3395 ## self.OnVectorSurface(event)
3396  id = event.GetId()
3397  if id in self.win['vector']['lines']['height'].values():
3398  vtype = 'lines'
3399  else:
3400  vtype = 'points'
3401 
3402  self.mapWindow.render['quick'] = False
3403  self.mapWindow.render['v' + vtype] = False
3404  self.mapWindow.Refresh(False)
3405 
3406  def OnVectorHeightText(self, event):
3407  """!Vector height changed, render in full resolution"""
3408 
3409  # self.OnVectorHeight(event)
3410  self.OnVectorHeightFull(event)
3411 
3412  def OnVectorSurface(self, event):
3413  """!Reference surface for vector map (lines/points)"""
3414  id = event.GetId()
3415  if id == self.win['vector']['lines']['surface']:
3416  vtype = 'lines'
3417  else:
3418  vtype = 'points'
3419  checkList = self.FindWindowById(self.win['vector'][vtype]['surface'])
3420  checked = []
3421  surfaces = []
3422  for items in range(checkList.GetCount()):
3423  checked.append(checkList.IsChecked(items))
3424  surfaces.append(checkList.GetString(items))
3425 
3426  data = self.GetLayerData('vector')
3427  data['vector'][vtype]['mode']['surface'] = { 'value' : surfaces,
3428  'show' : checked}
3429  data['vector'][vtype]['mode']['update'] = None
3430 
3431  # update properties
3432  event = wxUpdateProperties(data = data)
3433  wx.PostEvent(self.mapWindow, event)
3434 
3435  if self.mapDisplay.IsAutoRendered():
3436  self.mapWindow.Refresh(False)
3437 
3438 
3439  def OnVectorPoints(self, event):
3440  """!Set vector points mode, apply changes if auto-rendering is enabled"""
3441  data = self.GetLayerData('vector')
3442 
3443  size = self.FindWindowById(self.win['vector']['points']['size']).GetValue()
3444  marker = self.FindWindowById(self.win['vector']['points']['marker']).GetSelection()
3445  # width = self.FindWindowById(self.win['vector']['points']['width']).GetValue()
3446 
3447  for attrb in ('size', 'marker'):
3448  data['vector']['points'][attrb]['update'] = None
3449  data['vector']['points']['size']['value'] = size
3450  # data['vector']['points']['width']['value'] = width
3451  data['vector']['points']['marker']['value'] = marker
3452 
3453  color = self.FindWindowById(self.win['vector']['points']['color']).GetColour()
3454  if isinstance(color, csel.ColourSelect):
3455  pass #color picker not yet instantiated
3456  else:
3457  color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
3458  data['vector']['points']['color']['update'] = None
3459  data['vector']['points']['color']['value'] = color
3460 
3461  # update properties
3462  event = wxUpdateProperties(data = data)
3463  wx.PostEvent(self.mapWindow, event)
3464 
3465  if self.mapDisplay.IsAutoRendered():
3466  self.mapWindow.Refresh(False)
3467 
3468 
3469  def UpdateIsosurfButtons(self, list):
3470  """!Enable/disable buttons 'add', 'delete',
3471  'move up', 'move down'"""
3472  nitems = list.GetCount()
3473  add = self.parent.FindWindowById(self.win['volume']['btnAdd'])
3474  delete = self.parent.FindWindowById(self.win['volume']['btnDelete'])
3475  moveDown = self.parent.FindWindowById(self.win['volume']['btnMoveDown'])
3476  moveUp = self.parent.FindWindowById(self.win['volume']['btnMoveUp'])
3477  if nitems >= wxnviz.MAX_ISOSURFS:
3478  # disable add button on max
3479  add.Enable(False)
3480  else:
3481  add.Enable(True)
3482 
3483  if nitems < 1:
3484  # disable 'delete' if only one item in the lis
3485  delete.Enable(False)
3486  else:
3487  delete.Enable(True)
3488 
3489  if list.GetSelection() >= nitems - 1:
3490  # disable 'move-down' if last
3491  moveDown.Enable(False)
3492  else:
3493  moveDown.Enable(True)
3494 
3495  if list.GetSelection() < 1:
3496  # disable 'move-up' if first
3497  moveUp.Enable(False)
3498  else:
3499  moveUp.Enable(True)
3500 
3501  def OnVolumeMode(self, event):
3502  """!Change mode isosurfaces/slices"""
3503  mode = self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection()
3504  data = self.GetLayerData('volume')['volume']
3505 
3506  sizer = self.isoPanel.GetContainingSizer()
3507  sizer = self.slicePanel.GetContainingSizer()
3508  listBox = self.FindWindowByName('listStaticBox')
3509  if mode == 0:
3510  sizer.Show(self.isoPanel)
3511  sizer.Hide(self.slicePanel)
3512  listBox.SetLabel(" %s " % _("List of isosurfaces"))
3513  data['draw']['mode']['value'] = 0
3514  data['draw']['mode']['desc'] = 'isosurface'
3515  else:
3516  sizer.Hide(self.isoPanel)
3517  sizer.Show(self.slicePanel)
3518  listBox.SetLabel(" %s " % _("List of slices"))
3519  data['draw']['mode']['value'] = 1
3520  data['draw']['mode']['desc'] = 'slice'
3521 
3522  if event:
3523  name = self.FindWindowById(self.win['volume']['map']).GetValue()
3524  layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
3525  self.UpdateVolumePage(layer, data, updateName = False)
3526 
3527  sizer.Layout()
3528  listBox.GetParent().Fit()
3529 
3530  def OnVolumeDrawMode(self, event):
3531  """!Set isosurface/slice draw mode"""
3532  self.SetVolumeDrawMode(event.GetSelection())
3533 
3534  def SetVolumeDrawMode(self, selection):
3535  """!Set isosurface draw mode"""
3536  data = self.GetLayerData('volume')['volume']
3537  id = data['object']['id']
3538 
3539  mode = 0
3540  if selection == 0:
3541  mode |= wxnviz.DM_FLAT
3542  else:
3543  mode |= wxnviz.DM_GOURAUD
3544 
3545  if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
3546  self._display.SetIsosurfaceMode(id, mode)
3547  data['draw']['shading']['isosurface']['desc'] = 'gouraud'
3548  data['draw']['shading']['isosurface']['value'] = mode
3549  else:
3550  self._display.SetSliceMode(id, mode)
3551  data['draw']['shading']['slice']['desc'] = 'flat'
3552  data['draw']['shading']['slice']['value'] = mode
3553 
3554  if self.mapDisplay.IsAutoRendered():
3555  self.mapWindow.Refresh(False)
3556 
3557  def OnVolumeResolution(self, event):
3558  """!Set isosurface/slice draw resolution"""
3559  self.SetVolumeResolution(event.GetInt())
3560 
3561  def SetVolumeResolution(self, res):
3562  """!Set isosurface draw resolution"""
3563  data = self.GetLayerData('volume')['volume']
3564  id = data['object']['id']
3565 
3566  if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
3567  self._display.SetIsosurfaceRes(id, res)
3568  data['draw']['resolution']['isosurface']['value'] = res
3569  else:
3570  self._display.SetSliceRes(id, res)
3571  data['draw']['resolution']['slice']['value'] = res
3572 
3573  if self.mapDisplay.IsAutoRendered():
3574  self.mapWindow.Refresh(False)
3575 
3576  def OnInOutMode(self, event):
3577  """!Change isosurfaces mode inout"""
3578  data = self.GetLayerData('volume')['volume']
3579  id = data['object']['id']
3580  isosurfId = self.FindWindowById(self.win['volume']['isosurfs']).GetSelection()
3581 
3582  ret = self._display.SetIsosurfaceInOut(id, isosurfId, event.GetInt())
3583  if ret == 1:
3584  data['isosurface'][isosurfId]['inout'] = event.GetInt()
3585 
3586  if self.mapDisplay.IsAutoRendered():
3587  self.mapWindow.Refresh(False)
3588 
3589 
3590  def OnVolumeIsosurfMap(self, event):
3591  """!Set surface attribute"""
3592  if self.vetoGSelectEvt:
3593  self.vetoGSelectEvt = False
3594  return
3595  self.SetMapObjAttrb(nvizType = 'volume', winId = event.GetId())
3596 
3597  def OnVolumeCheck(self, event):
3598  """!Isosurface/slice checked (->load) or unchecked (->unload)"""
3599  if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
3600  mode = 'isosurf'
3601  else:
3602  mode = 'slice'
3603  index = event.GetSelection()
3604  list = self.FindWindowById(self.win['volume'][mode + 's'])
3605 
3606  data = self.GetLayerData('volume')['volume']
3607  vid = data['object']['id']
3608 
3609  id = event.GetSelection()
3610 
3611  if mode == 'isosurf':
3612  if list.IsChecked(index):
3613  if 'transp' in data['isosurface'][id] and\
3614  data['isosurface'][id]['transp']['map'] is not None:
3615  if data['isosurface'][id]['transp']['map']:
3616  map = True
3617  value = data['isosurface'][id]['transp']['value']
3618  elif data['isosurface'][id]['transp']['map'] is not None:
3619  map = False
3620  value = data['isosurface'][id]['transp']['value']
3621  self._display.SetIsosurfaceTransp(vid, id, map, value)
3622  else:
3623  self._display.SetIsosurfaceTransp(vid, id, False, "0")
3624  else:
3625  # disable -> make transparent
3626  self._display.SetIsosurfaceTransp(vid, id, False, "255")
3627  else:
3628  if list.IsChecked(index):
3629  value = data['slice'][id]['transp']['value']
3630  self._display.SetSliceTransp(vid, id, value)
3631  else:
3632  # disable -> make transparent
3633  self._display.SetSliceTransp(vid, id, 255)
3634 
3635  if self.mapDisplay.IsAutoRendered():
3636  self.mapWindow.Refresh(False)
3637 
3638  def OnVolumeSelect(self, event):
3639  """!Isosurface/Slice item selected"""
3640  if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
3641  mode = 'isosurf'
3642  else:
3643  mode = 'slice'
3644 
3645  winUp = self.FindWindowById(self.win['volume']['btnMoveUp'])
3646  winDown = self.FindWindowById(self.win['volume']['btnMoveDown'])
3647  selection = event.GetSelection()
3648  if selection == -1:
3649  return
3650  elif selection == 0:
3651  winUp.Enable(False)
3652  if not winDown.IsEnabled():
3653  winDown.Enable()
3654  elif selection == self.FindWindowById(event.GetId()).GetCount() - 1:
3655  winDown.Enable(False)
3656  if not winUp.IsEnabled():
3657  winUp.Enable()
3658  else:
3659  if not winDown.IsEnabled():
3660  winDown.Enable()
3661  if not winUp.IsEnabled():
3662  winUp.Enable()
3663 
3664  # update dialog
3665  name = self.FindWindowById(self.win['volume']['map']).GetValue()
3666  layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
3667 
3668  if mode == 'isosurf':
3669  data = self.GetLayerData('volume')['volume']['isosurface'][selection]
3670  self.UpdateVolumeIsosurfPage(data)
3671  else:
3672  data = self.GetLayerData('volume')['volume']['slice'][selection]
3673  self.UpdateVolumeSlicePage(data)
3674 
3675 
3676 
3677  def OnVolumeAdd(self, event):
3678  """!Add new isosurface/slice to the list"""
3679  if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
3680  mode = 'isosurf'
3681  else:
3682  mode = 'slice'
3683  list = self.FindWindowById(self.win['volume'][mode + 's'])
3684 
3685  name = self.FindWindowById(self.win['volume']['map']).GetValue()
3686  layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
3687  data = self.GetLayerData('volume')['volume']
3688  id = data['object']['id']
3689 
3690  sel = list.GetSelection()
3691  if mode == 'isosurf':
3692  isosurfData = self.mapWindow.nvizDefault.SetIsosurfaceDefaultProp()
3693  if isosurfData['color']['map']:
3694  isosurfData['color']['value'] = layer.name
3695 
3696  level = isosurfData['topo']['value'] = round(self._get3dRange(name = layer.name)[0], 2)
3697 
3698  if sel < 0 or sel >= list.GetCount() - 1:
3699  item = list.Append(item = "%s %s" % (_("Level"), str(level)))
3700  else:
3701  list.Insert(item = "%s %s" % (_("Level"), str(level)),
3702  pos = sel+1) # append
3703  item = sel + 1
3704  else:
3705  sliceData = self.mapWindow.nvizDefault.SetSliceDefaultProp()
3706  axis = ("X", "Y", "Z")[sliceData['position']['axis']]
3707  if sel < 0 or sel >= list.GetCount() - 1:
3708  item = list.Append(item = "%s %s" % (_("Slice parallel to"), axis))
3709  else:
3710  list.Insert(item = "%s" % (_("Slice parallel to"), axis),
3711  pos = sel+1) # append
3712  item = sel + 1
3713 
3714  list.Check(item)
3715  list.SetSelection(item)
3716 
3717  if mode == 'isosurf':
3718  data['isosurface'].insert(item, isosurfData)
3719  # add isosurface
3720  self._display.AddIsosurface(id, float(level))
3721  else:
3722  data['slice'].insert(item, sliceData)
3723  # add isosurface
3724  nslice = self._display.AddSlice(id)
3725  self._display.SetSlicePosition(id, nslice -1, sliceData['position']['x1'], sliceData['position']['x2'],
3726  sliceData['position']['y1'], sliceData['position']['y2'],
3727  sliceData['position']['z1'], sliceData['position']['z2'],
3728  sliceData['position']['axis'])
3729  # update properties
3730  event = wxUpdateProperties(data = data)
3731  wx.PostEvent(self.mapWindow, event)
3732 
3733  # update buttons
3734  self.UpdateIsosurfButtons(list)
3735  if mode == 'isosurf':
3736  self.UpdateVolumeIsosurfPage(isosurfData)
3737  else:
3738  self.UpdateVolumeSlicePage(sliceData)
3739 
3740  if self.mapDisplay.IsAutoRendered():
3741  self.mapWindow.Refresh(False)
3742 
3743  event.Skip()
3744 
3745  def OnVolumeDelete(self, event):
3746  """!Remove isosurface/slice from list"""
3747  if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
3748  mode = 'isosurf'
3749  else:
3750  mode = 'slice'
3751  list = self.FindWindowById(self.win['volume'][mode + 's'])
3752 
3753  # remove item from list
3754  id = list.GetSelection()
3755  list.Delete(id)
3756  # select last item
3757  if list.GetCount() > 0:
3758  list.SetSelection(list.GetCount()-1)
3759 
3760  name = self.FindWindowById(self.win['volume']['map']).GetValue()
3761  layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
3762  data = self.GetLayerData('volume')['volume']
3763 
3764  vid = data['object']['id']
3765 
3766  # delete isosurface
3767  if mode == 'isosurf':
3768  del data['isosurface'][id]
3769  self._display.DeleteIsosurface(vid, id)
3770  else:
3771  del data['slice'][id]
3772  self._display.DeleteSlice(vid, id)
3773 
3774  # update buttons
3775  if list.GetCount() > 0:
3776  if mode == 'isosurf':
3777  self.UpdateVolumeIsosurfPage(data['isosurface'][list.GetSelection()])
3778  else:
3779  self.UpdateVolumeSlicePage(data['slice'][list.GetSelection()])
3780  else:
3781  if mode == 'isosurf':
3782  self.UpdateVolumeIsosurfPage(data['attribute'])
3783  else:
3784  self.UpdateVolumeSlicePage(None)
3785  self.UpdateIsosurfButtons(list)
3786 
3787  if self.mapDisplay.IsAutoRendered():
3788  self.mapWindow.Refresh(False)
3789 
3790  event.Skip()
3791 
3792  def OnVolumeMoveUp(self, event):
3793  """!Move isosurface/slice up in the list"""
3794  if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
3795  mode = 'isosurf'
3796  else:
3797  mode = 'slice'
3798  list = self.FindWindowById(self.win['volume'][mode + 's'])
3799  sel = list.GetSelection()
3800 
3801  if sel < 1:
3802  return # this should not happen
3803 
3804  name = self.FindWindowById(self.win['volume']['map']).GetValue()
3805  layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
3806  data = self.GetLayerData('volume')['volume']
3807 
3808  id = data['object']['id']
3809 
3810  # move item up
3811  text = list.GetStringSelection()
3812  list.Insert(item = text, pos = sel-1)
3813  list.Check(sel-1)
3814  list.SetSelection(sel-1)
3815  list.Delete(sel+1)
3816  if mode == 'isosurf':
3817  data['isosurface'].insert(sel-1, data['isosurface'][sel])
3818  del data['isosurface'][sel+1]
3819  self._display.MoveIsosurface(id, sel, True)
3820  else:
3821  data['slice'].insert(sel-1, data['slice'][sel])
3822  del data['slice'][sel+1]
3823  self._display.MoveSlice(id, sel, True)
3824 
3825  # update buttons
3826  self.UpdateIsosurfButtons(list)
3827 
3828  if self.mapDisplay.IsAutoRendered():
3829  self.mapWindow.Refresh(False)
3830 
3831  event.Skip()
3832 
3833  def OnVolumeMoveDown(self, event):
3834  """!Move isosurface/slice down in the list"""
3835  if self.FindWindowById(self.win['volume']['draw']['mode']).GetSelection() == 0:
3836  mode = 'isosurf'
3837  else:
3838  mode = 'slice'
3839  list = self.FindWindowById(self.win['volume'][mode + 's'])
3840  sel = list.GetSelection()
3841 
3842  if sel >= list.GetCount() - 1:
3843  return # this should not happen
3844 
3845  name = self.FindWindowById(self.win['volume']['map']).GetValue()
3846  layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
3847  data = self.GetLayerData('volume')['volume']
3848 
3849  id = data['object']['id']
3850 
3851  # move item up
3852  text = list.GetStringSelection()
3853  list.Insert(item = text, pos = sel+2)
3854  list.Check(sel+2)
3855  list.SetSelection(sel+2)
3856  list.Delete(sel)
3857  if mode == 'isosurf':
3858  data['isosurface'].insert(sel+2, data['isosurface'][sel])
3859  del data['isosurface'][sel]
3860  self._display.MoveIsosurface(id, sel, False)
3861  else:
3862  data['slice'].insert(sel+2, data['slice'][sel])
3863  del data['slice'][sel]
3864  self._display.MoveSlice(id, sel, False)
3865 
3866  # update buttons
3867  self.UpdateIsosurfButtons(list)
3868 
3869  if self.mapDisplay.IsAutoRendered():
3870  self.mapWindow.Refresh(False)
3871 
3872  event.Skip()
3873 
3874  def OnVolumePositionChanged(self, event):
3875  """!Volume position changed"""
3876  self.mapWindow.render['quick'] = False
3877  self.mapWindow.Refresh(False)
3878 
3879  def OnVolumePosition(self, event):
3880  """!Volume position"""
3881  winName = self.__GetWindowName(self.win['volume'], event.GetId())
3882  if not winName:
3883  return
3884  axis = self.FindWindowById(self.win['volume']['position']['axis']).GetSelection()
3885 
3886  value = self.FindWindowById(event.GetId()).GetValue()
3887  slider = self.FindWindowById(self.win['volume'][winName]['slider'])
3888  self.AdjustSliderRange(slider = slider, value = value)
3889 
3890  for win in self.win['volume']['position'].itervalues():
3891  if win in (self.win['volume']['position']['axis'],
3892  self.win['volume']['position']['reset']):
3893  continue
3894  else:
3895  self.FindWindowById(win).SetValue(value)
3896 
3897  data = self.GetLayerData('volume')
3898  id = data['volume']['object']['id']
3899  x, y, z = self._display.GetVolumePosition(id)
3900 
3901  if axis == 0: # x
3902  x = value
3903  elif axis == 1: # y
3904  y = value
3905  else: # z
3906  z = value
3907 
3908  data['volume']['position']['x'] = x
3909  data['volume']['position']['y'] = y
3910  data['volume']['position']['z'] = z
3911  data['volume']['position']['update'] = None
3912  # update properties
3913 
3914  event = wxUpdateProperties(data = data)
3915  wx.PostEvent(self.mapWindow, event)
3916 
3917  self.mapWindow.render['quick'] = True
3918  if self.mapDisplay.IsAutoRendered():
3919  self.mapWindow.Refresh(False)
3920 
3921  def OnVolumeAxis(self, event):
3922  """!Volume position, axis changed"""
3923  data = self.GetLayerData('volume')
3924  id = data['volume']['object']['id']
3925 
3926  axis = self.FindWindowById(self.win['volume']['position']['axis']).GetSelection()
3927  slider = self.FindWindowById(self.win['volume']['position']['slider'])
3928  text = self.FindWindowById(self.win['volume']['position']['text'])
3929  xydim = self._display.GetLongDim()
3930  zdim = self._display.GetZRange()
3931  zdim = zdim[1] - zdim[0]
3932  x, y, z = self._display.GetVolumePosition(id)
3933 
3934  if axis == 0: # x
3935  slider.SetRange(-3 * xydim, 3 * xydim)
3936  slider.SetValue(x)
3937  text.SetValue(x)
3938  elif axis == 1: # y
3939  slider.SetRange(-3 * xydim, 3 * xydim)
3940  slider.SetValue(y)
3941  text.SetValue(y)
3942  else: # z
3943  slider.SetRange(-3 * zdim, 3 * zdim)
3944  slider.SetValue(z)
3945  text.SetValue(z)
3946 
3947  def OnVolumePositionText(self, event):
3948  """!Volume position changed by textctrl"""
3949  self.OnVolumePosition(event)
3950  self.OnVolumePositionChanged(None)
3951 
3952  def OnResetVolumePosition(self, event):
3953  """!Reset position of volume"""
3954  for win in self.win['volume']['position'].itervalues():
3955  if win == self.win['volume']['position']['axis']:
3956  self.FindWindowById(win).SetSelection(2) # Z
3957  elif win == self.win['volume']['position']['reset']:
3958  continue
3959  else:
3960  self.FindWindowById(win).SetValue(0)
3961 
3962  data = self.GetLayerData('volume')
3963  data['volume']['position']['x'] = 0
3964  data['volume']['position']['y'] = 0
3965  data['volume']['position']['z'] = 0
3966  data['volume']['position']['update'] = None
3967  # update properties
3968  event = wxUpdateProperties(data = data)
3969  wx.PostEvent(self.mapWindow, event)
3970 
3971  if self.mapDisplay.IsAutoRendered():
3972  self.mapWindow.Refresh(False)
3973 
3974  def OnVolumeSliceAxes(self, event):
3975  """!Slice axis changed"""
3976  self.UpdateSliceLabels()
3977  data = self.GetLayerData('volume')
3978  list = self.FindWindowById(self.win['volume']['slices'])
3979  sel = list.GetSelection()
3980  if sel < 0:
3981  return
3982  axis = self.FindWindowById(self.win['volume']['slice']['axes']).GetSelection()
3983  data['volume']['slice'][sel]['position']['axis'] = axis
3984  data['volume']['slice'][sel]['position']['update'] = None
3985 
3986  axis = ("X", "Y", "Z")[axis]
3987  list.SetString(sel, "%s %s" % (_("Slice parallel to"), axis))
3988  list.Check(sel)
3989 
3990  # update properties
3991  event = wxUpdateProperties(data = data)
3992  wx.PostEvent(self.mapWindow, event)
3993 
3994  if self.mapDisplay.IsAutoRendered():
3995  self.mapWindow.Refresh(False)
3996 
3997  def OnSliceTransparency(self, event):
3998  """!Slice transparency changed"""
3999  data = self.GetLayerData('volume')
4000 
4001  list = self.FindWindowById(self.win['volume']['slices'])
4002  sel = list.GetSelection()
4003  if sel < 0:
4004  return
4005 
4006  val = self.FindWindowById(self.win['volume']['slice']['transp']).GetValue()
4007  data['volume']['slice'][sel]['transp']['value'] = self._getPercent(val, toPercent = False)
4008  data['volume']['slice'][sel]['transp']['update'] = None
4009 
4010  # update properties
4011  event = wxUpdateProperties(data = data)
4012  wx.PostEvent(self.mapWindow, event)
4013 
4014  if self.mapDisplay.IsAutoRendered():
4015  self.mapWindow.Refresh(False)
4016 
4017  def OnSliceReset(self, event):
4018  """!Slice position reset"""
4019  data = self.GetLayerData('volume')
4020 
4021  list = self.FindWindowById(self.win['volume']['slices'])
4022  sel = list.GetSelection()
4023  if sel < 0:
4024  return
4025 
4026  for coord, val in zip(('x1', 'x2', 'y1', 'y2', 'z1', 'z2'),(0, 1, 0, 1, 0, 1, 0)):
4027  data['volume']['slice'][sel]['position'][coord] = val
4028  data['volume']['slice'][sel]['position']['update'] = None
4029 
4030  self.UpdateVolumeSlicePage(data['volume']['slice'][sel])
4031  # update properties
4032  event = wxUpdateProperties(data = data)
4033  wx.PostEvent(self.mapWindow, event)
4034 
4035  if self.mapDisplay.IsAutoRendered():
4036  self.mapWindow.Refresh(False)
4037 
4038  def OnSlicePositionChange(self, event):
4039  """!Slice position is changing"""
4040  data = self.GetLayerData('volume')
4041  list = self.FindWindowById(self.win['volume']['slices'])
4042  sel = list.GetSelection()
4043  if sel < 0:
4044  return
4045  win = self.win['volume']['slice']
4046  winId = event.GetId()
4047  value = event.GetInt()/100.
4048 
4049  for coord in ('x1', 'x2', 'y1', 'y2', 'z1', 'z2'):
4050  if win['slider_' + coord] == winId:
4051  data['volume']['slice'][sel]['position'][coord] = value
4052  data['volume']['slice'][sel]['position']['update'] = None
4053  break
4054  self.mapWindow.render['quick'] = True
4055  # update properties
4056  event = wxUpdateProperties(data = data)
4057  wx.PostEvent(self.mapWindow, event)
4058 
4059  if self.mapDisplay.IsAutoRendered():
4060  self.mapWindow.Refresh(False)
4061 
4062  def OnSlicePositionChanged(self, event):
4063  """!Slice position is changed"""
4064  self.mapWindow.render['quick'] = False
4065  if self.mapDisplay.IsAutoRendered():
4066  self.mapWindow.Refresh(False)
4067 
4068  def OnCPlaneSelection(self, event):
4069  """!Cutting plane selected"""
4070  plane = self.FindWindowById(self.win['cplane']['planes']).GetStringSelection()
4071  try:
4072  planeIndex = int(plane.split()[-1]) - 1
4073  self.EnablePage("cplane", enabled = True)
4074  except:
4075  planeIndex = -1
4076  self.EnablePage("cplane", enabled = False)
4077  self.mapWindow.SelectCPlane(planeIndex)
4078  if planeIndex >= 0:
4079  self.mapWindow.UpdateCPlane(planeIndex, changes = ['rotation', 'position', 'shading'])
4080 
4081  if self.mapDisplay.IsAutoRendered():
4082  self.mapWindow.Refresh(False)
4083  self.UpdateCPlanePage(planeIndex)
4084 
4085  def OnCPlaneChanging(self, event):
4086  """!Cutting plane is changing"""
4087  plane = self.FindWindowById(self.win['cplane']['planes']).GetStringSelection()
4088  try:
4089  planeIndex = int(plane.split()[-1]) - 1
4090  except:#TODO disabled page
4091  planeIndex = -1
4092 
4093  if event.GetId() in (self.win['cplane']['rotation']['rot'].values() +
4094  self.win['cplane']['rotation']['tilt'].values()):
4095  action = 'rotation'
4096  else:
4097  action = 'position'
4098  data = self.mapWindow.cplanes[planeIndex][action]
4099  self.OnScroll(event, self.win['cplane'][action], data)
4100 
4101  self.mapWindow.render['quick'] = True
4102  event = wxUpdateCPlane(update = (action,), current = planeIndex)
4103  wx.PostEvent(self.mapWindow, event)
4104 
4105  if self.mapDisplay.IsAutoRendered():
4106  self.mapWindow.Refresh(False)
4107 
4108  def OnCPlaneChangeDone(self, event):
4109  """!Cutting plane change done"""
4110  self.mapWindow.render['quick'] = False
4111  if self.mapDisplay.IsAutoRendered():
4112  self.mapWindow.Refresh(False)
4113 
4114  def OnCPlaneChangeText(self, event):
4115  """!Cutting plane changed by textctrl"""
4116  for axis in ('x', 'y', 'z'):
4117  if event.GetId() == self.win['cplane']['position'][axis]['text']:
4118  value = self.FindWindowById(event.GetId()).GetValue()
4119  slider = self.FindWindowById(self.win['cplane']['position'][axis]['slider'])
4120  self.AdjustSliderRange(slider = slider, value = value)
4121  self.OnCPlaneChanging(event = event)
4122  self.OnCPlaneChangeDone(None)
4123 
4124  def OnCPlaneShading(self, event):
4125  """!Cutting plane shading changed"""
4126  shading = self.FindWindowById(self.win['cplane']['shading']).GetSelection()
4127  plane = self.FindWindowById(self.win['cplane']['planes']).GetStringSelection()
4128  try:
4129  planeIndex = int(plane.split()[-1]) - 1
4130  except:#TODO disabled page
4131  planeIndex = -1
4132 
4133  self.mapWindow.cplanes[planeIndex]['shading'] = shading
4134 
4135  event = wxUpdateCPlane(update = ('shading',), current = planeIndex)
4136  wx.PostEvent(self.mapWindow, event)
4137 
4138  self.OnCPlaneChangeDone(None)
4139 
4140  def OnCPlaneReset(self, event):
4141  """!Reset current cutting plane"""
4142  plane = self.FindWindowById(self.win['cplane']['planes']).GetStringSelection()
4143  try:
4144  planeIndex = int(plane.split()[-1]) - 1
4145  except:#TODO disabled page
4146  planeIndex = -1
4147 
4148  self.mapWindow.cplanes[planeIndex] = copy.deepcopy(UserSettings.Get(group = 'nviz',
4149  key = 'cplane'))
4150  self.mapWindow.cplanes[planeIndex]['on'] = True
4151  event = wxUpdateCPlane(update = ('position','rotation','shading'), current = planeIndex)
4152  wx.PostEvent(self.mapWindow, event)
4153  self.OnCPlaneChangeDone(None)
4154  self.UpdateCPlanePage(planeIndex)
4155 
4156  def OnDecorationPlacement(self, event):
4157  """!Place an arrow/scalebar by clicking on display"""
4158  if event.GetId() == self.win['decoration']['arrow']['place']:
4159  type = 'arrow'
4160  elif event.GetId() == self.win['decoration']['scalebar']['place']:
4161  type = 'scalebar'
4162  else: return
4163 
4164  if event.GetInt():
4165  self.mapDisplay.Raise()
4166  self.mapWindow.mouse['use'] = type
4167  self.mapWindow.SetCursor(self.mapWindow.cursors["cross"])
4168  else:
4169  self.mapWindow.mouse['use'] = 'default'
4170  self.mapWindow.SetCursor(self.mapWindow.cursors["default"])
4171 
4172  def OnArrowDelete(self, event):
4173  """!Delete arrow"""
4174  self._display.DeleteArrow()
4175  self.mapWindow.decoration['arrow']['show'] = False
4176  self.mapWindow.Refresh(False)
4177 
4178  def OnScalebarDelete(self, event):
4179  """!Delete scalebar"""
4180  try:
4181  id = self.mapWindow.decoration['scalebar'][-1]['id']
4182  except IndexError:
4183  return
4184  self._display.DeleteScalebar(id = id)
4185  del self.mapWindow.decoration['scalebar'][-1]
4186 
4187  self.mapWindow.Refresh(False)
4188 
4189  def OnDecorationProp(self, event):
4190  """!Set arrow/scalebar properties"""
4191  if event.GetId() in self.win['decoration']['arrow'].values():
4192  type = 'arrow'
4193  elif event.GetId() in self.win['decoration']['scalebar'].values():
4194  type = 'scalebar'
4195  else: return
4196 
4197  color = self.FindWindowById(self.win['decoration'][type]['color']).GetValue()
4198  size = self.FindWindowById(self.win['decoration'][type]['size']).GetValue()
4199  if type == 'arrow':
4200  self.mapWindow.decoration[type]['color'] = self._getColorString(color)
4201  self.mapWindow.decoration[type]['size'] = size
4202  elif type == 'scalebar'and self.mapWindow.decoration['scalebar']:
4203  self.mapWindow.decoration[type][-1]['color'] = self._getColorString(color)
4204  self.mapWindow.decoration[type][-1]['size'] = size
4205 
4206  if type == 'arrow' and self.mapWindow.decoration['arrow']['show']:
4207  self._display.SetArrow(self.mapWindow.decoration['arrow']['position']['x'],
4208  self.mapWindow.decoration['arrow']['position']['y'],
4209  self.mapWindow.decoration['arrow']['size'],
4210  self.mapWindow.decoration['arrow']['color'])
4211  self._display.DrawArrow()
4212  elif type == 'scalebar' and self.mapWindow.decoration['scalebar']:
4213  self._display.SetScalebar(self.mapWindow.decoration['scalebar'][-1]['id'],
4214  self.mapWindow.decoration['scalebar'][-1]['position']['x'],
4215  self.mapWindow.decoration['scalebar'][-1]['position']['y'],
4216  self.mapWindow.decoration['scalebar'][-1]['size'],
4217  self.mapWindow.decoration['scalebar'][-1]['color'])
4218  self._display.DrawScalebar()
4219  self.mapWindow.Refresh(False)
4220 
4221  def UpdatePage(self, pageId):
4222  """!Update dialog (selected page)"""
4223  self.pageChanging = True
4224  Debug.msg(1, "NvizToolWindow.UpdatePage(): %s", pageId)
4225 
4226  if pageId == 'view':
4227  self.SetPage('view')
4228  hmin = self.mapWindow.iview['height']['min']
4229  hmax = self.mapWindow.iview['height']['max']
4230  hval = self.mapWindow.iview['height']['value']
4231  zmin = self.mapWindow.view['z-exag']['min']
4232  zmax = self.mapWindow.view['z-exag']['max']
4233  zval = self.mapWindow.view['z-exag']['value']
4234 
4235  for control in ('slider','text'):
4236  try:
4237  self.FindWindowById(self.win['view']['height'][control]).SetRange(
4238  hmin, hmax)
4239  except OverflowError:
4240  hmin = self.mapWindow.iview['height']['min'] = 0
4241  hmax = self.mapWindow.iview['height']['max'] = 10000
4242  hval = self.mapWindow.iview['height']['value'] = 5000
4243  self.FindWindowById(self.win['view']['height'][control]).SetRange(hmin, hmax)
4244  self.FindWindowById(self.win['view']['z-exag'][control]).SetRange(
4245  zmin, zmax)
4246  self.FindWindowById(self.win['view']['height'][control]).SetValue(hval)
4247 
4248  self.FindWindowById(self.win['view']['z-exag'][control]).SetValue(zval)
4249 
4250  self.FindWindowById(self.win['view']['background']['color']).SetColour(\
4251  self.mapWindow.view['background']['color'])
4252 
4253  tval = self.mapWindow.view['twist']['value']
4254  pval = self.mapWindow.view['persp']['value']
4255  for control in ('slider','text'):
4256  self.FindWindowById(self.win['view']['twist'][control]).SetValue(tval)
4257 
4258  self.FindWindowById(self.win['view']['persp'][control]).SetValue(pval)
4259 
4260 
4261  elif pageId in ('surface', 'vector', 'volume'):
4262  name = self.FindWindowById(self.win[pageId]['map']).GetValue()
4263  data = self.GetLayerData(pageId)
4264  if data:
4265  if pageId == 'surface':
4266  layer = self.mapWindow.GetLayerByName(name, mapType = 'raster')
4267  if layer:
4268  self.UpdateSurfacePage(layer, data['surface'])
4269  elif pageId == 'vector':
4270  layer = self.mapWindow.GetLayerByName(name, mapType = 'vector')
4271  if layer:
4272  self.UpdateVectorPage(layer, data['vector'])
4273  elif pageId == 'volume':
4274  layer = self.mapWindow.GetLayerByName(name, mapType = '3d-raster')
4275  if layer:
4276  self.UpdateVolumePage(layer, data['volume'])
4277  elif pageId == 'light':
4278  zval = self.mapWindow.light['position']['z']
4279  bval = self.mapWindow.light['bright']
4280  aval = self.mapWindow.light['ambient']
4281  for control in ('slider','text'):
4282  self.FindWindowById(self.win['light']['z'][control]).SetValue(zval)
4283  self.FindWindowById(self.win['light']['bright'][control]).SetValue(bval)
4284  self.FindWindowById(self.win['light']['ambient'][control]).SetValue(aval)
4285  self.FindWindowById(self.win['light']['color']).SetColour(self.mapWindow.light['color'])
4286  self.FindWindowById(self.win['light']['position']).PostDraw()
4287  elif pageId == 'fringe':
4288  win = self.FindWindowById(self.win['fringe']['map'])
4289  win.SetValue(self.FindWindowById(self.win['surface']['map']).GetValue())
4290  elif pageId == 'decoration':
4291  win = self.FindWindowById(self.win['decoration']['arrow']['size'])
4292  win.SetValue(self.mapWindow.decoration['arrow']['size'])
4293  win = self.FindWindowById(self.win['decoration']['scalebar']['size'])
4294  win.SetValue(self.mapWindow._getDecorationSize())
4295  elif pageId == 'constant':
4296  if self.mapWindow.constants:
4297  surface = self.FindWindowById(self.win['constant']['surface'])
4298  for item in self.mapWindow.constants:
4299  surface.Append(_("constant#") + str(item['constant']['object']['name']))
4300  surface.SetSelection(0)
4301  self.OnConstantSelection(None)
4302  self.EnablePage('constant', True)
4303  elif pageId == 'cplane':
4304  count = self._display.GetCPlanesCount()
4305  choices = [_("None"),]
4306  for plane in range(count):
4307  choices.append("%s %i" % (_("Plane"), plane+1))
4308  self.FindWindowById(self.win['cplane']['planes']).SetItems(choices)
4309  current = 0
4310  for i, cplane in enumerate(self.mapWindow.cplanes):
4311  if cplane['on']:
4312  current = i + 1
4313  self.FindWindowById(self.win['cplane']['planes']).SetSelection(current)
4314 
4315  xyRange, zRange = self._display.GetXYRange(), self._display.GetZRange()
4316  if xyRange > 0: # GTK warning
4317  self.FindWindowById(self.win['cplane']['position']['x']['slider']).SetRange(
4318  -xyRange/2., xyRange/2.)
4319  self.FindWindowById(self.win['cplane']['position']['y']['slider']).SetRange(
4320  -xyRange/2., xyRange/2.)
4321  if zRange[1] - zRange[0] > 1:
4322  self.FindWindowById(self.win['cplane']['position']['z']['slider']).SetRange(zRange[0], zRange[1])
4323  self.FindWindowById(self.win['cplane']['position']['z']['slider']).SetValue(zRange[0])
4324  self.FindWindowById(self.win['cplane']['position']['z']['text']).SetValue(zRange[0])
4325  self.OnCPlaneSelection(None)
4326 
4327  elif pageId == 'animation':
4328  self.UpdateAnimationPage()
4329 
4330  self.Update()
4331  self.pageChanging = False
4332 
4334  """!Update animation page"""
4335  # wrap help text according to tool window
4336  help = self.FindWindowById(self.win['anim']['help'])
4337  width = help.GetGrandParent().GetSizeTuple()[0]
4338  help.Wrap(width - 15)
4339  anim = self.mapWindow.GetAnimation()
4340  if anim.Exists():
4341  self.FindWindowById(self.win['anim']['play']).Enable()
4342  else:
4343  self.UpdateFrameIndex(index = 0)
4344 
4345  self.UpdateFrameCount()
4346 
4347  self.FindWindowById(self.win['anim']['play']).Disable()
4348  self.FindWindowById(self.win['anim']['record']).Enable()
4349  self.FindWindowById(self.win['anim']['pause']).Disable()
4350  self.FindWindowById(self.win['anim']['stop']).Disable()
4351  self.FindWindowById(self.win['anim']['frameIndex']['slider']).Disable()
4352  self.FindWindowById(self.win['anim']['frameIndex']['text']).Disable()
4353 
4354  def UpdateCPlanePage(self, index):
4355  """!Update widgets according to selected clip plane"""
4356  if index == -1:
4357  return
4358  data = self.mapWindow.cplanes[index]
4359  for widget in ('text', 'slider'):
4360  for axes in ('x', 'y', 'z'):
4361  self.FindWindowById(self.win['cplane']['position'][axes][widget]).SetValue(data['position'][axes])
4362  for each in ('tilt', 'rot'):
4363  self.FindWindowById(self.win['cplane']['rotation'][each][widget]).SetValue(data['rotation'][each])
4364  self.FindWindowById(self.win['cplane']['shading']).SetSelection(data['shading'])
4365 
4366  def UpdateSurfacePage(self, layer, data, updateName = True):
4367  """!Update surface page"""
4368  desc = grass.raster_info(layer.name)['title']
4369  if updateName:
4370  self.FindWindowById(self.win['surface']['map']).SetValue(layer.name)
4371  self.FindWindowById(self.win['surface']['desc']).SetLabel(desc)
4372 
4373  # attributes
4374  if layer and layer.type == 'raster':
4375  self.vetoGSelectEvt = True
4376  self.FindWindowById(self.win['surface']['color']['map']).SetValue(layer.name)
4377  else:
4378  self.FindWindowById(self.win['surface']['color']['map']).SetValue('')
4379 
4380  self.SetMapObjUseMap(nvizType = 'surface',
4381  attrb = 'color', map = True) # -> map
4382 
4383  if 'color' in data['attribute']:
4384  value = data['attribute']['color']['value']
4385 
4386  if data['attribute']['color']['map']:
4387  self.FindWindowById(self.win['surface']['color']['map']).SetValue(value)
4388  else: # constant
4389  color = map(int, value.split(':'))
4390  self.FindWindowById(self.win['surface']['color']['const']).SetColour(color)
4391  self.SetMapObjUseMap(nvizType = 'surface',
4392  attrb = 'color', map = data['attribute']['color']['map'])
4393 
4394  self.SetMapObjUseMap(nvizType = 'surface',
4395  attrb = 'shine', map = data['attribute']['shine']['map'])
4396  value = data['attribute']['shine']['value']
4397  if data['attribute']['shine']['map']:
4398  self.FindWindowById(self.win['surface']['shine']['map']).SetValue(value)
4399  else:
4400  self.FindWindowById(self.win['surface']['shine']['const']).SetValue(self._getPercent(value))
4401  if 'transp' in data['attribute']:
4402  value = data['attribute']['transp']['value']
4403  if data['attribute']['transp']['map']:
4404  self.FindWindowById(self.win['surface']['color']['map']).SetValue(value)
4405  else:
4406  self.FindWindowById(self.win['surface']['transp']['const']).SetValue(self._getPercent(value))
4407  self.SetMapObjUseMap(nvizType = 'surface', attrb = 'transp', map = data['attribute']['transp']['map'])
4408  else:
4409  self.SetMapObjUseMap(nvizType = 'surface', attrb = 'transp', map = None)
4410  #
4411  # draw
4412  #
4413  for control, drawData in data['draw'].iteritems():
4414  if control == 'all': # skip 'all' property
4415  continue
4416  if control == 'resolution':
4417  self.FindWindowById(self.win['surface']['draw']['res-coarse']).SetValue(drawData['coarse'])
4418  self.FindWindowById(self.win['surface']['draw']['res-fine']).SetValue(drawData['fine'])
4419  continue
4420 
4421  if control == 'mode':
4422  if drawData['desc']['mode'] == 'coarse':
4423  self.FindWindowById(self.win['surface']['draw']['mode']).SetSelection(0)
4424  elif drawData['desc']['mode'] == 'fine':
4425  self.FindWindowById(self.win['surface']['draw']['mode']).SetSelection(1)
4426  else: # both
4427  self.FindWindowById(self.win['surface']['draw']['mode']).SetSelection(2)
4428 
4429  if drawData['desc']['style'] == 'wire':
4430  self.FindWindowById(self.win['surface']['draw']['style']).SetSelection(0)
4431  else: # surface
4432  self.FindWindowById(self.win['surface']['draw']['style']).SetSelection(1)
4433 
4434  if drawData['desc']['shading'] == 'flat':
4435  self.FindWindowById(self.win['surface']['draw']['shading']).SetSelection(0)
4436  else: # gouraud
4437  self.FindWindowById(self.win['surface']['draw']['shading']).SetSelection(1)
4438 
4439  continue
4440 
4441  value = drawData['value']
4442  win = self.FindWindowById(self.win['surface']['draw'][control])
4443 
4444  name = win.GetName()
4445 
4446  if name == "selection":
4447  win.SetSelection(value)
4448  elif name == "colour":
4449  color = map(int, value.split(':'))
4450  win.SetColour(color)
4451  else:
4452  win.SetValue(value)
4453  #
4454  # position
4455  #
4456  self.OnSurfaceAxis(None)
4457 
4458  # enable/disable res widget + set draw mode
4459  self.OnSurfaceMode(event = None)
4460 
4461  def UpdateVectorPage(self, layer, data, updateName = True):
4462  """!Update vector page"""
4463  vInfo = grass.vector_info_topo(layer.GetName())
4464  if not vInfo:
4465  return
4466  if vInfo['map3d']:
4467  desc = _("Vector map is 3D")
4468  enable = False
4469  else:
4470  desc = _("Vector map is 2D")
4471  enable = True
4472  desc += " - " + _("%(features)d features (%(points)d points)") % \
4473  { 'features' : vInfo['primitives'], 'points' : vInfo['points']}
4474 
4475  if updateName:
4476  self.FindWindowById(self.win['vector']['map']).SetValue(layer.name)
4477  self.FindWindowById(self.win['vector']['desc']).SetLabel(desc)
4478 
4479  self.FindWindowById(self.win['vector']['lines']['flat']).Enable(enable)
4480  for v in ('lines', 'points'):
4481  self.FindWindowById(self.win['vector'][v]['surface']).Enable(enable)
4482  self.FindWindowById(self.win['vector'][v]['height']['slider']).Enable(enable)
4483  self.FindWindowById(self.win['vector'][v]['height']['text']).Enable(enable)
4484 
4485  #
4486  # lines
4487  #
4488  showLines = self.FindWindowById(self.win['vector']['lines']['show'])
4489  if 'object' in data['lines']:
4490  showLines.SetValue(True)
4491  else:
4492  showLines.SetValue(False)
4493  if (vInfo['lines'] + vInfo['boundaries']) > 0:
4494  showLines.Enable(True)
4495  else:
4496  showLines.Enable(False)
4497 
4498  self.UpdateVectorShow('lines', showLines.IsChecked())
4499 
4500  width = self.FindWindowById(self.win['vector']['lines']['width'])
4501  width.SetValue(data['lines']['width']['value'])
4502 
4503  color = self.FindWindowById(self.win['vector']['lines']['color'])
4504  color.SetValue(map(int, data['lines']['color']['value'].split(':')))
4505 
4506  for vtype in ('lines', 'points'):
4507  if vtype == 'lines':
4508  display = self.FindWindowById(self.win['vector']['lines']['flat'])
4509  if data[vtype]['mode']['type'] == 'flat':
4510  display.SetSelection(1)
4511  else:
4512  display.SetSelection(0)
4513  if data[vtype]['mode']['type'] == 'surface':
4514  rasters = self.mapWindow.GetLayerNames('raster')
4515  constants = self.mapWindow.GetLayerNames('constant')
4516  surfaces = rasters + constants
4517  surfaceWin = self.FindWindowById(self.win['vector'][vtype]['surface'])
4518  surfaceWin.SetItems(surfaces)
4519  for idx, surface in enumerate(surfaces):
4520  try:# TODO fix this mess
4521  selected = data[vtype]['mode']['surface']['show'][idx]
4522  except (TypeError, IndexError, KeyError):
4523  selected = False
4524  surfaceWin.Check(idx, selected)
4525 
4526  for type in ('slider', 'text'):
4527  win = self.FindWindowById(self.win['vector']['lines']['height'][type])
4528  win.SetValue(data['lines']['height']['value'])
4529 
4530  #
4531  # points
4532  #
4533  showPoints = self.FindWindowById(self.win['vector']['points']['show'])
4534 
4535  if 'object' in data['points']:
4536  showPoints.SetValue(True)
4537  else:
4538  showPoints.SetValue(False)
4539  if (vInfo['points'] + vInfo['centroids']) > 0:
4540  showPoints.Enable(True)
4541  else:
4542  showPoints.Enable(False)
4543 
4544  self.UpdateVectorShow('points', showPoints.IsChecked())
4545  # size, width, marker, color
4546  for prop in ('size', 'marker', 'color'):
4547  win = self.FindWindowById(self.win['vector']['points'][prop])
4548  name = win.GetName()
4549  if name == 'selection':
4550  win.SetSelection(data['points'][prop]['value'])
4551  elif name == 'color':
4552  color = map(int, data['points'][prop]['value'].split(':'))
4553  win.SetValue(color)
4554  else:
4555  win.SetValue(data['points'][prop]['value'])
4556 
4557  # height
4558  for type in ('slider', 'text'):
4559  win = self.FindWindowById(self.win['vector']['points']['height'][type])
4560  win.SetValue(data['points']['height']['value'])
4561 
4562  def UpdateVolumePage(self, layer, data, updateName = True):
4563  """!Update volume page"""
4564  if updateName:
4565  self.FindWindowById(self.win['volume']['map']).SetValue(layer.name)
4566 
4567  # draw
4568  for control, idata in data['draw'].iteritems():
4569  if control == 'all': # skip 'all' property
4570  continue
4571 
4572  win = self.FindWindowById(self.win['volume']['draw'][control])
4573  if control == 'mode':
4574  value = data['draw']['mode']['value']
4575  if control == 'shading':
4576  if data['draw']['shading'][data['draw']['mode']['desc']]['desc'] == 'flat':
4577  value = 0
4578  else:
4579  value = 1
4580  if control == 'resolution':
4581  value = idata[data['draw']['mode']['desc']]['value']
4582 
4583  if win.GetName() == "selection":
4584  win.SetSelection(value)
4585  else:
4586  win.SetValue(value)
4587 
4588  self.OnVolumeMode(None)
4589  id = data['object']['id']
4590  if data['draw']['mode']['desc'] == 'isosurface':
4591  self._display.SetIsosurfaceMode(id, data['draw']['shading']['isosurface']['value'])
4592  self._display.SetIsosurfaceRes(id, data['draw']['resolution']['isosurface']['value'])
4593  else:
4594  self._display.SetSliceMode(id, data['draw']['shading']['slice']['value'])
4595  self._display.SetSliceRes(id, data['draw']['resolution']['slice']['value'])
4596  box = self.FindWindowById(self.win['volume']['isosurfs'])
4597 
4598  if data['draw']['mode']['desc'] == 'isosurface':
4599  isosurfaces = []
4600  for iso in data['isosurface']:
4601  level = iso['topo']['value']
4602  isosurfaces.append("%s %s" % (_("Level"), level))
4603  box.Set(isosurfaces)
4604  for i in range(len(isosurfaces)):
4605  box.Check(i)
4606  if data['isosurface']:
4607  box.SetSelection(0)
4608  self.UpdateVolumeIsosurfPage(data['isosurface'][0])
4609  else:
4610  self.UpdateVolumeIsosurfPage(data['attribute'])
4611  else:
4612  slices = []
4613  for slice in data['slice']:
4614  axis = ("X", "Y", "Z")[slice['position']['axis']]
4615  slices.append("%s %s" % (_("Slice parallel to"), axis))
4616  box.Set(slices)
4617  for i in range(len(slices)):
4618  box.Check(i)
4619  if data['slice']:
4620  box.SetSelection(0)
4621  self.UpdateVolumeSlicePage(data['slice'][0])
4622  else:
4623  self.UpdateVolumeSlicePage(None)
4624  #
4625  # position
4626  #
4627  if 'z' in data['position']:
4628  zval = data['position']['z']
4629  self.FindWindowById(self.win['volume']['position']['axis']).SetSelection(2)
4630  for control in ('slider','text'):
4631  self.FindWindowById(self.win['volume']['position'][control]).SetValue(zval)
4632  # set topo range
4633  mapRange = self._get3dRange(name = layer.name)
4634  desc = self.FindWindowById(self.win['volume']['desc'])
4635  desc.SetLabel("%s %.2f - %.2f" % (_("range:"), mapRange[0], mapRange[1]))
4636 
4637  def UpdateVolumeIsosurfPage(self, data):
4638  """!Update dialog -- isosurface attributes"""
4639  #
4640  # isosurface attributes
4641  #
4642  for attrb in ('topo', 'color', 'mask',
4643  'transp', 'shine'):
4644  # skip empty attributes
4645  if attrb not in data:
4646  self.SetMapObjUseMap(nvizType = 'volume', attrb = attrb, map = None)
4647  continue
4648 
4649  value = data[attrb]['value']
4650  if attrb == 'color':
4651  if data[attrb]['map']:
4652  self.FindWindowById(self.win['volume'][attrb]['map']).SetValue(value)
4653  else: # constant
4654  color = map(int, value.split(':'))
4655  self.FindWindowById(self.win['volume'][attrb]['const']).SetColour(color)
4656  else:
4657  if data[attrb]['map']:
4658  self.vetoGSelectEvt = True
4659  win = self.FindWindowById(self.win['volume'][attrb]['map'])
4660  win.SetValue(value)
4661  else:
4662  if value:
4663  win = self.FindWindowById(self.win['volume'][attrb]['const'])
4664  if attrb == 'topo':
4665  win.SetValue(float(value))
4666  else:
4667  win.SetValue(self._getPercent(value))
4668 
4669  self.SetMapObjUseMap(nvizType = 'volume',
4670  attrb = attrb, map = data[attrb]['map'])
4671  # set inout
4672  if 'inout' in data:
4673  self.FindWindowById(self.win['volume']['inout']).SetValue(data['inout'])
4674 
4675  def UpdateVolumeSlicePage(self, data):
4676  """!Update dialog -- slice attributes"""
4677  if data:
4678  for coord in ('x1', 'x2', 'y1', 'y2', 'z1', 'z2'):
4679  win = self.FindWindowById(self.win['volume']['slice']['slider_' + coord])
4680  win.Enable()
4681  win.SetValue(data['position'][coord] * 100)
4682  win = self.FindWindowById(self.win['volume']['slice']['axes'])
4683  win.SetSelection(data['position']['axis'])
4684  win.Enable()
4685 
4686  win = self.FindWindowById(self.win['volume']['slice']['transp'])
4687  win.SetValue(self._getPercent(data['transp']['value']))
4688  win.Enable()
4689  self.FindWindowById(self.win['volume']['slice']['reset']).Enable()
4690  else:
4691  for coord in ('x1', 'x2', 'y1', 'y2', 'z1', 'z2'):
4692  self.FindWindowById(self.win['volume']['slice']['slider_' + coord]).Disable()
4693  self.FindWindowById(self.win['volume']['slice']['axes']).Disable()
4694  self.FindWindowById(self.win['volume']['slice']['transp']).Disable()
4695  self.FindWindowById(self.win['volume']['slice']['reset']).Disable()
4696 
4697  self.UpdateSliceLabels()
4698 
4700  """!Update text labels of slice controls according to axis"""
4701  sel = self.FindWindowById(self.win['volume']['slice']['axes']).GetSelection()
4702  if sel == 0:
4703  self.FindWindowByName('label_edge_0').SetLabel(_("North edge:"))
4704  self.FindWindowByName('label_edge_1').SetLabel(_("South edge:"))
4705  self.FindWindowByName('label_edge_2').SetLabel(_("West edge:"))
4706  self.FindWindowByName('label_edge_3').SetLabel(_("East edge:"))
4707 
4708  self.FindWindowByName('label_coord_0').SetLabel(_("Northing (Y):"))
4709  self.FindWindowByName('label_coord_1').SetLabel(_("Height (Z):"))
4710  self.FindWindowByName('label_coord_2').SetLabel(_("Easting (X):"))
4711  elif sel == 1:
4712  self.FindWindowByName('label_edge_0').SetLabel(_("West edge:"))
4713  self.FindWindowByName('label_edge_1').SetLabel(_("East edge:"))
4714  self.FindWindowByName('label_edge_2').SetLabel(_("North edge:"))
4715  self.FindWindowByName('label_edge_3').SetLabel(_("South edge:"))
4716 
4717  self.FindWindowByName('label_coord_0').SetLabel(_("Easting (X):"))
4718  self.FindWindowByName('label_coord_1').SetLabel(_("Height (Z):"))
4719  self.FindWindowByName('label_coord_2').SetLabel(_("Northing (Y):"))
4720  else:
4721  self.FindWindowByName('label_edge_0').SetLabel(_("West edge:"))
4722  self.FindWindowByName('label_edge_1').SetLabel(_("East edge:"))
4723  self.FindWindowByName('label_edge_2').SetLabel(_("Bottom edge:"))
4724  self.FindWindowByName('label_edge_3').SetLabel(_("Top edge:"))
4725 
4726  self.FindWindowByName('label_coord_0').SetLabel(_("Easting (X):"))
4727  self.FindWindowByName('label_coord_1').SetLabel(_("Northing (Y):"))
4728  self.FindWindowByName('label_coord_2').SetLabel(_("Height (Z):"))
4729 
4730  def SetPage(self, name):
4731  """!Get named page"""
4732  if name == 'view':
4733  self.SetSelection(0)
4734  elif name in ('surface', 'vector', 'volume'):
4735  self.SetSelection(1)
4736  else:
4737  self.SetSelection(2)
4738 
4739  win = self.FindWindowById(self.page[name]['notebook'])
4740  try:
4741  win.Expand(win.GetFoldPanel(self.page[name]['id']))
4742  self.UpdateScrolling((win.GetFoldPanel(self.page[name]['id']).GetGrandParent(),))
4743  except AttributeError:
4744  win.SetSelection(self.page[name]['id'])
4745 
4746 class PositionWindow(wx.Window):
4747  """!Abstract position control window, see subclasses
4748  ViewPostionWindow and LightPositionWindow"""
4749  def __init__(self, parent, mapwindow, id = wx.ID_ANY,
4750  **kwargs):
4751  self.mapWindow = mapwindow
4752  self.quick = True
4753 
4754  wx.Window.__init__(self, parent, id, **kwargs)
4755 
4756  self.SetBackgroundColour("WHITE")
4757 
4758  self.pdc = wx.PseudoDC()
4759 
4760  self.pdc.SetBrush(wx.Brush(colour = 'dark green', style = wx.SOLID))
4761  self.pdc.SetPen(wx.Pen(colour = 'dark green', width = 2, style = wx.SOLID))
4762 
4763  self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x: None)
4764  self.Bind(wx.EVT_PAINT, self.OnPaint)
4765  # self.Bind(wx.EVT_MOTION, self.OnMouse)
4766  self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse)
4767 
4768  def Draw(self, pos, scale = False):
4769  w, h = self.GetClientSize()
4770  x, y = pos
4771  if scale:
4772  x = x * w
4773  y = y * h
4774  self.pdc.Clear()
4775  self.pdc.BeginDrawing()
4776  self.pdc.DrawLine(w / 2, h / 2, x, y)
4777  self.pdc.DrawCircle(x, y, 5)
4778  self.pdc.EndDrawing()
4779 
4780  def OnPaint(self, event):
4781  dc = wx.BufferedPaintDC(self)
4782  dc.SetBackground(wx.Brush("White"))
4783  dc.Clear()
4784 
4785  self.PrepareDC(dc)
4786  self.pdc.DrawToDC(dc)
4787 
4788  def UpdatePos(self, xcoord, ycoord):
4789  """!Update position coordinates (origin: UL)"""
4790  if xcoord < 0.0:
4791  xcoord = 0.0
4792  elif xcoord > 1.0:
4793  xcoord = 1.0
4794  if ycoord < 0.0:
4795  ycoord = 0.0
4796  elif ycoord > 1.0:
4797  ycoord = 1.0
4798 
4799  x, y = self.TransformCoordinates(xcoord, ycoord)
4800  self.data['position']['x'] = x
4801  self.data['position']['y'] = y
4802 
4803  return xcoord, ycoord
4804 
4805  def OnMouse(self, event):
4806  if event.LeftIsDown():
4807  x, y = event.GetPosition()
4808  self.Draw(pos = (x, y))
4809  w, h = self.GetClientSize()
4810  x = float(x) / w
4811  y = float(y) / h
4812  self.UpdatePos(x, y)
4813  self.Refresh(False)
4814 
4815  event.Skip()
4816 
4817  def PostDraw(self):
4818  x, y = self.UpdatePos(self.data['position']['x'],
4819  self.data['position']['y'])
4820 
4821  self.Draw(pos = (x,y), scale = True)
4822 
4824  """!View position control widget"""
4825  def __init__(self, parent, mapwindow, id = wx.ID_ANY,
4826  **kwargs):
4827  PositionWindow.__init__(self, parent, mapwindow, id, **kwargs)
4828  self.SetToolTipString(_("Adjusts the distance and direction of the image viewpoint"))
4829  self.data = self.mapWindow.view
4830  self.PostDraw()
4831 
4832  def UpdatePos(self, xcoord, ycoord):
4833  x, y = PositionWindow.UpdatePos(self, xcoord, ycoord)
4834 
4835  event = wxUpdateView(zExag = True)
4836  wx.PostEvent(self.mapWindow, event)
4837 
4838  return x, y
4839 
4840  def TransformCoordinates(self, x, y, toLight = True):
4841  return x, y
4842 
4843  def OnMouse(self, event):
4844  self.mapWindow.iview['dir']['use'] = False # use focus instead of viewdir
4845  PositionWindow.OnMouse(self, event)
4846  if event.LeftIsDown():
4847  self.mapWindow.render['quick'] = self.quick
4848  self.mapWindow.Refresh(eraseBackground = False)
4849  elif event.LeftUp():
4850  self.mapWindow.render['quick'] = False
4851  self.mapWindow.Refresh(eraseBackground = False)
4852 
4853  event.Skip()
4854 
4856  """!Light position control widget"""
4857  def __init__(self, parent, mapwindow, id = wx.ID_ANY,
4858  **kwargs):
4859  PositionWindow.__init__(self, parent, mapwindow, id, **kwargs)
4860  self.SetToolTipString(_("Adjusts the light direction. "
4861  "Click and drag the puck to change the light direction."))
4862 
4863  self.data = self.mapWindow.light
4864  self.quick = False
4865  self.PostDraw()
4866 
4867  def UpdatePos(self, xcoord, ycoord):
4868  x, y = PositionWindow.UpdatePos(self, xcoord, ycoord)
4869 
4870  event = wxUpdateLight(refresh = False)
4871  wx.PostEvent(self.mapWindow, event)
4872 
4873  return x, y
4874 
4875  def TransformCoordinates(self, x, y, toLight = True):
4876  if toLight:
4877  x = 2 * x - 1
4878  y = -2 * y + 1
4879  else:
4880  x = (x + 1)/2
4881  y = (1 - y)/2
4882  return x, y
4883 
4884  def PostDraw(self):
4885  event = wxUpdateLight(refresh = True)
4886  wx.PostEvent(self.mapWindow, event)
4887  x, y = self.data['position']['x'], self.data['position']['y']
4888  x, y = self.TransformCoordinates(x, y, toLight = False)
4889 
4890  self.Draw(pos = (x,y), scale = True)
4891 
4892  def OnMouse(self, event):
4893  PositionWindow.OnMouse(self, event)
4894  if event.LeftUp():
4895  self.mapWindow.render['quick'] = False
4896  self.mapWindow.Refresh(eraseBackground = False)
def UpdateVolumePage
Update volume page.
Definition: tools.py:4562
def UpdateAnimationPage
Update animation page.
Definition: tools.py:4333
def OnSlicePositionChange
Slice position is changing.
Definition: tools.py:4038
def OnFPS
Frames per second changed.
Definition: tools.py:2049
def OnInOutMode
Change isosurfaces mode inout.
Definition: tools.py:3576
def GetValue
Definition: widgets.py:118
Abstract position control window, see subclasses ViewPostionWindow and LightPositionWindow.
Definition: tools.py:4746
wxGUI command interface
def OnVolumeCheck
Isosurface/slice checked (-&gt;load) or unchecked (-&gt;unload)
Definition: tools.py:3597
def SetSurfaceResolution
Set draw resolution.
Definition: tools.py:3025
def OnSurfacePosition
Surface position.
Definition: tools.py:3181
wxGUI 3D view mode (map canvas)
def EnablePage
Enable/disable all widgets on page.
Definition: tools.py:2904
int
Definition: y.tab.c:1344
def OnCPlaneChangeDone
Cutting plane change done.
Definition: tools.py:4108
def OnPlay
Animation: replay.
Definition: tools.py:1983
def PostViewEvent
Change view settings.
Definition: tools.py:178
def OnVolumeMoveDown
Move isosurface/slice down in the list.
Definition: tools.py:3833
def OnVolumePositionChanged
Volume position changed.
Definition: tools.py:3874
def OnVolumeAdd
Add new isosurface/slice to the list.
Definition: tools.py:3677
def OnVolumeSelect
Isosurface/Slice item selected.
Definition: tools.py:3638
def OnSetVector
Vector map selected, update properties page.
Definition: tools.py:2660
#define min(x, y)
Definition: draw2.c:68
def SetMapObjUseMap
Update dialog widgets when attribute type changed.
Definition: tools.py:2922
wxGUI debugging
def OnLightValue
Light brightness/ambient changing.
Definition: tools.py:2617
def OnSurfaceWireColor
Set wire color.
Definition: tools.py:3140
def OnLookAt
Look here/center.
Definition: tools.py:2746
def UpdateSettings
Update view from settings values stored in self.mapWindow.view dictionary.
Definition: tools.py:2551
Core GUI widgets.
def SetVolumeResolution
Set isosurface draw resolution.
Definition: tools.py:3561
def GetLayerData
Get nviz data.
Definition: tools.py:1938
def OnVectorLines
Set vector lines mode, apply changes if auto-rendering is enabled.
Definition: tools.py:3321
Light position control widget.
Definition: tools.py:4855
def _createAnimationPage
Create view settings page.
Definition: tools.py:369
def OnCPlaneChanging
Cutting plane is changing.
Definition: tools.py:4085
def OnVolumeIsosurfMap
Set surface attribute.
Definition: tools.py:3590
def OnViewChange
Change view, render in quick mode.
Definition: tools.py:2685
def OnNewConstant
Create new surface with constant value.
Definition: tools.py:2141
def OnVolumeAxis
Volume position, axis changed.
Definition: tools.py:3921
def UpdatePos
Update position coordinates (origin: UL)
Definition: tools.py:4788
def UpdateCPlanePage
Update widgets according to selected clip plane.
Definition: tools.py:4354
def OnConstantSelection
Constant selected.
Definition: tools.py:2186
def OnVolumeDelete
Remove isosurface/slice from list.
Definition: tools.py:3745
def LoadSettings
Load Nviz settings and apply to current session.
Definition: tools.py:158
def OnVolumeMode
Change mode isosurfaces/slices.
Definition: tools.py:3501
def SetValue
Definition: widgets.py:115
#define max(x, y)
Definition: draw2.c:69
def OnVolumeMoveUp
Move isosurface/slice up in the list.
Definition: tools.py:3792
def OnSetRaster3D
3D Raster map selected, update surface page
Definition: tools.py:2672
def OnCPlaneReset
Reset current cutting plane.
Definition: tools.py:4140
def OnSetRaster
Raster map selected, update surface page.
Definition: tools.py:2647
def OnCPlaneSelection
Cutting plane selected.
Definition: tools.py:4068
Nviz (3D view) tools panel.
Definition: tools.py:59
def OnSaveAnimation
Save animation as a sequence of images.
Definition: tools.py:2113
def UpdateVectorPage
Update vector page.
Definition: tools.py:4461
def OnMapObjUse
Set surface attribute – use – map/constant.
Definition: tools.py:2847
def OnStop
Animation: stop recording/replaying.
Definition: tools.py:1997
Custom control that selects elements.
def OnBgColor
Background color changed.
Definition: tools.py:2625
def UpdateVectorShow
Enable/disable lines/points widgets.
Definition: tools.py:3234
def split
Platform spefic shlex.split.
Definition: core/utils.py:37
def UpdateFrameCount
Update frame count label.
Definition: tools.py:2076
def UpdateSurfacePage
Update surface page.
Definition: tools.py:4366
def SetMapObjAttrb
Set map object (surface/isosurface) attribute (map/constant)
Definition: tools.py:2956
def OnVolumeSliceAxes
Slice axis changed.
Definition: tools.py:3974
def OnAnimationUpdateIndex
Animation: frame index changed.
Definition: tools.py:2106
def OnCPlaneChangeText
Cutting plane changed by textctrl.
Definition: tools.py:4114
def OnVectorPoints
Set vector points mode, apply changes if auto-rendering is enabled.
Definition: tools.py:3439
def OnLightChange
Position of the light changing.
Definition: tools.py:2589
def OnResetVolumePosition
Reset position of volume.
Definition: tools.py:3952
def _createViewPage
Create view settings page.
Definition: tools.py:209
def OnSetConstantProp
Change properties (color, value, resolution) of currently selected constant surface.
Definition: tools.py:2201
View position control widget.
Definition: tools.py:4823
def OnFrameIndexText
Frame index changed by (textCtrl)
Definition: tools.py:2044
def GselectOnPopup
Definition: tools.py:1426
def OnSurfacePositionText
Surface position changed by textctrl.
Definition: tools.py:3229
def OnDecorationPlacement
Place an arrow/scalebar by clicking on display.
Definition: tools.py:4156
def OnAnimationFinished
Animation finished.
Definition: tools.py:2082
def OnFringe
Show/hide fringe.
Definition: tools.py:2220
def OnSurfaceModeAll
Set draw mode (including wire color) for all loaded surfaces.
Definition: tools.py:3070
def OnSurfacePositionChanged
Surface position changed.
Definition: tools.py:3224
def OnSurfaceAxis
Surface position, axis changed.
Definition: tools.py:3154
def OnSliceTransparency
Slice transparency changed.
Definition: tools.py:3997
def OnFrameIndex
Frame index changed (by slider)
Definition: tools.py:2039
def OnLightChanged
Light changed.
Definition: tools.py:2605
def OnSurfaceResolution
Draw resolution changed.
Definition: tools.py:3017
def OnVectorHeightText
Vector height changed, render in full resolution.
Definition: tools.py:3406
def OnResetSurfacePosition
Reset position of surface.
Definition: tools.py:2776
def OnViewChangedText
View changed, render in full resolution.
Definition: tools.py:2737
def OnDeleteConstant
Delete selected constant surface.
Definition: tools.py:2162
def OnVectorDisplay
Display vector lines on surface/flat.
Definition: tools.py:3299
def UpdatePage
Update dialog (selected page)
Definition: tools.py:4221
def OnSize
After window is resized, update scrolling.
Definition: tools.py:188
def AdjustSliderRange
Definition: tools.py:2246
def OnSliceReset
Slice position reset.
Definition: tools.py:4017
def PostLightEvent
Change light settings.
Definition: tools.py:183
def UpdateVolumeSlicePage
Update dialog – slice attributes.
Definition: tools.py:4675
def OnLightColor
Color of the light changed.
Definition: tools.py:2609
def OnShowLightModel
Show light model.
Definition: tools.py:2584
def OnVectorHeightFull
Vector height changed, render in full resolution.
Definition: tools.py:3392
def OnVolumeDrawMode
Set isosurface/slice draw mode.
Definition: tools.py:3530
def OnScalebarDelete
Delete scalebar.
Definition: tools.py:4178
def OnSlicePositionChanged
Slice position is changed.
Definition: tools.py:4062
def UpdateVolumeIsosurfPage
Update dialog – isosurface attributes.
Definition: tools.py:4637
def OnCPlaneShading
Cutting plane shading changed.
Definition: tools.py:4124
def SetRange
Definition: widgets.py:128
def SetVolumeDrawMode
Set isosurface draw mode.
Definition: tools.py:3534
def OnPause
Pause animation.
Definition: tools.py:2015
def OnVolumePosition
Volume position.
Definition: tools.py:3879
def OnPressCaption
When foldpanel item collapsed/expanded, update scrollbars.
Definition: tools.py:195
def SetInitialMaps
Set initial raster and vector map.
Definition: tools.py:124
def OnSurfaceMap
Set surface attribute.
Definition: tools.py:2949
def SetSurfaceMode
Set draw mode.
Definition: tools.py:3039
def UpdateScrolling
Update scrollbars in foldpanel.
Definition: tools.py:201
def UpdateIsosurfButtons
Enable/disable buttons &#39;add&#39;, &#39;delete&#39;, &#39;move up&#39;, &#39;move down&#39;.
Definition: tools.py:3469
#define round(x)
Definition: draw2.c:71
Default GUI settings.
def OnDecorationProp
Set arrow/scalebar properties.
Definition: tools.py:4189
def OnVolumePositionText
Volume position changed by textctrl.
Definition: tools.py:3947
tuple range
Definition: tools.py:1402
def OnScroll
Generic scrolling handler.
Definition: tools.py:2235
def OnSetSurface
Surface selected, currently used for fringes.
Definition: tools.py:2635
def OnVectorSurface
Reference surface for vector map (lines/points)
Definition: tools.py:3412
def UpdateSliceLabels
Update text labels of slice controls according to axis.
Definition: tools.py:4699
def OnRecord
Animation: start recording.
Definition: tools.py:1953
Nviz (3D view) animation.
def OnViewChanged
View changed, render in full resolution.
Definition: tools.py:2727
def OnResetView
Reset to default view (view page)
Definition: tools.py:2770
def _createDataPage
Create data (surface, vector, volume) settings page.
Definition: tools.py:516
def OnVectorHeight
Definition: tools.py:3363
def SetPage
Get named page.
Definition: tools.py:4730
def OnLookFrom
Position of view/light changed by buttons.
Definition: tools.py:2799
def OnVectorShow
Show vector lines/points.
Definition: tools.py:3259
def RunCommand
Run GRASS command.
Definition: gcmd.py:633
def OnVolumeResolution
Set isosurface/slice draw resolution.
Definition: tools.py:3557
def OnArrowDelete
Delete arrow.
Definition: tools.py:4172
def OnSurfaceMode
Set draw mode.
Definition: tools.py:3054
def UpdateFrameIndex
Update frame index.
Definition: tools.py:2054