dialogs/FBDBlockDialog.py
changeset 676 0f10f5091245
parent 646 97bed1acd860
child 714 131ea7f237b9
equal deleted inserted replaced
675:0ea836add01f 676:0f10f5091245
    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()