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() |
|