328 if len(values) > 2 and values[2] == "move": |
330 if len(values) > 2 and values[2] == "move": |
329 self.ParentWindow.MoveGraph(values[0], target_idx) |
331 self.ParentWindow.MoveGraph(values[0], target_idx) |
330 else: |
332 else: |
331 self.ParentWindow.InsertValue(values[0], target_idx, force=True) |
333 self.ParentWindow.InsertValue(values[0], target_idx, force=True) |
332 else: |
334 else: |
333 ax, ay, aw, ah = self.ParentControl.Axes.get_position().bounds |
335 rect = self.ParentControl.GetAxesBoundingBox() |
334 rect = wx.Rect(ax * width, height - (ay + ah) * height, |
|
335 aw * width, ah * height) |
|
336 if rect.InsideXY(x, y): |
336 if rect.InsideXY(x, y): |
337 merge_rect = wx.Rect(ax * width, height - (ay + ah) * height, |
337 merge_rect = wx.Rect(rect.x, rect.y, rect.width / 2., rect.height) |
338 aw * width / 2., ah * height) |
|
339 if merge_rect.InsideXY(x, y): |
338 if merge_rect.InsideXY(x, y): |
340 merge_type = GRAPH_ORTHOGONAL |
339 merge_type = GRAPH_ORTHOGONAL |
341 wx.CallAfter(self.ParentWindow.MergeGraphs, values[0], target_idx, merge_type, force=True) |
340 wx.CallAfter(self.ParentWindow.MergeGraphs, values[0], target_idx, merge_type, force=True) |
342 else: |
341 else: |
343 if y > height / 2: |
342 if y > height / 2: |
617 if xp == yp: |
616 if xp == yp: |
618 mask.append(xp) |
617 mask.append(xp) |
619 else: |
618 else: |
620 mask.append("*") |
619 mask.append("*") |
621 return mask |
620 return mask |
622 |
621 |
|
622 class DraggingFigureCanvas(FigureCanvas): |
|
623 |
|
624 def __init__(self, parent, window, *args, **kwargs): |
|
625 FigureCanvas.__init__(self, parent, *args, **kwargs) |
|
626 |
|
627 self.ParentWindow = window |
|
628 |
|
629 def draw(self, drawDC=None): |
|
630 FigureCanvasAgg.draw(self) |
|
631 |
|
632 self.bitmap = _convert_agg_to_wx_bitmap(self.get_renderer(), None) |
|
633 if self.ParentWindow.IsDragging(): |
|
634 destBBox = self.ParentWindow.GetDraggingAxesClippingRegion(self.Parent) |
|
635 if destBBox.width > 0 and destBBox.height > 0: |
|
636 srcPanel = self.ParentWindow.DraggingAxesPanel |
|
637 srcBBox = srcPanel.GetAxesBoundingBox() |
|
638 |
|
639 if destBBox.x == 0: |
|
640 srcX = srcBBox.x + srcBBox.width - destBBox.width |
|
641 else: |
|
642 srcX = srcBBox.x |
|
643 if destBBox.y == 0: |
|
644 srcY = srcBBox.y + srcBBox.height - destBBox.height |
|
645 else: |
|
646 srcY = srcBBox.y |
|
647 |
|
648 srcBmp = _convert_agg_to_wx_bitmap(srcPanel.Canvas.get_renderer(), None) |
|
649 srcDC = wx.MemoryDC() |
|
650 srcDC.SelectObject(srcBmp) |
|
651 |
|
652 destDC = wx.MemoryDC() |
|
653 destDC.SelectObject(self.bitmap) |
|
654 |
|
655 destDC.BeginDrawing() |
|
656 destDC.Blit(destBBox.x, destBBox.y, |
|
657 int(destBBox.width), int(destBBox.height), |
|
658 srcDC, srcX, srcY) |
|
659 destDC.EndDrawing() |
|
660 |
|
661 self._isDrawn = True |
|
662 self.gui_repaint(drawDC=drawDC) |
|
663 |
623 class DebugVariableGraphic(DebugVariableViewer): |
664 class DebugVariableGraphic(DebugVariableViewer): |
624 |
665 |
625 def __init__(self, parent, window, items, graph_type): |
666 def __init__(self, parent, window, items, graph_type): |
626 DebugVariableViewer.__init__(self, parent, window, items) |
667 DebugVariableViewer.__init__(self, parent, window, items) |
627 |
668 |
631 self.ResetGraphics() |
672 self.ResetGraphics() |
632 |
673 |
633 def AddViewer(self): |
674 def AddViewer(self): |
634 self.Figure = matplotlib.figure.Figure(facecolor='w') |
675 self.Figure = matplotlib.figure.Figure(facecolor='w') |
635 |
676 |
636 self.Canvas = FigureCanvas(self, -1, self.Figure) |
677 self.Canvas = DraggingFigureCanvas(self, self.ParentWindow, -1, self.Figure) |
637 self.Canvas.SetMinSize(wx.Size(200, 200)) |
678 self.Canvas.SetMinSize(wx.Size(200, 200)) |
638 self.Canvas.SetDropTarget(DebugVariableDropTarget(self.ParentWindow, self)) |
679 self.Canvas.SetDropTarget(DebugVariableDropTarget(self.ParentWindow, self)) |
|
680 self.Canvas.Bind(wx.EVT_LEFT_DOWN, self.OnCanvasLeftDown) |
639 self.Canvas.mpl_connect('motion_notify_event', self.OnCanvasMotion) |
681 self.Canvas.mpl_connect('motion_notify_event', self.OnCanvasMotion) |
640 self.Canvas.Bind(wx.EVT_LEFT_DOWN, self.OnCanvasClick) |
682 self.Canvas.mpl_connect('button_release_event', self.OnCanvasLeftUp) |
641 |
683 |
642 self.MainSizer.AddWindow(self.Canvas, flag=wx.GROW) |
684 self.MainSizer.AddWindow(self.Canvas, flag=wx.GROW) |
643 |
685 |
644 def AddButtons(self): |
686 def AddButtons(self): |
645 button_sizer = wx.BoxSizer(wx.VERTICAL) |
687 button_sizer = wx.BoxSizer(wx.VERTICAL) |
657 size=wx.Size(28, 28), style=wx.NO_BORDER) |
699 size=wx.Size(28, 28), style=wx.NO_BORDER) |
658 button.SetToolTipString(help) |
700 button.SetToolTipString(help) |
659 setattr(self, name, button) |
701 setattr(self, name, button) |
660 self.Bind(wx.EVT_BUTTON, getattr(self, "On" + name), button) |
702 self.Bind(wx.EVT_BUTTON, getattr(self, "On" + name), button) |
661 button_sizer.AddWindow(button, border=5, flag=wx.LEFT) |
703 button_sizer.AddWindow(button, border=5, flag=wx.LEFT) |
662 |
704 |
663 def OnCanvasClick(self, event): |
705 def GetAxesBoundingBox(self, absolute=False): |
|
706 width, height = self.Canvas.GetSize() |
|
707 ax, ay, aw, ah = self.Axes.get_position().bounds |
|
708 bbox = wx.Rect(ax * width, height - (ay + ah) * height - 1, |
|
709 aw * width + 2, ah * height + 1) |
|
710 if absolute: |
|
711 xw, yw = self.GetPosition() |
|
712 bbox.x += xw |
|
713 bbox.y += yw |
|
714 return bbox |
|
715 |
|
716 def OnCanvasLeftDown(self, event): |
664 x, y = event.GetPosition() |
717 x, y = event.GetPosition() |
665 width, height = self.Canvas.GetSize() |
718 width, height = self.Canvas.GetSize() |
666 if len(self.Items) == 1: |
719 if len(self.Items) == 1: |
667 ax, ay, aw, ah = self.Axes.get_position().bounds |
720 rect = self.GetAxesBoundingBox() |
668 rect = wx.Rect(ax * width, height - (ay + ah) * height, |
|
669 aw * width, ah * height) |
|
670 if rect.InsideXY(x, y): |
721 if rect.InsideXY(x, y): |
671 self.DoDragDrop(0) |
722 xw, yw = self.GetPosition() |
|
723 self.ParentWindow.StartDragNDrop(self, x + xw, y + yw) |
672 return |
724 return |
673 elif self.Legend is not None: |
725 elif self.Legend is not None: |
674 item_idx = None |
726 item_idx = None |
675 for i, t in enumerate(self.Legend.get_texts()): |
727 for i, t in enumerate(self.Legend.get_texts()): |
676 (x0, y0), (x1, y1) = t.get_window_extent().get_points() |
728 (x0, y0), (x1, y1) = t.get_window_extent().get_points() |
681 if item_idx is not None: |
733 if item_idx is not None: |
682 self.DoDragDrop(item_idx) |
734 self.DoDragDrop(item_idx) |
683 return |
735 return |
684 event.Skip() |
736 event.Skip() |
685 |
737 |
|
738 def OnCanvasLeftUp(self, event): |
|
739 if self.ParentWindow.IsDragging(): |
|
740 width, height = self.Canvas.GetSize() |
|
741 xw, yw = self.GetPosition() |
|
742 self.ParentWindow.StopDragNDrop( |
|
743 self.Items[0].GetVariable(), |
|
744 xw + event.x, |
|
745 yw + height - event.y) |
|
746 |
686 def DoDragDrop(self, item_idx): |
747 def DoDragDrop(self, item_idx): |
687 self.ParentWindow.ResetCursorTickRatio() |
748 self.ParentWindow.ResetCursorTickRatio() |
688 data = wx.TextDataObject(str((self.Items[item_idx].GetVariable(), "debug", "move"))) |
749 data = wx.TextDataObject(str((self.Items[item_idx].GetVariable(), "debug", "move"))) |
689 dragSource = wx.DropSource(self.Canvas) |
750 dragSource = wx.DropSource(self.Canvas) |
690 dragSource.SetData(data) |
751 dragSource.SetData(data) |
696 if current_time - self.LastMotionTime > REFRESH_PERIOD: |
757 if current_time - self.LastMotionTime > REFRESH_PERIOD: |
697 self.LastMotionTime = current_time |
758 self.LastMotionTime = current_time |
698 Axes3D._on_move(self.Axes, event) |
759 Axes3D._on_move(self.Axes, event) |
699 |
760 |
700 def OnCanvasMotion(self, event): |
761 def OnCanvasMotion(self, event): |
701 if not self.Is3DCanvas(): |
762 if self.ParentWindow.IsDragging(): |
|
763 width, height = self.Canvas.GetSize() |
|
764 xw, yw = self.GetPosition() |
|
765 self.ParentWindow.MoveDragNDrop( |
|
766 xw + event.x, |
|
767 yw + height - event.y) |
|
768 elif not self.Is3DCanvas(): |
702 if event.inaxes == self.Axes: |
769 if event.inaxes == self.Axes: |
703 start_tick, end_tick = self.ParentWindow.GetRange() |
770 start_tick, end_tick = self.ParentWindow.GetRange() |
704 cursor_tick_ratio = None |
771 cursor_tick_ratio = None |
705 if self.GraphType == GRAPH_ORTHOGONAL: |
772 if self.GraphType == GRAPH_ORTHOGONAL: |
706 x_data = self.Items[0].GetData(start_tick, end_tick) |
773 x_data = self.Items[0].GetData(start_tick, end_tick) |
954 self.Ticks = numpy.array([]) |
1021 self.Ticks = numpy.array([]) |
955 self.RangeValues = None |
1022 self.RangeValues = None |
956 self.StartTick = 0 |
1023 self.StartTick = 0 |
957 self.Fixed = False |
1024 self.Fixed = False |
958 self.Force = False |
1025 self.Force = False |
|
1026 self.CursorTickRatio = None |
|
1027 self.DraggingAxesPanel = None |
|
1028 self.DraggingAxesBoundingBox = None |
|
1029 self.DraggingAxesMousePos = None |
959 |
1030 |
960 self.GraphicPanels = [] |
1031 self.GraphicPanels = [] |
961 |
1032 |
962 graphics_button_sizer = wx.BoxSizer(wx.HORIZONTAL) |
1033 graphics_button_sizer = wx.BoxSizer(wx.HORIZONTAL) |
963 main_sizer.AddSizer(graphics_button_sizer, border=5, flag=wx.GROW|wx.ALL) |
1034 main_sizer.AddSizer(graphics_button_sizer, border=5, flag=wx.GROW|wx.ALL) |
1003 |
1074 |
1004 self.GraphicsSizer = wx.BoxSizer(wx.VERTICAL) |
1075 self.GraphicsSizer = wx.BoxSizer(wx.VERTICAL) |
1005 self.GraphicsWindow.SetSizer(self.GraphicsSizer) |
1076 self.GraphicsWindow.SetSizer(self.GraphicsSizer) |
1006 |
1077 |
1007 self.RefreshCanvasRange() |
1078 self.RefreshCanvasRange() |
1008 self.CursorTickRatio = None |
|
1009 |
1079 |
1010 else: |
1080 else: |
1011 main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) |
1081 main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) |
1012 main_sizer.AddGrowableCol(0) |
1082 main_sizer.AddGrowableCol(0) |
1013 main_sizer.AddGrowableRow(1) |
1083 main_sizer.AddGrowableRow(1) |
1147 not_null = True |
1217 not_null = True |
1148 |
1218 |
1149 duration += "%gms" % (float(tick_duration % SECOND) / MILLISECOND) |
1219 duration += "%gms" % (float(tick_duration % SECOND) / MILLISECOND) |
1150 label += "(%s)" % duration |
1220 label += "(%s)" % duration |
1151 return label |
1221 return label |
|
1222 |
|
1223 def StartDragNDrop(self, panel, x_mouse, y_mouse): |
|
1224 self.DraggingAxesPanel = panel |
|
1225 self.DraggingAxesBoundingBox = panel.GetAxesBoundingBox(absolute=True) |
|
1226 self.DraggingAxesMousePos = wx.Point( |
|
1227 x_mouse - self.DraggingAxesBoundingBox.x, |
|
1228 y_mouse - self.DraggingAxesBoundingBox.y) |
|
1229 self.ResetCursorTickRatio() |
|
1230 |
|
1231 def MoveDragNDrop(self, x_mouse, y_mouse): |
|
1232 self.DraggingAxesBoundingBox.x = x_mouse - self.DraggingAxesMousePos.x |
|
1233 self.DraggingAxesBoundingBox.y = y_mouse - self.DraggingAxesMousePos.y |
|
1234 self.ForceRefresh() |
|
1235 |
|
1236 def IsDragging(self): |
|
1237 return self.DraggingAxesPanel is not None |
|
1238 |
|
1239 def GetDraggingAxesClippingRegion(self, panel): |
|
1240 x, y = panel.GetPosition() |
|
1241 width, height = panel.Canvas.GetSize() |
|
1242 bbox = wx.Rect(x, y, width, height) |
|
1243 bbox = bbox.Intersect(self.DraggingAxesBoundingBox) |
|
1244 bbox.x -= x |
|
1245 bbox.y -= y |
|
1246 return bbox |
|
1247 |
|
1248 def StopDragNDrop(self, variable, x_mouse, y_mouse): |
|
1249 self.DraggingAxesPanel = None |
|
1250 self.DraggingAxesBoundingBox = None |
|
1251 self.DraggingAxesMousePos = None |
|
1252 for idx, panel in enumerate(self.GraphicPanels): |
|
1253 xw, yw = panel.GetPosition() |
|
1254 width, height = panel.Canvas.GetSize() |
|
1255 bbox = wx.Rect(xw, yw, width, height) |
|
1256 if bbox.InsideXY(x_mouse, y_mouse): |
|
1257 merge_type = GRAPH_PARALLEL |
|
1258 if panel.Is3DCanvas(): |
|
1259 if y_mouse > yw + height / 2: |
|
1260 idx += 1 |
|
1261 wx.CallAfter(self.MoveGraph, variable, idx) |
|
1262 return |
|
1263 else: |
|
1264 rect = panel.GetAxesBoundingBox(True) |
|
1265 if rect.InsideXY(x_mouse, y_mouse): |
|
1266 merge_rect = wx.Rect(rect.x, rect.y, rect.width / 2., rect.height) |
|
1267 if merge_rect.InsideXY(x_mouse, y_mouse): |
|
1268 merge_type = GRAPH_ORTHOGONAL |
|
1269 wx.CallAfter(self.MergeGraphs, variable, idx, merge_type, force=True) |
|
1270 else: |
|
1271 if y_mouse > yw + height / 2: |
|
1272 idx += 1 |
|
1273 wx.CallAfter(self.MoveGraph, variable, idx) |
|
1274 break |
|
1275 self.ForceRefresh() |
1152 |
1276 |
1153 def RefreshView(self, only_values=False): |
1277 def RefreshView(self, only_values=False): |
1154 if USE_MPL: |
1278 if USE_MPL: |
1155 self.RefreshCanvasPosition() |
1279 self.RefreshCanvasPosition() |
1156 |
1280 |