diff -r d34ba528346b -r 101625efb1c1 dialogs/LDElementDialog.py --- a/dialogs/LDElementDialog.py Tue Jun 11 19:33:03 2013 +0200 +++ b/dialogs/LDElementDialog.py Tue Jun 11 23:08:06 2013 +0200 @@ -24,198 +24,194 @@ import wx -from graphics import * +from graphics.GraphicCommons import CONTACT_NORMAL, CONTACT_REVERSE, \ + CONTACT_RISING, CONTACT_FALLING, COIL_NORMAL, COIL_REVERSE, COIL_SET, \ + COIL_RESET, COIL_RISING, COIL_FALLING +from graphics.LD_Objects import LD_Contact, LD_Coil +from BlockPreviewDialog import BlockPreviewDialog #------------------------------------------------------------------------------- -# Edit Ladder Element Properties Dialog +# Set Ladder Element Parmeters Dialog #------------------------------------------------------------------------------- -class LDElementDialog(wx.Dialog): +""" +Class that implements a dialog for defining parameters of a LD contact or coil +graphic element +""" + +class LDElementDialog(BlockPreviewDialog): - def __init__(self, parent, controller, type): - if type == "contact": - wx.Dialog.__init__(self, parent, size=wx.Size(350, 260), - title=_("Edit Contact Values")) - else: - wx.Dialog.__init__(self, parent, size=wx.Size(350, 310), - title=_("Edit Coil Values")) - + def __init__(self, parent, controller, tagname, type): + """ + Constructor + @param parent: Parent wx.Window of dialog for modal + @param controller: Reference to project controller + @param tagname: Tagname of project POU edited + @param type: Type of LD element ('contact or 'coil') + """ + BlockPreviewDialog.__init__(self, parent, controller, tagname, + size=wx.Size(350, 260 if type == "contact" else 310), + title=(_("Edit Contact Values") + if type == "contact" + else _("Edit Coil Values"))) + + # Create dialog main sizer main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10) main_sizer.AddGrowableCol(0) main_sizer.AddGrowableRow(0) + # Create a sizer for dividing LD element parameters in two columns column_sizer = wx.BoxSizer(wx.HORIZONTAL) main_sizer.AddSizer(column_sizer, border=20, flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT) - if type == "contact": - left_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, rows=7, vgap=0) - else: - left_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, rows=9, vgap=0) + # Create a sizer for left column + left_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, + rows=(7 if type == "contact" else 9), vgap=0) left_gridsizer.AddGrowableCol(0) column_sizer.AddSizer(left_gridsizer, 1, border=5, flag=wx.GROW|wx.RIGHT) + # Create label for LD element modifier modifier_label = wx.StaticText(self, label=_('Modifier:')) - left_gridsizer.AddWindow(modifier_label, border=5, flag=wx.GROW|wx.BOTTOM) - - self.Normal = wx.RadioButton(self, label=_("Normal"), style=wx.RB_GROUP) - self.Normal.SetValue(True) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, self.Normal) - left_gridsizer.AddWindow(self.Normal, flag=wx.GROW) - - self.Negated = wx.RadioButton(self, label=_("Negated")) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, self.Negated) - left_gridsizer.AddWindow(self.Negated, flag=wx.GROW) - - if type != "contact": - self.Set = wx.RadioButton(self, label=_("Set")) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, self.Set) - left_gridsizer.AddWindow(self.Set, flag=wx.GROW) - - self.Reset = wx.RadioButton(self, label=_("Reset")) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, self.Reset) - left_gridsizer.AddWindow(self.Reset, flag=wx.GROW) - - self.RisingEdge = wx.RadioButton(self, label=_("Rising Edge")) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, self.RisingEdge) - left_gridsizer.AddWindow(self.RisingEdge, flag=wx.GROW) - - self.FallingEdge = wx.RadioButton(self, label=_("Falling Edge")) - self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, self.FallingEdge) - left_gridsizer.AddWindow(self.FallingEdge, flag=wx.GROW) - - element_name_label = wx.StaticText(self, label=_('Name:')) - left_gridsizer.AddWindow(element_name_label, border=5, flag=wx.GROW|wx.TOP) - - self.ElementName = wx.ComboBox(self, style=wx.CB_READONLY) - self.Bind(wx.EVT_COMBOBOX, self.OnNameChanged, self.ElementName) - left_gridsizer.AddWindow(self.ElementName, border=5, flag=wx.GROW|wx.TOP) - + left_gridsizer.AddWindow(modifier_label, border=5, + flag=wx.GROW|wx.BOTTOM) + + # Create radio buttons for selecting LD element modifier + self.ModifierRadioButtons = {} + first = True + element_modifiers = ([CONTACT_NORMAL, CONTACT_REVERSE, + CONTACT_RISING, CONTACT_FALLING] + if type == "contact" + else [COIL_NORMAL, COIL_REVERSE, COIL_SET, + COIL_RESET, COIL_RISING, COIL_FALLING]) + modifiers_label = [_("Normal"), _("Negated")] + \ + ([_("Set"), _("Reset")] if type == "coil" else []) + \ + [_("Rising Edge"), _("Falling Edge")] + + for modifier, label in zip(element_modifiers, modifiers_label): + radio_button = wx.RadioButton(self, label=label, + style=(wx.RB_GROUP if first else wx.RB_SINGLE)) + radio_button.SetValue(first) + self.Bind(wx.EVT_RADIOBUTTON, self.OnModifierChanged, radio_button) + left_gridsizer.AddWindow(radio_button, flag=wx.GROW) + self.ModifierRadioButtons[modifier] = radio_button + first = False + + # Create label for LD element variable + element_variable_label = wx.StaticText(self, label=_('Variable:')) + left_gridsizer.AddWindow(element_variable_label, border=5, + flag=wx.GROW|wx.TOP) + + # Create a combo box for defining LD element variable + self.ElementVariable = wx.ComboBox(self, style=wx.CB_READONLY) + self.Bind(wx.EVT_COMBOBOX, self.OnVariableChanged, + self.ElementVariable) + left_gridsizer.AddWindow(self.ElementVariable, border=5, + flag=wx.GROW|wx.TOP) + + # Create a sizer for right column right_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5) right_gridsizer.AddGrowableCol(0) right_gridsizer.AddGrowableRow(1) column_sizer.AddSizer(right_gridsizer, 1, border=5, flag=wx.GROW|wx.LEFT) - preview_label = wx.StaticText(self, label=_('Preview:')) - right_gridsizer.AddWindow(preview_label, flag=wx.GROW) - - self.Preview = wx.Panel(self, - style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER) - self.Preview.SetBackgroundColour(wx.Colour(255,255,255)) - setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE) - setattr(self.Preview, "GetScaling", lambda:None) - setattr(self.Preview, "IsOfType", controller.IsOfType) - self.Preview.Bind(wx.EVT_PAINT, self.OnPaint) + # Add preview panel and associated label to sizers + right_gridsizer.AddWindow(self.PreviewLabel, flag=wx.GROW) right_gridsizer.AddWindow(self.Preview, flag=wx.GROW) - button_sizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE) - main_sizer.AddSizer(button_sizer, border=20, + # Add buttons sizer to sizers + main_sizer.AddSizer(self.ButtonSizer, border=20, flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT) self.SetSizer(main_sizer) - if type == "contact": - self.Element = LD_Contact(self.Preview, CONTACT_NORMAL, "") - else: - self.Element = LD_Coil(self.Preview, COIL_NORMAL, "") - - self.Type = type - - self.Normal.SetFocus() + # Save LD element class + self.ElementClass = (LD_Contact if type == "contact" else LD_Coil) + + # Extract list of variables defined in POU + self.RefreshVariableList() + + # Set values in ElementVariable + for name, (var_type, value_type) in self.VariableList.iteritems(): + # Only select BOOL variable and avoid input for coil + if (type == "contact" or var_type != "Input") and \ + value_type == "BOOL": + self.ElementVariable.Append(name) + self.ElementVariable.Enable(self.ElementVariable.GetCount() > 0) + + # Normal radio button is default control having keyboard focus + self.ModifierRadioButtons[element_modifiers[0]].SetFocus() - def SetPreviewFont(self, font): - self.Preview.SetFont(font) - - def SetElementSize(self, size): - min_width, min_height = self.Element.GetMinSize() - width, height = max(min_width, size[0]), max(min_height, size[1]) - self.Element.SetSize(width, height) - - def SetVariables(self, vars): - self.ElementName.Clear() - for name in vars: - self.ElementName.Append(name) - self.ElementName.Enable(self.ElementName.GetCount() > 0) + def GetElementModifier(self): + """ + Return modifier selected for LD element + @return: Modifier selected (None if not found) + """ + # Go through radio buttons and return modifier associated to the one + # that is selected + for modifier, control in self.ModifierRadioButtons.iteritems(): + if control.GetValue(): + return modifier + return None def SetValues(self, values): + """ + Set default LD element parameters + @param values: Block parameters values + """ + # For each parameters defined, set corresponding control value for name, value in values.items(): - if name == "name": - self.Element.SetName(value) - self.ElementName.SetStringSelection(value) - elif name == "type": - self.Element.SetType(value) - if self.Type == "contact": - if value == CONTACT_NORMAL: - self.Normal.SetValue(True) - elif value == CONTACT_REVERSE: - self.Negated.SetValue(True) - elif value == CONTACT_RISING: - self.RisingEdge.SetValue(True) - elif value == CONTACT_FALLING: - self.FallingEdge.SetValue(True) - elif self.Type == "coil": - if value == COIL_NORMAL: - self.Normal.SetValue(True) - elif value == COIL_REVERSE: - self.Negated.SetValue(True) - elif value == COIL_SET: - self.Set.SetValue(True) - elif value == COIL_RESET: - self.Reset.SetValue(True) - elif value == COIL_RISING: - self.RisingEdge.SetValue(True) - elif value == COIL_FALLING: - self.FallingEdge.SetValue(True) + + # Parameter is LD element variable + if name == "variable": + self.ElementVariable.SetStringSelection(value) + + # Set value of other controls + elif name == "modifier": + self.ModifierRadioButtons[value].SetValue(True) + + # Refresh preview panel + self.RefreshPreview() def GetValues(self): - values = {} - values["name"] = self.Element.GetName() - values["type"] = self.Element.GetType() + """ + Return LD element parameters defined in dialog + @return: {parameter_name: parameter_value,...} + """ + values = { + "variable": self.ElementVariable.GetValue(), + "modifier": self.GetElementModifier()} values["width"], values["height"] = self.Element.GetSize() return values - def OnTypeChanged(self, event): - if self.Type == "contact": - if self.Normal.GetValue(): - self.Element.SetType(CONTACT_NORMAL) - elif self.Negated.GetValue(): - self.Element.SetType(CONTACT_REVERSE) - elif self.RisingEdge.GetValue(): - self.Element.SetType(CONTACT_RISING) - elif self.FallingEdge.GetValue(): - self.Element.SetType(CONTACT_FALLING) - elif self.Type == "coil": - if self.Normal.GetValue(): - self.Element.SetType(COIL_NORMAL) - elif self.Negated.GetValue(): - self.Element.SetType(COIL_REVERSE) - elif self.Set.GetValue(): - self.Element.SetType(COIL_SET) - elif self.Reset.GetValue(): - self.Element.SetType(COIL_RESET) - elif self.RisingEdge.GetValue(): - self.Element.SetType(COIL_RISING) - elif self.FallingEdge.GetValue(): - self.Element.SetType(COIL_FALLING) + def OnModifierChanged(self, event): + """ + Called when LD element modifier changed + @param event: wx.RadioButtonEvent + """ self.RefreshPreview() event.Skip() - def OnNameChanged(self, event): - self.Element.SetName(self.ElementName.GetStringSelection()) + def OnVariableChanged(self, event): + """ + Called when LD element associated variable changed + @param event: wx.ComboBoxEvent + """ self.RefreshPreview() event.Skip() def RefreshPreview(self): - dc = wx.ClientDC(self.Preview) - dc.SetFont(self.Preview.GetFont()) - dc.Clear() - clientsize = self.Preview.GetClientSize() - width, height = self.Element.GetSize() - self.Element.SetPosition((clientsize.width - width) / 2, (clientsize.height - height) / 2) - self.Element.Draw(dc) - - def OnPaint(self, event): - self.RefreshPreview() - event.Skip() + """ + Refresh preview panel of graphic element + Override BlockPreviewDialog function + """ + # Set graphic element displayed, creating a LD element + self.Element = self.ElementClass( + self.Preview, + self.GetElementModifier(), + self.ElementVariable.GetStringSelection()) + + # Call BlockPreviewDialog function + BlockPreviewDialog.RefreshPreview(self)