dialogs/LDElementDialog.py
changeset 1246 101625efb1c1
parent 814 5743cbdff669
child 1247 92588e69d853
equal deleted inserted replaced
1245:d34ba528346b 1246:101625efb1c1
    22 #License along with this library; if not, write to the Free Software
    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
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24 
    24 
    25 import wx
    25 import wx
    26 
    26 
    27 from graphics import *
    27 from graphics.GraphicCommons import CONTACT_NORMAL, CONTACT_REVERSE, \
       
    28     CONTACT_RISING, CONTACT_FALLING, COIL_NORMAL, COIL_REVERSE, COIL_SET, \
       
    29     COIL_RESET, COIL_RISING, COIL_FALLING
       
    30 from graphics.LD_Objects import LD_Contact, LD_Coil
       
    31 from BlockPreviewDialog import BlockPreviewDialog
    28 
    32 
    29 #-------------------------------------------------------------------------------
    33 #-------------------------------------------------------------------------------
    30 #                        Edit Ladder Element Properties Dialog
    34 #                       Set Ladder Element Parmeters Dialog
    31 #-------------------------------------------------------------------------------
    35 #-------------------------------------------------------------------------------
    32 
    36 
    33 class LDElementDialog(wx.Dialog):
    37 """
       
    38 Class that implements a dialog for defining parameters of a LD contact or coil
       
    39 graphic element
       
    40 """
       
    41 
       
    42 class LDElementDialog(BlockPreviewDialog):
    34     
    43     
    35     def __init__(self, parent, controller, type):
    44     def __init__(self, parent, controller, tagname, type):
    36         if type == "contact":
    45         """
    37             wx.Dialog.__init__(self, parent, size=wx.Size(350, 260),
    46         Constructor
    38                   title=_("Edit Contact Values"))
    47         @param parent: Parent wx.Window of dialog for modal
    39         else:
    48         @param controller: Reference to project controller
    40             wx.Dialog.__init__(self, parent, size=wx.Size(350, 310),
    49         @param tagname: Tagname of project POU edited
    41                   title=_("Edit Coil Values"))
    50         @param type: Type of LD element ('contact or 'coil')
    42         
    51         """
       
    52         BlockPreviewDialog.__init__(self, parent, controller, tagname, 
       
    53               size=wx.Size(350, 260 if type == "contact" else 310),
       
    54               title=(_("Edit Contact Values")
       
    55                      if type == "contact"
       
    56                      else _("Edit Coil Values")))
       
    57         
       
    58         # Create dialog main sizer
    43         main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
    59         main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
    44         main_sizer.AddGrowableCol(0)
    60         main_sizer.AddGrowableCol(0)
    45         main_sizer.AddGrowableRow(0)
    61         main_sizer.AddGrowableRow(0)
    46         
    62         
       
    63         # Create a sizer for dividing LD element parameters in two columns
    47         column_sizer = wx.BoxSizer(wx.HORIZONTAL)
    64         column_sizer = wx.BoxSizer(wx.HORIZONTAL)
    48         main_sizer.AddSizer(column_sizer, border=20, 
    65         main_sizer.AddSizer(column_sizer, border=20, 
    49               flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
    66               flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
    50         
    67         
    51         if type == "contact":
    68         # Create a sizer for left column
    52             left_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, rows=7, vgap=0)
    69         left_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, 
    53         else:
    70               rows=(7 if type == "contact" else 9), vgap=0)
    54             left_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, rows=9, vgap=0)
       
    55         left_gridsizer.AddGrowableCol(0)
    71         left_gridsizer.AddGrowableCol(0)
    56         column_sizer.AddSizer(left_gridsizer, 1, border=5, 
    72         column_sizer.AddSizer(left_gridsizer, 1, border=5, 
    57               flag=wx.GROW|wx.RIGHT)
    73               flag=wx.GROW|wx.RIGHT)
    58         
    74         
       
    75         # Create label for LD element modifier
    59         modifier_label = wx.StaticText(self, label=_('Modifier:'))
    76         modifier_label = wx.StaticText(self, label=_('Modifier:'))
    60         left_gridsizer.AddWindow(modifier_label, border=5, flag=wx.GROW|wx.BOTTOM)
    77         left_gridsizer.AddWindow(modifier_label, border=5, 
    61         
    78               flag=wx.GROW|wx.BOTTOM)
    62         self.Normal = wx.RadioButton(self, label=_("Normal"), style=wx.RB_GROUP)
    79         
    63         self.Normal.SetValue(True)
    80         # Create radio buttons for selecting LD element modifier
    64         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, self.Normal)
    81         self.ModifierRadioButtons = {}
    65         left_gridsizer.AddWindow(self.Normal, flag=wx.GROW)
    82         first = True
    66         
    83         element_modifiers = ([CONTACT_NORMAL, CONTACT_REVERSE, 
    67         self.Negated = wx.RadioButton(self, label=_("Negated"))
    84                               CONTACT_RISING, CONTACT_FALLING]
    68         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, self.Negated)
    85                              if type == "contact"
    69         left_gridsizer.AddWindow(self.Negated, flag=wx.GROW)
    86                              else [COIL_NORMAL, COIL_REVERSE, COIL_SET,
    70         
    87                                    COIL_RESET, COIL_RISING, COIL_FALLING])
    71         if type != "contact":
    88         modifiers_label = [_("Normal"), _("Negated")] + \
    72             self.Set = wx.RadioButton(self, label=_("Set"))
    89                           ([_("Set"), _("Reset")] if type == "coil" else []) + \
    73             self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, self.Set)
    90                           [_("Rising Edge"), _("Falling Edge")]
    74             left_gridsizer.AddWindow(self.Set, flag=wx.GROW)
    91         
    75             
    92         for modifier, label in zip(element_modifiers, modifiers_label):
    76             self.Reset = wx.RadioButton(self, label=_("Reset"))
    93             radio_button = wx.RadioButton(self, label=label, 
    77             self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, self.Reset)
    94                   style=(wx.RB_GROUP if first else wx.RB_SINGLE))
    78             left_gridsizer.AddWindow(self.Reset, flag=wx.GROW)
    95             radio_button.SetValue(first)
    79             
    96             self.Bind(wx.EVT_RADIOBUTTON, self.OnModifierChanged, radio_button)
    80         self.RisingEdge = wx.RadioButton(self, label=_("Rising Edge"))
    97             left_gridsizer.AddWindow(radio_button, flag=wx.GROW)
    81         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, self.RisingEdge)
    98             self.ModifierRadioButtons[modifier] = radio_button
    82         left_gridsizer.AddWindow(self.RisingEdge, flag=wx.GROW)
    99             first = False
    83         
   100         
    84         self.FallingEdge = wx.RadioButton(self, label=_("Falling Edge"))
   101         # Create label for LD element variable
    85         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, self.FallingEdge)
   102         element_variable_label = wx.StaticText(self, label=_('Variable:'))
    86         left_gridsizer.AddWindow(self.FallingEdge, flag=wx.GROW)
   103         left_gridsizer.AddWindow(element_variable_label, border=5,
    87         
   104               flag=wx.GROW|wx.TOP)
    88         element_name_label = wx.StaticText(self, label=_('Name:'))
   105         
    89         left_gridsizer.AddWindow(element_name_label, border=5, flag=wx.GROW|wx.TOP)
   106         # Create a combo box for defining LD element variable
    90         
   107         self.ElementVariable = wx.ComboBox(self, style=wx.CB_READONLY)
    91         self.ElementName = wx.ComboBox(self, style=wx.CB_READONLY)
   108         self.Bind(wx.EVT_COMBOBOX, self.OnVariableChanged, 
    92         self.Bind(wx.EVT_COMBOBOX, self.OnNameChanged, self.ElementName)
   109                   self.ElementVariable)
    93         left_gridsizer.AddWindow(self.ElementName, border=5, flag=wx.GROW|wx.TOP)
   110         left_gridsizer.AddWindow(self.ElementVariable, border=5,
    94         
   111              flag=wx.GROW|wx.TOP)
       
   112         
       
   113         # Create a sizer for right column
    95         right_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
   114         right_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
    96         right_gridsizer.AddGrowableCol(0)
   115         right_gridsizer.AddGrowableCol(0)
    97         right_gridsizer.AddGrowableRow(1)
   116         right_gridsizer.AddGrowableRow(1)
    98         column_sizer.AddSizer(right_gridsizer, 1, border=5, 
   117         column_sizer.AddSizer(right_gridsizer, 1, border=5, 
    99               flag=wx.GROW|wx.LEFT)
   118               flag=wx.GROW|wx.LEFT)
   100         
   119         
   101         preview_label = wx.StaticText(self, label=_('Preview:'))
   120         # Add preview panel and associated label to sizers
   102         right_gridsizer.AddWindow(preview_label, flag=wx.GROW)
   121         right_gridsizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
   103 
       
   104         self.Preview = wx.Panel(self,
       
   105               style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
   106         self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
       
   107         setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
       
   108         setattr(self.Preview, "GetScaling", lambda:None)
       
   109         setattr(self.Preview, "IsOfType", controller.IsOfType)
       
   110         self.Preview.Bind(wx.EVT_PAINT, self.OnPaint)
       
   111         right_gridsizer.AddWindow(self.Preview, flag=wx.GROW)
   122         right_gridsizer.AddWindow(self.Preview, flag=wx.GROW)
   112         
   123         
   113         button_sizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
   124         # Add buttons sizer to sizers
   114         main_sizer.AddSizer(button_sizer, border=20, 
   125         main_sizer.AddSizer(self.ButtonSizer, border=20, 
   115               flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
   126               flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
   116         
   127         
   117         self.SetSizer(main_sizer)
   128         self.SetSizer(main_sizer)
   118         
   129         
   119         if type == "contact":
   130         # Save LD element class
   120             self.Element = LD_Contact(self.Preview, CONTACT_NORMAL, "")
   131         self.ElementClass = (LD_Contact if type == "contact" else LD_Coil)
   121         else:
   132         
   122             self.Element = LD_Coil(self.Preview, COIL_NORMAL, "")
   133         # Extract list of variables defined in POU
   123         
   134         self.RefreshVariableList()
   124         self.Type = type
   135         
   125         
   136         # Set values in ElementVariable
   126         self.Normal.SetFocus()
   137         for name, (var_type, value_type) in self.VariableList.iteritems():
       
   138             # Only select BOOL variable and avoid input for coil
       
   139             if (type == "contact" or var_type != "Input") and \
       
   140                value_type == "BOOL":
       
   141                 self.ElementVariable.Append(name)
       
   142         self.ElementVariable.Enable(self.ElementVariable.GetCount() > 0)
       
   143         
       
   144         # Normal radio button is default control having keyboard focus
       
   145         self.ModifierRadioButtons[element_modifiers[0]].SetFocus()
   127     
   146     
   128     def SetPreviewFont(self, font):
   147     def GetElementModifier(self):
   129         self.Preview.SetFont(font)
   148         """
   130     
   149         Return modifier selected for LD element
   131     def SetElementSize(self, size):
   150         @return: Modifier selected (None if not found)
   132         min_width, min_height = self.Element.GetMinSize()
   151         """
   133         width, height = max(min_width, size[0]), max(min_height, size[1])
   152         # Go through radio buttons and return modifier associated to the one
   134         self.Element.SetSize(width, height)
   153         # that is selected
   135         
   154         for modifier, control in self.ModifierRadioButtons.iteritems():
   136     def SetVariables(self, vars):
   155             if control.GetValue():
   137         self.ElementName.Clear()
   156                 return modifier
   138         for name in vars:
   157         return None
   139             self.ElementName.Append(name)
       
   140         self.ElementName.Enable(self.ElementName.GetCount() > 0)
       
   141 
   158 
   142     def SetValues(self, values):
   159     def SetValues(self, values):
       
   160         """
       
   161         Set default LD element parameters
       
   162         @param values: Block parameters values
       
   163         """
       
   164         # For each parameters defined, set corresponding control value
   143         for name, value in values.items():
   165         for name, value in values.items():
   144             if name == "name":
   166             
   145                 self.Element.SetName(value)
   167             # Parameter is LD element variable
   146                 self.ElementName.SetStringSelection(value)
   168             if name == "variable":
   147             elif name == "type":
   169                 self.ElementVariable.SetStringSelection(value)
   148                 self.Element.SetType(value)
   170             
   149                 if self.Type == "contact":
   171             # Set value of other controls
   150                     if value == CONTACT_NORMAL:
   172             elif name == "modifier":
   151                         self.Normal.SetValue(True)
   173                 self.ModifierRadioButtons[value].SetValue(True)
   152                     elif value == CONTACT_REVERSE:
   174         
   153                         self.Negated.SetValue(True)
   175         # Refresh preview panel
   154                     elif value == CONTACT_RISING:
   176         self.RefreshPreview()
   155                         self.RisingEdge.SetValue(True)
       
   156                     elif value == CONTACT_FALLING:
       
   157                         self.FallingEdge.SetValue(True)
       
   158                 elif self.Type == "coil":
       
   159                     if value == COIL_NORMAL:
       
   160                         self.Normal.SetValue(True)
       
   161                     elif value == COIL_REVERSE:
       
   162                         self.Negated.SetValue(True)
       
   163                     elif value == COIL_SET:
       
   164                         self.Set.SetValue(True)
       
   165                     elif value == COIL_RESET:
       
   166                         self.Reset.SetValue(True)
       
   167                     elif value == COIL_RISING:
       
   168                         self.RisingEdge.SetValue(True)
       
   169                     elif value == COIL_FALLING:
       
   170                         self.FallingEdge.SetValue(True)
       
   171 
   177 
   172     def GetValues(self):
   178     def GetValues(self):
   173         values = {}
   179         """
   174         values["name"] = self.Element.GetName()
   180         Return LD element parameters defined in dialog
   175         values["type"] = self.Element.GetType()
   181         @return: {parameter_name: parameter_value,...}
       
   182         """
       
   183         values = {
       
   184             "variable": self.ElementVariable.GetValue(),
       
   185             "modifier": self.GetElementModifier()}
   176         values["width"], values["height"] = self.Element.GetSize()
   186         values["width"], values["height"] = self.Element.GetSize()
   177         return values
   187         return values
   178 
   188 
   179     def OnTypeChanged(self, event):
   189     def OnModifierChanged(self, event):
   180         if self.Type == "contact":
   190         """
   181             if self.Normal.GetValue():
   191         Called when LD element modifier changed
   182                 self.Element.SetType(CONTACT_NORMAL)
   192         @param event: wx.RadioButtonEvent
   183             elif self.Negated.GetValue():
   193         """
   184                 self.Element.SetType(CONTACT_REVERSE)
       
   185             elif self.RisingEdge.GetValue():
       
   186                 self.Element.SetType(CONTACT_RISING)
       
   187             elif self.FallingEdge.GetValue():
       
   188                 self.Element.SetType(CONTACT_FALLING)
       
   189         elif self.Type == "coil":
       
   190             if self.Normal.GetValue():
       
   191                 self.Element.SetType(COIL_NORMAL)
       
   192             elif self.Negated.GetValue():
       
   193                 self.Element.SetType(COIL_REVERSE)
       
   194             elif self.Set.GetValue():
       
   195                 self.Element.SetType(COIL_SET)
       
   196             elif self.Reset.GetValue():
       
   197                 self.Element.SetType(COIL_RESET)
       
   198             elif self.RisingEdge.GetValue():
       
   199                 self.Element.SetType(COIL_RISING)
       
   200             elif self.FallingEdge.GetValue():
       
   201                 self.Element.SetType(COIL_FALLING)
       
   202         self.RefreshPreview()
   194         self.RefreshPreview()
   203         event.Skip()
   195         event.Skip()
   204 
   196 
   205     def OnNameChanged(self, event):
   197     def OnVariableChanged(self, event):
   206         self.Element.SetName(self.ElementName.GetStringSelection())
   198         """
       
   199         Called when LD element associated variable changed
       
   200         @param event: wx.ComboBoxEvent
       
   201         """
   207         self.RefreshPreview()
   202         self.RefreshPreview()
   208         event.Skip()
   203         event.Skip()
   209 
   204 
   210     def RefreshPreview(self):
   205     def RefreshPreview(self):
   211         dc = wx.ClientDC(self.Preview)
   206         """
   212         dc.SetFont(self.Preview.GetFont())
   207         Refresh preview panel of graphic element
   213         dc.Clear()
   208         Override BlockPreviewDialog function
   214         clientsize = self.Preview.GetClientSize()
   209         """
   215         width, height = self.Element.GetSize()
   210         # Set graphic element displayed, creating a LD element
   216         self.Element.SetPosition((clientsize.width - width) / 2, (clientsize.height - height) / 2)
   211         self.Element = self.ElementClass(
   217         self.Element.Draw(dc)
   212                 self.Preview, 
   218 
   213                 self.GetElementModifier(),
   219     def OnPaint(self, event):
   214                 self.ElementVariable.GetStringSelection())
   220         self.RefreshPreview()
   215         
   221         event.Skip()
   216         # Call BlockPreviewDialog function
       
   217         BlockPreviewDialog.RefreshPreview(self)