dialogs/SFCTransitionDialog.py
changeset 1252 18cd1357e8d3
parent 814 5743cbdff669
child 1554 01d2c8a8a928
equal deleted inserted replaced
1251:d9ed42e44a50 1252:18cd1357e8d3
    21 #License along with this library; if not, write to the Free Software
    21 #License along with this library; if not, write to the Free Software
    22 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    22 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    23 
    23 
    24 import wx
    24 import wx
    25 
    25 
    26 from graphics import *
    26 from graphics.SFC_Objects import SFC_Transition
       
    27 from BlockPreviewDialog import BlockPreviewDialog
    27 
    28 
    28 #-------------------------------------------------------------------------------
    29 #-------------------------------------------------------------------------------
    29 #                          Edit Transition Content Dialog
    30 #                        Set Transition Parameters Dialog
    30 #-------------------------------------------------------------------------------
    31 #-------------------------------------------------------------------------------
    31 
    32 
    32 class SFCTransitionDialog(wx.Dialog):
    33 """
    33     
    34 Class that implements a dialog for defining parameters of a transition graphic
    34     def __init__(self, parent, controller, connection):
    35 element
    35         self.Connection = connection
    36 """
    36         
    37 
    37         wx.Dialog.__init__(self, parent, 
    38 class SFCTransitionDialog(BlockPreviewDialog):
       
    39     
       
    40     def __init__(self, parent, controller, tagname, connection=True):
       
    41         """
       
    42         Constructor
       
    43         @param parent: Parent wx.Window of dialog for modal
       
    44         @param controller: Reference to project controller
       
    45         @param tagname: Tagname of project POU edited
       
    46         @param connection: True if transition value can be defined by a
       
    47         connection (default: True)
       
    48         """
       
    49         BlockPreviewDialog.__init__(self, parent, controller, tagname,
    38               size=wx.Size(350, 300), title=_('Edit transition'))
    50               size=wx.Size(350, 300), title=_('Edit transition'))
    39         
    51         
    40         main_sizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
    52         # Init common sizers
    41         main_sizer.AddGrowableCol(0)
    53         self._init_sizers(2, 0, 8, None, 2, 1)
    42         main_sizer.AddGrowableRow(0)
    54         
    43         
    55         # Create label for transition type
    44         column_sizer = wx.BoxSizer(wx.HORIZONTAL)
       
    45         main_sizer.AddSizer(column_sizer, border=20, 
       
    46               flag=wx.GROW|wx.TOP|wx.LEFT|wx.RIGHT)
       
    47         
       
    48         left_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, rows=8, vgap=5)
       
    49         left_gridsizer.AddGrowableCol(0)
       
    50         column_sizer.AddSizer(left_gridsizer, 1, border=5, 
       
    51                               flag=wx.GROW|wx.RIGHT)
       
    52         
       
    53         type_label = wx.StaticText(self, label=_('Type:'))
    56         type_label = wx.StaticText(self, label=_('Type:'))
    54         left_gridsizer.AddWindow(type_label, flag=wx.GROW)
    57         self.LeftGridSizer.AddWindow(type_label, flag=wx.GROW)
    55         
    58         
    56         self.ReferenceRadioButton = wx.RadioButton(self,
    59         # Create combo box for selecting reference value
    57               label=_('Reference'), style=wx.RB_GROUP)
    60         reference = wx.ComboBox(self, style=wx.CB_READONLY)
    58         self.ReferenceRadioButton.SetValue(True)
    61         reference.Append("")
    59         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, self.ReferenceRadioButton)
    62         for transition in controller.GetEditedElementTransitions(tagname):
    60         left_gridsizer.AddWindow(self.ReferenceRadioButton, flag=wx.GROW)
    63             reference.Append(transition)
    61         
    64         self.Bind(wx.EVT_COMBOBOX, self.OnReferenceChanged, reference)
    62         self.Reference = wx.ComboBox(self, style=wx.CB_READONLY)
    65         
    63         self.Bind(wx.EVT_COMBOBOX, self.OnReferenceChanged, self.Reference)
    66         # Create Text control for defining inline value
    64         left_gridsizer.AddWindow(self.Reference, flag=wx.GROW)
    67         inline = wx.TextCtrl(self)
    65         
    68         self.Bind(wx.EVT_TEXT, self.OnInlineChanged, inline)
    66         self.InlineRadioButton = wx.RadioButton(self, label=_('Inline'))
    69         
    67         self.InlineRadioButton.SetValue(False)
    70         # Create radio buttons for selecting power rail type
    68         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, self.InlineRadioButton)
    71         self.TypeRadioButtons = {}
    69         left_gridsizer.AddWindow(self.InlineRadioButton, flag=wx.GROW)
    72         first = True
    70         
    73         for type, label, control in [('reference', _('Reference'), reference),
    71         self.Inline = wx.TextCtrl(self)
    74                                      ('inline', _('Inline'), inline),
    72         self.Inline.Enable(False)
    75                                      ('connection', _('Connection'), None)]:
    73         self.Bind(wx.EVT_TEXT, self.OnInlineChanged, self.Inline)
    76             radio_button = wx.RadioButton(self, label=label, 
    74         left_gridsizer.AddWindow(self.Inline, flag=wx.GROW)
    77                   style=(wx.RB_GROUP if first else 0))
    75         
    78             radio_button.SetValue(first)
    76         self.ConnectionRadioButton = wx.RadioButton(self, label=_('Connection'))
    79             self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, radio_button)
    77         self.Bind(wx.EVT_RADIOBUTTON, self.OnTypeChanged, self.ConnectionRadioButton)
    80             self.LeftGridSizer.AddWindow(radio_button, flag=wx.GROW)
    78         self.ConnectionRadioButton.SetValue(False)
    81             if control is not None:
    79         if not self.Connection:
    82                 control.Enable(first)
    80             self.ConnectionRadioButton.Hide()
    83                 self.LeftGridSizer.AddWindow(control, flag=wx.GROW)
    81         left_gridsizer.AddWindow(self.ConnectionRadioButton, flag=wx.GROW)
    84             self.TypeRadioButtons[type] = (radio_button, control)
    82         
    85             first = False
       
    86         
       
    87         # Create label for transition priority
    83         priority_label = wx.StaticText(self, label=_('Priority:'))
    88         priority_label = wx.StaticText(self, label=_('Priority:'))
    84         left_gridsizer.AddWindow(priority_label, flag=wx.GROW)
    89         self.LeftGridSizer.AddWindow(priority_label, flag=wx.GROW)
    85         
    90         
       
    91         # Create spin control for defining priority value
    86         self.Priority = wx.SpinCtrl(self, min=0, style=wx.SP_ARROW_KEYS)
    92         self.Priority = wx.SpinCtrl(self, min=0, style=wx.SP_ARROW_KEYS)
    87         self.Bind(wx.EVT_TEXT, self.OnPriorityChanged, self.Priority)
    93         self.Bind(wx.EVT_TEXT, self.OnPriorityChanged, self.Priority)
    88         left_gridsizer.AddWindow(self.Priority, flag=wx.GROW)
    94         self.LeftGridSizer.AddWindow(self.Priority, flag=wx.GROW)
    89         
    95         
    90         right_gridsizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
    96         # Add preview panel and associated label to sizers
    91         right_gridsizer.AddGrowableCol(0)
    97         self.RightGridSizer.AddWindow(self.PreviewLabel, flag=wx.GROW)
    92         right_gridsizer.AddGrowableRow(1)
    98         self.RightGridSizer.AddWindow(self.Preview, flag=wx.GROW)
    93         column_sizer.AddSizer(right_gridsizer, 1, border=5, 
    99         
    94               flag=wx.GROW|wx.LEFT)
   100         # Add buttons sizer to sizers
    95         
   101         self.MainSizer.AddSizer(self.ButtonSizer, border=20, 
    96         preview_label = wx.StaticText(self, label=_('Preview:'))
       
    97         right_gridsizer.AddWindow(preview_label, flag=wx.GROW)
       
    98         
       
    99         self.Preview = wx.Panel(self, 
       
   100               style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
   101         self.Preview.SetBackgroundColour(wx.Colour(255,255,255))
       
   102         setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
       
   103         setattr(self.Preview, "RefreshTransitionModel", lambda x:None)
       
   104         setattr(self.Preview, "GetScaling", lambda:None)
       
   105         setattr(self.Preview, "IsOfType", controller.IsOfType)
       
   106         self.Preview.Bind(wx.EVT_PAINT, self.OnPaint)
       
   107         right_gridsizer.AddWindow(self.Preview, flag=wx.GROW)
       
   108         
       
   109         button_sizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
       
   110         self.Bind(wx.EVT_BUTTON, self.OnOK, 
       
   111               button_sizer.GetAffirmativeButton())
       
   112         main_sizer.AddSizer(button_sizer, border=20, 
       
   113               flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
   102               flag=wx.ALIGN_RIGHT|wx.BOTTOM|wx.LEFT|wx.RIGHT)
   114         
   103         
   115         self.SetSizer(main_sizer)
   104         # Reference radio button is default control having keyboard focus
   116         
   105         self.TypeRadioButtons["reference"][0].SetFocus()
   117         self.Transition = None
   106     
   118         self.MinTransitionSize = None
   107     def GetTransitionType(self):
   119         
   108         """
       
   109         Return type selected for SFC transition and associated value
       
   110         @return: Type selected and associated value (None if no value)
       
   111         """
       
   112         # Go through radio buttons and return type and value associated to the
       
   113         # one that is selected
       
   114         for type, (radio, control) in self.TypeRadioButtons.iteritems():
       
   115             if radio.GetValue():
       
   116                 if isinstance(control, wx.ComboBox):
       
   117                     return type, control.GetStringSelection()
       
   118                 elif isinstance(control, wx.TextCtrl):
       
   119                     return type, control.GetValue()
       
   120                 else:
       
   121                     return type, None
       
   122         return None, None
       
   123     
       
   124     def SetValues(self, values):
       
   125         """
       
   126         Set default SFC transition parameters
       
   127         @param values: Transition parameters values
       
   128         """
       
   129         # Extract transition value according to type
       
   130         type_value = values.get("value", None)
       
   131         
       
   132         # For each parameters defined, set corresponding control value
       
   133         for name, value in values.items():
       
   134             
       
   135             # Parameter is SFC transition priority
       
   136             if name == "priority":
       
   137                 self.Priority.SetValue(values["priority"])
       
   138             
       
   139             # Parameter is SFC transition type
       
   140             elif name == "type":
       
   141                 for type, (radio, control) in self.TypeRadioButtons.iteritems():
       
   142                     radio.SetValue(type == value)
       
   143                     if control is not None:
       
   144                         # Enable associated control to type and set value
       
   145                         control.Enable(type == value)
       
   146                         if type == value:
       
   147                             if isinstance(control, wx.ComboBox):
       
   148                                 control.SetStringSelection(type_value)
       
   149                             elif isinstance(control, wx.TextCtrl):
       
   150                                 control.ChangeValue(type_value)
       
   151         
       
   152         # Refresh preview panel
       
   153         self.RefreshPreview()
       
   154         
       
   155     def GetValues(self):
       
   156         """
       
   157         Return SFC transition parameters defined in dialog
       
   158         @return: {parameter_name: parameter_value,...}
       
   159         """
       
   160         values = {"priority" : self.Priority.GetValue()}
       
   161         values["type"], values["value"] = self.GetTransitionType()
       
   162         values["width"], values["height"] = self.Element.GetSize()
       
   163         return values
       
   164     
       
   165     def OnOK(self, event):
       
   166         """
       
   167         Called when dialog OK button is pressed
       
   168         Test if parameters defined are valid
       
   169         @param event: wx.Event from OK button
       
   170         """
       
   171         message = None
       
   172         
       
   173         # Get transition type and value associated
       
   174         type, value = self.GetTransitionType()
       
   175         
       
   176         # Test that value associated to type is defined
       
   177         if type != "connection" and value == "":
       
   178             message = _("Form isn't complete. %s must be filled!") % type
       
   179         
       
   180         # Show error message if an error is detected
       
   181         if message is not None:
       
   182             self.ShowErrorMessage(message)
       
   183         
       
   184         else:
       
   185             # Call BlockPreviewDialog function
       
   186             BlockPreviewDialog.OnOK(self, event)
       
   187 
       
   188     def OnTypeChanged(self, event):
       
   189         """
       
   190         Called when transition type changed
       
   191         @param event: wx.RadioButtonEvent
       
   192         """
       
   193         # Refresh sensibility of control associated to transition types
       
   194         for type, (radio, control) in self.TypeRadioButtons.iteritems():
       
   195             if control is not None:
       
   196                 control.Enable(radio.GetValue())
       
   197         
       
   198         # Refresh preview panel
       
   199         self.RefreshPreview()
       
   200         event.Skip()
       
   201 
       
   202     def OnReferenceChanged(self, event):
       
   203         """
       
   204         Called when SFC transition reference value changed
       
   205         @param event: wx.ComboBoxEvent
       
   206         """
       
   207         self.RefreshPreview()
       
   208         event.Skip()
       
   209 
       
   210     def OnInlineChanged(self, event):
       
   211         """
       
   212         Called when SFC transition inline value changed
       
   213         @param event: wx.TextEvent
       
   214         """
       
   215         self.RefreshPreview()
       
   216         event.Skip()
       
   217 
       
   218     def OnPriorityChanged(self, event):
       
   219         """
       
   220         Called when block inputs number changed
       
   221         @param event: wx.SpinEvent
       
   222         """
       
   223         self.RefreshPreview()
       
   224         event.Skip()
       
   225 
       
   226     def RefreshPreview(self):
       
   227         """
       
   228         Refresh preview panel of graphic element
       
   229         Override BlockPreviewDialog function
       
   230         """
       
   231         # Set graphic element displayed, creating a SFC transition
   120         self.Element = SFC_Transition(self.Preview)
   232         self.Element = SFC_Transition(self.Preview)
   121         
   233         self.Element.SetType(*self.GetTransitionType())
   122         self.ReferenceRadioButton.SetFocus()
   234         self.Element.SetPriority(self.Priority.GetValue())
   123     
   235         
   124     def SetPreviewFont(self, font):
   236         # Call BlockPreviewDialog function
   125         self.Preview.SetFont(font)
   237         BlockPreviewDialog.RefreshPreview(self)
   126     
       
   127     def SetElementSize(self, size):
       
   128         min_width, min_height = self.Element.GetMinSize()
       
   129         width, height = max(min_width, size[0]), max(min_height, size[1])
       
   130         self.Element.SetSize(width, height)
       
   131     
       
   132     def OnOK(self, event):
       
   133         error = []
       
   134         if self.ReferenceRadioButton.GetValue() and self.Reference.GetStringSelection() == "":
       
   135             error.append(_("Reference"))
       
   136         if self.InlineRadioButton.GetValue() and self.Inline.GetValue() == "":
       
   137             error.append(_("Inline"))
       
   138         if len(error) > 0:
       
   139             text = ""
       
   140             for i, item in enumerate(error):
       
   141                 if i == 0:
       
   142                     text += item
       
   143                 elif i == len(error) - 1:
       
   144                     text += _(" and %s")%item
       
   145                 else:
       
   146                     text += _(", %s")%item 
       
   147             dialog = wx.MessageDialog(self, _("Form isn't complete. %s must be filled!")%text, _("Error"), wx.OK|wx.ICON_ERROR)
       
   148             dialog.ShowModal()
       
   149             dialog.Destroy()
       
   150         else:
       
   151             self.EndModal(wx.ID_OK)
       
   152 
       
   153     def OnTypeChanged(self, event):
       
   154         if self.ReferenceRadioButton.GetValue():
       
   155             self.Element.SetType("reference", self.Reference.GetStringSelection())
       
   156             self.Reference.Enable(True)
       
   157             self.Inline.Enable(False)
       
   158         elif self.InlineRadioButton.GetValue():
       
   159             self.Element.SetType("inline", self.Inline.GetValue())
       
   160             self.Reference.Enable(False)
       
   161             self.Inline.Enable(True)
       
   162         else:
       
   163             self.Element.SetType("connection")
       
   164             self.Reference.Enable(False)
       
   165             self.Inline.Enable(False)
       
   166         self.RefreshPreview()
       
   167         event.Skip()
       
   168 
       
   169     def OnReferenceChanged(self, event):
       
   170         self.Element.SetType("reference", self.Reference.GetStringSelection())
       
   171         self.RefreshPreview()
       
   172         event.Skip()
       
   173 
       
   174     def OnInlineChanged(self, event):
       
   175         self.Element.SetType("inline", self.Inline.GetValue())
       
   176         self.RefreshPreview()
       
   177         event.Skip()
       
   178 
       
   179     def OnPriorityChanged(self, event):
       
   180         self.Element.SetPriority(int(self.Priority.GetValue()))
       
   181         self.RefreshPreview()
       
   182         event.Skip()
       
   183 
       
   184     def SetTransitions(self, transitions):
       
   185         self.Reference.Append("")
       
   186         for transition in transitions:
       
   187             self.Reference.Append(transition)
       
   188 
       
   189     def SetValues(self, values):
       
   190         if values["type"] == "reference":
       
   191             self.ReferenceRadioButton.SetValue(True)
       
   192             self.InlineRadioButton.SetValue(False)
       
   193             self.ConnectionRadioButton.SetValue(False)
       
   194             self.Reference.Enable(True)
       
   195             self.Inline.Enable(False)
       
   196             self.Reference.SetStringSelection(values["value"])
       
   197             self.Element.SetType("reference", values["value"])
       
   198         elif values["type"] == "inline":
       
   199             self.ReferenceRadioButton.SetValue(False)
       
   200             self.InlineRadioButton.SetValue(True)
       
   201             self.ConnectionRadioButton.SetValue(False)
       
   202             self.Reference.Enable(False)
       
   203             self.Inline.Enable(True)
       
   204             self.Inline.SetValue(values["value"])
       
   205             self.Element.SetType("inline", values["value"])
       
   206         elif values["type"] == "connection" and self.Connection:
       
   207             self.ReferenceRadioButton.SetValue(False)
       
   208             self.InlineRadioButton.SetValue(False)
       
   209             self.ConnectionRadioButton.SetValue(True)
       
   210             self.Reference.Enable(False)
       
   211             self.Inline.Enable(False)
       
   212             self.Element.SetType("connection")
       
   213         self.Priority.SetValue(values["priority"])
       
   214         self.Element.SetPriority(values["priority"])
       
   215         self.RefreshPreview()
       
   216         
       
   217     def GetValues(self):
       
   218         values = {"priority" : int(self.Priority.GetValue())}
       
   219         if self.ReferenceRadioButton.GetValue():
       
   220             values["type"] = "reference"
       
   221             values["value"] = self.Reference.GetStringSelection()
       
   222         elif self.InlineRadioButton.GetValue():
       
   223             values["type"] = "inline"
       
   224             values["value"] = self.Inline.GetValue()
       
   225         else:
       
   226             values["type"] = "connection"
       
   227             values["value"] = None
       
   228         return values
       
   229 
       
   230     def RefreshPreview(self):
       
   231         dc = wx.ClientDC(self.Preview)
       
   232         dc.SetFont(self.Preview.GetFont())
       
   233         dc.Clear()
       
   234         clientsize = self.Preview.GetClientSize()
       
   235         posx, posy = self.Element.GetPosition()
       
   236         rect = self.Element.GetBoundingBox()
       
   237         diffx, diffy = posx - rect.x, posy - rect.y
       
   238         self.Element.SetPosition((clientsize.width - rect.width) / 2 + diffx, (clientsize.height - rect.height) / 2 + diffy)
       
   239         self.Element.Draw(dc)
       
   240 
       
   241     def OnPaint(self, event):
       
   242         self.RefreshPreview()
       
   243         event.Skip()