controls/DebugVariablePanel/DebugVariableTextViewer.py
changeset 1200 501cb0bb4c05
parent 1199 fc0e7d80494f
child 1207 fb9799a0c0f7
equal deleted inserted replaced
1199:fc0e7d80494f 1200:501cb0bb4c05
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
       
     5 #based on the plcopen standard. 
       
     6 #
       
     7 #Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD
       
     8 #
       
     9 #See COPYING file for copyrights details.
       
    10 #
       
    11 #This library is free software; you can redistribute it and/or
       
    12 #modify it under the terms of the GNU General Public
       
    13 #License as published by the Free Software Foundation; either
       
    14 #version 2.1 of the License, or (at your option) any later version.
       
    15 #
       
    16 #This library is distributed in the hope that it will be useful,
       
    17 #but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    19 #General Public License for more details.
       
    20 #
       
    21 #You should have received a copy of the GNU General Public
       
    22 #License along with this library; if not, write to the Free Software
       
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    24 
       
    25 from types import TupleType
       
    26 
       
    27 import wx
       
    28 
       
    29 from DebugVariableItem import DebugVariableItem
       
    30 from DebugVariableViewer import DebugVariableViewer
       
    31 from GraphButton import GraphButton
       
    32 
       
    33 #-------------------------------------------------------------------------------
       
    34 #                     Debug Variable Text Viewer Drop Target
       
    35 #-------------------------------------------------------------------------------
       
    36 
       
    37 """
       
    38 Class that implements a custom drop target class for Debug Variable Text Viewer
       
    39 """
       
    40 
       
    41 class DebugVariableTextDropTarget(wx.TextDropTarget):
       
    42     
       
    43     def __init__(self, parent, window):
       
    44         """
       
    45         Constructor
       
    46         @param parent: Reference to Debug Variable Text Viewer
       
    47         @param window: Reference to the Debug Variable Panel
       
    48         """
       
    49         wx.TextDropTarget.__init__(self)
       
    50         self.ParentControl = parent
       
    51         self.ParentWindow = window
       
    52     
       
    53     def __del__(self):
       
    54         """
       
    55         Destructor
       
    56         """
       
    57         # Remove reference to Debug Variable Text Viewer and Debug Variable
       
    58         # Panel
       
    59         self.ParentControl = None
       
    60         self.ParentWindow = None
       
    61         
       
    62     def OnDragOver(self, x, y, d):
       
    63         """
       
    64         Function called when mouse is dragged over Drop Target
       
    65         @param x: X coordinate of mouse pointer
       
    66         @param y: Y coordinate of mouse pointer
       
    67         @param d: Suggested default for return value
       
    68         """
       
    69         # Signal parent that mouse is dragged over
       
    70         self.ParentControl.OnMouseDragging(x, y)
       
    71         
       
    72         return wx.TextDropTarget.OnDragOver(self, x, y, d)
       
    73         
       
    74     def OnDropText(self, x, y, data):
       
    75         """
       
    76         Function called when mouse is dragged over Drop Target
       
    77         @param x: X coordinate of mouse pointer
       
    78         @param y: Y coordinate of mouse pointer
       
    79         @param data: Text associated to drag'n drop
       
    80         """
       
    81         message = None
       
    82         
       
    83         # Check that data is valid regarding DebugVariablePanel
       
    84         try:
       
    85             values = eval(data)
       
    86             if not isinstance(values, TupleType):
       
    87                 raise
       
    88         except:
       
    89             message = _("Invalid value \"%s\" for debug variable") % data
       
    90             values = None
       
    91         
       
    92         # Display message if data is invalid
       
    93         if message is not None:
       
    94             wx.CallAfter(self.ShowMessage, message)
       
    95         
       
    96         # Data contain a reference to a variable to debug
       
    97         elif values[1] == "debug":
       
    98             
       
    99             # Get Before which Viewer the variable has to be moved or added
       
   100             # according to the position of mouse in Viewer.
       
   101             width, height = self.ParentControl.GetSize()
       
   102             target_idx = self.ParentControl.GetIndex()
       
   103             if y > height / 2:
       
   104                 target_idx += 1
       
   105             
       
   106             # Drag'n Drop is an internal is an internal move inside Debug
       
   107             # Variable Panel 
       
   108             if len(values) > 2 and values[2] == "move":
       
   109                 self.ParentWindow.MoveValue(values[0], 
       
   110                                             target_idx)
       
   111             
       
   112             # Drag'n Drop was initiated by another control of Beremiz
       
   113             else:
       
   114                 self.ParentWindow.InsertValue(values[0], 
       
   115                                               target_idx, 
       
   116                                               force=True)
       
   117     
       
   118     def OnLeave(self):
       
   119         """
       
   120         Function called when mouse is leave Drop Target
       
   121         """
       
   122         # Signal Debug Variable Panel to reset highlight
       
   123         self.ParentWindow.ResetHighlight()
       
   124         
       
   125         return wx.TextDropTarget.OnLeave(self)
       
   126     
       
   127     def ShowMessage(self, message):
       
   128         """
       
   129         Show error message in Error Dialog
       
   130         @param message: Error message to display
       
   131         """
       
   132         dialog = wx.MessageDialog(self.ParentWindow, 
       
   133                                   message, 
       
   134                                   _("Error"), 
       
   135                                   wx.OK|wx.ICON_ERROR)
       
   136         dialog.ShowModal()
       
   137         dialog.Destroy()
       
   138 
       
   139 
       
   140 #-------------------------------------------------------------------------------
       
   141 #                      Debug Variable Text Viewer Class
       
   142 #-------------------------------------------------------------------------------
       
   143 
       
   144 """
       
   145 Class that implements a Viewer that display variable values as a text
       
   146 """
       
   147 
       
   148 class DebugVariableTextViewer(DebugVariableViewer, wx.Panel):
       
   149     
       
   150     def __init__(self, parent, window, items=[]):
       
   151         """
       
   152         Constructor
       
   153         @param parent: Parent wx.Window of DebugVariableText
       
   154         @param window: Reference to the Debug Variable Panel
       
   155         @param items: List of DebugVariableItem displayed by Viewer
       
   156         """
       
   157         DebugVariableViewer.__init__(self, window, items)
       
   158         
       
   159         wx.Panel.__init__(self, parent)
       
   160         # Set panel background colour
       
   161         self.SetBackgroundColour(wx.WHITE)
       
   162         # Define panel drop target
       
   163         self.SetDropTarget(DebugVariableTextDropTarget(self, window))
       
   164         
       
   165         # Bind events
       
   166         self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
       
   167         self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
       
   168         self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnter)
       
   169         self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
       
   170         self.Bind(wx.EVT_SIZE, self.OnResize)
       
   171         self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
       
   172         self.Bind(wx.EVT_PAINT, self.OnPaint)
       
   173         
       
   174         # Define panel min size for parent sizer layout
       
   175         self.SetMinSize(wx.Size(0, 25))
       
   176         
       
   177         # Add buttons to Viewer
       
   178         for bitmap, callback in [("force", self.OnForceButton),
       
   179                                  ("release", self.OnReleaseButton),
       
   180                                  ("delete_graph", self.OnCloseButton)]:
       
   181             self.Buttons.append(GraphButton(0, 0, bitmap, callback))
       
   182         
       
   183         # Hide buttons until mouse enter Viewer
       
   184         self.ShowButtons(False)
       
   185     
       
   186     def RefreshViewer(self):
       
   187         """
       
   188         Method that refresh the content displayed by Viewer
       
   189         """
       
   190         # Create buffered DC for drawing in panel
       
   191         width, height = self.GetSize()
       
   192         bitmap = wx.EmptyBitmap(width, height)
       
   193         dc = wx.BufferedDC(wx.ClientDC(self), bitmap)
       
   194         dc.Clear()
       
   195         dc.BeginDrawing()
       
   196         
       
   197         # Get Graphics Context for DC, for anti-aliased and transparent
       
   198         # rendering
       
   199         gc = wx.GCDC(dc)
       
   200         
       
   201         # Get first item
       
   202         item = self.ItemsDict.values()[0]
       
   203         
       
   204         # Get item variable path masked according Debug Variable Panel mask
       
   205         item_path = item.GetVariable(
       
   206                 self.ParentWindow.GetVariableNameMask())
       
   207         
       
   208         # Draw item variable path at Viewer left side
       
   209         w, h = gc.GetTextExtent(item_path)
       
   210         gc.DrawText(item_path, 20, (height - h) / 2)
       
   211         
       
   212         # Update 'Release' button state and text color according to item forced
       
   213         # flag value
       
   214         item_forced = item.IsForced()
       
   215         self.Buttons[1].Enable(item_forced)
       
   216         self.RefreshButtonsPosition()
       
   217         if item_forced:
       
   218             gc.SetTextForeground(wx.BLUE)
       
   219         
       
   220         # Draw item current value at right side of Viewer
       
   221         item_value = item.GetValue()
       
   222         w, h = gc.GetTextExtent(item_value)
       
   223         gc.DrawText(item_value, width - 40 - w, (height - h) / 2)
       
   224         
       
   225         # Draw other Viewer common elements
       
   226         self.DrawCommonElements(gc)
       
   227         
       
   228         gc.EndDrawing()
       
   229     
       
   230     def OnLeftDown(self, event):
       
   231         """
       
   232         Function called when mouse left button is pressed
       
   233         @param event: wx.MouseEvent
       
   234         """
       
   235         # Get first item
       
   236         item = self.ItemsDict.values()[0]
       
   237         
       
   238         # Calculate item path bounding box
       
   239         width, height = self.GetSize()
       
   240         item_path = item.GetVariable(
       
   241                 self.ParentWindow.GetVariableNameMask())
       
   242         w, h = self.GetTextExtent(item_path)
       
   243         
       
   244         # Test if mouse has been pressed in this bounding box. In that case
       
   245         # start a move drag'n drop of item variable 
       
   246         x, y = event.GetPosition()
       
   247         item_path_bbox = wx.Rect(20, (height - h) / 2, w, h)
       
   248         if item_path_bbox.InsideXY(x, y):
       
   249             data = wx.TextDataObject(str((item.GetVariable(), "debug", "move")))
       
   250             dragSource = wx.DropSource(self)
       
   251             dragSource.SetData(data)
       
   252             dragSource.DoDragDrop()
       
   253         
       
   254         # In other case handle event normally
       
   255         else:
       
   256             event.Skip()
       
   257     
       
   258     def OnLeftUp(self, event):
       
   259         """
       
   260         Function called when mouse left button is released
       
   261         @param event: wx.MouseEvent
       
   262         """
       
   263         # Execute callback on button under mouse pointer if it exists
       
   264         x, y = event.GetPosition()
       
   265         wx.CallAfter(self.HandleButton, x, y)
       
   266         event.Skip()
       
   267     
       
   268     def OnPaint(self, event):
       
   269         """
       
   270         Function called when redrawing Viewer content is needed
       
   271         @param event: wx.PaintEvent
       
   272         """
       
   273         self.RefreshViewer()
       
   274         event.Skip()