20 # |
20 # |
21 #You should have received a copy of the GNU General Public |
21 #You should have received a copy of the GNU General Public |
22 #License along with this library; if not, write to the Free Software |
22 #License along with this library; if not, write to the Free Software |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 |
24 |
25 from types import TupleType |
25 from types import TupleType, FloatType |
|
26 from time import time as gettime |
|
27 import numpy |
26 |
28 |
27 import wx |
29 import wx |
28 import wx.lib.buttons |
30 import wx.lib.buttons |
29 |
31 import matplotlib |
30 from graphics import DebugDataConsumer, DebugViewer |
32 matplotlib.use('WX') |
|
33 import matplotlib.pyplot |
|
34 from matplotlib.backends.backend_wx import FigureCanvasWx as FigureCanvas |
|
35 from mpl_toolkits.mplot3d import Axes3D |
|
36 |
|
37 from graphics import DebugDataConsumer, DebugViewer, REFRESH_PERIOD |
31 from controls import CustomGrid, CustomTable |
38 from controls import CustomGrid, CustomTable |
32 from dialogs.ForceVariableDialog import ForceVariableDialog |
39 from dialogs.ForceVariableDialog import ForceVariableDialog |
33 from util.BitmapLibrary import GetBitmap |
40 from util.BitmapLibrary import GetBitmap |
34 |
41 |
35 def AppendMenu(parent, help, id, kind, text): |
42 def AppendMenu(parent, help, id, kind, text): |
36 parent.Append(help=help, id=id, kind=kind, text=text) |
43 parent.Append(help=help, id=id, kind=kind, text=text) |
37 |
44 |
38 def GetDebugVariablesTableColnames(): |
45 def GetDebugVariablesTableColnames(): |
39 _ = lambda x : x |
46 _ = lambda x : x |
40 return [_("Variable"), _("Value")] |
47 return [_("Variable"), _("Value"), _("3DAxis")] |
41 |
48 |
42 class VariableTableItem(DebugDataConsumer): |
49 class VariableTableItem(DebugDataConsumer): |
43 |
50 |
44 def __init__(self, parent, variable, value): |
51 def __init__(self, parent, variable): |
45 DebugDataConsumer.__init__(self) |
52 DebugDataConsumer.__init__(self) |
46 self.Parent = parent |
53 self.Parent = parent |
47 self.Variable = variable |
54 self.Variable = variable |
48 self.Value = value |
55 self.RefreshVariableType() |
|
56 self.Value = "" |
|
57 self.Axis3D = False |
49 |
58 |
50 def __del__(self): |
59 def __del__(self): |
51 self.Parent = None |
60 self.Parent = None |
52 |
61 |
53 def SetVariable(self, variable): |
62 def SetVariable(self, variable): |
54 if self.Parent and self.Variable != variable: |
63 if self.Parent and self.Variable != variable: |
55 self.Variable = variable |
64 self.Variable = variable |
|
65 self.RefreshVariableType() |
56 self.Parent.RefreshGrid() |
66 self.Parent.RefreshGrid() |
57 |
67 |
58 def GetVariable(self): |
68 def GetVariable(self): |
59 return self.Variable |
69 return self.Variable |
|
70 |
|
71 def RefreshVariableType(self): |
|
72 self.VariableType = self.Parent.GetDataType(self.Variable) |
|
73 self.ResetData() |
|
74 |
|
75 def GetVariableType(self): |
|
76 return self.VariableType |
|
77 |
|
78 def GetData(self): |
|
79 return self.Data |
|
80 |
|
81 def ResetData(self): |
|
82 if self.IsNumVariable(): |
|
83 self.Data = numpy.array([]).reshape(0, 2) |
|
84 else: |
|
85 self.Data = None |
|
86 |
|
87 def IsNumVariable(self): |
|
88 return self.Parent.IsNumType(self.VariableType) |
|
89 |
|
90 def NewValue(self, tick, value, forced=False): |
|
91 if self.IsNumVariable(): |
|
92 value = {True:1., False:0.}.get(value, float(value)) |
|
93 self.Data = numpy.append(self.Data, [[float(tick), value]], axis=0) |
|
94 self.Parent.HasNewData = True |
|
95 DebugDataConsumer.NewValue(self, tick, value, forced) |
60 |
96 |
61 def SetForced(self, forced): |
97 def SetForced(self, forced): |
62 if self.Forced != forced: |
98 if self.Forced != forced: |
63 self.Forced = forced |
99 self.Forced = forced |
64 self.Parent.HasNewData = True |
100 self.Parent.HasNewData = True |
91 if row < self.GetNumberRows(): |
137 if row < self.GetNumberRows(): |
92 if colname == "Variable": |
138 if colname == "Variable": |
93 return self.data[row].GetVariable() |
139 return self.data[row].GetVariable() |
94 elif colname == "Value": |
140 elif colname == "Value": |
95 return self.data[row].GetValue() |
141 return self.data[row].GetValue() |
|
142 elif colname == "3DAxis": |
|
143 return self.data[row].GetAxis3D() |
96 return "" |
144 return "" |
97 |
145 |
98 def SetValueByName(self, row, colname, value): |
146 def SetValueByName(self, row, colname, value): |
99 if row < self.GetNumberRows(): |
147 if row < self.GetNumberRows(): |
100 if colname == "Variable": |
148 if colname == "Variable": |
101 self.data[row].SetVariable(value) |
149 self.data[row].SetVariable(value) |
102 elif colname == "Value": |
150 elif colname == "Value": |
103 self.data[row].SetValue(value) |
151 self.data[row].SetValue(value) |
|
152 elif colname == "3DAxis": |
|
153 self.data[row].SetAxis3D(value) |
104 |
154 |
105 def IsForced(self, row): |
155 def IsForced(self, row): |
106 if row < self.GetNumberRows(): |
156 if row < self.GetNumberRows(): |
107 return self.data[row].IsForced() |
157 return self.data[row].IsForced() |
108 return False |
158 return False |
109 |
159 |
|
160 def IsNumVariable(self, row): |
|
161 if row < self.GetNumberRows(): |
|
162 return self.data[row].IsNumVariable() |
|
163 return False |
|
164 |
110 def _updateColAttrs(self, grid): |
165 def _updateColAttrs(self, grid): |
111 """ |
166 """ |
112 wx.grid.Grid -> update the column attributes to add the |
167 wx.grid.Grid -> update the column attributes to add the |
113 appropriate renderer given the column name. |
168 appropriate renderer given the column name. |
114 |
169 |
115 Otherwise default to the default renderer. |
170 Otherwise default to the default renderer. |
116 """ |
171 """ |
117 |
172 |
118 for row in range(self.GetNumberRows()): |
173 for row in range(self.GetNumberRows()): |
119 for col in range(self.GetNumberCols()): |
174 for col in range(self.GetNumberCols()): |
120 if self.GetColLabelValue(col, False) == "Value": |
175 colname = self.GetColLabelValue(col, False) |
121 if self.IsForced(row): |
176 if colname == "3DAxis": |
122 grid.SetCellTextColour(row, col, wx.BLUE) |
177 if self.IsNumVariable(row): |
|
178 grid.SetCellRenderer(row, col, wx.grid.GridCellBoolRenderer()) |
|
179 grid.SetCellEditor(row, col, wx.grid.GridCellBoolEditor()) |
|
180 grid.SetReadOnly(row, col, False) |
123 else: |
181 else: |
124 grid.SetCellTextColour(row, col, wx.BLACK) |
182 grid.SetReadOnly(row, col, True) |
125 grid.SetReadOnly(row, col, True) |
183 else: |
|
184 if colname == "Value": |
|
185 if self.IsForced(row): |
|
186 grid.SetCellTextColour(row, col, wx.BLUE) |
|
187 else: |
|
188 grid.SetCellTextColour(row, col, wx.BLACK) |
|
189 grid.SetReadOnly(row, col, True) |
126 self.ResizeRow(grid, row) |
190 self.ResizeRow(grid, row) |
127 |
191 |
128 def AppendItem(self, data): |
192 def AppendItem(self, data): |
129 self.data.append(data) |
193 self.data.append(data) |
130 |
194 |
168 def ShowMessage(self, message): |
232 def ShowMessage(self, message): |
169 dialog = wx.MessageDialog(self.ParentWindow, message, _("Error"), wx.OK|wx.ICON_ERROR) |
233 dialog = wx.MessageDialog(self.ParentWindow, message, _("Error"), wx.OK|wx.ICON_ERROR) |
170 dialog.ShowModal() |
234 dialog.ShowModal() |
171 dialog.Destroy() |
235 dialog.Destroy() |
172 |
236 |
173 class DebugVariablePanel(wx.Panel, DebugViewer): |
237 SCROLLBAR_UNIT = 10 |
|
238 |
|
239 class DebugVariablePanel(wx.SplitterWindow, DebugViewer): |
174 |
240 |
175 def __init__(self, parent, producer): |
241 def __init__(self, parent, producer): |
176 wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL) |
242 wx.SplitterWindow.__init__(self, parent, style=wx.SP_3D) |
177 DebugViewer.__init__(self, producer, True) |
243 DebugViewer.__init__(self, producer, True) |
178 |
244 |
179 main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) |
245 self.SetSashGravity(0.5) |
180 main_sizer.AddGrowableCol(0) |
246 self.SetNeedUpdating(True) |
181 main_sizer.AddGrowableRow(1) |
247 self.SetMinimumPaneSize(1) |
|
248 |
|
249 self.MainPanel = wx.Panel(self, style=wx.TAB_TRAVERSAL) |
|
250 |
|
251 main_panel_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) |
|
252 main_panel_sizer.AddGrowableCol(0) |
|
253 main_panel_sizer.AddGrowableRow(1) |
182 |
254 |
183 button_sizer = wx.BoxSizer(wx.HORIZONTAL) |
255 button_sizer = wx.BoxSizer(wx.HORIZONTAL) |
184 main_sizer.AddSizer(button_sizer, border=5, |
256 main_panel_sizer.AddSizer(button_sizer, border=5, |
185 flag=wx.ALIGN_RIGHT|wx.ALL) |
257 flag=wx.ALIGN_RIGHT|wx.ALL) |
186 |
258 |
187 for name, bitmap, help in [ |
259 for name, bitmap, help in [ |
188 ("DeleteButton", "remove_element", _("Remove debug variable")), |
260 ("DeleteButton", "remove_element", _("Remove debug variable")), |
189 ("UpButton", "up", _("Move debug variable up")), |
261 ("UpButton", "up", _("Move debug variable up")), |
190 ("DownButton", "down", _("Move debug variable down"))]: |
262 ("DownButton", "down", _("Move debug variable down"))]: |
191 button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap), |
263 button = wx.lib.buttons.GenBitmapButton(self.MainPanel, bitmap=GetBitmap(bitmap), |
192 size=wx.Size(28, 28), style=wx.NO_BORDER) |
264 size=wx.Size(28, 28), style=wx.NO_BORDER) |
193 button.SetToolTipString(help) |
265 button.SetToolTipString(help) |
194 setattr(self, name, button) |
266 setattr(self, name, button) |
195 button_sizer.AddWindow(button, border=5, flag=wx.LEFT) |
267 button_sizer.AddWindow(button, border=5, flag=wx.LEFT) |
196 |
268 |
197 self.VariablesGrid = CustomGrid(self, size=wx.Size(0, 150), style=wx.VSCROLL) |
269 self.VariablesGrid = CustomGrid(self.MainPanel, size=wx.Size(-1, 150), style=wx.VSCROLL) |
198 self.VariablesGrid.SetDropTarget(DebugVariableDropTarget(self)) |
270 self.VariablesGrid.SetDropTarget(DebugVariableDropTarget(self)) |
199 self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_RIGHT_CLICK, |
271 self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_RIGHT_CLICK, |
200 self.OnVariablesGridCellRightClick) |
272 self.OnVariablesGridCellRightClick) |
201 main_sizer.AddWindow(self.VariablesGrid, flag=wx.GROW) |
273 self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, |
202 |
274 self.OnVariablesGridCellChange) |
203 self.SetSizer(main_sizer) |
275 main_panel_sizer.AddWindow(self.VariablesGrid, flag=wx.GROW) |
|
276 |
|
277 self.MainPanel.SetSizer(main_panel_sizer) |
204 |
278 |
205 self.HasNewData = False |
279 self.HasNewData = False |
206 |
280 |
207 self.Table = DebugVariableTable(self, [], GetDebugVariablesTableColnames()) |
281 self.Table = DebugVariableTable(self, [], GetDebugVariablesTableColnames()) |
208 self.VariablesGrid.SetTable(self.Table) |
282 self.VariablesGrid.SetTable(self.Table) |
216 |
290 |
217 def _DeleteVariable(row): |
291 def _DeleteVariable(row): |
218 item = self.Table.GetItem(row) |
292 item = self.Table.GetItem(row) |
219 self.RemoveDataConsumer(item) |
293 self.RemoveDataConsumer(item) |
220 self.Table.RemoveItem(row) |
294 self.Table.RemoveItem(row) |
|
295 self.ResetGraphics() |
221 self.RefreshGrid() |
296 self.RefreshGrid() |
222 setattr(self.VariablesGrid, "_DeleteRow", _DeleteVariable) |
297 setattr(self.VariablesGrid, "_DeleteRow", _DeleteVariable) |
223 |
298 |
224 def _MoveVariable(row, move): |
299 def _MoveVariable(row, move): |
225 new_row = max(0, min(row + move, self.Table.GetNumberRows() - 1)) |
300 new_row = max(0, min(row + move, self.Table.GetNumberRows() - 1)) |
226 if new_row != row: |
301 if new_row != row: |
227 self.Table.MoveItem(row, new_row) |
302 self.Table.MoveItem(row, new_row) |
|
303 self.ResetGraphics() |
228 self.RefreshGrid() |
304 self.RefreshGrid() |
229 return new_row |
305 return new_row |
230 setattr(self.VariablesGrid, "_MoveRow", _MoveVariable) |
306 setattr(self.VariablesGrid, "_MoveRow", _MoveVariable) |
231 |
307 |
232 self.VariablesGrid.SetRowLabelSize(0) |
308 self.VariablesGrid.SetRowLabelSize(0) |
233 |
309 |
234 for col in range(self.Table.GetNumberCols()): |
310 for col in range(self.Table.GetNumberCols()): |
235 attr = wx.grid.GridCellAttr() |
311 attr = wx.grid.GridCellAttr() |
236 attr.SetAlignment(wx.ALIGN_RIGHT, wx.ALIGN_CENTER) |
312 if self.Table.GetColLabelValue(col, False) == "3DAxis": |
|
313 attr.SetAlignment(wx.ALIGN_CENTER, wx.ALIGN_CENTER) |
|
314 else: |
|
315 attr.SetAlignment(wx.ALIGN_RIGHT, wx.ALIGN_CENTER) |
237 self.VariablesGrid.SetColAttr(col, attr) |
316 self.VariablesGrid.SetColAttr(col, attr) |
238 self.VariablesGrid.SetColSize(col, 100) |
317 self.VariablesGrid.SetColSize(col, 100) |
239 |
318 |
240 self.Table.ResetView(self.VariablesGrid) |
319 self.Table.ResetView(self.VariablesGrid) |
241 self.VariablesGrid.RefreshButtons() |
320 self.VariablesGrid.RefreshButtons() |
|
321 |
|
322 self.GraphicsPanel = wx.Panel(self, style=wx.TAB_TRAVERSAL) |
|
323 |
|
324 graphics_panel_sizer = wx.BoxSizer(wx.VERTICAL) |
|
325 |
|
326 self.GraphicsCanvasWindow = wx.ScrolledWindow(self.GraphicsPanel, style=wx.HSCROLL|wx.VSCROLL) |
|
327 self.GraphicsCanvasWindow.Bind(wx.EVT_SIZE, self.OnGraphicsCanvasWindowResize) |
|
328 graphics_panel_sizer.AddWindow(self.GraphicsCanvasWindow, 1, flag=wx.GROW) |
|
329 |
|
330 graphics_canvas_window_sizer = wx.BoxSizer(wx.VERTICAL) |
|
331 |
|
332 self.GraphicsFigure = matplotlib.figure.Figure() |
|
333 self.GraphicsFigure.subplots_adjust(hspace=0) |
|
334 self.GraphicsAxes = [] |
|
335 |
|
336 self.GraphicsCanvas = FigureCanvas(self.GraphicsCanvasWindow, -1, self.GraphicsFigure) |
|
337 graphics_canvas_window_sizer.AddWindow(self.GraphicsCanvas, 1, flag=wx.GROW) |
|
338 |
|
339 self.GraphicsCanvasWindow.SetSizer(graphics_canvas_window_sizer) |
|
340 |
|
341 self.Graphics3DFigure = matplotlib.figure.Figure() |
|
342 self.Graphics3DFigure.subplotpars.update(left=0.0, right=1.0, bottom=0.0, top=1.0) |
|
343 |
|
344 self.LastMotionTime = gettime() |
|
345 self.Graphics3DAxes = self.Graphics3DFigure.gca(projection='3d') |
|
346 self.Graphics3DAxes.set_color_cycle(['b']) |
|
347 setattr(self.Graphics3DAxes, "_on_move", self.OnGraphics3DMotion) |
|
348 |
|
349 self.Graphics3DCanvas = FigureCanvas(self.GraphicsPanel, -1, self.Graphics3DFigure) |
|
350 self.Graphics3DCanvas.SetMinSize(wx.Size(0, 0)) |
|
351 graphics_panel_sizer.AddWindow(self.Graphics3DCanvas, 1, flag=wx.GROW) |
|
352 |
|
353 self.Graphics3DAxes.mouse_init() |
|
354 |
|
355 self.GraphicsPanel.SetSizer(graphics_panel_sizer) |
|
356 |
|
357 self.SplitHorizontally(self.MainPanel, self.GraphicsPanel, -200) |
|
358 |
|
359 self.ResetGraphics() |
242 |
360 |
243 def RefreshNewData(self): |
361 def RefreshNewData(self): |
244 if self.HasNewData: |
362 if self.HasNewData: |
245 self.HasNewData = False |
363 self.HasNewData = False |
246 self.RefreshGrid() |
364 self.RefreshGrid(only_values=True) |
247 DebugViewer.RefreshNewData(self) |
365 DebugViewer.RefreshNewData(self) |
248 |
366 |
249 def RefreshGrid(self): |
367 def RefreshGrid(self, only_values=False): |
250 self.Freeze() |
368 self.Freeze() |
251 self.Table.ResetView(self.VariablesGrid) |
369 if only_values: |
|
370 for col in xrange(self.Table.GetNumberCols()): |
|
371 if self.Table.GetColLabelValue(col, False) == "Value": |
|
372 for row in xrange(self.Table.GetNumberRows()): |
|
373 self.VariablesGrid.SetCellValue(row, col, str(self.Table.GetValueByName(row, "Value"))) |
|
374 else: |
|
375 self.Table.ResetView(self.VariablesGrid) |
252 self.VariablesGrid.RefreshButtons() |
376 self.VariablesGrid.RefreshButtons() |
|
377 |
|
378 # Refresh graphics |
|
379 idx = 0 |
|
380 for item in self.Table.GetData(): |
|
381 data = item.GetData() |
|
382 if data is not None: |
|
383 self.GraphicsAxes[idx].clear() |
|
384 self.GraphicsAxes[idx].plot(data[:, 0], data[:, 1]) |
|
385 idx += 1 |
|
386 self.GraphicsCanvas.draw() |
|
387 |
|
388 # Refresh 3D graphics |
|
389 while len(self.Graphics3DAxes.lines) > 0: |
|
390 self.Graphics3DAxes.lines.pop() |
|
391 if self.Axis3DValues is not None: |
|
392 self.Graphics3DAxes.plot( |
|
393 self.Axis3DValues[0][1].GetData()[self.Axis3DValues[0][0]:, 1], |
|
394 self.Axis3DValues[1][1].GetData()[self.Axis3DValues[1][0]:, 1], |
|
395 zs = self.Axis3DValues[2][1].GetData()[self.Axis3DValues[2][0]:, 1]) |
|
396 self.Graphics3DCanvas.draw() |
|
397 |
253 self.Thaw() |
398 self.Thaw() |
254 |
399 |
255 def UnregisterObsoleteData(self): |
400 def UnregisterObsoleteData(self): |
256 items = [(idx, item) for idx, item in enumerate(self.Table.GetData())] |
401 items = [(idx, item) for idx, item in enumerate(self.Table.GetData())] |
257 items.reverse() |
402 items.reverse() |
258 for idx, item in items: |
403 for idx, item in items: |
259 iec_path = item.GetVariable().upper() |
404 iec_path = item.GetVariable().upper() |
260 if self.GetDataType(iec_path) is None: |
405 if self.GetDataType(iec_path) is None: |
261 self.RemoveDataConsumer(item) |
406 self.RemoveDataConsumer(item) |
262 self.Table.RemoveItem(idx) |
407 self.Table.RemoveItem(idx) |
263 else: |
408 else: |
264 self.AddDataConsumer(iec_path, item) |
409 self.AddDataConsumer(iec_path, item) |
|
410 item.RefreshVariableType() |
265 self.Freeze() |
411 self.Freeze() |
266 self.Table.ResetView(self.VariablesGrid) |
412 self.Table.ResetView(self.VariablesGrid) |
267 self.VariablesGrid.RefreshButtons() |
413 self.VariablesGrid.RefreshButtons() |
268 self.Thaw() |
414 self.Thaw() |
269 |
415 |
312 self.PopupMenu(menu) |
459 self.PopupMenu(menu) |
313 |
460 |
314 menu.Destroy() |
461 menu.Destroy() |
315 event.Skip() |
462 event.Skip() |
316 |
463 |
317 def InsertValue(self, iec_path, idx = None, force=False): |
464 def OnVariablesGridCellChange(self, event): |
|
465 row, col = event.GetRow(), event.GetCol() |
|
466 if self.Table.GetColLabelValue(col, False) == "3DAxis": |
|
467 wx.CallAfter(self.Reset3DGraphics) |
|
468 event.Skip() |
|
469 |
|
470 def InsertValue(self, iec_path, idx = None, force=False, axis3D=False): |
318 if idx is None: |
471 if idx is None: |
319 idx = self.Table.GetNumberRows() |
472 idx = self.Table.GetNumberRows() |
320 for item in self.Table.GetData(): |
473 for item in self.Table.GetData(): |
321 if iec_path == item.GetVariable(): |
474 if iec_path == item.GetVariable(): |
322 return |
475 return |
323 item = VariableTableItem(self, iec_path, "") |
476 item = VariableTableItem(self, iec_path) |
324 result = self.AddDataConsumer(iec_path.upper(), item) |
477 result = self.AddDataConsumer(iec_path.upper(), item) |
325 if result is not None or force: |
478 if result is not None or force: |
326 self.Table.InsertItem(idx, item) |
479 self.Table.InsertItem(idx, item) |
|
480 item.SetAxis3D(int(axis3D)) |
|
481 self.ResetGraphics() |
327 self.RefreshGrid() |
482 self.RefreshGrid() |
328 |
483 |
329 def GetDebugVariables(self): |
484 def GetDebugVariables(self): |
330 return [item.GetVariable() for item in self.Table.GetData()] |
485 return [item.GetVariable() for item in self.Table.GetData()] |
|
486 |
|
487 def GetAxis3D(self): |
|
488 return [item.GetVariable() for item in self.Table.GetData() if item.GetAxis3D()] |
|
489 |
|
490 def ResetGraphicsValues(self): |
|
491 for item in self.Table.GetData(): |
|
492 item.ResetData() |
|
493 |
|
494 def ResetGraphics(self): |
|
495 self.GraphicsFigure.clear() |
|
496 self.GraphicsAxes = [] |
|
497 |
|
498 axes_num = 0 |
|
499 for item in self.Table.GetData(): |
|
500 if item.IsNumVariable(): |
|
501 axes_num += 1 |
|
502 |
|
503 for idx in xrange(axes_num): |
|
504 if idx == 0: |
|
505 axes = self.GraphicsFigure.add_subplot(axes_num, 1, idx + 1) |
|
506 else: |
|
507 axes = self.GraphicsFigure.add_subplot(axes_num, 1, idx + 1, sharex=self.GraphicsAxes[0]) |
|
508 self.GraphicsAxes.append(axes) |
|
509 |
|
510 self.RefreshGraphicsCanvasWindowScrollbars() |
|
511 self.GraphicsCanvas.draw() |
|
512 |
|
513 self.Reset3DGraphics() |
|
514 |
|
515 def Reset3DGraphics(self): |
|
516 axis = [item for item in self.Table.GetData() if item.GetAxis3D()] |
|
517 if len(axis) == 3: |
|
518 max_tick = None |
|
519 xaxis, yaxis, zaxis = [item.GetData() for item in axis] |
|
520 if len(xaxis) > 0 and len(yaxis) > 0 and len(zaxis) > 0: |
|
521 max_tick = max(xaxis[0, 0], yaxis[0, 0], zaxis[0, 0]) |
|
522 if max_tick is not None: |
|
523 self.Axis3DValues = [(numpy.argmin(abs(item.GetData()[:, 0] - max_tick)), item) |
|
524 for item in axis] |
|
525 else: |
|
526 self.Axis3DValues = [(0, item) for item in axis] |
|
527 else: |
|
528 self.Axis3DValues = None |
|
529 |
|
530 def OnGraphics3DMotion(self, event): |
|
531 current_time = gettime() |
|
532 if current_time - self.LastMotionTime > REFRESH_PERIOD: |
|
533 self.LastMotionTime = current_time |
|
534 Axes3D._on_move(self.Graphics3DAxes, event) |
|
535 |
|
536 def RefreshGraphicsCanvasWindowScrollbars(self): |
|
537 xstart, ystart = self.GraphicsCanvasWindow.GetViewStart() |
|
538 window_size = self.GraphicsCanvasWindow.GetClientSize() |
|
539 vwidth, vheight = (window_size[0], (len(self.GraphicsAxes) + 1) * 50) |
|
540 self.GraphicsCanvas.SetMinSize(wx.Size(vwidth, vheight)) |
|
541 posx = max(0, min(xstart, (vwidth - window_size[0]) / SCROLLBAR_UNIT)) |
|
542 posy = max(0, min(ystart, (vheight - window_size[1]) / SCROLLBAR_UNIT)) |
|
543 self.GraphicsCanvasWindow.Scroll(posx, posy) |
|
544 self.GraphicsCanvasWindow.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT, |
|
545 vwidth / SCROLLBAR_UNIT, vheight / SCROLLBAR_UNIT, posx, posy) |
|
546 |
|
547 def OnGraphicsCanvasWindowResize(self, event): |
|
548 self.RefreshGraphicsCanvasWindowScrollbars() |
|
549 event.Skip() |