Added support for opening text viewer by default and toggling between GraphicViewer and TextViewer
authorLaurent Bessard
Mon, 03 Jun 2013 17:29:03 +0200
changeset 1214 2ef048b5383c
parent 1213 599e43ec921b
child 1215 786f2533200a
Added support for opening text viewer by default and toggling between GraphicViewer and TextViewer
IDEFrame.py
controls/DebugVariablePanel/DebugVariableGraphicPanel.py
controls/DebugVariablePanel/DebugVariableGraphicViewer.py
controls/DebugVariablePanel/DebugVariableItem.py
controls/DebugVariablePanel/DebugVariableTablePanel.py
controls/DebugVariablePanel/DebugVariableTextViewer.py
controls/PouInstanceVariablesPanel.py
graphics/DebugDataConsumer.py
--- a/IDEFrame.py	Mon Jun 03 11:52:13 2013 +0200
+++ b/IDEFrame.py	Mon Jun 03 17:29:03 2013 +0200
@@ -2029,9 +2029,9 @@
                     editor.SubscribeAllDataConsumers()
             self.DebugVariablePanel.SubscribeAllDataConsumers()
     
-    def AddDebugVariable(self, iec_path, force=False):
+    def AddDebugVariable(self, iec_path, force=False, graph=False):
         if self.EnableDebug:
-            self.DebugVariablePanel.InsertValue(iec_path, force=force)
+            self.DebugVariablePanel.InsertValue(iec_path, force=force, graph=graph)
             self.EnsureTabVisible(self.DebugVariablePanel)
             
 #-------------------------------------------------------------------------------
--- a/controls/DebugVariablePanel/DebugVariableGraphicPanel.py	Mon Jun 03 11:52:13 2013 +0200
+++ b/controls/DebugVariablePanel/DebugVariableGraphicPanel.py	Mon Jun 03 17:29:03 2013 +0200
@@ -215,6 +215,9 @@
         
         self.SetSizer(main_sizer)
     
+    def __del__(self):
+        DebugViewer.__del__(self)
+    
     def SetTickTime(self, ticktime=0):
         self.Ticktime = ticktime
         if self.Ticktime == 0:
@@ -377,7 +380,7 @@
                 if isinstance(panel, DebugVariableTextViewer) or panel.Is3DCanvas():
                     if y_mouse > yw + height / 2:
                         idx += 1
-                    wx.CallAfter(self.MoveValue, variable, idx)
+                    wx.CallAfter(self.MoveValue, variable, idx, True)
                 else:
                     rect = panel.GetAxesBoundingBox(True)
                     if rect.InsideXY(x_mouse, y_mouse):
@@ -388,13 +391,13 @@
                     else:
                         if y_mouse > yw + height / 2:
                             idx += 1
-                        wx.CallAfter(self.MoveValue, variable, idx)
+                        wx.CallAfter(self.MoveValue, variable, idx, True)
                 self.ForceRefresh()
                 return 
         width, height = self.GraphicsWindow.GetVirtualSize()
         rect = wx.Rect(0, 0, width, height)
         if rect.InsideXY(x_mouse, y_mouse):
-            wx.CallAfter(self.MoveValue, variable, len(self.GraphicPanels))
+            wx.CallAfter(self.MoveValue, variable, len(self.GraphicPanels), True)
         self.ForceRefresh()
     
     def RefreshView(self):
@@ -591,9 +594,6 @@
     def IsViewerFirst(self, viewer):
         return viewer == self.GraphicPanels[0]
     
-    def IsViewerLast(self, viewer):
-        return viewer == self.GraphicPanels[-1]
-    
     def HighlightPreviousViewer(self, viewer):
         if self.IsViewerFirst(viewer):
             return
@@ -619,7 +619,7 @@
     def GetVariableNameMask(self):
         return self.VariableNameMask
     
-    def InsertValue(self, iec_path, idx = None, force=False):
+    def InsertValue(self, iec_path, idx = None, force=False, graph=False):
         for panel in self.GraphicPanels:
             if panel.GetItem(iec_path) is not None:
                 return
@@ -630,7 +630,7 @@
         if result is not None or force:
             
             self.Freeze()
-            if item.IsNumVariable():
+            if item.IsNumVariable() and graph:
                 panel = DebugVariableGraphicViewer(self.GraphicsWindow, self, [item], GRAPH_PARALLEL)
                 if self.CursorTick is not None:
                     panel.SetCursorTick(self.CursorTick)
@@ -645,7 +645,7 @@
             self.Thaw()
             self.ForceRefresh()
     
-    def MoveValue(self, iec_path, idx = None):
+    def MoveValue(self, iec_path, idx = None, graph=False):
         if idx is None:
             idx = len(self.GraphicPanels)
         source_panel = None
@@ -656,22 +656,29 @@
                 source_panel = panel
                 break
         if source_panel is not None:
+            source_panel_idx = self.GraphicPanels.index(source_panel)
+            if len(panel.GetItems()) == 1 and \
+               idx in [source_panel_idx, source_panel_idx + 1]:
+                return
+            
             source_panel.RemoveItem(item)
             source_size = source_panel.GetSize()
+            if item.IsNumVariable() and graph:
+                panel = DebugVariableGraphicViewer(self.GraphicsWindow, self, [item], GRAPH_PARALLEL)
+                panel.SetCanvasSize(source_size.width, source_size.height)
+                if self.CursorTick is not None:
+                    panel.SetCursorTick(self.CursorTick)
+            else:
+                panel = DebugVariableTextViewer(self.GraphicsWindow, self, [item])
+            
+            self.GraphicPanels.insert(idx, panel)
+            
             if source_panel.ItemsIsEmpty():
                 if source_panel.HasCapture():
                     source_panel.ReleaseMouse()
                 self.GraphicPanels.remove(source_panel)
                 source_panel.Destroy()
             
-            if item.IsNumVariable():
-                panel = DebugVariableGraphicViewer(self.GraphicsWindow, self, [item], GRAPH_PARALLEL)
-                panel.SetCanvasSize(source_size.width, source_size.height)
-                if self.CursorTick is not None:
-                    panel.SetCursorTick(self.CursorTick)
-            else:
-                panel = DebugVariableTextViewer(self.GraphicsWindow, self, [item])
-            self.GraphicPanels.insert(idx, panel)
             self.ResetVariableNameMask()
             self.RefreshGraphicsSizer()
             self.ForceRefresh()
@@ -751,6 +758,22 @@
                     self.RefreshGraphicsSizer()
             self.ForceRefresh()
     
+    def ToggleViewerType(self, panel):
+        panel_idx = self.GetViewerIndex(panel)
+        if panel_idx is not None:
+            self.GraphicPanels.remove(panel)
+            items = panel.GetItems()
+            if isinstance(panel, DebugVariableGraphicViewer):
+                for idx, item in enumerate(items):
+                    new_panel = DebugVariableTextViewer(self.GraphicsWindow, self, [item])
+                    self.GraphicPanels.insert(panel_idx + idx, new_panel)
+            else:
+                new_panel = DebugVariableGraphicViewer(self.GraphicsWindow, self, items, GRAPH_PARALLEL)
+                self.GraphicPanels.insert(panel_idx, new_panel)
+            panel.Destroy()
+        self.RefreshGraphicsSizer()
+        self.ForceRefresh()
+    
     def ResetGraphicsValues(self):
         self.Ticks = numpy.array([])
         self.StartTick = 0
--- a/controls/DebugVariablePanel/DebugVariableGraphicViewer.py	Mon Jun 03 11:52:13 2013 +0200
+++ b/controls/DebugVariablePanel/DebugVariableGraphicViewer.py	Mon Jun 03 17:29:03 2013 +0200
@@ -239,6 +239,7 @@
         self.SetBackgroundColour(wx.WHITE)
         
         # Bind wx events
+        self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDClick)
         self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
         self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter)
         self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
@@ -613,7 +614,6 @@
         else:
             # Reset any move in progress
             self.MouseStartPos = None
-            self.StartCursorTick = None
             self.CanvasStartSize = None
             
             # Handle button under mouse if it exist
@@ -752,6 +752,23 @@
             # Vetoing event to prevent parent panel to be scrolled
             self.ParentWindow.VetoScrollEvent = True
     
+    def OnLeftDClick(self, event):
+        """
+        Function called when a left mouse button is double clicked
+        @param event: Mouse event
+        """
+        # Check that double click was done inside figure
+        pos = event.GetPosition()
+        rect = self.GetAxesBoundingBox()
+        if rect.InsideXY(pos.x, pos.y):
+            # Reset Cursor tick to value before starting clicking
+            self.ParentWindow.SetCursorTick(self.StartCursorTick)
+            # Toggle to text Viewer(s)
+            self.ParentWindow.ToggleViewerType(self)
+        
+        else:
+            event.Skip()
+    
     # Cursor tick move for each arrow key
     KEY_CURSOR_INCREMENT = {
         wx.WXK_LEFT: -1,
@@ -982,7 +999,7 @@
         # text position in figure don't change when canvas size change, we
         # expressed border and text position in pixel on screen and apply the
         # ratio calculated hereafter to get border and text position in
-        # matplotlib coordinate 
+        # matplotlib coordinate
         canvas_ratio = 1. / height # Divide by canvas height in pixel
         graph_ratio = 1. / (
             (1.0 - (CANVAS_BORDER[0] + CANVAS_BORDER[1]) * canvas_ratio)
--- a/controls/DebugVariablePanel/DebugVariableItem.py	Mon Jun 03 11:52:13 2013 +0200
+++ b/controls/DebugVariablePanel/DebugVariableItem.py	Mon Jun 03 17:29:03 2013 +0200
@@ -211,7 +211,7 @@
         @param value: Value captured
         @param forced: Forced flag, True if value is forced (default: False)
         """
-        DebugDataConsumer.NewValue(self, tick, value, forced)
+        DebugDataConsumer.NewValue(self, tick, value, forced, raw_bool=False)
         
         if self.Data is not None:
             # String data value is CRC
--- a/controls/DebugVariablePanel/DebugVariableTablePanel.py	Mon Jun 03 11:52:13 2013 +0200
+++ b/controls/DebugVariablePanel/DebugVariableTablePanel.py	Mon Jun 03 17:29:03 2013 +0200
@@ -470,7 +470,7 @@
             menu.Destroy()
         event.Skip()
     
-    def InsertValue(self, iec_path, index=None, force=False):
+    def InsertValue(self, iec_path, index=None, force=False, graph=False):
         """
         Insert a new variable to debug in table
         @param iec_path: Variable path to debug
@@ -478,6 +478,8 @@
         insert at last position)
         @param force: Force insertion of variable even if not defined in
         producer side
+        @param graph: Values must be displayed in graph canvas (Do nothing,
+        here for compatibility with Debug Variable Graphic Panel)
         """
         # Return immediately if variable is already debugged
         for item in self.Table.GetData():
--- a/controls/DebugVariablePanel/DebugVariableTextViewer.py	Mon Jun 03 11:52:13 2013 +0200
+++ b/controls/DebugVariablePanel/DebugVariableTextViewer.py	Mon Jun 03 17:29:03 2013 +0200
@@ -165,6 +165,7 @@
         # Bind events
         self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
         self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
+        self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDClick)
         self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter)
         self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
         self.Bind(wx.EVT_SIZE, self.OnResize)
@@ -244,6 +245,7 @@
         x, y = event.GetPosition()
         item_path_bbox = wx.Rect(20, (height - h) / 2, w, h)
         if item_path_bbox.InsideXY(x, y):
+            self.ShowButtons(False)
             data = wx.TextDataObject(str((item.GetVariable(), "debug", "move")))
             dragSource = wx.DropSource(self)
             dragSource.SetData(data)
@@ -263,6 +265,15 @@
         wx.CallAfter(self.HandleButton, x, y)
         event.Skip()
     
+    def OnLeftDClick(self, event):
+        """
+        Function called when mouse left button is double clicked
+        @param event: wx.MouseEvent
+        """
+        # Only numeric variables can be toggled to graph canvas
+        if self.ItemsDict.values()[0].IsNumVariable():
+            self.ParentWindow.ToggleViewerType(self)
+    
     def OnPaint(self, event):
         """
         Function called when redrawing Viewer content is needed
--- a/controls/PouInstanceVariablesPanel.py	Mon Jun 03 11:52:13 2013 +0200
+++ b/controls/PouInstanceVariablesPanel.py	Mon Jun 03 17:29:03 2013 +0200
@@ -174,6 +174,7 @@
                           bitmap=GetBitmap("debug_instance"), 
                           size=wx.Size(28, 28), style=wx.NO_BORDER)
                     self.Bind(wx.EVT_BUTTON, self.GenDebugButtonCallback(var_infos), debug_button)
+                    debug_button.Bind(wx.EVT_RIGHT_UP, self.GenDebugButtonRightClickCallback(var_infos))
                     buttons.append(debug_button)
                 
                 button_num = len(buttons)
@@ -279,6 +280,18 @@
             event.Skip()
         return DebugButtonCallback
     
+    def GenDebugButtonRightClickCallback(self, infos):
+        def DebugButtonCallback(event):
+            if self.InstanceChoice.GetSelection() != -1:
+                if infos["class"] in ITEMS_VARIABLE:
+                    self.ParentWindow.AddDebugVariable(
+                        "%s.%s" % (self.InstanceChoice.GetStringSelection(), 
+                                   infos["name"]), 
+                        force=True,
+                        graph=True)
+            event.Skip()
+        return DebugButtonCallback
+    
     def GenGraphButtonCallback(self, infos):
         def GraphButtonCallback(event):
             if self.InstanceChoice.GetSelection() != -1:
--- a/graphics/DebugDataConsumer.py	Mon Jun 03 11:52:13 2013 +0200
+++ b/graphics/DebugDataConsumer.py	Mon Jun 03 17:29:03 2013 +0200
@@ -141,8 +141,7 @@
     "STRING": lambda v: "'%s'" % v,
     "WSTRING": lambda v: '"%s"' % v,
     "REAL": lambda v: "%.6g" % v,
-    "LREAL": lambda v: "%.6g" % v,
-    "BOOL": lambda v: v}
+    "LREAL": lambda v: "%.6g" % v}
 
 #-------------------------------------------------------------------------------
 #                            Debug Data Consumer Class
@@ -198,15 +197,17 @@
         """
         self.DataType = data_type
     
-    def NewValue(self, tick, value, forced=False):
+    def NewValue(self, tick, value, forced=False, raw_bool=True):
         """
         Function called by debug thread when a new debug value is available
         @param tick: PLC tick when value was captured
         @param value: Value captured
         @param forced: Forced flag, True if value is forced (default: False)
+        @param raw_bool: Bool values must be treated rawly (default: True)
         """
         # Translate value to IEC literal
-        value = TYPE_TRANSLATOR.get(self.DataType, str)(value)
+        if self.DataType != "BOOL" or not raw_bool:
+            value = TYPE_TRANSLATOR.get(self.DataType, str)(value)
         
         # Store value and forced flag when value update is inhibited
         if self.Inhibited: