controls/DebugVariablePanel.py
changeset 929 c562031146e4
parent 928 a94e7fea7051
child 930 4be515ac635e
equal deleted inserted replaced
928:a94e7fea7051 929:c562031146e4
   333                 target_idx = self.ParentControl.GetIndex()
   333                 target_idx = self.ParentControl.GetIndex()
   334                 merge_type = GRAPH_PARALLEL
   334                 merge_type = GRAPH_PARALLEL
   335                 if self.ParentControl.Is3DCanvas():
   335                 if self.ParentControl.Is3DCanvas():
   336                     if y > height / 2:
   336                     if y > height / 2:
   337                         target_idx += 1
   337                         target_idx += 1
   338                     if len(values) > 2 and values[2] == "move":
   338                     self.ParentWindow.InsertValue(values[0], target_idx, force=True)
   339                         self.ParentWindow.MoveGraph(values[0], target_idx)
       
   340                     else:
       
   341                         self.ParentWindow.InsertValue(values[0], target_idx, force=True)
       
   342                 else:
   339                 else:
   343                     rect = self.ParentControl.GetAxesBoundingBox()
   340                     rect = self.ParentControl.GetAxesBoundingBox()
   344                     if rect.InsideXY(x, y):
   341                     if rect.InsideXY(x, y):
   345                         merge_rect = wx.Rect(rect.x, rect.y, rect.width / 2., rect.height)
   342                         merge_rect = wx.Rect(rect.x, rect.y, rect.width / 2., rect.height)
   346                         if merge_rect.InsideXY(x, y):
   343                         if merge_rect.InsideXY(x, y):
   347                             merge_type = GRAPH_ORTHOGONAL
   344                             merge_type = GRAPH_ORTHOGONAL
   348                         wx.CallAfter(self.ParentWindow.MergeGraphs, values[0], target_idx, merge_type, force=True)
   345                         wx.CallAfter(self.ParentWindow.MergeGraphs, values[0], target_idx, merge_type, force=True)
   349                     else:
   346                     else:
   350                         if y > height / 2:
   347                         if y > height / 2:
   351                             target_idx += 1
   348                             target_idx += 1
   352                         if len(values) > 2 and values[2] == "move":
   349                         self.ParentWindow.InsertValue(values[0], target_idx, force=True)
   353                             self.ParentWindow.MoveGraph(values[0], target_idx)
   350             self.ParentWindow.InsertValue(values[0], force=True)
   354                         else:
       
   355                             self.ParentWindow.InsertValue(values[0], target_idx, force=True)
       
   356             elif len(values) > 2 and values[2] == "move":
       
   357                 self.ParentWindow.MoveGraph(values[0])
       
   358             else:
       
   359                 self.ParentWindow.InsertValue(values[0], force=True)
       
   360     
   351     
   361     def OnLeave(self):
   352     def OnLeave(self):
   362         if self.ParentControl is not None:
   353         if self.ParentControl is not None:
   363             self.ParentControl.OnCanvasLeave()
   354             self.ParentControl.OnCanvasLeave()
   364         return wx.TextDropTarget.OnLeave(self)
   355         return wx.TextDropTarget.OnLeave(self)
   420             self.SetDropTarget(DebugVariableDropTarget(window, self))
   411             self.SetDropTarget(DebugVariableDropTarget(window, self))
   421             
   412             
   422             self.ParentWindow = window
   413             self.ParentWindow = window
   423             self.Items = items
   414             self.Items = items
   424             
   415             
   425             self.MainSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=0)
       
   426             self.AddViewer()
       
   427             self.AddButtons()
       
   428             self.MainSizer.AddGrowableCol(0)
       
   429             
       
   430             self.SetSizer(self.MainSizer)
       
   431         
       
   432         def __del__(self):
   416         def __del__(self):
   433             self.ParentWindow = None
   417             self.ParentWindow = None
   434             
   418             
   435         def GetIndex(self):
   419         def GetIndex(self):
   436             return self.ParentWindow.GetViewerIndex(self)
   420             return self.ParentWindow.GetViewerIndex(self)
   565         def OnDeleteAllValuesMenu(self, event):
   549         def OnDeleteAllValuesMenu(self, event):
   566             wx.CallAfter(self.ParentWindow.DeleteValue, self)
   550             wx.CallAfter(self.ParentWindow.DeleteValue, self)
   567         
   551         
   568     class DebugVariableText(DebugVariableViewer):
   552     class DebugVariableText(DebugVariableViewer):
   569         
   553         
   570         def AddViewer(self):
   554         def __init__(self, parent, window, items=[]):
       
   555             DebugVariableViewer.__init__(self, parent, window, items)
       
   556         
       
   557             main_sizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=0)
       
   558             main_sizer.AddGrowableCol(0)
       
   559             
   571             viewer_sizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=0)
   560             viewer_sizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=0)
   572             viewer_sizer.AddGrowableCol(0)
   561             viewer_sizer.AddGrowableCol(0)
   573             self.MainSizer.AddSizer(viewer_sizer, border=5, 
   562             main_sizer.AddSizer(viewer_sizer, border=5, 
   574                 flag=wx.ALL|wx.GROW|wx.ALIGN_CENTER_VERTICAL)
   563                 flag=wx.ALL|wx.GROW|wx.ALIGN_CENTER_VERTICAL)
   575             
   564             
   576             variable_name_label = wx.TextCtrl(self, size=wx.Size(0, -1),
   565             variable_name_label = wx.TextCtrl(self, size=wx.Size(0, -1),
   577                 value=self.Items[0].GetVariable(), style=wx.TE_READONLY|wx.TE_RIGHT|wx.NO_BORDER)
   566                 value=self.Items[0].GetVariable(), style=wx.TE_READONLY|wx.TE_RIGHT|wx.NO_BORDER)
   578             variable_name_label.SetSelection(variable_name_label.GetLastPosition(), -1)
   567             variable_name_label.SetSelection(variable_name_label.GetLastPosition(), -1)
   580             
   569             
   581             self.ValueLabel = wx.TextCtrl(self,
   570             self.ValueLabel = wx.TextCtrl(self,
   582                 size=wx.Size(100, -1), style=wx.TE_READONLY|wx.TE_RIGHT|wx.NO_BORDER)
   571                 size=wx.Size(100, -1), style=wx.TE_READONLY|wx.TE_RIGHT|wx.NO_BORDER)
   583             viewer_sizer.AddWindow(self.ValueLabel, 
   572             viewer_sizer.AddWindow(self.ValueLabel, 
   584                 border=5, flag=wx.LEFT)
   573                 border=5, flag=wx.LEFT)
   585         
   574             
   586         def AddButtons(self):
       
   587             button_sizer = wx.BoxSizer(wx.HORIZONTAL)
   575             button_sizer = wx.BoxSizer(wx.HORIZONTAL)
   588             self.MainSizer.AddSizer(button_sizer, border=5, 
   576             self.MainSizer.AddSizer(button_sizer, border=5, 
   589                 flag=wx.TOP|wx.BOTTOM|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
   577                 flag=wx.TOP|wx.BOTTOM|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
   590             
   578             
   591             buttons = [
   579             buttons = [
   592                 ("ForceButton", "force", _("Force value")),
   580                 ("ForceButton", "force", _("Force value")),
   593                 ("ReleaseButton", "release", _("Release value")),
   581                 ("ReleaseButton", "release", _("Release value")),
   594                 ("DeleteButton", "remove_element", _("Remove debug variable"))]
   582                 ("DeleteButton", "delete_graph", _("Remove debug variable"))]
   595             
   583             
   596             for name, bitmap, help in buttons:
   584             for name, bitmap, help in buttons:
   597                 button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap), 
   585                 button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap), 
   598                       size=wx.Size(28, 28), style=wx.NO_BORDER)
   586                       size=wx.Size(20, 20), style=wx.NO_BORDER)
   599                 button.SetToolTipString(help)
   587                 button.SetToolTipString(help)
   600                 setattr(self, name, button)
   588                 setattr(self, name, button)
   601                 self.Bind(wx.EVT_BUTTON, getattr(self, "On" + name), button)
   589                 self.Bind(wx.EVT_BUTTON, getattr(self, "On" + name), button)
   602                 button_sizer.AddWindow(button, border=5, flag=wx.LEFT)
   590                 button_sizer.AddWindow(button, border=5, flag=wx.LEFT)
       
   591             
       
   592             self.SetSizer(main_sizer)
   603     
   593     
   604         def Refresh(self):
   594         def Refresh(self):
   605             self.ValueLabel.ChangeValue(self.Items[0].GetValue())
   595             self.ValueLabel.ChangeValue(self.Items[0].GetValue())
   606             if self.Items[0].IsForced():
   596             if self.Items[0].IsForced():
   607                 self.ValueLabel.SetForegroundColour(wx.BLUE)
   597                 self.ValueLabel.SetForegroundColour(wx.BLUE)
   626      HIGHLIGHT_RIGHT] = range(5)
   616      HIGHLIGHT_RIGHT] = range(5)
   627     
   617     
   628     HIGHLIGHT_PEN = wx.Pen(wx.Colour(0, 128, 255))
   618     HIGHLIGHT_PEN = wx.Pen(wx.Colour(0, 128, 255))
   629     HIGHLIGHT_BRUSH = wx.Brush(wx.Colour(0, 128, 255, 128))
   619     HIGHLIGHT_BRUSH = wx.Brush(wx.Colour(0, 128, 255, 128))
   630     
   620     
       
   621     if wx.Platform == '__WXMSW__':
       
   622         popupclass = wx.PopupTransientWindow
       
   623     else:
       
   624         popupclass = wx.PopupWindow
       
   625     
       
   626     class PopupWithButtons(popupclass):
       
   627     
       
   628         def __init__(self, parent, window, item, style=wx.HORIZONTAL):
       
   629             popupclass.__init__(self, parent, wx.NO_BORDER)
       
   630             self.SetBackgroundColour(wx.WHITE)
       
   631             
       
   632             self.ParentWindow = window
       
   633             self.Item = item
       
   634             
       
   635             main_sizer = wx.BoxSizer(style)
       
   636             
       
   637             if self.Item.IsForced():
       
   638                 buttons = [("ReleaseButton", "release", _("Release value"))]
       
   639             
       
   640             else:
       
   641                 buttons = [("ForceButton", "force", _("Force value"))]
       
   642             buttons.append(("DeleteButton", "delete_graph", _("Remove debug variable")))
       
   643             
       
   644             for name, bitmap, help in buttons:
       
   645                 button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap), 
       
   646                       size=wx.Size(20, 20), style=wx.NO_BORDER)
       
   647                 button.SetToolTipString(help)
       
   648                 setattr(self, name, button)
       
   649                 self.Bind(wx.EVT_BUTTON, getattr(self, "On" + name), button)
       
   650                 main_sizer.AddWindow(button)
       
   651             main_sizer.Layout()
       
   652             
       
   653             self.SetSizer(main_sizer)
       
   654             main_sizer.Fit(self)
       
   655         
       
   656         def GetItem(self):
       
   657             return self.Item
       
   658         
       
   659         def OnForceButton(self, event):
       
   660             wx.CallAfter(self.Parent.DismissButtons)
       
   661             wx.CallAfter(self.Parent.ForceValue, self.Item)
       
   662             event.Skip()
       
   663         
       
   664         def OnReleaseButton(self, event):
       
   665             wx.CallAfter(self.Parent.DismissButtons)
       
   666             wx.CallAfter(self.Parent.ReleaseValue, self.Item)
       
   667             event.Skip()
       
   668         
       
   669         def OnDeleteButton(self, event):            
       
   670             wx.CallAfter(self.Parent.DismissButtons)
       
   671             wx.CallAfter(self.ParentWindow.DeleteValue, self.Parent, self.Item)
       
   672             event.Skip()
       
   673     
       
   674         def OnDismiss(self):
       
   675             wx.CallAfter(self.Parent.DismissButtons)
       
   676     
   631     class DraggingFigureCanvas(FigureCanvas):
   677     class DraggingFigureCanvas(FigureCanvas):
   632         
   678         
   633         def __init__(self, parent, window, *args, **kwargs):
   679         def __init__(self, parent, window, *args, **kwargs):
   634             FigureCanvas.__init__(self, parent, *args, **kwargs)
   680             FigureCanvas.__init__(self, parent, *args, **kwargs)
       
   681             self.SetBackgroundColour(wx.WHITE)
       
   682             self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow)
       
   683             self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)
       
   684             self.Bind(wx.EVT_SIZE, self.OnResizeWindow)
   635             
   685             
   636             self.ParentWindow = window
   686             self.ParentWindow = window
   637             self.Highlight = HIGHLIGHT_NONE
   687             self.Highlight = HIGHLIGHT_NONE
   638         
   688             
       
   689             self.ChangeSizeButton = wx.lib.buttons.GenBitmapToggleButton(self, 
       
   690                     bitmap=GetBitmap("minimize_graph"), 
       
   691                     size=wx.Size(20, 20), style=wx.NO_BORDER)
       
   692             self.ChangeSizeButton.SetBitmapSelected(GetBitmap("maximize_graph"))
       
   693             self.Bind(wx.EVT_BUTTON, self.OnChangeSizeButton, self.ChangeSizeButton)
       
   694             
       
   695             self.CloseButton = wx.lib.buttons.GenBitmapButton(self, 
       
   696                     bitmap=GetBitmap("delete_graph"), 
       
   697                     size=wx.Size(20, 20), style=wx.NO_BORDER)
       
   698             self.Bind(wx.EVT_BUTTON, self.OnCloseButton, self.CloseButton)
       
   699             
       
   700             self.ShowButtons(False)
       
   701             
   639         def SetHighlight(self, highlight):
   702         def SetHighlight(self, highlight):
   640             if self.Highlight != highlight:
   703             if self.Highlight != highlight:
   641                 self.Highlight = highlight
   704                 self.Highlight = highlight
   642                 return True
   705                 return True
   643             return False
   706             return False
   700                     
   763                     
   701             destGC.EndDrawing()
   764             destGC.EndDrawing()
   702             
   765             
   703             self._isDrawn = True
   766             self._isDrawn = True
   704             self.gui_repaint(drawDC=drawDC)
   767             self.gui_repaint(drawDC=drawDC)
       
   768         
       
   769         def ShowButtons(self, show):
       
   770             if show:
       
   771                 self.ChangeSizeButton.Show()
       
   772                 self.CloseButton.Show()
       
   773             else:
       
   774                 self.ChangeSizeButton.Hide()
       
   775                 self.CloseButton.Hide()
       
   776         
       
   777         def OnEnterWindow(self, event):
       
   778             self.ShowButtons(True)
       
   779             event.Skip()
       
   780             
       
   781         def OnLeaveWindow(self, event):
       
   782             x, y = event.GetPosition()
       
   783             width, height = self.GetSize()
       
   784             if (x <= 0 or x >= width - 1 or
       
   785                 y <= 0 or y >= height - 1):
       
   786                 self.ShowButtons(False)
       
   787             event.Skip()
       
   788         
       
   789         def OnChangeSizeButton(self, event):
       
   790             if self.ChangeSizeButton.GetToggle():
       
   791                 self.Parent.Minimize()
       
   792             else:
       
   793                 self.Parent.Maximize()
       
   794             event.Skip()
       
   795         
       
   796         def OnCloseButton(self, event):
       
   797             wx.CallAfter(self.ParentWindow.DeleteValue, self.Parent)
       
   798             event.Skip()
       
   799     
       
   800         def OnResizeWindow(self, event):
       
   801             width, height = self.GetSize()
       
   802             self.ChangeSizeButton.SetPosition(wx.Point(width - 50, 5))
       
   803             self.CloseButton.SetPosition(wx.Point(width - 25, 5))
       
   804             event.Skip()
   705     
   805     
   706     class DebugVariableGraphic(DebugVariableViewer):
   806     class DebugVariableGraphic(DebugVariableViewer):
   707         
   807         
   708         def __init__(self, parent, window, items, graph_type):
   808         def __init__(self, parent, window, items, graph_type):
   709             DebugVariableViewer.__init__(self, parent, window, items)
   809             DebugVariableViewer.__init__(self, parent, window, items)
   710         
   810         
   711             self.GraphType = graph_type
   811             self.GraphType = graph_type
   712             self.CursorTick = None
   812             self.CursorTick = None
   713             self.MouseStartPos = None
   813             self.MouseStartPos = None
   714             self.StartCursorTick = None
   814             self.StartCursorTick = None
   715             
   815             self.ItemButtons = None
   716             self.ResetGraphics()
   816             
   717         
   817             main_sizer = wx.BoxSizer(wx.VERTICAL)
   718         def AddViewer(self):
   818             
   719             self.Figure = matplotlib.figure.Figure(facecolor='w')
   819             self.Figure = matplotlib.figure.Figure(facecolor='w')
   720             
   820             
   721             self.Canvas = DraggingFigureCanvas(self, self.ParentWindow, -1, self.Figure)
   821             self.Canvas = DraggingFigureCanvas(self, self.ParentWindow, -1, self.Figure)
   722             self.Canvas.SetMinSize(wx.Size(200, 200))
   822             self.Canvas.SetMinSize(wx.Size(200, 200))
   723             self.Canvas.SetDropTarget(DebugVariableDropTarget(self.ParentWindow, self))
   823             self.Canvas.SetDropTarget(DebugVariableDropTarget(self.ParentWindow, self))
   724             self.Canvas.Bind(wx.EVT_LEFT_DOWN, self.OnCanvasLeftDown)
   824             self.Canvas.Bind(wx.EVT_MOUSEWHEEL, self.OnCanvasMouseWheel)
   725             self.Canvas.mpl_connect('button_press_event', self.OnCanvasButtonPressed)
   825             self.Canvas.mpl_connect('button_press_event', self.OnCanvasButtonPressed)
   726             self.Canvas.mpl_connect('motion_notify_event', self.OnCanvasMotion)
   826             self.Canvas.mpl_connect('motion_notify_event', self.OnCanvasMotion)
   727             self.Canvas.mpl_connect('button_release_event', self.OnCanvasButtonReleased)
   827             self.Canvas.mpl_connect('button_release_event', self.OnCanvasButtonReleased)
   728             self.Canvas.mpl_connect('scroll_event', self.OnCanvasScroll)
   828             self.Canvas.mpl_connect('scroll_event', self.OnCanvasScroll)
   729             
   829             
   730             self.MainSizer.AddWindow(self.Canvas, flag=wx.GROW)
   830             main_sizer.AddWindow(self.Canvas, 1, flag=wx.GROW)
   731         
   831             self.SetSizer(main_sizer)
   732         def AddButtons(self):
   832             
   733             button_sizer = wx.BoxSizer(wx.VERTICAL)
   833             self.ResetGraphics()
   734             self.MainSizer.AddSizer(button_sizer, border=5, 
   834         
   735                 flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
   835         def Minimize(self):
   736             
   836             self.Canvas.SetMinSize(wx.Size(200, 100))
   737             buttons = [
   837             self.Figure.subplotpars.update(bottom=0.20)
   738                 ("ForceButton", "force", _("Force value")),
   838             self.ParentWindow.RefreshGraphicsSizer()
   739                 ("ReleaseButton", "release", _("Release value")),
   839         
   740                 ("SplitButton", "split", _("Split graphs")),
   840         def Maximize(self):
   741                 ("DeleteButton", "remove_element", _("Remove debug variable"))]
   841             self.Canvas.SetMinSize(wx.Size(200, 200))
   742             
   842             self.Figure.subplotpars.update(bottom=0.1)
   743             for name, bitmap, help in buttons:
   843             self.ParentWindow.RefreshGraphicsSizer()
   744                 button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap), 
       
   745                       size=wx.Size(28, 28), style=wx.NO_BORDER)
       
   746                 button.SetToolTipString(help)
       
   747                 setattr(self, name, button)
       
   748                 self.Bind(wx.EVT_BUTTON, getattr(self, "On" + name), button)
       
   749                 button_sizer.AddWindow(button, border=5, flag=wx.LEFT)
       
   750         
   844         
   751         def GetAxesBoundingBox(self, absolute=False):
   845         def GetAxesBoundingBox(self, absolute=False):
   752             bbox = self.Canvas.GetAxesBoundingBox()
   846             bbox = self.Canvas.GetAxesBoundingBox()
   753             if absolute:
   847             if absolute:
   754                 xw, yw = self.GetPosition()
   848                 xw, yw = self.GetPosition()
   755                 bbox.x += xw
   849                 bbox.x += xw
   756                 bbox.y += yw
   850                 bbox.y += yw
   757             return bbox
   851             return bbox
   758         
   852         
   759         def OnCanvasLeftDown(self, event):
   853         def OnCanvasButtonPressed(self, event):
   760             if not self.Is3DCanvas():
   854             if not self.Is3DCanvas():
   761                 x, y = event.GetPosition()
       
   762                 width, height = self.Canvas.GetSize()
   855                 width, height = self.Canvas.GetSize()
       
   856                 x, y = event.x, height - event.y
   763                 rect = self.GetAxesBoundingBox()
   857                 rect = self.GetAxesBoundingBox()
   764                 if rect.InsideXY(x, y):
   858                 if rect.InsideXY(x, y):
   765                     self.MouseStartPos = wx.Point(x, y)
   859                     self.MouseStartPos = wx.Point(x, y)
   766                 if self.Legend is not None:
   860                 if self.Legend is not None:
   767                     item_idx = None
   861                     texts = self.Legend.get_texts()
   768                     for i, t in enumerate(self.Legend.get_texts()):
   862                 elif len(self.AxesLabels) > 0:
   769                         (x0, y0), (x1, y1) = t.get_window_extent().get_points()
   863                     texts = self.AxesLabels
   770                         rect = wx.Rect(x0, height - y1, x1 - x0, y1 - y0)
   864                 else:
   771                         if rect.InsideXY(x, y):
   865                     texts = []
   772                             item_idx = i
   866                 item_idx = None
   773                             break
   867                 for i, t in enumerate(texts):
   774                     if item_idx is not None:
   868                     (x0, y0), (x1, y1) = t.get_window_extent().get_points()
   775                         self.DoDragDrop(item_idx)
   869                     rect = wx.Rect(x0, height - y1, x1 - x0, y1 - y0)
   776                         return
   870                     if rect.InsideXY(x, y):
   777             event.Skip()
   871                         item_idx = i
   778         
   872                         break
   779         def OnCanvasButtonPressed(self, event):
   873                 if item_idx is not None:
   780             if not self.Is3DCanvas():
   874                     self.Canvas.ShowButtons(False)
   781                 if event.button == 1:
   875                     self.DismissButtons()
       
   876                     xw, yw = self.GetPosition()
       
   877                     self.ParentWindow.StartDragNDrop(self, 
       
   878                         self.Items[item_idx], x + xw, y + yw, x + xw, y + yw)
       
   879                 elif event.button == 1:
   782                     self.HandleCursorMove(event)
   880                     self.HandleCursorMove(event)
   783                 elif event.button == 2 and self.GraphType == GRAPH_PARALLEL:
   881                 elif event.button == 2 and self.GraphType == GRAPH_PARALLEL:
   784                     width, height = self.Canvas.GetSize()
   882                     width, height = self.Canvas.GetSize()
   785                     start_tick, end_tick = self.ParentWindow.GetRange()
   883                     start_tick, end_tick = self.ParentWindow.GetRange()
   786                     self.MouseStartPos = wx.Point(event.x, height - event.y)
   884                     self.MouseStartPos = wx.Point(event.x, height - event.y)
   797             else:
   895             else:
   798                 self.MouseStartPos = None
   896                 self.MouseStartPos = None
   799                 self.StartCursorTick = None
   897                 self.StartCursorTick = None
   800         
   898         
   801         def OnCanvasMotion(self, event):
   899         def OnCanvasMotion(self, event):
       
   900             width, height = self.Canvas.GetSize()
   802             if self.ParentWindow.IsDragging():
   901             if self.ParentWindow.IsDragging():
   803                 width, height = self.Canvas.GetSize()
       
   804                 xw, yw = self.GetPosition()
   902                 xw, yw = self.GetPosition()
   805                 self.ParentWindow.MoveDragNDrop(
   903                 self.ParentWindow.MoveDragNDrop(
   806                     xw + event.x, 
   904                     xw + event.x, 
   807                     yw + height - event.y)
   905                     yw + height - event.y)
   808             elif not self.Is3DCanvas():
   906             elif not self.Is3DCanvas():
   809                 if event.button == 1:
   907                 if event.button == 1:
   810                     if event.inaxes == self.Axes:
   908                     if event.inaxes == self.Axes:
   811                         if self.MouseStartPos is not None:
   909                         if self.MouseStartPos is not None:
   812                             self.HandleCursorMove(event)
   910                             self.HandleCursorMove(event)
   813                     elif self.MouseStartPos is not None:
   911                     elif self.MouseStartPos is not None and len(self.Items) == 1:
   814                         xw, yw = self.GetPosition()
   912                         xw, yw = self.GetPosition()
   815                         width, height = self.Canvas.GetSize()
       
   816                         self.ParentWindow.StartDragNDrop(self, 
   913                         self.ParentWindow.StartDragNDrop(self, 
       
   914                             self.Items[0],
   817                             event.x + xw, height - event.y + yw, 
   915                             event.x + xw, height - event.y + yw, 
   818                             self.MouseStartPos.x + xw, self.MouseStartPos.y + yw)
   916                             self.MouseStartPos.x + xw, self.MouseStartPos.y + yw)
   819                 elif event.button == 2 and self.GraphType == GRAPH_PARALLEL:
   917                 elif event.button == 2 and self.GraphType == GRAPH_PARALLEL:
   820                     start_tick, end_tick = self.ParentWindow.GetRange()
   918                     start_tick, end_tick = self.ParentWindow.GetRange()
   821                     rect = self.GetAxesBoundingBox()
   919                     rect = self.GetAxesBoundingBox()
   822                     self.ParentWindow.SetCanvasPosition(
   920                     self.ParentWindow.SetCanvasPosition(
   823                         self.StartCursorTick + (self.MouseStartPos.x - event.x) *
   921                         self.StartCursorTick + (self.MouseStartPos.x - event.x) *
   824                         (end_tick - start_tick) / rect.width)
   922                         (end_tick - start_tick) / rect.width)
       
   923                 elif event.button is None:
       
   924                     if self.Legend is not None:
       
   925                         labels = self.Legend.get_texts()
       
   926                         texts = zip(labels, [wx.HORIZONTAL] * len(labels))
       
   927                     elif len(self.AxesLabels) > 0:
       
   928                         texts = zip(self.AxesLabels, [wx.HORIZONTAL, wx.VERTICAL])
       
   929                     else:
       
   930                         texts = []
       
   931                     item_idx = None
       
   932                     item_style = None
       
   933                     for i, (t, style) in enumerate(texts):
       
   934                         (x0, y0), (x1, y1) = t.get_window_extent().get_points()
       
   935                         rect = wx.Rect(x0, height - y1, x1 - x0, y1 - y0)
       
   936                         if rect.InsideXY(event.x, height - event.y):
       
   937                             item_idx = i
       
   938                             item_style = style
       
   939                             break
       
   940                     if item_idx is not None:
       
   941                         self.PopupButtons(item_idx, rect, item_style)
       
   942                         return 
       
   943                     if self.ItemButtons is not None:
       
   944                         self.DismissButtons()
   825         
   945         
   826         def OnCanvasDragging(self, x, y, refresh=True):
   946         def OnCanvasDragging(self, x, y, refresh=True):
   827             width, height = self.Canvas.GetSize()
   947             width, height = self.Canvas.GetSize()
   828             bbox = self.Canvas.GetAxesBoundingBox()
   948             bbox = self.Canvas.GetAxesBoundingBox()
   829             if bbox.InsideXY(x, y):
   949             if bbox.InsideXY(x, y) and not self.Is3DCanvas():
   830                 rect = wx.Rect(bbox.x, bbox.y, bbox.width / 2, bbox.height)
   950                 rect = wx.Rect(bbox.x, bbox.y, bbox.width / 2, bbox.height)
   831                 if rect.InsideXY(x, y):
   951                 if rect.InsideXY(x, y):
   832                     self.Canvas.SetHighlight(HIGHLIGHT_LEFT)
   952                     self.Canvas.SetHighlight(HIGHLIGHT_LEFT)
   833                 else:
   953                 else:
   834                     self.Canvas.SetHighlight(HIGHLIGHT_RIGHT)
   954                     self.Canvas.SetHighlight(HIGHLIGHT_RIGHT)
   850                     start_tick, end_tick = self.ParentWindow.GetRange()
   970                     start_tick, end_tick = self.ParentWindow.GetRange()
   851                     tick = (start_tick + end_tick) / 2.
   971                     tick = (start_tick + end_tick) / 2.
   852                 else:
   972                 else:
   853                     tick = event.xdata
   973                     tick = event.xdata
   854                 self.ParentWindow.ChangeRange(int(-event.step) / 3, tick)
   974                 self.ParentWindow.ChangeRange(int(-event.step) / 3, tick)
       
   975         
       
   976         def OnCanvasMouseWheel(self, event):
       
   977             if self.ItemButtons is not None:
       
   978                 event.Skip()
   855         
   979         
   856         def HandleCursorMove(self, event):
   980         def HandleCursorMove(self, event):
   857             start_tick, end_tick = self.ParentWindow.GetRange()
   981             start_tick, end_tick = self.ParentWindow.GetRange()
   858             cursor_tick = None
   982             cursor_tick = None
   859             if self.GraphType == GRAPH_ORTHOGONAL:
   983             if self.GraphType == GRAPH_ORTHOGONAL:
   869                     cursor_tick = data[numpy.argmin(numpy.abs(data[:,0] - event.xdata)), 0]
   993                     cursor_tick = data[numpy.argmin(numpy.abs(data[:,0] - event.xdata)), 0]
   870             if cursor_tick is not None:
   994             if cursor_tick is not None:
   871                 self.ParentWindow.SetCursorTick(cursor_tick)
   995                 self.ParentWindow.SetCursorTick(cursor_tick)
   872         
   996         
   873         def DoDragDrop(self, item_idx):
   997         def DoDragDrop(self, item_idx):
       
   998             self.Canvas.ShowButtons(False)
       
   999             self.DismissButtons()
   874             data = wx.TextDataObject(str((self.Items[item_idx].GetVariable(), "debug", "move")))
  1000             data = wx.TextDataObject(str((self.Items[item_idx].GetVariable(), "debug", "move")))
   875             dragSource = wx.DropSource(self.Canvas)
  1001             dragSource = wx.DropSource(self.Canvas)
   876             dragSource.SetData(data)
  1002             dragSource.SetData(data)
   877             dragSource.DoDragDrop()
  1003             dragSource.DoDragDrop()
       
  1004         
       
  1005         def PopupButtons(self, item_idx, rect, style=wx.HORIZONTAL):
       
  1006             item = self.Items[item_idx]
       
  1007             if self.ItemButtons is not None and item != self.ItemButtons.GetItem():
       
  1008                 self.DismissButtons()
       
  1009             if self.ItemButtons is None:
       
  1010                 
       
  1011                 self.ItemButtons = PopupWithButtons(self, self.ParentWindow, item, style)
       
  1012                 
       
  1013                 # Show the popup right below or above the button
       
  1014                 # depending on available screen space...
       
  1015                 w, h = self.ItemButtons.GetSize()
       
  1016                 if style == wx.HORIZONTAL:
       
  1017                     x = rect.x + rect.width
       
  1018                     y = rect.y + (rect.height - h) / 2
       
  1019                 else:
       
  1020                     x = rect.x + (rect.width - w ) / 2
       
  1021                     y = rect.y - h
       
  1022                 self.ItemButtons.SetPosition(self.ClientToScreen((x, y)))
       
  1023                 
       
  1024                 if wx.Platform == '__WXMSW__':
       
  1025                     self.ItemButtons.Popup()
       
  1026                 else:
       
  1027                     self.ItemButtons.Show()
       
  1028         
       
  1029         def DismissButtons(self):
       
  1030             if self.ItemButtons:
       
  1031                 if wx.Platform == '__WXMSW__':
       
  1032                     self.ItemButtons.Dismiss()
       
  1033                 else:
       
  1034                     self.ItemButtons.Destroy()
       
  1035                 self.ItemButtons = None
   878         
  1036         
   879         def OnAxesMotion(self, event):
  1037         def OnAxesMotion(self, event):
   880             if self.Is3DCanvas():
  1038             if self.Is3DCanvas():
   881                 current_time = gettime()
  1039                 current_time = gettime()
   882                 if current_time - self.LastMotionTime > REFRESH_PERIOD:
  1040                 if current_time - self.LastMotionTime > REFRESH_PERIOD:
   883                     self.LastMotionTime = current_time
  1041                     self.LastMotionTime = current_time
   884                     Axes3D._on_move(self.Axes, event)
  1042                     Axes3D._on_move(self.Axes, event)
   885         
       
   886         def OnSplitButton(self, event):
       
   887             if len(self.Items) == 2 or self.GraphType == GRAPH_ORTHOGONAL:
       
   888                 wx.CallAfter(self.ParentWindow.SplitGraphs, self)
       
   889             else:
       
   890                 menu = wx.Menu(title='')
       
   891                 for item in self.Items:
       
   892                     new_id = wx.NewId()
       
   893                     AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, 
       
   894                         text=item.GetVariable(self.ParentWindow.GetVariableNameMask()))
       
   895                     self.Bind(wx.EVT_MENU, 
       
   896                         self.GetSplitGraphMenuFunction(item),
       
   897                         id=new_id)
       
   898                 
       
   899                 new_id = wx.NewId()
       
   900                 AppendMenu(menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("All"))
       
   901                 self.Bind(wx.EVT_MENU, self.OnSplitAllGraphsMenu, id=new_id)
       
   902                 
       
   903                 self.PopupMenu(menu)
       
   904             event.Skip()
       
   905         
  1043         
   906         def ResetGraphics(self):
  1044         def ResetGraphics(self):
   907             self.Figure.clear()
  1045             self.Figure.clear()
   908             if self.Is3DCanvas():
  1046             if self.Is3DCanvas():
   909                 self.Axes = self.Figure.gca(projection='3d')
  1047                 self.Axes = self.Figure.gca(projection='3d')
   911                 self.LastMotionTime = gettime()
  1049                 self.LastMotionTime = gettime()
   912                 setattr(self.Axes, "_on_move", self.OnAxesMotion)
  1050                 setattr(self.Axes, "_on_move", self.OnAxesMotion)
   913                 self.Axes.mouse_init()
  1051                 self.Axes.mouse_init()
   914             else:
  1052             else:
   915                 self.Axes = self.Figure.gca()
  1053                 self.Axes = self.Figure.gca()
   916                 self.Figure.subplotpars.update(top=0.95)
  1054                 self.Figure.subplotpars.update(top=0.95, right=0.95)
   917                 if self.GraphType == GRAPH_ORTHOGONAL:
       
   918                     self.Figure.subplotpars.update(bottom=0.15)
       
   919             self.Plots = []
  1055             self.Plots = []
   920             self.VLine = None
  1056             self.VLine = None
   921             self.HLine = None
  1057             self.HLine = None
   922             self.Legend = None
  1058             self.Legend = None
   923             self.Labels = []
  1059             self.Labels = []
   924             if self.GraphType == GRAPH_PARALLEL:
  1060             self.AxesLabels = []
       
  1061             if self.GraphType == GRAPH_PARALLEL or self.Is3DCanvas():
   925                 num_item = len(self.Items)
  1062                 num_item = len(self.Items)
       
  1063                 if not self.Is3DCanvas():
       
  1064                     text_func = self.Axes.text
       
  1065                 else:
       
  1066                     text_func = self.Axes.text2D
   926                 for idx in xrange(num_item):
  1067                 for idx in xrange(num_item):
   927                     self.Labels.append(
  1068                     self.Labels.append(
   928                         self.Axes.text(0.95, 0.05 + (num_item - idx - 1) * 0.1, 
  1069                         text_func(0.95, 0.05 + (num_item - idx - 1) * 0.1, 
   929                                        "", size = 'large', 
  1070                                   "", size='large', 
   930                                        horizontalalignment='right',
  1071                                   horizontalalignment='right',
   931                                        color = color_cycle[idx % len(color_cycle)],
  1072                                   color=color_cycle[idx % len(color_cycle)],
   932                                        transform = self.Axes.transAxes))
  1073                                   transform=self.Axes.transAxes))
   933             self.SplitButton.Enable(len(self.Items) > 1)
  1074             else:
   934         
  1075                 self.AxesLabels.append(
       
  1076                     self.Axes.text(0.1, 0.05, "", size='small',
       
  1077                                    transform=self.Axes.transAxes))
       
  1078                 self.Labels.append(
       
  1079                     self.Axes.text(0.95, 0.05, "", size='large',
       
  1080                                    horizontalalignment='right',
       
  1081                                    transform=self.Axes.transAxes))
       
  1082                 self.AxesLabels.append(
       
  1083                     self.Axes.text(0.05, 0.1, "", size='small',
       
  1084                                    rotation='vertical',
       
  1085                                    verticalalignment='bottom',
       
  1086                                    transform=self.Axes.transAxes))
       
  1087                 self.Labels.append(
       
  1088                     self.Axes.text(0.05, 0.95, "", size='large',
       
  1089                                    rotation='vertical',
       
  1090                                    verticalalignment='top',
       
  1091                                    transform=self.Axes.transAxes))
       
  1092             
   935         def AddItem(self, item):
  1093         def AddItem(self, item):
   936             DebugVariableViewer.AddItem(self, item)
  1094             DebugVariableViewer.AddItem(self, item)
   937             self.ResetGraphics()
  1095             self.ResetGraphics()
   938             
  1096             
   939         def RemoveItem(self, item):
  1097         def RemoveItem(self, item):
   940             DebugVariableViewer.RemoveItem(self, item)
  1098             DebugVariableViewer.RemoveItem(self, item)
   941             if not self.IsEmpty():
  1099             if not self.IsEmpty():
       
  1100                 if len(self.Items) == 1:
       
  1101                     self.GraphType = GRAPH_PARALLEL
   942                 self.ResetGraphics()
  1102                 self.ResetGraphics()
   943         
  1103         
   944         def UnregisterObsoleteData(self):
  1104         def UnregisterObsoleteData(self):
   945             DebugVariableViewer.UnregisterObsoleteData(self)
  1105             DebugVariableViewer.UnregisterObsoleteData(self)
   946             if not self.IsEmpty():
  1106             if not self.IsEmpty():
  1067             variable_name_mask = self.ParentWindow.GetVariableNameMask()
  1227             variable_name_mask = self.ParentWindow.GetVariableNameMask()
  1068             if self.CursorTick is not None:
  1228             if self.CursorTick is not None:
  1069                 values, forced = apply(zip, [item.GetValue(self.CursorTick) for item in self.Items])
  1229                 values, forced = apply(zip, [item.GetValue(self.CursorTick) for item in self.Items])
  1070             else:
  1230             else:
  1071                 values, forced = apply(zip, [(item.GetValue(), item.IsForced()) for item in self.Items])
  1231                 values, forced = apply(zip, [(item.GetValue(), item.IsForced()) for item in self.Items])
  1072             names = [item.GetVariable(variable_name_mask) for item in self.Items]
  1232             labels = [item.GetVariable(variable_name_mask) for item in self.Items]
  1073             labels = map(lambda x: "%s: %s" % x, zip(names, values))
       
  1074             colors = map(lambda x: {True: 'b', False: 'k'}[x], forced)
  1233             colors = map(lambda x: {True: 'b', False: 'k'}[x], forced)
  1075             if self.GraphType == GRAPH_PARALLEL:
  1234             if self.GraphType == GRAPH_PARALLEL:
  1076                 if self.Legend is None:
  1235                 if self.Legend is None:
  1077                     self.Legend = self.Axes.legend(self.Plots, labels, 
  1236                     self.Legend = self.Axes.legend(self.Plots, labels, 
  1078                         loc="upper left", frameon=False, prop={'size':'small'}, 
  1237                         loc="upper left", frameon=False, prop={'size':'small'}, 
  1079                         title = '.'.join(variable_name_mask))
  1238                         title = '.'.join(variable_name_mask))
  1080                     self.Legend.get_title().set_fontsize('small')
  1239                     self.Legend.get_title().set_fontsize('small')
  1081                 for t, color in zip(self.Legend.get_texts(), colors):
  1240                 for t, color in zip(self.Legend.get_texts(), colors):
  1082                     t.set_color(color)
  1241                     t.set_color(color)
  1083                 for label, value in zip(self.Labels, values):
       
  1084                     label.set_text(value)
       
  1085             else:
  1242             else:
  1086                 self.Legend = None
  1243                 self.Legend = None
  1087                 self.Axes.set_xlabel(labels[0], fontdict={'size':'small','color':colors[0]})
  1244                 if self.Is3DCanvas():
  1088                 self.Axes.set_ylabel(labels[1], fontdict={'size':'small','color':colors[1]})
  1245                     self.Axes.set_xlabel(labels[0], fontdict={'size':'small','color':colors[0]})
  1089                 if len(labels) > 2:
  1246                     self.Axes.set_ylabel(labels[1], fontdict={'size':'small','color':colors[1]})
  1090                     self.Axes.set_zlabel(labels[2], fontdict={'size':'small','color':colors[2]})
  1247                     self.Axes.set_zlabel(labels[2], fontdict={'size':'small','color':colors[2]})
       
  1248                 else:
       
  1249                     for label, text, color in zip(self.AxesLabels, labels, colors):
       
  1250                         label.set_text(text)
       
  1251                         label.set_color(color)
       
  1252             for label, value in zip(self.Labels, values):
       
  1253                 label.set_text(value)
       
  1254                         
  1091             self.Canvas.draw()
  1255             self.Canvas.draw()
  1092         
       
  1093         def GetSplitGraphMenuFunction(self, item):
       
  1094             def SplitGraphFunction(event):
       
  1095                 self.ParentWindow.SplitGraphs(self, item)
       
  1096             return SplitGraphFunction
       
  1097         
       
  1098         def OnSplitAllGraphsMenu(self, event):
       
  1099             self.ParentWindow.SplitGraphs(self)
       
  1100     
  1256     
  1101 class DebugVariablePanel(wx.Panel, DebugViewer):
  1257 class DebugVariablePanel(wx.Panel, DebugViewer):
  1102     
  1258     
  1103     def __init__(self, parent, producer, window):
  1259     def __init__(self, parent, producer, window):
  1104         wx.Panel.__init__(self, parent, style=wx.SP_3D|wx.TAB_TRAVERSAL)
  1260         wx.Panel.__init__(self, parent, style=wx.SP_3D|wx.TAB_TRAVERSAL)
  1310         for panel in self.GraphicPanels:
  1466         for panel in self.GraphicPanels:
  1311             if isinstance(panel, DebugVariableGraphic):
  1467             if isinstance(panel, DebugVariableGraphic):
  1312                 panel.SetCursorTick(self.CursorTick)
  1468                 panel.SetCursorTick(self.CursorTick)
  1313         self.ForceRefresh()
  1469         self.ForceRefresh()
  1314     
  1470     
  1315     def StartDragNDrop(self, panel, x_mouse, y_mouse, x_mouse_start, y_mouse_start):
  1471     def StartDragNDrop(self, panel, item, x_mouse, y_mouse, x_mouse_start, y_mouse_start):
  1316         self.DraggingAxesPanel = panel
  1472         if len(panel.GetItems()) > 1:
       
  1473             self.DraggingAxesPanel = DebugVariableGraphic(self.GraphicsWindow, self, [item], GRAPH_PARALLEL)
       
  1474             self.DraggingAxesPanel.SetCursorTick(self.CursorTick)
       
  1475             width, height = panel.GetSize()
       
  1476             self.DraggingAxesPanel.SetMinSize(wx.Size(width, height))
       
  1477             self.DraggingAxesPanel.SetPosition(wx.Point(0, -height))
       
  1478         else:
       
  1479             self.DraggingAxesPanel = panel
  1317         self.DraggingAxesBoundingBox = panel.GetAxesBoundingBox(absolute=True)
  1480         self.DraggingAxesBoundingBox = panel.GetAxesBoundingBox(absolute=True)
  1318         self.DraggingAxesMousePos = wx.Point(
  1481         self.DraggingAxesMousePos = wx.Point(
  1319             x_mouse_start - self.DraggingAxesBoundingBox.x, 
  1482             x_mouse_start - self.DraggingAxesBoundingBox.x, 
  1320             y_mouse_start - self.DraggingAxesBoundingBox.y)
  1483             y_mouse_start - self.DraggingAxesBoundingBox.y)
  1321         self.MoveDragNDrop(x_mouse, y_mouse)
  1484         self.MoveDragNDrop(x_mouse, y_mouse)
  1322         
  1485         
  1323     def MoveDragNDrop(self, x_mouse, y_mouse):
  1486     def MoveDragNDrop(self, x_mouse, y_mouse):
  1324         self.DraggingAxesBoundingBox.x = x_mouse - self.DraggingAxesMousePos.x
  1487         self.DraggingAxesBoundingBox.x = x_mouse - self.DraggingAxesMousePos.x
  1325         self.DraggingAxesBoundingBox.y = y_mouse - self.DraggingAxesMousePos.y
  1488         self.DraggingAxesBoundingBox.y = y_mouse - self.DraggingAxesMousePos.y
  1326         for panel in self.GraphicPanels:
  1489         for idx, panel in enumerate(self.GraphicPanels):
  1327             x, y = panel.GetPosition()
  1490             x, y = panel.GetPosition()
  1328             width, height = panel.Canvas.GetSize()
  1491             width, height = panel.Canvas.GetSize()
  1329             rect = wx.Rect(x, y, width, height)
  1492             rect = wx.Rect(x, y, width, height)
  1330             if rect.InsideXY(x_mouse, y_mouse):
  1493             if (rect.InsideXY(x_mouse, y_mouse) or 
       
  1494                 idx == 0 and y_mouse < 0 or
       
  1495                 idx == len(self.GraphicPanels) - 1 and y_mouse > panel.GetPosition()[1]):
  1331                 panel.OnCanvasDragging(x_mouse - x, y_mouse - y, False)
  1496                 panel.OnCanvasDragging(x_mouse - x, y_mouse - y, False)
  1332             else:
  1497             else:
  1333                 panel.OnCanvasLeave(False)
  1498                 panel.OnCanvasLeave(False)
  1334         self.ForceRefresh()
  1499         self.ForceRefresh()
  1335     
  1500     
  1358                 merge_type = GRAPH_PARALLEL
  1523                 merge_type = GRAPH_PARALLEL
  1359                 if panel.Is3DCanvas():
  1524                 if panel.Is3DCanvas():
  1360                     if y_mouse > yw + height / 2:
  1525                     if y_mouse > yw + height / 2:
  1361                         idx += 1
  1526                         idx += 1
  1362                     wx.CallAfter(self.MoveGraph, variable, idx)
  1527                     wx.CallAfter(self.MoveGraph, variable, idx)
  1363                     return
       
  1364                 else:
  1528                 else:
  1365                     rect = panel.GetAxesBoundingBox(True)
  1529                     rect = panel.GetAxesBoundingBox(True)
  1366                     if rect.InsideXY(x_mouse, y_mouse):
  1530                     if rect.InsideXY(x_mouse, y_mouse):
  1367                         merge_rect = wx.Rect(rect.x, rect.y, rect.width / 2., rect.height)
  1531                         merge_rect = wx.Rect(rect.x, rect.y, rect.width / 2., rect.height)
  1368                         if merge_rect.InsideXY(x_mouse, y_mouse):
  1532                         if merge_rect.InsideXY(x_mouse, y_mouse):
  1370                         wx.CallAfter(self.MergeGraphs, variable, idx, merge_type, force=True)
  1534                         wx.CallAfter(self.MergeGraphs, variable, idx, merge_type, force=True)
  1371                     else:
  1535                     else:
  1372                         if y_mouse > yw + height / 2:
  1536                         if y_mouse > yw + height / 2:
  1373                             idx += 1
  1537                             idx += 1
  1374                         wx.CallAfter(self.MoveGraph, variable, idx)
  1538                         wx.CallAfter(self.MoveGraph, variable, idx)
  1375                 break
  1539                 self.ForceRefresh()
       
  1540                 return 
       
  1541         width, height = self.GraphicsWindow.GetVirtualSize()
       
  1542         rect = wx.Rect(0, 0, width, height)
       
  1543         if rect.InsideXY(x_mouse, y_mouse):
       
  1544             wx.CallAfter(self.MoveGraph, variable, len(self.GraphicPanels))
  1376         self.ForceRefresh()
  1545         self.ForceRefresh()
  1377     
  1546     
  1378     def RefreshView(self, only_values=False):
  1547     def RefreshView(self, only_values=False):
  1379         if USE_MPL:
  1548         if USE_MPL:
  1380             self.RefreshCanvasPosition()
  1549             self.RefreshCanvasPosition()
  1381             
  1550             
       
  1551             width, height = self.GraphicsWindow.GetVirtualSize()
       
  1552             bitmap = wx.EmptyBitmap(width, height)
       
  1553             dc = wx.BufferedPaintDC(self.GraphicsWindow, bitmap)
       
  1554             dc.Clear()
       
  1555             dc.BeginDrawing()
       
  1556             if self.DraggingAxesPanel is not None:
       
  1557                 destBBox = self.DraggingAxesBoundingBox
       
  1558                 srcBBox = self.DraggingAxesPanel.GetAxesBoundingBox()
       
  1559                 
       
  1560                 srcBmp = _convert_agg_to_wx_bitmap(self.DraggingAxesPanel.Canvas.get_renderer(), None)
       
  1561                 srcDC = wx.MemoryDC()
       
  1562                 srcDC.SelectObject(srcBmp)
       
  1563                     
       
  1564                 dc.Blit(destBBox.x, destBBox.y, 
       
  1565                         int(destBBox.width), int(destBBox.height), 
       
  1566                         srcDC, srcBBox.x, srcBBox.y)
       
  1567             dc.EndDrawing()
       
  1568             
  1382             if not self.Fixed or self.Force:
  1569             if not self.Fixed or self.Force:
  1383                 self.Force = False
  1570                 self.Force = False
  1384                 refresh_graphics = True
  1571                 refresh_graphics = True
  1385             else:
  1572             else:
  1386                 refresh_graphics = False
  1573                 refresh_graphics = False
  1387             
  1574             
       
  1575             if self.DraggingAxesPanel is not None and self.DraggingAxesPanel not in self.GraphicPanels:
       
  1576                 self.DraggingAxesPanel.Refresh()
  1388             for panel in self.GraphicPanels:
  1577             for panel in self.GraphicPanels:
  1389                 if isinstance(panel, DebugVariableGraphic):
  1578                 if isinstance(panel, DebugVariableGraphic):
  1390                     panel.Refresh(refresh_graphics)
  1579                     panel.Refresh(refresh_graphics)
  1391                 else:
  1580                 else:
  1392                     panel.Refresh()
  1581                     panel.Refresh()
  1732             
  1921             
  1733             panel = DebugVariableGraphic(self.GraphicsWindow, self, [item], GRAPH_PARALLEL)
  1922             panel = DebugVariableGraphic(self.GraphicsWindow, self, [item], GRAPH_PARALLEL)
  1734             if self.CursorTick is not None:
  1923             if self.CursorTick is not None:
  1735                 panel.SetCursorTick(self.CursorTick)
  1924                 panel.SetCursorTick(self.CursorTick)
  1736             self.GraphicPanels.insert(idx, panel)
  1925             self.GraphicPanels.insert(idx, panel)
  1737             self.ResetVariableNameMask()
       
  1738             self.RefreshGraphicsSizer()
       
  1739             self.ForceRefresh()
       
  1740     
       
  1741     def SplitGraphs(self, source_panel, item=None):
       
  1742         source_idx = self.GetViewerIndex(source_panel)
       
  1743         if source_idx is not None:
       
  1744             
       
  1745             if item is None:
       
  1746                 source_items = source_panel.GetItems()
       
  1747                 while len(source_items) > 1:
       
  1748                     item = source_items.pop(-1)
       
  1749                     if item.IsNumVariable():
       
  1750                         panel = DebugVariableGraphic(self.GraphicsWindow, self, [item], GRAPH_PARALLEL)
       
  1751                         if self.CursorTick is not None:
       
  1752                             panel.SetCursorTick(self.CursorTick)
       
  1753                     else:
       
  1754                         panel = DebugVariableText(self.GraphicsWindow, self, [item])
       
  1755                     self.GraphicPanels.insert(source_idx + 1, panel)
       
  1756                 if isinstance(source_panel, DebugVariableGraphic):
       
  1757                     source_panel.GraphType = GRAPH_PARALLEL
       
  1758                     source_panel.ResetGraphics()
       
  1759                     
       
  1760             else:
       
  1761                 source_panel.RemoveItem(item)
       
  1762                 if item.IsNumVariable():
       
  1763                     panel = DebugVariableGraphic(self.GraphicsWindow, self, [item], GRAPH_PARALLEL)
       
  1764                     if self.CursorTick is not None:
       
  1765                         panel.SetCursorTick(self.CursorTick)
       
  1766                 else:
       
  1767                     panel = DebugVariableText(self.GraphicsWindow, self, [item])
       
  1768                 self.GraphicPanels.insert(source_idx + 1, panel)
       
  1769             
       
  1770             self.ResetVariableNameMask()
  1926             self.ResetVariableNameMask()
  1771             self.RefreshGraphicsSizer()
  1927             self.RefreshGraphicsSizer()
  1772             self.ForceRefresh()
  1928             self.ForceRefresh()
  1773     
  1929     
  1774     def MergeGraphs(self, source, target_idx, merge_type, force=False):
  1930     def MergeGraphs(self, source, target_idx, merge_type, force=False):