220 def RefreshNewData(self, *args, **kwargs): |
220 def RefreshNewData(self, *args, **kwargs): |
221 self.RefreshView(*args, **kwargs) |
221 self.RefreshView(*args, **kwargs) |
222 DebugViewer.RefreshNewData(self) |
222 DebugViewer.RefreshNewData(self) |
223 |
223 |
224 def GetNearestData(self, tick, adjust): |
224 def GetNearestData(self, tick, adjust): |
225 ticks = numpy.array(zip(*self.Datas)[0]) |
225 ticks = self.Data[:, 0] |
226 new_cursor = numpy.argmin(abs(ticks - tick)) |
226 new_cursor = numpy.argmin(abs(ticks - tick)) |
227 if adjust == -1 and ticks[new_cursor] > tick and new_cursor > 0: |
227 if adjust == -1 and ticks[new_cursor] > tick and new_cursor > 0: |
228 new_cursor -= 1 |
228 new_cursor -= 1 |
229 elif adjust == 1 and ticks[new_cursor] < tick and new_cursor < len(self.Datas): |
229 elif adjust == 1 and ticks[new_cursor] < tick and new_cursor < len(ticks): |
230 new_cursor += 1 |
230 new_cursor += 1 |
231 return new_cursor |
231 return new_cursor |
232 |
232 |
233 def GetBounds(self): |
233 def GetBounds(self): |
234 if self.StartIdx is None or self.EndIdx is None: |
234 if self.StartIdx is None or self.EndIdx is None: |
255 self.CanvasRange.SetStringSelection(TIME_RANGE_VALUES[0][0]) |
255 self.CanvasRange.SetStringSelection(TIME_RANGE_VALUES[0][0]) |
256 self.CurrentRange = TIME_RANGE_VALUES[0][1] / self.Ticktime |
256 self.CurrentRange = TIME_RANGE_VALUES[0][1] / self.Ticktime |
257 |
257 |
258 def RefreshView(self, force=False): |
258 def RefreshView(self, force=False): |
259 self.Freeze() |
259 self.Freeze() |
260 if force or not self.Fixed or (len(self.Datas) > 0 and self.StartTick + self.CurrentRange > self.Datas[-1][0]): |
260 if force or not self.Fixed or (len(self.Data) > 0 and self.StartTick + self.CurrentRange > self.Data[-1, 0]): |
261 if (self.MinValue is not None and |
261 if (self.MinValue is not None and |
262 self.MaxValue is not None and |
262 self.MaxValue is not None and |
263 self.MinValue != self.MaxValue): |
263 self.MinValue != self.MaxValue): |
264 Yrange = float(self.MaxValue - self.MinValue) / self.CurrentZoom |
264 Yrange = float(self.MaxValue - self.MinValue) / self.CurrentZoom |
265 else: |
265 else: |
266 Yrange = 2. / self.CurrentZoom |
266 Yrange = 2. / self.CurrentZoom |
267 |
267 |
268 if not force and not self.Fixed and len(self.Datas) > 0: |
268 if not force and not self.Fixed and len(self.Data) > 0: |
269 self.YCenter = max(self.Datas[-1][1] - Yrange / 2, |
269 self.YCenter = max(self.Data[-1, 1] - Yrange / 2, |
270 min(self.YCenter, |
270 min(self.YCenter, |
271 self.Datas[-1][1] + Yrange / 2)) |
271 self.Data[-1, 1] + Yrange / 2)) |
272 |
272 |
273 var_name = self.InstancePath.split(".")[-1] |
273 var_name = self.InstancePath.split(".")[-1] |
274 |
274 |
275 self.GetBounds() |
275 self.GetBounds() |
276 self.VariableGraphic = plot.PolyLine(self.Datas[self.StartIdx:self.EndIdx + 1], |
276 self.VariableGraphic = plot.PolyLine(self.Data[self.StartIdx:self.EndIdx + 1], |
277 legend=var_name, colour=colours[0]) |
277 legend=var_name, colour=colours[0]) |
278 self.GraphicsObject = plot.PlotGraphics([self.VariableGraphic], _("%s Graphics") % var_name, _("Tick"), _("Values")) |
278 self.GraphicsObject = plot.PlotGraphics([self.VariableGraphic], _("%s Graphics") % var_name, _("Tick"), _("Values")) |
279 self.Canvas.Draw(self.GraphicsObject, |
279 self.Canvas.Draw(self.GraphicsObject, |
280 xAxis=(self.StartTick, self.StartTick + self.CurrentRange), |
280 xAxis=(self.StartTick, self.StartTick + self.CurrentRange), |
281 yAxis=(self.YCenter - Yrange * 1.1 / 2., self.YCenter + Yrange * 1.1 / 2.)) |
281 yAxis=(self.YCenter - Yrange * 1.1 / 2., self.YCenter + Yrange * 1.1 / 2.)) |
294 def IsViewing(self, tagname): |
294 def IsViewing(self, tagname): |
295 return self.InstancePath == tagname |
295 return self.InstancePath == tagname |
296 |
296 |
297 def NewValue(self, tick, value, forced=False): |
297 def NewValue(self, tick, value, forced=False): |
298 value = {True:1., False:0.}.get(value, float(value)) |
298 value = {True:1., False:0.}.get(value, float(value)) |
299 self.Datas.append((float(tick), value)) |
299 self.Data = numpy.append(self.Data, [[float(tick), value]], axis=0) |
300 if self.MinValue is None: |
300 if self.MinValue is None: |
301 self.MinValue = value |
301 self.MinValue = value |
302 else: |
302 else: |
303 self.MinValue = min(self.MinValue, value) |
303 self.MinValue = min(self.MinValue, value) |
304 if self.MaxValue is None: |
304 if self.MaxValue is None: |
305 self.MaxValue = value |
305 self.MaxValue = value |
306 else: |
306 else: |
307 self.MaxValue = max(self.MaxValue, value) |
307 self.MaxValue = max(self.MaxValue, value) |
308 if not self.Fixed or tick < self.StartTick + self.CurrentRange: |
308 if not self.Fixed or tick < self.StartTick + self.CurrentRange: |
309 self.GetBounds() |
309 self.GetBounds() |
310 while int(self.Datas[self.StartIdx][0]) < tick - self.CurrentRange: |
310 while int(self.Data[self.StartIdx, 0]) < tick - self.CurrentRange: |
311 self.StartIdx += 1 |
311 self.StartIdx += 1 |
312 self.EndIdx += 1 |
312 self.EndIdx += 1 |
313 self.StartTick = self.Datas[self.StartIdx][0] |
313 self.StartTick = self.Data[self.StartIdx, 0] |
314 self.NewDataAvailable() |
314 self.NewDataAvailable() |
315 |
315 |
316 def RefreshScrollBar(self): |
316 def RefreshScrollBar(self): |
317 if len(self.Datas) > 0: |
317 if len(self.Data) > 0: |
318 self.GetBounds() |
318 self.GetBounds() |
319 pos = int(self.Datas[self.StartIdx][0] - self.Datas[0][0]) |
319 pos = int(self.Data[self.StartIdx, 0] - self.Data[0, 0]) |
320 range = int(self.Datas[-1][0] - self.Datas[0][0]) |
320 range = int(self.Data[-1, 0] - self.Data[0, 0]) |
321 else: |
321 else: |
322 pos = 0 |
322 pos = 0 |
323 range = 0 |
323 range = 0 |
324 self.CanvasPosition.SetScrollbar(pos, self.CurrentRange, range, self.CurrentRange) |
324 self.CanvasPosition.SetScrollbar(pos, self.CurrentRange, range, self.CurrentRange) |
325 |
325 |
326 def RefreshRange(self): |
326 def RefreshRange(self): |
327 if len(self.Datas) > 0: |
327 if len(self.Data) > 0: |
328 if self.Fixed and self.Datas[-1][0] - self.Datas[0][0] < self.CurrentRange: |
328 if self.Fixed and self.Data[-1, 0] - self.Data[0, 0] < self.CurrentRange: |
329 self.Fixed = False |
329 self.Fixed = False |
330 self.ResetBounds() |
330 self.ResetBounds() |
331 if self.Fixed: |
331 if self.Fixed: |
332 self.StartTick = min(self.StartTick, self.Datas[-1][0] - self.CurrentRange) |
332 self.StartTick = min(self.StartTick, self.Data[-1, 0] - self.CurrentRange) |
333 else: |
333 else: |
334 self.StartTick = max(self.Datas[0][0], self.Datas[-1][0] - self.CurrentRange) |
334 self.StartTick = max(self.Data[0, 0], self.Data[-1, 0] - self.CurrentRange) |
335 self.RefreshView(True) |
335 self.RefreshView(True) |
336 |
336 |
337 def OnRangeChanged(self, event): |
337 def OnRangeChanged(self, event): |
338 try: |
338 try: |
339 if self.Ticktime == 0: |
339 if self.Ticktime == 0: |
349 self.CurrentZoom = ZOOM_VALUES[self.CanvasZoom.GetSelection()][1] |
349 self.CurrentZoom = ZOOM_VALUES[self.CanvasZoom.GetSelection()][1] |
350 wx.CallAfter(self.RefreshView, True) |
350 wx.CallAfter(self.RefreshView, True) |
351 event.Skip() |
351 event.Skip() |
352 |
352 |
353 def OnPositionChanging(self, event): |
353 def OnPositionChanging(self, event): |
354 if len(self.Datas) > 0: |
354 if len(self.Data) > 0: |
355 self.ResetBounds() |
355 self.ResetBounds() |
356 self.StartTick = self.Datas[0][0] + event.GetPosition() |
356 self.StartTick = self.Data[0, 0] + event.GetPosition() |
357 self.Fixed = True |
357 self.Fixed = True |
358 self.NewDataAvailable(True) |
358 self.NewDataAvailable(True) |
359 event.Skip() |
359 event.Skip() |
360 |
360 |
361 def OnResetButton(self, event): |
361 def OnResetButton(self, event): |
362 self.Fixed = False |
362 self.Fixed = False |
363 self.ResetView() |
363 self.ResetView() |
364 event.Skip() |
364 event.Skip() |
365 |
365 |
366 def OnCurrentButton(self, event): |
366 def OnCurrentButton(self, event): |
367 if len(self.Datas) > 0: |
367 if len(self.Data) > 0: |
368 self.ResetBounds() |
368 self.ResetBounds() |
369 self.StartTick = max(self.Datas[0][0], self.Datas[-1][0] - self.CurrentRange) |
369 self.StartTick = max(self.Data[0, 0], self.Data[-1, 0] - self.CurrentRange) |
370 self.Fixed = False |
370 self.Fixed = False |
371 self.NewDataAvailable(True) |
371 self.NewDataAvailable(True) |
372 event.Skip() |
372 event.Skip() |
373 |
373 |
374 def OnResetZoomOffsetButton(self, event): |
374 def OnResetZoomOffsetButton(self, event): |
375 if len(self.Datas) > 0: |
375 if len(self.Data) > 0: |
376 self.YCenter = (self.MaxValue + self.MinValue) / 2 |
376 self.YCenter = (self.MaxValue + self.MinValue) / 2 |
377 else: |
377 else: |
378 self.YCenter = 0.0 |
378 self.YCenter = 0.0 |
379 self.CurrentZoom = 1.0 |
379 self.CurrentZoom = 1.0 |
380 self.CanvasZoom.SetSelection(0) |
380 self.CanvasZoom.SetSelection(0) |
381 wx.CallAfter(self.RefreshView, True) |
381 wx.CallAfter(self.RefreshView, True) |
382 event.Skip() |
382 event.Skip() |
383 |
383 |
384 def OnExportGraphButtonClick(self, event): |
384 def OnExportGraphButtonClick(self, event): |
385 data_copy = self.Datas[:] |
385 data_copy = self.Data[:] |
386 text = "tick;%s;\n" % self.InstancePath |
386 text = "tick;%s;\n" % self.InstancePath |
387 for tick, value in data_copy: |
387 for tick, value in data_copy: |
388 text += "%d;%.3f;\n" % (tick, value) |
388 text += "%d;%.3f;\n" % (tick, value) |
389 self.ParentWindow.SetCopyBuffer(text) |
389 self.ParentWindow.SetCopyBuffer(text) |
390 event.Skip() |
390 event.Skip() |
391 |
391 |
392 def OnCanvasLeftDown(self, event): |
392 def OnCanvasLeftDown(self, event): |
393 self.Fixed = True |
393 self.Fixed = True |
394 self.Canvas.canvas.CaptureMouse() |
394 self.Canvas.canvas.CaptureMouse() |
395 if len(self.Datas) > 0: |
395 if len(self.Data) > 0: |
396 if self.Mode == MODE_SELECTION: |
396 if self.Mode == MODE_SELECTION: |
397 self.Dragging = True |
397 self.Dragging = True |
398 pos = self.Canvas.PositionScreenToUser(event.GetPosition()) |
398 pos = self.Canvas.PositionScreenToUser(event.GetPosition()) |
399 self.CursorIdx = self.GetNearestData(pos[0], -1) |
399 self.CursorIdx = self.GetNearestData(pos[0], -1) |
400 self.RefreshCursor() |
400 self.RefreshCursor() |
401 elif self.Mode == MODE_MOTION: |
401 elif self.Mode == MODE_MOTION: |
402 self.GetBounds() |
402 self.GetBounds() |
403 self.CurrentMousePos = event.GetPosition() |
403 self.CurrentMousePos = event.GetPosition() |
404 self.CurrentMotionValue = self.Datas[self.StartIdx][0] |
404 self.CurrentMotionValue = self.Data[self.StartIdx, 0] |
405 event.Skip() |
405 event.Skip() |
406 |
406 |
407 def OnCanvasLeftUp(self, event): |
407 def OnCanvasLeftUp(self, event): |
408 self.Dragging = False |
408 self.Dragging = False |
409 if self.Mode == MODE_MOTION: |
409 if self.Mode == MODE_MOTION: |
414 event.Skip() |
414 event.Skip() |
415 |
415 |
416 def OnCanvasMiddleDown(self, event): |
416 def OnCanvasMiddleDown(self, event): |
417 self.Fixed = True |
417 self.Fixed = True |
418 self.Canvas.canvas.CaptureMouse() |
418 self.Canvas.canvas.CaptureMouse() |
419 if len(self.Datas) > 0: |
419 if len(self.Data) > 0: |
420 self.GetBounds() |
420 self.GetBounds() |
421 self.CurrentMousePos = event.GetPosition() |
421 self.CurrentMousePos = event.GetPosition() |
422 self.CurrentMotionValue = self.Datas[self.StartIdx][0] |
422 self.CurrentMotionValue = self.Data[self.StartIdx, 0] |
423 event.Skip() |
423 event.Skip() |
424 |
424 |
425 def OnCanvasMiddleUp(self, event): |
425 def OnCanvasMiddleUp(self, event): |
426 self.CurrentMousePos = None |
426 self.CurrentMousePos = None |
427 self.CurrentMotionValue = None |
427 self.CurrentMotionValue = None |
433 if self.Mode == MODE_SELECTION and self.Dragging: |
433 if self.Mode == MODE_SELECTION and self.Dragging: |
434 pos = self.Canvas.PositionScreenToUser(event.GetPosition()) |
434 pos = self.Canvas.PositionScreenToUser(event.GetPosition()) |
435 graphics, xAxis, yAxis = self.Canvas.last_draw |
435 graphics, xAxis, yAxis = self.Canvas.last_draw |
436 self.CursorIdx = self.GetNearestData(max(xAxis[0], min(pos[0], xAxis[1])), -1) |
436 self.CursorIdx = self.GetNearestData(max(xAxis[0], min(pos[0], xAxis[1])), -1) |
437 self.RefreshCursor() |
437 self.RefreshCursor() |
438 elif self.CurrentMousePos is not None and len(self.Datas) > 0: |
438 elif self.CurrentMousePos is not None and len(self.Data) > 0: |
439 oldpos = self.Canvas.PositionScreenToUser(self.CurrentMousePos) |
439 oldpos = self.Canvas.PositionScreenToUser(self.CurrentMousePos) |
440 newpos = self.Canvas.PositionScreenToUser(event.GetPosition()) |
440 newpos = self.Canvas.PositionScreenToUser(event.GetPosition()) |
441 self.CurrentMotionValue += oldpos[0] - newpos[0] |
441 self.CurrentMotionValue += oldpos[0] - newpos[0] |
442 self.YCenter += oldpos[1] - newpos[1] |
442 self.YCenter += oldpos[1] - newpos[1] |
443 self.ResetBounds() |
443 self.ResetBounds() |
444 self.StartTick = max(self.Datas[0][0], min(self.CurrentMotionValue, self.Datas[-1][0] - self.CurrentRange)) |
444 self.StartTick = max(self.Data[0, 0], min(self.CurrentMotionValue, self.Data[-1, 0] - self.CurrentRange)) |
445 self.CurrentMousePos = event.GetPosition() |
445 self.CurrentMousePos = event.GetPosition() |
446 self.NewDataAvailable(True) |
446 self.NewDataAvailable(True) |
447 event.Skip() |
447 event.Skip() |
448 |
448 |
449 def OnCanvasMouseWheel(self, event): |
449 def OnCanvasMouseWheel(self, event): |