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