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