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 import * |
|
28 from controls import LibraryPanel |
28 |
29 |
29 #------------------------------------------------------------------------------- |
30 #------------------------------------------------------------------------------- |
30 # Create New Block Dialog |
31 # Create New Block Dialog |
31 #------------------------------------------------------------------------------- |
32 #------------------------------------------------------------------------------- |
32 |
33 |
61 def _init_coll_MainSizer_Items(self, parent): |
62 def _init_coll_MainSizer_Items(self, parent): |
62 parent.AddSizer(self.LeftBoxSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) |
63 parent.AddSizer(self.LeftBoxSizer, 1, border=5, flag=wx.GROW|wx.RIGHT) |
63 parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) |
64 parent.AddSizer(self.RightGridSizer, 1, border=5, flag=wx.GROW|wx.LEFT) |
64 |
65 |
65 def _init_coll_LeftBoxSizer_Items(self, parent): |
66 def _init_coll_LeftBoxSizer_Items(self, parent): |
66 parent.AddWindow(self.TypeTree, 3, border=5, flag=wx.GROW|wx.BOTTOM) |
67 parent.AddWindow(self.LibraryPanel, 1, border=5, flag=wx.GROW|wx.TOP) |
67 parent.AddWindow(self.TypeDesc, 1, border=0, flag=wx.GROW) |
68 |
68 |
|
69 def _init_coll_RightGridSizer_Items(self, parent): |
69 def _init_coll_RightGridSizer_Items(self, parent): |
70 parent.AddSizer(self.RightUpGridSizer, 0, border=0, flag=wx.GROW) |
70 parent.AddSizer(self.RightUpGridSizer, 0, border=0, flag=wx.GROW) |
71 parent.AddWindow(self.staticText6, 0, border=0, flag=wx.GROW) |
71 parent.AddWindow(self.staticText6, 0, border=0, flag=wx.GROW) |
72 parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) |
72 parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW) |
73 |
73 |
135 |
135 |
136 self.staticText6 = wx.StaticText(id=ID_FBDBLOCKDIALOGSTATICTEXT6, |
136 self.staticText6 = wx.StaticText(id=ID_FBDBLOCKDIALOGSTATICTEXT6, |
137 label=_('Preview:'), name='staticText6', parent=self, |
137 label=_('Preview:'), name='staticText6', parent=self, |
138 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
138 pos=wx.Point(0, 0), size=wx.DefaultSize, style=0) |
139 |
139 |
140 self.TypeTree = wx.TreeCtrl(id=ID_FBDBLOCKDIALOGTYPETREE, |
140 self.LibraryPanel = LibraryPanel(self) |
141 name='TypeTree', parent=self, pos=wx.Point(0, 0), |
|
142 size=wx.Size(0, 0), style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER|wx.TR_HIDE_ROOT|wx.TR_LINES_AT_ROOT) |
|
143 self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTypeTreeItemSelected, |
|
144 id=ID_FBDBLOCKDIALOGTYPETREE) |
|
145 |
|
146 self.TypeDesc = wx.TextCtrl(id=ID_FBDBLOCKDIALOGTYPEDESC, |
|
147 name='TypeDesc', parent=self, pos=wx.Point(0, 0), |
|
148 size=wx.Size(0, 0), style=wx.TE_READONLY|wx.TE_MULTILINE) |
|
149 |
141 |
150 self.BlockName = wx.TextCtrl(id=ID_FBDBLOCKDIALOGNAME, value='', |
142 self.BlockName = wx.TextCtrl(id=ID_FBDBLOCKDIALOGNAME, value='', |
151 name='BlockName', parent=self, pos=wx.Point(0, 0), |
143 name='BlockName', parent=self, pos=wx.Point(0, 0), |
152 size=wx.Size(0, 24), style=0) |
144 size=wx.Size(0, 24), style=0) |
153 self.Bind(wx.EVT_TEXT, self.OnNameChanged, id=ID_FBDBLOCKDIALOGNAME) |
145 self.Bind(wx.EVT_TEXT, self.OnNameChanged, id=ID_FBDBLOCKDIALOGNAME) |
196 self.MinBlockSize = None |
188 self.MinBlockSize = None |
197 self.First = True |
189 self.First = True |
198 |
190 |
199 self.PouNames = [] |
191 self.PouNames = [] |
200 self.PouElementNames = [] |
192 self.PouElementNames = [] |
201 |
193 |
202 self.TypeTree.SetFocus() |
194 self.LibraryPanel.SetControler(controler) |
|
195 setattr(self.LibraryPanel, "_OnTreeItemSelected", self.OnLibraryTreeItemSelected) |
|
196 self.LibraryPanel.SetFocus() |
|
197 |
|
198 def SetBlockList(self, blocklist): |
|
199 self.LibraryPanel.SetBlockList(blocklist) |
203 |
200 |
204 def SetPreviewFont(self, font): |
201 def SetPreviewFont(self, font): |
205 self.Preview.SetFont(font) |
202 self.Preview.SetFont(font) |
206 |
203 |
207 def FindTreeItem(self, root, name, inputs = None): |
|
208 if root.IsOk(): |
|
209 pydata = self.TypeTree.GetPyData(root) |
|
210 if pydata is not None: |
|
211 type_inputs = pydata.get("inputs", None) |
|
212 type_extension = pydata.get("extension", None) |
|
213 if inputs is not None and type_inputs is not None: |
|
214 if type_extension is not None: |
|
215 same_inputs = type_inputs == inputs[:type_extension] |
|
216 else: |
|
217 same_inputs = type_inputs == inputs |
|
218 else: |
|
219 same_inputs = True |
|
220 if pydata is not None and self.TypeTree.GetItemText(root) == name and same_inputs: |
|
221 return root |
|
222 else: |
|
223 if wx.VERSION < (2, 6, 0): |
|
224 item, root_cookie = self.TypeTree.GetFirstChild(root, 0) |
|
225 else: |
|
226 item, root_cookie = self.TypeTree.GetFirstChild(root) |
|
227 while item.IsOk(): |
|
228 result = self.FindTreeItem(item, name, inputs) |
|
229 if result: |
|
230 return result |
|
231 item, root_cookie = self.TypeTree.GetNextChild(root, root_cookie) |
|
232 return None |
|
233 |
|
234 def OnOK(self, event): |
204 def OnOK(self, event): |
235 selected = self.TypeTree.GetSelection() |
205 selected = self.LibraryPanel.GetSelectedBlock() |
236 block_name = self.BlockName.GetValue() |
206 block_name = self.BlockName.GetValue() |
237 name_enabled = self.BlockName.IsEnabled() |
207 name_enabled = self.BlockName.IsEnabled() |
238 if not selected.IsOk() or self.TypeTree.GetItemParent(selected) == self.TypeTree.GetRootItem() or selected == self.TypeTree.GetRootItem(): |
208 if selected is None: |
239 message = wx.MessageDialog(self, _("Form isn't complete. Valid block type must be selected!"), _("Error"), wx.OK|wx.ICON_ERROR) |
209 message = wx.MessageDialog(self, _("Form isn't complete. Valid block type must be selected!"), _("Error"), wx.OK|wx.ICON_ERROR) |
240 message.ShowModal() |
210 message.ShowModal() |
241 message.Destroy() |
211 message.Destroy() |
242 elif name_enabled and block_name == "": |
212 elif name_enabled and block_name == "": |
243 message = wx.MessageDialog(self, _("Form isn't complete. Name must be filled!"), _("Error"), wx.OK|wx.ICON_ERROR) |
213 message = wx.MessageDialog(self, _("Form isn't complete. Name must be filled!"), _("Error"), wx.OK|wx.ICON_ERROR) |
260 message.ShowModal() |
230 message.ShowModal() |
261 message.Destroy() |
231 message.Destroy() |
262 else: |
232 else: |
263 self.EndModal(wx.ID_OK) |
233 self.EndModal(wx.ID_OK) |
264 |
234 |
265 def SetBlockList(self, blocktypes): |
|
266 root = self.TypeTree.AddRoot("") |
|
267 for category in blocktypes: |
|
268 category_name = category["name"] |
|
269 category_item = self.TypeTree.AppendItem(root, _(category_name)) |
|
270 self.TypeTree.SetPyData(category_item, {"type" : CATEGORY}) |
|
271 for blocktype in category["list"]: |
|
272 blocktype_item = self.TypeTree.AppendItem(category_item, blocktype["name"]) |
|
273 block_data = {"type" : BLOCK, |
|
274 "inputs" : tuple([type for name, type, modifier in blocktype["inputs"]]), |
|
275 "extension" : None} |
|
276 if blocktype["extensible"]: |
|
277 block_data["extension"] = len(blocktype["inputs"]) |
|
278 self.TypeTree.SetPyData(blocktype_item, block_data) |
|
279 |
|
280 def SetMinBlockSize(self, size): |
235 def SetMinBlockSize(self, size): |
281 self.MinBlockSize = size |
236 self.MinBlockSize = size |
282 |
237 |
283 def SetPouNames(self, pou_names): |
238 def SetPouNames(self, pou_names): |
284 self.PouNames = [pou_name.upper() for pou_name in pou_names] |
239 self.PouNames = [pou_name.upper() for pou_name in pou_names] |
287 self.PouElementNames = [element_name.upper() for element_name in element_names] |
242 self.PouElementNames = [element_name.upper() for element_name in element_names] |
288 |
243 |
289 def SetValues(self, values): |
244 def SetValues(self, values): |
290 blocktype = values.get("type", None) |
245 blocktype = values.get("type", None) |
291 if blocktype is not None: |
246 if blocktype is not None: |
292 inputs = values.get("inputs", None) |
247 self.LibraryPanel.SelectTreeItem(blocktype, values.get("inputs", None)) |
293 item = self.FindTreeItem(self.TypeTree.GetRootItem(), blocktype, inputs) |
|
294 if item: |
|
295 self.TypeTree.SelectItem(item) |
|
296 self.TypeTree.EnsureVisible(item) |
|
297 for name, value in values.items(): |
248 for name, value in values.items(): |
298 if name == "name": |
249 if name == "name": |
299 self.BlockName.SetValue(value) |
250 self.BlockName.SetValue(value) |
300 elif name == "extension": |
251 elif name == "extension": |
301 self.Inputs.SetValue(value) |
252 self.Inputs.SetValue(value) |
304 elif name == "executionControl": |
255 elif name == "executionControl": |
305 self.ExecutionControl.SetValue(value) |
256 self.ExecutionControl.SetValue(value) |
306 self.RefreshPreview() |
257 self.RefreshPreview() |
307 |
258 |
308 def GetValues(self): |
259 def GetValues(self): |
309 values = {} |
260 values = self.LibraryPanel.GetSelectedBlock() |
310 item = self.TypeTree.GetSelection() |
|
311 values["type"] = self.TypeTree.GetItemText(item) |
|
312 values["inputs"] = self.TypeTree.GetPyData(item)["inputs"] |
|
313 if self.BlockName.GetValue() != "": |
261 if self.BlockName.GetValue() != "": |
314 values["name"] = self.BlockName.GetValue() |
262 values["name"] = self.BlockName.GetValue() |
315 values["width"], values["height"] = self.Block.GetSize() |
263 values["width"], values["height"] = self.Block.GetSize() |
316 values["extension"] = self.Inputs.GetValue() |
264 values["extension"] = self.Inputs.GetValue() |
317 values["executionOrder"] = self.ExecutionOrder.GetValue() |
265 values["executionOrder"] = self.ExecutionOrder.GetValue() |
318 values["executionControl"] = self.ExecutionControl.GetValue() |
266 values["executionControl"] = self.ExecutionControl.GetValue() |
319 return values |
267 return values |
320 |
268 |
321 def OnTypeTreeItemSelected(self, event): |
269 def OnLibraryTreeItemSelected(self, event): |
322 selected = event.GetItem() |
270 values = self.LibraryPanel.GetSelectedBlock() |
323 pydata = self.TypeTree.GetPyData(selected) |
271 if values is not None: |
324 if pydata["type"] != CATEGORY: |
272 blocktype = self.Controler.GetBlockType(values["type"], values["inputs"]) |
325 blocktype = self.Controler.GetBlockType(self.TypeTree.GetItemText(selected), pydata["inputs"]) |
273 else: |
326 if blocktype: |
274 blocktype = None |
327 self.Inputs.SetValue(len(blocktype["inputs"])) |
275 if blocktype is not None: |
328 self.Inputs.Enable(blocktype["extensible"]) |
276 self.Inputs.SetValue(len(blocktype["inputs"])) |
329 self.BlockName.Enable(blocktype["type"] != "function") |
277 self.Inputs.Enable(blocktype["extensible"]) |
330 comment = blocktype["comment"] |
278 self.BlockName.Enable(blocktype["type"] != "function") |
331 self.TypeDesc.SetValue(_(comment) + blocktype.get("usage", "")) |
279 wx.CallAfter(self.RefreshPreview) |
332 wx.CallAfter(self.RefreshPreview) |
|
333 else: |
|
334 self.BlockName.Enable(False) |
|
335 self.Inputs.Enable(False) |
|
336 self.Inputs.SetValue(2) |
|
337 self.TypeDesc.SetValue("") |
|
338 wx.CallAfter(self.ErasePreview) |
|
339 else: |
280 else: |
340 self.BlockName.Enable(False) |
281 self.BlockName.Enable(False) |
341 self.Inputs.Enable(False) |
282 self.Inputs.Enable(False) |
342 self.Inputs.SetValue(2) |
283 self.Inputs.SetValue(2) |
343 self.TypeDesc.SetValue("") |
|
344 wx.CallAfter(self.ErasePreview) |
284 wx.CallAfter(self.ErasePreview) |
345 event.Skip() |
285 |
346 |
|
347 def OnNameChanged(self, event): |
286 def OnNameChanged(self, event): |
348 if self.BlockName.IsEnabled(): |
287 if self.BlockName.IsEnabled(): |
349 self.RefreshPreview() |
288 self.RefreshPreview() |
350 event.Skip() |
289 event.Skip() |
351 |
290 |
369 |
308 |
370 def RefreshPreview(self): |
309 def RefreshPreview(self): |
371 dc = wx.ClientDC(self.Preview) |
310 dc = wx.ClientDC(self.Preview) |
372 dc.SetFont(self.Preview.GetFont()) |
311 dc.SetFont(self.Preview.GetFont()) |
373 dc.Clear() |
312 dc.Clear() |
374 item = self.TypeTree.GetSelection() |
313 values = self.LibraryPanel.GetSelectedBlock() |
375 if item.IsOk(): |
314 if values is not None: |
376 pydata = self.TypeTree.GetPyData(item) |
315 self.Block = FBD_Block(self.Preview, values["type"], |
377 if pydata["type"] == CATEGORY: |
316 self.BlockName.GetValue(), |
378 self.Block = None |
317 extension = self.Inputs.GetValue(), |
379 else: |
318 inputs = values["inputs"], |
380 blocktype = self.TypeTree.GetItemText(item) |
319 executionControl = self.ExecutionControl.GetValue(), |
381 if blocktype: |
320 executionOrder = self.ExecutionOrder.GetValue()) |
382 self.Block = FBD_Block(self.Preview, blocktype, |
321 width, height = self.MinBlockSize |
383 self.BlockName.GetValue(), |
322 min_width, min_height = self.Block.GetMinSize() |
384 extension = self.Inputs.GetValue(), |
323 width, height = max(min_width, width), max(min_height, height) |
385 inputs = pydata["inputs"], |
324 self.Block.SetSize(width, height) |
386 executionControl = self.ExecutionControl.GetValue(), |
325 clientsize = self.Preview.GetClientSize() |
387 executionOrder = self.ExecutionOrder.GetValue()) |
326 x = (clientsize.width - width) / 2 |
388 width, height = self.MinBlockSize |
327 y = (clientsize.height - height) / 2 |
389 min_width, min_height = self.Block.GetMinSize() |
328 self.Block.SetPosition(x, y) |
390 width, height = max(min_width, width), max(min_height, height) |
329 self.Block.Draw(dc) |
391 self.Block.SetSize(width, height) |
330 else: |
392 clientsize = self.Preview.GetClientSize() |
331 self.Block = None |
393 x = (clientsize.width - width) / 2 |
|
394 y = (clientsize.height - height) / 2 |
|
395 self.Block.SetPosition(x, y) |
|
396 self.Block.Draw(dc) |
|
397 else: |
|
398 self.Block = None |
|
399 |
332 |
400 def OnPaint(self, event): |
333 def OnPaint(self, event): |
401 if self.Block is not None: |
334 if self.Block is not None: |
402 self.RefreshPreview() |
335 self.RefreshPreview() |
403 event.Skip() |
336 event.Skip() |