etisserant@0: #!/usr/bin/env python etisserant@0: # -*- coding: utf-8 -*- etisserant@0: etisserant@0: #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor etisserant@0: #based on the plcopen standard. etisserant@0: # etisserant@0: #Copyright (C): Edouard TISSERANT and Laurent BESSARD etisserant@0: # etisserant@0: #See COPYING file for copyrights details. etisserant@0: # etisserant@0: #This library is free software; you can redistribute it and/or etisserant@0: #modify it under the terms of the GNU Lesser General Public etisserant@0: #License as published by the Free Software Foundation; either etisserant@0: #version 2.1 of the License, or (at your option) any later version. etisserant@0: # etisserant@0: #This library is distributed in the hope that it will be useful, etisserant@0: #but WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@0: #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU etisserant@0: #Lesser General Public License for more details. etisserant@0: # etisserant@0: #You should have received a copy of the GNU Lesser General Public etisserant@0: #License along with this library; if not, write to the Free Software etisserant@0: #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA etisserant@0: etisserant@0: from wxPython.wx import * etisserant@0: import wx etisserant@0: etisserant@0: from plcopen.structures import * etisserant@0: from graphics.GraphicCommons import * etisserant@0: from graphics.FBD_Objects import * etisserant@0: from Viewer import * etisserant@0: etisserant@0: class FBD_Viewer(Viewer): etisserant@0: etisserant@0: def __init__(self, parent, window, controler): etisserant@0: Viewer.__init__(self, parent, window, controler) etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Mouse event functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: def OnViewerLeftDown(self, event): etisserant@0: if self.Mode == MODE_SELECTION: etisserant@0: pos = event.GetPosition() etisserant@0: if event.ControlDown() and self.SelectedElement: etisserant@0: element = self.FindElement(pos, True) etisserant@0: if element: etisserant@0: if isinstance(self.SelectedElement, Graphic_Group): etisserant@0: self.SelectedElement.SetSelected(False) etisserant@0: self.SelectedElement.SelectElement(element) etisserant@0: elif self.SelectedElement: etisserant@0: group = Graphic_Group(self) etisserant@0: group.SelectElement(self.SelectedElement) etisserant@0: group.SelectElement(element) etisserant@0: self.SelectedElement = group etisserant@0: elements = self.SelectedElement.GetElements() etisserant@0: if len(elements) == 0: etisserant@0: self.SelectedElement = element etisserant@0: elif len(elements) == 1: etisserant@0: self.SelectedElement = elements[0] etisserant@0: self.SelectedElement.SetSelected(True) etisserant@0: else: etisserant@0: element = self.FindElement(pos) etisserant@0: if self.SelectedElement and self.SelectedElement != element: etisserant@0: self.SelectedElement.SetSelected(False) etisserant@0: self.SelectedElement = None etisserant@0: self.Refresh() etisserant@0: if element: etisserant@0: self.SelectedElement = element etisserant@0: self.SelectedElement.OnLeftDown(event, self.Scaling) etisserant@0: self.Refresh() etisserant@0: else: etisserant@0: self.rubberBand.Reset() etisserant@0: self.rubberBand.OnLeftDown(event, self.Scaling) etisserant@0: elif self.Mode in [MODE_BLOCK,MODE_VARIABLE,MODE_CONNECTION,MODE_COMMENT]: etisserant@0: self.rubberBand.Reset() etisserant@0: self.rubberBand.OnLeftDown(event, self.Scaling) etisserant@0: elif self.Mode == MODE_WIRE: etisserant@0: pos = GetScaledEventPosition(event, self.Scaling) etisserant@0: wire = Wire(self, [wxPoint(pos.x, pos.y), EAST], [wxPoint(pos.x, pos.y), WEST]) etisserant@0: wire.oldPos = pos etisserant@0: wire.Handle = (HANDLE_POINT, 0) etisserant@0: wire.ProcessDragging(0, 0) etisserant@0: wire.Handle = (HANDLE_POINT, 1) etisserant@0: self.Wires.append(wire) etisserant@0: self.Elements.append(wire) etisserant@0: if self.SelectedElement: etisserant@0: self.SelectedElement.SetSelected(False) etisserant@0: self.SelectedElement = wire etisserant@0: self.Refresh() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnViewerLeftUp(self, event): etisserant@0: if self.rubberBand.IsShown(): etisserant@0: if self.Mode == MODE_SELECTION: etisserant@0: elements = self.SearchElements(self.rubberBand.GetCurrentExtent()) etisserant@0: self.rubberBand.OnLeftUp(event, self.Scaling) etisserant@0: if len(elements) > 0: etisserant@0: self.SelectedElement = Graphic_Group(self) etisserant@0: self.SelectedElement.SetElements(elements) etisserant@0: self.SelectedElement.SetSelected(True) etisserant@0: self.Refresh() etisserant@0: elif self.Mode == MODE_BLOCK: etisserant@0: bbox = self.rubberBand.GetCurrentExtent() etisserant@0: self.rubberBand.OnLeftUp(event, self.Scaling) etisserant@0: wxCallAfter(self.AddNewBlock, bbox) etisserant@0: elif self.Mode == MODE_VARIABLE: etisserant@0: bbox = self.rubberBand.GetCurrentExtent() etisserant@0: self.rubberBand.OnLeftUp(event, self.Scaling) etisserant@0: wxCallAfter(self.AddNewVariable, bbox) etisserant@0: elif self.Mode == MODE_CONNECTION: etisserant@0: bbox = self.rubberBand.GetCurrentExtent() etisserant@0: self.rubberBand.OnLeftUp(event, self.Scaling) etisserant@0: wxCallAfter(self.AddNewConnection, bbox) etisserant@0: elif self.Mode == MODE_COMMENT: etisserant@0: bbox = self.rubberBand.GetCurrentExtent() etisserant@0: self.rubberBand.OnLeftUp(event, self.Scaling) etisserant@0: wxCallAfter(self.AddNewComment, bbox) etisserant@0: elif self.Mode == MODE_SELECTION and self.SelectedElement: etisserant@0: self.SelectedElement.OnLeftUp(event, self.Scaling) etisserant@0: wxCallAfter(self.SetCursor, wxNullCursor) etisserant@0: self.ReleaseMouse() etisserant@0: self.Refresh() etisserant@0: elif self.Mode == MODE_WIRE and self.SelectedElement: etisserant@0: self.SelectedElement.ResetPoints() etisserant@0: self.SelectedElement.OnMotion(event, self.Scaling) etisserant@0: self.SelectedElement.GeneratePoints() etisserant@0: self.SelectedElement.RefreshModel() etisserant@0: self.SelectedElement.SetSelected(True) etisserant@0: self.Refresh() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnViewerRightUp(self, event): etisserant@0: pos = event.GetPosition() etisserant@0: element = self.FindElement(pos) etisserant@0: if element: etisserant@0: if self.SelectedElement and self.SelectedElement != element: etisserant@0: self.SelectedElement.SetSelected(False) etisserant@0: self.SelectedElement = element etisserant@0: self.SelectedElement.SetSelected(True) etisserant@0: self.SelectedElement.OnRightUp(event, self.Scaling) etisserant@0: wxCallAfter(self.SetCursor, wxNullCursor) etisserant@0: self.ReleaseMouse() etisserant@0: self.Refresh() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnViewerLeftDClick(self, event): etisserant@0: if self.Mode == MODE_SELECTION and self.SelectedElement: etisserant@0: self.SelectedElement.OnLeftDClick(event, self.Scaling) etisserant@0: self.Refresh() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnViewerMotion(self, event): etisserant@0: if self.rubberBand.IsShown(): etisserant@0: self.rubberBand.OnMotion(event, self.Scaling) etisserant@0: elif self.Mode == MODE_SELECTION and self.SelectedElement: etisserant@0: self.SelectedElement.OnMotion(event, self.Scaling) etisserant@0: self.Refresh() etisserant@0: elif self.Mode == MODE_WIRE and self.SelectedElement: etisserant@0: self.SelectedElement.ResetPoints() etisserant@0: self.SelectedElement.OnMotion(event, self.Scaling) etisserant@0: self.SelectedElement.GeneratePoints() etisserant@0: self.Refresh() etisserant@0: event.Skip() etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Keyboard event functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: def OnChar(self, event): etisserant@0: keycode = event.GetKeyCode() etisserant@0: if self.Scaling: etisserant@0: scaling = self.Scaling etisserant@0: else: etisserant@0: scaling = (8, 8) etisserant@0: if keycode == WXK_DELETE and self.SelectedElement: etisserant@0: self.SelectedElement.Clean() etisserant@0: self.SelectedElement.Delete() etisserant@0: self.SelectedElement = None etisserant@0: elif keycode == WXK_LEFT and self.SelectedElement: etisserant@0: self.SelectedElement.Move(-scaling[0], 0) etisserant@0: elif keycode == WXK_RIGHT and self.SelectedElement: etisserant@0: self.SelectedElement.Move(scaling[0], 0) etisserant@0: elif keycode == WXK_UP and self.SelectedElement: etisserant@0: self.SelectedElement.Move(0, -scaling[1]) etisserant@0: elif keycode == WXK_DOWN and self.SelectedElement: etisserant@0: self.SelectedElement.Move(0, scaling[1]) etisserant@0: self.Refresh() etisserant@0: event.Skip() etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Adding element functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: def AddNewBlock(self, bbox): etisserant@0: dialog = BlockPropertiesDialog(self.Parent) etisserant@0: dialog.SetBlockList(self.Controler.GetBlockTypes()) etisserant@0: dialog.SetMinBlockSize((bbox.width, bbox.height)) etisserant@0: if dialog.ShowModal() == wxID_OK: etisserant@0: id = self.GetNewId() etisserant@0: values = dialog.GetValues() etisserant@0: if "name" in values: etisserant@0: block = FBD_Block(self, values["type"], values["name"], id, values["extension"]) etisserant@0: else: etisserant@0: block = FBD_Block(self, values["type"], "", id, values["extension"]) etisserant@0: block.SetPosition(bbox.x, bbox.y) etisserant@0: block.SetSize(values["width"], values["height"]) etisserant@0: self.Blocks.append(block) etisserant@0: self.Elements.append(block) etisserant@0: self.Controler.AddCurrentElementEditingBlock(id) etisserant@0: self.RefreshBlockModel(block) etisserant@0: self.Parent.RefreshProjectTree() etisserant@0: self.Refresh() etisserant@0: dialog.Destroy() etisserant@0: etisserant@0: def AddNewVariable(self, bbox): etisserant@0: dialog = VariablePropertiesDialog(self.Parent) etisserant@0: dialog.SetMinVariableSize((bbox.width, bbox.height)) etisserant@0: varlist = [] etisserant@0: vars = self.Controler.GetCurrentElementEditingInterfaceVars() etisserant@0: if vars: etisserant@0: for var in vars: etisserant@0: varlist.append((var["Name"], var["Class"], var["Type"])) etisserant@0: returntype = self.Controler.GetCurrentElementEditingInterfaceReturnType() etisserant@0: if returntype: etisserant@0: varlist.append((self.Controler.GetCurrentElementEditingName(), "Output", returntype)) etisserant@0: dialog.SetVariables(varlist) etisserant@0: if dialog.ShowModal() == wxID_OK: etisserant@0: id = self.GetNewId() etisserant@0: values = dialog.GetValues() etisserant@0: variable = FBD_Variable(self, values["type"], values["name"], values["value_type"], id) etisserant@0: variable.SetPosition(bbox.x, bbox.y) etisserant@0: variable.SetSize(values["width"], values["height"]) etisserant@0: self.Blocks.append(variable) etisserant@0: self.Elements.append(variable) etisserant@0: self.Controler.AddCurrentElementEditingVariable(id, values["type"]) etisserant@0: self.RefreshVariableModel(variable) etisserant@0: self.Parent.RefreshProjectTree() etisserant@0: self.Refresh() etisserant@0: dialog.Destroy() etisserant@0: etisserant@0: def AddNewConnection(self, bbox): etisserant@0: dialog = ConnectionPropertiesDialog(self.Parent) etisserant@0: dialog.SetMinConnectionSize((bbox.width, bbox.height)) etisserant@0: if dialog.ShowModal() == wxID_OK: etisserant@0: id = self.GetNewId() etisserant@0: values = dialog.GetValues() etisserant@0: connection = FBD_Connection(self, values["type"], values["name"], id) etisserant@0: connection.SetPosition(bbox.x, bbox.y) etisserant@0: connection.SetSize(values["width"], values["height"]) etisserant@0: self.Blocks.append(connection) etisserant@0: self.Elements.append(connection) etisserant@0: self.Controler.AddCurrentElementEditingConnection(id, values["type"]) etisserant@0: self.RefreshConnectionModel(connection) etisserant@0: self.Parent.RefreshProjectTree() etisserant@0: self.Refresh() etisserant@0: dialog.Destroy() etisserant@0: etisserant@0: def AddNewComment(self, bbox): etisserant@0: dialog = wxTextEntryDialog(self.Parent, "Add a new comment", "Please enter comment text", "", wxOK|wxCANCEL|wxTE_MULTILINE) etisserant@0: if dialog.ShowModal() == wxID_OK: etisserant@0: value = dialog.GetValue() etisserant@0: id = self.GetNewId() etisserant@0: comment = Comment(self, value, id) etisserant@0: comment.SetPosition(bbox.x, bbox.y) etisserant@0: min_width, min_height = comment.GetMinSize() etisserant@0: comment.SetSize(max(min_width,bbox.width),max(min_height,bbox.height)) etisserant@0: self.Elements.append(comment) etisserant@0: self.Controler.AddCurrentElementEditingComment(id) etisserant@0: self.RefreshCommentModel(comment) etisserant@0: self.Refresh() etisserant@0: dialog.Destroy() etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Delete element functions etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: def DeleteBlock(self, block): etisserant@0: wires = [] etisserant@0: for output in block.GetConnectors()["outputs"]: etisserant@0: wires.extend([wire[0] for wire in output.GetWires()]) etisserant@0: block.Clean() etisserant@0: self.Blocks.remove(block) etisserant@0: self.Elements.remove(block) etisserant@0: self.Controler.RemoveCurrentElementEditingInstance(block.GetId()) etisserant@0: for wire in wires: etisserant@0: wire.RefreshModel() etisserant@0: self.Parent.RefreshProjectTree() etisserant@0: etisserant@0: def DeleteVariable(self, variable): etisserant@0: wires = [] etisserant@0: if self.SelectedElement.GetType() == INPUT: etisserant@0: connector = variable.GetConnector() etisserant@0: wires.extend([wire[0] for wire in connector.GetWires()]) etisserant@0: variable.Clean() etisserant@0: self.Blocks.remove(self.SelectedElement) etisserant@0: self.Elements.remove(self.SelectedElement) etisserant@0: self.Controler.RemoveCurrentElementEditingInstance(variable.GetId()) etisserant@0: for wire in wires: etisserant@0: wire.RefreshModel() etisserant@0: self.Parent.RefreshProjectTree() etisserant@0: etisserant@0: def DeleteConnection(self, connection): etisserant@0: wires = [] etisserant@0: if self.SelectedElement.GetType() == CONTINUATION: etisserant@0: connector = connection.GetConnector() etisserant@0: wires.extend([wire[0] for wire in connector.GetWires()]) etisserant@0: connection.Clean() etisserant@0: self.Blocks.remove(self.SelectedElement) etisserant@0: self.Elements.remove(self.SelectedElement) etisserant@0: self.Controler.RemoveCurrentElementEditingInstance(connection.GetId()) etisserant@0: for wire in wires: etisserant@0: wire.RefreshModel() etisserant@0: self.Parent.RefreshProjectTree() etisserant@0: etisserant@0: def DeleteComment(self, comment): etisserant@0: self.Elements.remove(self.SelectedElement) etisserant@0: self.Controler.RemoveCurrentElementEditingInstance(comment.GetId()) etisserant@0: etisserant@0: def DeleteWire(self, wire): etisserant@0: connected = wire.GetConnected() etisserant@0: self.SelectedElement.Clean() etisserant@0: self.Wires.remove(self.SelectedElement) etisserant@0: self.Elements.remove(self.SelectedElement) etisserant@0: for connector in connected: etisserant@0: connector.RefreshParentBlock() etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Create New Block Dialog etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: [wxID_BLOCKPROPERTIESDIALOG, wxID_BLOCKPROPERTIESDIALOGMAINPANEL, etisserant@0: wxID_BLOCKPROPERTIESDIALOGNAME, wxID_BLOCKPROPERTIESDIALOGTYPETREE, etisserant@0: wxID_BLOCKPROPERTIESDIALOGTYPEDESC, wxID_BLOCKPROPERTIESDIALOGINPUTS, etisserant@0: wxID_BLOCKPROPERTIESDIALOGPREVIEW, wxID_BLOCKPROPERTIESDIALOGSTATICTEXT1, etisserant@0: wxID_BLOCKPROPERTIESDIALOGSTATICTEXT2, wxID_BLOCKPROPERTIESDIALOGSTATICTEXT3, etisserant@0: wxID_BLOCKPROPERTIESDIALOGSTATICTEXT4, etisserant@0: ] = [wx.NewId() for _init_ctrls in range(11)] etisserant@0: etisserant@0: class BlockPropertiesDialog(wx.Dialog): etisserant@0: def _init_coll_flexGridSizer1_Items(self, parent): etisserant@0: # generated method, don't edit etisserant@0: etisserant@0: parent.AddWindow(self.MainPanel, 0, border=0, flag=0) etisserant@0: etisserant@0: def _init_sizers(self): etisserant@0: # generated method, don't edit etisserant@0: self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) etisserant@0: etisserant@0: self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) etisserant@0: etisserant@0: self.SetSizer(self.flexGridSizer1) etisserant@0: etisserant@0: def _init_ctrls(self, prnt): etisserant@0: # generated method, don't edit etisserant@0: wx.Dialog.__init__(self, id=wxID_BLOCKPROPERTIESDIALOG, etisserant@0: name='BlockPropertiesDialog', parent=prnt, pos=wx.Point(376, 223), etisserant@0: size=wx.Size(600, 360), style=wx.DEFAULT_DIALOG_STYLE, etisserant@0: title='Block Properties') etisserant@0: self.SetClientSize(wx.Size(600, 360)) etisserant@0: etisserant@0: self.MainPanel = wx.Panel(id=wxID_BLOCKPROPERTIESDIALOGMAINPANEL, etisserant@0: name='MainPanel', parent=self, pos=wx.Point(0, 0), etisserant@0: size=wx.Size(600, 320), style=wx.TAB_TRAVERSAL) etisserant@0: self.MainPanel.SetAutoLayout(True) etisserant@0: etisserant@0: self.staticbox1 = wx.StaticBox(id=wxID_BLOCKPROPERTIESDIALOGSTATICTEXT1, etisserant@0: label='Type:', name='staticBox1', parent=self.MainPanel, etisserant@0: pos=wx.Point(24, 24), size=wx.Size(245, 280), style=0) etisserant@0: etisserant@0: self.staticText2 = wx.StaticText(id=wxID_BLOCKPROPERTIESDIALOGSTATICTEXT2, etisserant@0: label='Name:', name='staticText2', parent=self.MainPanel, etisserant@0: pos=wx.Point(274, 24), size=wx.Size(70, 17), style=0) etisserant@0: etisserant@0: self.staticText3 = wx.StaticText(id=wxID_BLOCKPROPERTIESDIALOGSTATICTEXT2, etisserant@0: label='Inputs:', name='staticText4', parent=self.MainPanel, etisserant@0: pos=wx.Point(424, 24), size=wx.Size(70, 17), style=0) etisserant@0: etisserant@0: self.staticText4 = wx.StaticText(id=wxID_BLOCKPROPERTIESDIALOGSTATICTEXT4, etisserant@0: label='Preview:', name='staticText4', parent=self.MainPanel, etisserant@0: pos=wx.Point(274, 80), size=wx.Size(100, 17), style=0) etisserant@0: etisserant@0: self.TypeTree = wx.TreeCtrl(id=wxID_BLOCKPROPERTIESDIALOGTYPETREE, etisserant@0: name='TypeTree', parent=self.MainPanel, pos=wx.Point(34, 44), etisserant@0: size=wx.Size(225, 180), style=wx.TR_HAS_BUTTONS|wx.TR_HIDE_ROOT|wx.TR_SINGLE|wx.SUNKEN_BORDER) etisserant@0: EVT_TREE_SEL_CHANGED(self, wxID_BLOCKPROPERTIESDIALOGTYPETREE, self.OnTypeTreeItemSelected) etisserant@0: etisserant@0: self.TypeDesc = wx.TextCtrl(id=wxID_BLOCKPROPERTIESDIALOGTYPEDESC, etisserant@0: name='TypeDesc', parent=self.MainPanel, pos=wx.Point(34, 230), etisserant@0: size=wx.Size(225, 65), style=wx.TE_READONLY|wx.TE_MULTILINE) etisserant@0: etisserant@0: self.Name = wx.TextCtrl(id=wxID_BLOCKPROPERTIESDIALOGNAME, value='', etisserant@0: name='Name', parent=self.MainPanel, pos=wx.Point(274, 48), etisserant@0: size=wx.Size(145, 24), style=0) etisserant@0: EVT_TEXT(self, wxID_BLOCKPROPERTIESDIALOGNAME, self.OnNameChanged) etisserant@0: etisserant@0: self.Inputs = wx.SpinCtrl(id=wxID_BLOCKPROPERTIESDIALOGINPUTS, etisserant@0: name='Inputs', parent=self.MainPanel, pos=wx.Point(424, 48), etisserant@0: size=wx.Size(145, 24), style=0, min=2, max=20) etisserant@0: EVT_SPINCTRL(self, wxID_BLOCKPROPERTIESDIALOGINPUTS, self.OnInputsChanged) etisserant@0: etisserant@0: self.Preview = wx.Panel(id=wxID_BLOCKPROPERTIESDIALOGPREVIEW, etisserant@0: name='Preview', parent=self.MainPanel, pos=wx.Point(274, 104), etisserant@0: size=wx.Size(300, 200), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER) etisserant@0: self.Preview.SetBackgroundColour(wxColour(255,255,255)) etisserant@0: etisserant@0: self._init_sizers() etisserant@0: etisserant@0: def __init__(self, parent): etisserant@0: self._init_ctrls(parent) etisserant@0: self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL) etisserant@0: self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT) etisserant@0: self.Name.SetValue("") etisserant@0: self.Name.Enable(False) etisserant@0: self.Inputs.Enable(False) etisserant@0: self.Block = None etisserant@0: self.MinBlockSize = None etisserant@0: etisserant@0: EVT_PAINT(self, self.OnPaint) etisserant@0: EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK) etisserant@0: etisserant@0: def OnOK(self, event): etisserant@0: error = [] etisserant@0: selected = self.TypeTree.GetSelection() etisserant@0: if not selected.IsOk() or self.TypeTree.GetItemParent(selected) == self.TypeTree.GetRootItem() or selected == self.TypeTree.GetRootItem(): etisserant@0: message = wxMessageDialog(self, "Form isn't complete. Valid block type must be selected!", "Error", wxOK|wxICON_ERROR) etisserant@0: message.ShowModal() etisserant@0: message.Destroy() etisserant@0: elif self.Name.IsEnabled() and self.Name.GetValue() == "": etisserant@0: message = wxMessageDialog(self, "Form isn't complete. Name must be filled!", "Error", wxOK|wxICON_ERROR) etisserant@0: message.ShowModal() etisserant@0: message.Destroy() etisserant@0: else: etisserant@0: self.EndModal(wxID_OK) etisserant@0: etisserant@0: def SetBlockList(self, blocktypes): etisserant@0: root = self.TypeTree.AddRoot("") etisserant@0: for category in blocktypes: etisserant@0: category_item = self.TypeTree.AppendItem(root, category["name"]) etisserant@0: for blocktype in category["list"]: etisserant@0: blocktype_item = self.TypeTree.AppendItem(category_item, blocktype["name"]) etisserant@0: etisserant@0: def SetMinBlockSize(self, size): etisserant@0: self.MinBlockSize = size etisserant@0: etisserant@0: def GetValues(self): etisserant@0: values = {} etisserant@0: values["type"] = self.TypeTree.GetItemText(self.TypeTree.GetSelection()) etisserant@0: if self.Name.GetValue() != "": etisserant@0: values["name"] = self.Name.GetValue() etisserant@0: values["width"], values["height"] = self.Block.GetSize() etisserant@0: values["extension"] = self.Inputs.GetValue() etisserant@0: return values etisserant@0: etisserant@0: def OnTypeTreeItemSelected(self, event): etisserant@0: self.Name.SetValue("") etisserant@0: selected = event.GetItem() etisserant@0: if self.TypeTree.GetItemParent(selected) != self.TypeTree.GetRootItem(): etisserant@0: blocktype = GetBlockType(self.TypeTree.GetItemText(selected)) etisserant@0: if blocktype: etisserant@0: self.Inputs.SetValue(len(blocktype["inputs"])) etisserant@0: self.Inputs.Enable(blocktype["extensible"]) etisserant@0: self.Name.Enable(blocktype["type"] != "function") etisserant@0: self.TypeDesc.SetValue(blocktype["comment"]) etisserant@0: wxCallAfter(self.RefreshPreview) etisserant@0: else: etisserant@0: self.Name.Enable(False) etisserant@0: self.Inputs.Enable(False) etisserant@0: self.Inputs.SetValue(2) etisserant@0: self.TypeDesc.SetValue("") etisserant@0: wxCallAfter(self.ErasePreview) etisserant@0: else: etisserant@0: self.Name.Enable(False) etisserant@0: self.Inputs.Enable(False) etisserant@0: self.Inputs.SetValue(2) etisserant@0: self.TypeDesc.SetValue("") etisserant@0: wxCallAfter(self.ErasePreview) etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnNameChanged(self, event): etisserant@0: if self.Name.IsEnabled(): etisserant@0: self.RefreshPreview() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnInputsChanged(self, event): etisserant@0: if self.Inputs.IsEnabled(): etisserant@0: self.RefreshPreview() etisserant@0: event.Skip() etisserant@0: etisserant@0: def ErasePreview(self): etisserant@0: dc = wxClientDC(self.Preview) etisserant@0: dc.Clear() etisserant@0: self.Block = None etisserant@0: etisserant@0: def RefreshPreview(self): etisserant@0: dc = wxClientDC(self.Preview) etisserant@0: dc.Clear() etisserant@0: blocktype = self.TypeTree.GetItemText(self.TypeTree.GetSelection()) etisserant@0: self.Block = FBD_Block(self.Preview, blocktype, self.Name.GetValue(), extension = self.Inputs.GetValue()) etisserant@0: width, height = self.MinBlockSize etisserant@0: min_width, min_height = self.Block.GetMinSize() etisserant@0: width, height = max(min_width, width), max(min_height, height) etisserant@0: self.Block.SetSize(width, height) etisserant@0: clientsize = self.Preview.GetClientSize() etisserant@0: x = (clientsize.width - width) / 2 etisserant@0: y = (clientsize.height - height) / 2 etisserant@0: self.Block.SetPosition(x, y) etisserant@0: self.Block.Draw(dc) etisserant@0: etisserant@0: def OnPaint(self, event): etisserant@0: if self.Block: etisserant@0: self.RefreshPreview() etisserant@0: else: etisserant@0: self.ErasePreview() etisserant@0: etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Create New Variable Dialog etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: [wxID_VARIABLEPROPERTIESDIALOG, wxID_VARIABLEPROPERTIESDIALOGMAINPANEL, etisserant@0: wxID_VARIABLEPROPERTIESDIALOGNAME, wxID_VARIABLEPROPERTIESDIALOGCLASS, etisserant@0: wxID_VARIABLEPROPERTIESDIALOGPREVIEW, wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT1, etisserant@0: wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT2, wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT3, etisserant@0: ] = [wx.NewId() for _init_ctrls in range(8)] etisserant@0: etisserant@0: class VariablePropertiesDialog(wx.Dialog): etisserant@0: def _init_coll_flexGridSizer1_Items(self, parent): etisserant@0: # generated method, don't edit etisserant@0: etisserant@0: parent.AddWindow(self.MainPanel, 0, border=0, flag=0) etisserant@0: etisserant@0: def _init_sizers(self): etisserant@0: # generated method, don't edit etisserant@0: self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) etisserant@0: etisserant@0: self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) etisserant@0: etisserant@0: self.SetSizer(self.flexGridSizer1) etisserant@0: etisserant@0: def _init_ctrls(self, prnt): etisserant@0: # generated method, don't edit etisserant@0: wx.Dialog.__init__(self, id=wxID_VARIABLEPROPERTIESDIALOG, etisserant@0: name='VariablePropertiesDialog', parent=prnt, pos=wx.Point(376, 223), etisserant@0: size=wx.Size(400, 320), style=wx.DEFAULT_DIALOG_STYLE, etisserant@0: title='Variable Properties') etisserant@0: self.SetClientSize(wx.Size(400, 320)) etisserant@0: etisserant@0: self.MainPanel = wx.Panel(id=wxID_VARIABLEPROPERTIESDIALOGMAINPANEL, etisserant@0: name='MainPanel', parent=self, pos=wx.Point(0, 0), etisserant@0: size=wx.Size(400, 280), style=wx.TAB_TRAVERSAL) etisserant@0: self.MainPanel.SetAutoLayout(True) etisserant@0: etisserant@0: self.staticText1 = wx.StaticText(id=wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT1, etisserant@0: label='Class:', name='staticText1', parent=self.MainPanel, etisserant@0: pos=wx.Point(24, 24), size=wx.Size(70, 17), style=0) etisserant@0: etisserant@0: self.staticText2 = wx.StaticText(id=wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT2, etisserant@0: label='Name:', name='staticText2', parent=self.MainPanel, etisserant@0: pos=wx.Point(204, 24), size=wx.Size(70, 17), style=0) etisserant@0: etisserant@0: self.staticText3 = wx.StaticText(id=wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT3, etisserant@0: label='Preview:', name='staticText3', parent=self.MainPanel, etisserant@0: pos=wx.Point(24, 72), size=wx.Size(100, 17), style=0) etisserant@0: etisserant@0: self.Class = wx.Choice(id=wxID_VARIABLEPROPERTIESDIALOGCLASS, etisserant@0: name='Class', parent=self.MainPanel, pos=wx.Point(24, 48), etisserant@0: size=wx.Size(145, 24), style=0) etisserant@0: EVT_CHOICE(self, wxID_VARIABLEPROPERTIESDIALOGCLASS, self.OnClassChanged) etisserant@0: etisserant@0: self.Name = wx.Choice(id=wxID_VARIABLEPROPERTIESDIALOGNAME, etisserant@0: name='Name', parent=self.MainPanel, pos=wx.Point(204, 48), etisserant@0: size=wx.Size(145, 24), style=0) etisserant@0: EVT_CHOICE(self, wxID_VARIABLEPROPERTIESDIALOGNAME, self.OnNameChanged) etisserant@0: etisserant@0: self.Preview = wx.Panel(id=wxID_VARIABLEPROPERTIESDIALOGPREVIEW, etisserant@0: name='Preview', parent=self.MainPanel, pos=wx.Point(24, 104), etisserant@0: size=wx.Size(350, 150), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER) etisserant@0: self.Preview.SetBackgroundColour(wxColour(255,255,255)) etisserant@0: etisserant@0: self._init_sizers() etisserant@0: etisserant@0: def __init__(self, parent): etisserant@0: self._init_ctrls(parent) etisserant@0: self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL) etisserant@0: self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT) etisserant@0: self.Variable = None etisserant@0: self.VarList = [] etisserant@0: self.MinVariableSize = None etisserant@0: self.RefreshNameList() etisserant@0: etisserant@0: for choice in ["Input", "Output", "InOut"]: etisserant@0: self.Class.Append(choice) etisserant@0: self.Class.SetStringSelection("Input") etisserant@0: etisserant@0: EVT_PAINT(self, self.OnPaint) etisserant@0: etisserant@0: def RefreshNameList(self): etisserant@0: selected = self.Name.GetStringSelection() etisserant@0: self.Name.Clear() etisserant@0: for name, var_type, value_type in self.VarList: etisserant@0: if var_type in ["Local","Temp","Output","InOut"]: etisserant@0: self.Name.Append(name) etisserant@0: elif var_type == "Input" and self.Class.GetStringSelection() == "Input": etisserant@0: self.Name.Append(name) etisserant@0: if self.Name.FindString(selected) != wxNOT_FOUND: etisserant@0: self.Name.SetStringSelection(selected) etisserant@0: self.Name.Enable(self.Name.GetCount() > 0) etisserant@0: etisserant@0: def SetMinVariableSize(self, size): etisserant@0: self.MinVariableSize = size etisserant@0: etisserant@0: def SetVariables(self, vars): etisserant@0: self.VarList = vars etisserant@0: self.RefreshNameList() etisserant@0: etisserant@0: def GetValues(self): etisserant@0: values = {} etisserant@0: classtype = self.Class.GetStringSelection() etisserant@0: if classtype == "Input": etisserant@0: values["type"] = INPUT etisserant@0: elif classtype == "Output": etisserant@0: values["type"] = OUTPUT etisserant@0: elif classtype == "InOut": etisserant@0: values["type"] = INOUT etisserant@0: values["name"] = self.Name.GetStringSelection() etisserant@0: values["value_type"] = "" etisserant@0: for var_name, var_type, value_type in self.VarList: etisserant@0: if var_name == values["name"]: etisserant@0: values["value_type"] = value_type etisserant@0: values["width"], values["height"] = self.Variable.GetSize() etisserant@0: return values etisserant@0: etisserant@0: def OnClassChanged(self, event): etisserant@0: self.RefreshNameList() etisserant@0: self.RefreshPreview() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnNameChanged(self, event): etisserant@0: self.RefreshPreview() etisserant@0: event.Skip() etisserant@0: etisserant@0: def RefreshPreview(self): etisserant@0: dc = wxClientDC(self.Preview) etisserant@0: dc.Clear() etisserant@0: name = self.Name.GetStringSelection() etisserant@0: type = "" etisserant@0: for var_name, var_type, value_type in self.VarList: etisserant@0: if var_name == name: etisserant@0: type = value_type etisserant@0: classtype = self.Class.GetStringSelection() etisserant@0: if classtype == "Input": etisserant@0: self.Variable = FBD_Variable(self.Preview, INPUT, name, type) etisserant@0: elif classtype == "Output": etisserant@0: self.Variable = FBD_Variable(self.Preview, OUTPUT, name, type) etisserant@0: elif classtype == "InOut": etisserant@0: self.Variable = FBD_Variable(self.Preview, INOUT, name, type) etisserant@0: width, height = self.MinVariableSize etisserant@0: min_width, min_height = self.Variable.GetMinSize() etisserant@0: width, height = max(min_width, width), max(min_height, height) etisserant@0: self.Variable.SetSize(width, height) etisserant@0: clientsize = self.Preview.GetClientSize() etisserant@0: x = (clientsize.width - width) / 2 etisserant@0: y = (clientsize.height - height) / 2 etisserant@0: self.Variable.SetPosition(x, y) etisserant@0: self.Variable.Draw(dc) etisserant@0: etisserant@0: def OnPaint(self, event): etisserant@0: self.RefreshPreview() etisserant@0: etisserant@0: #------------------------------------------------------------------------------- etisserant@0: # Create New Connection Dialog etisserant@0: #------------------------------------------------------------------------------- etisserant@0: etisserant@0: [wxID_CONNECTIONPROPERTIESDIALOG, wxID_CONNECTIONPROPERTIESDIALOGMAINPANEL, etisserant@0: wxID_CONNECTIONPROPERTIESDIALOGNAME, wxID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON1, etisserant@0: wxID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON2, wxID_CONNECTIONPROPERTIESDIALOGPREVIEW, etisserant@0: wxID_CONNECTIONPROPERTIESDIALOGSTATICTEXT1, wxID_CONNECTIONPROPERTIESDIALOGSTATICTEXT2, etisserant@0: wxID_CONNECTIONPROPERTIESDIALOGSTATICTEXT3, etisserant@0: ] = [wx.NewId() for _init_ctrls in range(9)] etisserant@0: etisserant@0: class ConnectionPropertiesDialog(wx.Dialog): etisserant@0: def _init_coll_flexGridSizer1_Items(self, parent): etisserant@0: # generated method, don't edit etisserant@0: etisserant@0: parent.AddWindow(self.MainPanel, 0, border=0, flag=0) etisserant@0: etisserant@0: def _init_sizers(self): etisserant@0: # generated method, don't edit etisserant@0: self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) etisserant@0: etisserant@0: self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) etisserant@0: etisserant@0: self.SetSizer(self.flexGridSizer1) etisserant@0: etisserant@0: def _init_ctrls(self, prnt): etisserant@0: # generated method, don't edit etisserant@0: wx.Dialog.__init__(self, id=wxID_CONNECTIONPROPERTIESDIALOG, etisserant@0: name='ConnectionPropertiesDialog', parent=prnt, pos=wx.Point(376, 223), etisserant@0: size=wx.Size(350, 220), style=wx.DEFAULT_DIALOG_STYLE, etisserant@0: title='Connection Properties') etisserant@0: self.SetClientSize(wx.Size(350, 220)) etisserant@0: etisserant@0: self.MainPanel = wx.Panel(id=wxID_CONNECTIONPROPERTIESDIALOGMAINPANEL, etisserant@0: name='MainPanel', parent=self, pos=wx.Point(0, 0), etisserant@0: size=wx.Size(340, 360), style=wx.TAB_TRAVERSAL) etisserant@0: self.MainPanel.SetAutoLayout(True) etisserant@0: etisserant@0: self.staticText1 = wx.StaticText(id=wxID_CONNECTIONPROPERTIESDIALOGSTATICTEXT1, etisserant@0: label='Type:', name='staticText1', parent=self.MainPanel, etisserant@0: pos=wx.Point(24, 24), size=wx.Size(70, 17), style=0) etisserant@0: etisserant@0: self.staticText2 = wx.StaticText(id=wxID_CONNECTIONPROPERTIESDIALOGSTATICTEXT2, etisserant@0: label='Name:', name='staticText2', parent=self.MainPanel, etisserant@0: pos=wx.Point(24, 104), size=wx.Size(70, 17), style=0) etisserant@0: etisserant@0: self.staticText3 = wx.StaticText(id=wxID_CONNECTIONPROPERTIESDIALOGSTATICTEXT3, etisserant@0: label='Preview:', name='staticText3', parent=self.MainPanel, etisserant@0: pos=wx.Point(174, 24), size=wx.Size(100, 17), style=0) etisserant@0: etisserant@0: self.radioButton1 = wx.RadioButton(id=wxID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON1, etisserant@0: label='Connector', name='radioButton1', parent=self.MainPanel, etisserant@0: pos=wx.Point(24, 48), size=wx.Size(114, 24), style=0) etisserant@0: EVT_RADIOBUTTON(self, wxID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON1, self.OnTypeChanged) etisserant@0: self.radioButton1.SetValue(True) etisserant@0: etisserant@0: self.radioButton2 = wx.RadioButton(id=wxID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON2, etisserant@0: label='Continuation', name='radioButton2', parent=self.MainPanel, etisserant@0: pos=wx.Point(24, 72), size=wx.Size(128, 24), style=0) etisserant@0: EVT_RADIOBUTTON(self, wxID_CONNECTIONPROPERTIESDIALOGRADIOBUTTON2, self.OnTypeChanged) etisserant@0: self.radioButton2.SetValue(False) etisserant@0: etisserant@0: self.Name = wx.TextCtrl(id=wxID_CONNECTIONPROPERTIESDIALOGNAME, etisserant@0: name='Name', parent=self.MainPanel, pos=wx.Point(24, 130), etisserant@0: size=wx.Size(145, 24), style=0) etisserant@0: EVT_TEXT(self, wxID_CONNECTIONPROPERTIESDIALOGNAME, self.OnNameChanged) etisserant@0: etisserant@0: self.Preview = wx.Panel(id=wxID_CONNECTIONPROPERTIESDIALOGPREVIEW, etisserant@0: name='Preview', parent=self.MainPanel, pos=wx.Point(174, 48), etisserant@0: size=wx.Size(150, 100), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER) etisserant@0: self.Preview.SetBackgroundColour(wxColour(255,255,255)) etisserant@0: etisserant@0: self._init_sizers() etisserant@0: etisserant@0: def __init__(self, parent): etisserant@0: self._init_ctrls(parent) etisserant@0: self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL) etisserant@0: self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT) etisserant@0: self.Connection = None etisserant@0: self.MinConnectionSize = None etisserant@0: etisserant@0: EVT_PAINT(self, self.OnPaint) etisserant@0: etisserant@0: def SetMinConnectionSize(self, size): etisserant@0: self.MinConnectionSize = size etisserant@0: etisserant@0: def GetValues(self): etisserant@0: values = {} etisserant@0: if self.radioButton1.GetValue(): etisserant@0: values["type"] = CONNECTOR etisserant@0: else: etisserant@0: values["type"] = CONTINUATION etisserant@0: values["name"] = self.Name.GetValue() etisserant@0: values["width"], values["height"] = self.Connection.GetSize() etisserant@0: return values etisserant@0: etisserant@0: def OnTypeChanged(self, event): etisserant@0: self.RefreshPreview() etisserant@0: event.Skip() etisserant@0: etisserant@0: def OnNameChanged(self, event): etisserant@0: self.RefreshPreview() etisserant@0: event.Skip() etisserant@0: etisserant@0: def RefreshPreview(self): etisserant@0: dc = wxClientDC(self.Preview) etisserant@0: dc.Clear() etisserant@0: if self.radioButton1.GetValue(): etisserant@0: self.Connection = FBD_Connector(self.Preview, CONNECTOR, self.Name.GetValue()) etisserant@0: else: etisserant@0: self.Connection = FBD_Connector(self.Preview, CONTINUATION, self.Name.GetValue()) etisserant@0: width, height = self.MinConnectionSize etisserant@0: min_width, min_height = self.Connection.GetMinSize() etisserant@0: width, height = max(min_width, width), max(min_height, height) etisserant@0: self.Connection.SetSize(width, height) etisserant@0: clientsize = self.Preview.GetClientSize() etisserant@0: x = (clientsize.width - width) / 2 etisserant@0: y = (clientsize.height - height) / 2 etisserant@0: self.Connection.SetPosition(x, y) etisserant@0: self.Connection.Draw(dc) etisserant@0: etisserant@0: def OnPaint(self, event): etisserant@0: self.RefreshPreview()