lbessard@137: import os, shutil, sys etisserant@20: base_folder = os.path.split(sys.path[0])[0] lbessard@137: sys.path.append(os.path.join(base_folder, "wxsvg", "SVGUIEditor")) lbessard@137: sys.path.append(os.path.join(base_folder, "plcopeneditor", "graphics")) lbessard@137: lbessard@137: import wx lbessard@137: lbessard@147: from SVGUIGenerator import * lbessard@137: from SVGUIControler import * lbessard@137: from SVGUIEditor import * etisserant@37: from FBD_Objects import * lbessard@11: lbessard@137: from wxPopen import ProcessLogger lbessard@189: from wx.wxsvg import SVGDocument lbessard@137: lbessard@137: [ID_SVGUIEDITORFBDPANEL, lbessard@137: ] = [wx.NewId() for _init_ctrls in range(1)] lbessard@137: lbessard@137: SVGUIFB_Types = {ITEM_CONTAINER : "Container", lbessard@137: ITEM_BUTTON : "Button", lbessard@137: ITEM_TEXT : "TextCtrl", lbessard@137: ITEM_SCROLLBAR : "ScrollBar", lbessard@137: ITEM_ROTATING : "RotatingCtrl", lbessard@137: ITEM_NOTEBOOK : "NoteBook", lbessard@137: ITEM_TRANSFORM : "Transform"} lbessard@137: lbessard@137: class _SVGUIEditor(SVGUIEditor): etisserant@37: """ lbessard@137: This Class add IEC specific features to the SVGUIEditor : etisserant@37: - FDB preview etisserant@37: - FBD begin drag etisserant@37: """ lbessard@137: lbessard@137: def _init_coll_EditorGridSizer_Items(self, parent): lbessard@137: SVGUIEditor._init_coll_EditorGridSizer_Items(self, parent) lbessard@137: parent.AddWindow(self.FBDPanel, 0, border=0, flag=wx.GROW) lbessard@137: lbessard@137: def _init_ctrls(self, prnt): lbessard@137: SVGUIEditor._init_ctrls(self, prnt, False) lbessard@137: lbessard@137: self.FBDPanel = wx.Panel(id=ID_SVGUIEDITORFBDPANEL, lbessard@137: name='FBDPanel', parent=self.EditorPanel, pos=wx.Point(0, 0), lbessard@137: size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER) lbessard@137: self.FBDPanel.SetBackgroundColour(wx.WHITE) lbessard@137: self.FBDPanel.Bind(wx.EVT_LEFT_DOWN, self.OnFBDPanelClick) lbessard@137: self.FBDPanel.Bind(wx.EVT_PAINT, self.OnPaintFBDPanel) lbessard@137: lbessard@137: setattr(self.FBDPanel, "GetScaling", lambda: None) lbessard@137: lbessard@137: self._init_sizers() lbessard@137: lbessard@137: def __init__(self, parent, controler = None, fileOpen = None): lbessard@137: SVGUIEditor.__init__(self, parent, controler, fileOpen) lbessard@137: lbessard@137: self.FBDBlock = None lbessard@137: lbessard@137: def RefreshView(self, select_id = None): lbessard@137: SVGUIEditor.RefreshView(self, select_id) lbessard@137: self.FBDPanel.Refresh() lbessard@137: lbessard@137: def OnPaintFBDPanel(self,event): lbessard@137: dc = wx.ClientDC(self.FBDPanel) etisserant@37: dc.Clear() lbessard@137: selected = self.GetSelected() lbessard@137: if selected is not None: lbessard@137: selected_type = self.Controler.GetElementType(selected) lbessard@137: if selected_type is not None: lbessard@137: self.FBDBlock = FBD_Block(parent=self.FBDPanel,type=SVGUIFB_Types[selected_type],name=self.Controler.GetElementName(selected)) lbessard@137: width, height = self.FBDBlock.GetMinSize() lbessard@137: self.FBDBlock.SetSize(width,height) lbessard@137: clientsize = self.FBDPanel.GetClientSize() etisserant@37: x = (clientsize.width - width) / 2 etisserant@37: y = (clientsize.height - height) / 2 lbessard@137: self.FBDBlock.SetPosition(x, y) lbessard@137: self.FBDBlock.Draw(dc) lbessard@137: else: lbessard@137: self.FBDBlock = None etisserant@37: event.Skip() etisserant@37: lbessard@137: def OnFBDPanelClick(self, event): lbessard@137: if self.FBDBlock: lbessard@137: data = wx.TextDataObject(str((self.FBDBlock.GetType(), "functionBlock", self.FBDBlock.GetName()))) lbessard@137: DropSrc = wx.DropSource(self.FBDPanel) etisserant@37: DropSrc.SetData(data) etisserant@37: DropSrc.DoDragDrop() lbessard@137: event.Skip() lbessard@137: lbessard@137: def OnInterfaceTreeItemSelected(self, event): lbessard@137: self.FBDPanel.Refresh() lbessard@137: SVGUIEditor.OnInterfaceTreeItemSelected(self, event) lbessard@137: etisserant@37: def OnGenerate(self,event): etisserant@37: self.SaveProject() etisserant@37: self.Controler.PlugGenerate_C(sys.path[0],(0,0,4,5),None) etisserant@37: event.Skip() etisserant@37: etisserant@37: TYPECONVERSION = {"BOOL" : "X", "SINT" : "B", "INT" : "W", "DINT" : "D", "LINT" : "L", etisserant@37: "USINT" : "B", "UINT" : "W", "UDINT" : "D", "ULINT" : "L", "REAL" : "D", "LREAL" : "L", etisserant@37: "STRING" : "B", "BYTE" : "B", "WORD" : "W", "DWORD" : "D", "LWORD" : "L", "WSTRING" : "W"} lbessard@137: etisserant@44: CTYPECONVERSION = {"BOOL" : "IEC_BOOL", "UINT" : "IEC_UINT", "STRING" : "IEC_STRING", "REAL" : "IEC_REAL"} etisserant@37: CPRINTTYPECONVERSION = {"BOOL" : "d", "UINT" : "d", "STRING" : "s", "REAL" : "f"} lbessard@137: lbessard@137: class RootClass(SVGUIControler): etisserant@37: etisserant@38: def __init__(self): lbessard@137: SVGUIControler.__init__(self) lbessard@137: filepath = os.path.join(self.PlugPath(), "gui.xml") etisserant@37: etisserant@12: if os.path.isfile(filepath): etisserant@37: svgfile = os.path.join(self.PlugPath(), "gui.svg") etisserant@37: if os.path.isfile(svgfile): etisserant@37: self.SvgFilepath = svgfile etisserant@12: self.OpenXMLFile(filepath) etisserant@13: else: lbessard@137: self.CreateNewInterface() etisserant@12: self.SetFilePath(filepath) etisserant@12: lbessard@137: def GetElementIdFromName(self, name): lbessard@137: element = self.GetElementByName(name) lbessard@137: if element is not None: lbessard@137: return element.getid() lbessard@137: return None lbessard@137: etisserant@38: _View = None etisserant@203: def _OpenView(self): etisserant@38: if not self._View: etisserant@38: def _onclose(): etisserant@38: self._View = None etisserant@38: def _onsave(): etisserant@38: self.GetPlugRoot().SaveProject() lbessard@137: self._View = _SVGUIEditor(self.GetPlugRoot().AppFrame, self) etisserant@38: self._View._onclose = _onclose etisserant@38: self._View._onsave = _onsave etisserant@38: self._View.Show() etisserant@38: etisserant@203: def _ImportSVG(self): lbessard@137: if not self._View: lbessard@137: dialog = wx.FileDialog(self.GetPlugRoot().AppFrame, "Choose a SVG file", os.getcwd(), "", "SVG files (*.svg)|*.svg|All files|*.*", wx.OPEN) lbessard@137: if dialog.ShowModal() == wx.ID_OK: lbessard@137: svgpath = dialog.GetPath() lbessard@137: if os.path.isfile(svgpath): lbessard@137: shutil.copy(svgpath, os.path.join(self.PlugPath(), "gui.svg")) lbessard@137: else: etisserant@203: self.logger.write_error("No such SVG file: %s\n"%svgpath) lbessard@137: dialog.Destroy() lbessard@137: etisserant@203: def _ImportXML(self): lbessard@137: if not self._View: lbessard@137: dialog = wx.FileDialog(self.GetPlugRoot().AppFrame, "Choose a XML file", os.getcwd(), "", "XML files (*.xml)|*.xml|All files|*.*", wx.OPEN) lbessard@137: if dialog.ShowModal() == wx.ID_OK: lbessard@137: xmlpath = dialog.GetPath() lbessard@137: if os.path.isfile(xmlpath): lbessard@137: shutil.copy(xmlpath, os.path.join(self.PlugPath(), "gui.xml")) lbessard@137: else: etisserant@203: self.logger.write_error("No such XML file: %s\n"%xmlpath) lbessard@137: dialog.Destroy() lbessard@137: lbessard@65: PluginMethods = [ lbessard@82: {"bitmap" : os.path.join("images","HMIEditor"), lbessard@65: "name" : "HMI Editor", lbessard@65: "tooltip" : "HMI Editor", etisserant@105: "method" : "_OpenView"}, lbessard@82: {"bitmap" : os.path.join("images","ImportSVG"), lbessard@65: "name" : "Import SVG", lbessard@65: "tooltip" : "Import SVG", lbessard@137: "method" : "_ImportSVG"}, lbessard@82: {"bitmap" : os.path.join("images","ImportDEF"), lbessard@137: "name" : "Import XML", lbessard@137: "tooltip" : "Import XML", greg@139: "method" : "_ImportXML"}, lbessard@65: ] etisserant@38: etisserant@37: def OnPlugSave(self): lbessard@198: self.SaveXMLFile(os.path.join(self.PlugPath(), "gui.xml")) etisserant@12: return True etisserant@37: etisserant@203: def PlugGenerate_C(self, buildpath, locations): lbessard@137: progname = "SVGUI_%s"%"_".join(map(str, self.GetCurrentLocation())) lbessard@147: lbessard@189: doc = SVGDocument(self.GetSVGFilePath()) lbessard@189: root_element = doc.GetRootElement() lbessard@191: window_size = (int(float(root_element.GetAttribute("width"))), lbessard@191: int(float(root_element.GetAttribute("height")))) lbessard@191: etisserant@203: # svgfilepath = self.GetSVGFilePath() etisserant@203: # xmlfilepath = self.GetFilePath() etisserant@203: # shutil.copy(svgfilepath, buildpath) etisserant@203: # shutil.copy(xmlfilepath, buildpath) etisserant@203: etisserant@203: SVGFilePath = self.GetSVGFilePath() etisserant@203: SVGFileBaseName = os.path.split(SVGFilePath)[1] etisserant@203: FilePath = self.GetFilePath() etisserant@203: FileBaseName = os.path.split(FilePath)[1] lbessard@192: lbessard@201: generator = _SVGUICGenerator(self, self.GetElementsByType(), lbessard@192: os.path.split(self.GetSVGFilePath())[1], lbessard@192: os.path.split(self.GetFilePath())[1], lbessard@192: self.GetCurrentLocation()) lbessard@189: generator.GenerateProgram(window_size, buildpath, progname) etisserant@47: Gen_C_file = os.path.join(buildpath, progname+".cpp" ) lbessard@137: lbessard@147: if wx.Platform == '__WXMSW__': lbessard@147: cxx_flags = "-I..\\..\\wxPython-src-2.8.7.1\\bld\\lib\\wx\\include\\msw-unicode-release-2.8 -I..\\..\\wxPython-src-2.8.7.1\\include -I..\\..\\wxPython-src-2.8.7.1\\contrib\\include -I..\\..\\matiec\\lib -DWXUSINGDLL -D__WXMSW__ -mthreads" lbessard@147: libs = "\"..\\lib\\libwxsvg.a\" \"..\\lib\\libwxsvg_agg.a\" \"..\\lib\\libagg.a\" \"..\\lib\\libaggplatformwin32.a\" \"..\\lib\\libaggfontwin32tt.a\" -L..\\..\\wxPython-src-2.8.7.1\\bld\\lib -mno-cygwin -mwindows -mthreads -mno-cygwin -mwindows -Wl,--subsystem,windows -mwindows -lwx_mswu_richtext-2.8 -lwx_mswu_aui-2.8 -lwx_mswu_xrc-2.8 -lwx_mswu_qa-2.8 -lwx_mswu_html-2.8 -lwx_mswu_adv-2.8 -lwx_mswu_core-2.8 -lwx_baseu_xml-2.8 -lwx_baseu_net-2.8 -lwx_baseu-2.8" lbessard@147: else: etisserant@203: status, result, err_result = ProcessLogger(self.logger, "wx-config --cxxflags", no_stdout=True).spin() lbessard@147: if status: etisserant@203: self.logger.write_error("Unable to get wx cxxflags\n") lbessard@147: cxx_flags = result.strip() + " -I../matiec/lib" lbessard@147: etisserant@203: status, result, err_result = ProcessLogger(self.logger, "wx-config --libs", no_stdout=True).spin() lbessard@147: if status: etisserant@203: self.logger.write_error("Unable to get wx libs\n") lbessard@147: libs = result.strip() + " -lwxsvg" lbessard@137: etisserant@203: return [(Gen_C_file, cxx_flags)],libs,True,(SVGFileBaseName, file(SVGFilePath, "rb")), (FileBaseName, file(FilePath, "rb")) etisserant@13: etisserant@12: def BlockTypesFactory(self): lbessard@201: lbessard@201: SVGUIBlock_Types = [] lbessard@201: lbessard@201: def GetSVGUIBlockType(type): lbessard@201: for category in SVGUIBlock_Types: lbessard@201: for blocktype in category["list"]: lbessard@201: if blocktype["name"] == type: lbessard@201: return blocktype lbessard@201: setattr(self, "GetSVGUIBlockType", GetSVGUIBlockType) lbessard@201: lbessard@73: def generate_svgui_block(generator, block, body, link, order=False): lbessard@137: name = block.getinstanceName() lbessard@42: block_id = self.GetElementIdFromName(name) etisserant@12: if block_id == None: etisserant@12: raise ValueError, "No corresponding block found" lbessard@137: type = block.gettypeName() lbessard@201: block_infos = GetSVGUIBlockType(type) lbessard@43: current_location = ".".join(map(str, self.GetCurrentLocation())) lbessard@186: if not generator.ComputedBlocks.get(block, False) and not order: lbessard@147: generator.ComputedBlocks[block] = True lbessard@137: for num, variable in enumerate(block.inputVariables.getvariable()): lbessard@137: connections = variable.connectionPointIn.getconnections() lbessard@201: input_info = (generator.TagName, "block", block.getlocalId(), "input", num) etisserant@12: if connections and len(connections) == 1: etisserant@47: parameter = "%sQ%s%s.%d.%d"%("%", TYPECONVERSION[block_infos["inputs"][num][1]], current_location, block_id, num+1) etisserant@12: value = generator.ComputeFBDExpression(body, connections[0]) lbessard@201: generator.Program += [(generator.CurrentIndent, ()), lbessard@201: (parameter, input_info), lbessard@201: (" := ", ())] lbessard@201: generator.Program += generator.ExtractModifier(variable, value, input_info) lbessard@201: generator.Program += [(";\n", ())] etisserant@12: if link: lbessard@137: connectionPoint = link.getposition()[-1] lbessard@137: for num, variable in enumerate(block.outputVariables.getvariable()): lbessard@137: blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY() lbessard@201: output_info = (generator.TagName, "block", block.getlocalId(), "output", num) lbessard@137: if block.getx() + blockPointx == connectionPoint.getx() and block.gety() + blockPointy == connectionPoint.gety(): lbessard@201: return [("%sI%s%s.%d.%d"%("%", TYPECONVERSION[block_infos["outputs"][num][1]], current_location, block_id, num+1), output_info)] etisserant@12: raise ValueError, "No output variable found" etisserant@12: else: etisserant@12: return None lbessard@11: lbessard@138: def initialise_block(type, name, block = None): lbessard@43: block_id = self.GetElementIdFromName(name) lbessard@43: if block_id == None: lbessard@43: raise ValueError, "No corresponding block found" lbessard@201: block_infos = GetSVGUIBlockType(type) lbessard@43: current_location = ".".join(map(str, self.GetCurrentLocation())) lbessard@43: variables = [] lbessard@138: if block is not None: lbessard@138: input_variables = block.inputVariables.getvariable() lbessard@138: output_variables = block.outputVariables.getvariable() lbessard@138: else: lbessard@138: input_variables = None lbessard@138: output_variables = None lbessard@43: for num, (input_name, input_type, input_modifier) in enumerate(block_infos["inputs"]): lbessard@138: if input_variables is not None and num < len(input_variables): lbessard@138: connections = input_variables[num].connectionPointIn.getconnections() lbessard@138: if input_variables is None or connections and len(connections) == 1: lbessard@138: variables.append((input_type, None, "%sQ%s%s.%d.%d"%("%", TYPECONVERSION[input_type], current_location, block_id, num+1), None)) lbessard@43: for num, (output_name, output_type, output_modifier) in enumerate(block_infos["outputs"]): etisserant@47: variables.append((output_type, None, "%sI%s%s.%d.%d"%("%", TYPECONVERSION[input_type], current_location, block_id, num+1), None)) lbessard@43: return variables lbessard@43: lbessard@201: SVGUIBlock_Types.extend([{"name" : "SVGUI function blocks", "list" : lbessard@137: [{"name" : "Container", "type" : "functionBlock", "extensible" : False, lbessard@138: "inputs" : [("Show","BOOL","none"),("Enable","BOOL","none")], lbessard@138: "outputs" : [], lbessard@42: "comment" : "SVGUI Container", lbessard@43: "generate" : generate_svgui_block, "initialise" : initialise_block}, etisserant@37: {"name" : "Button", "type" : "functionBlock", "extensible" : False, lbessard@186: "inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("Value","BOOL","none")], lbessard@138: "outputs" : [("State","BOOL","none")], lbessard@42: "comment" : "SVGUI Button", lbessard@43: "generate" : generate_svgui_block, "initialise" : initialise_block}, etisserant@37: {"name" : "TextCtrl", "type" : "functionBlock", "extensible" : False, lbessard@138: "inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("SetText","STRING","none")], lbessard@138: "outputs" : [("Text","STRING","none")], lbessard@42: "comment" : "SVGUI Text Control", lbessard@43: "generate" : generate_svgui_block, "initialise" : initialise_block}, etisserant@37: {"name" : "ScrollBar", "type" : "functionBlock", "extensible" : False, lbessard@138: "inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("SetThumb","UINT","none"),("SetRange","UINT","none"),("SetPosition","UINT","none")], lbessard@138: "outputs" : [("Position","UINT","none")], lbessard@42: "comment" : "SVGUI ScrollBar", lbessard@43: "generate" : generate_svgui_block, "initialise" : initialise_block}, etisserant@37: {"name" : "NoteBook", "type" : "functionBlock", "extensible" : False, lbessard@138: "inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("SetSelected","BOOL","none")], lbessard@138: "outputs" : [("Selected","UINT","none")], lbessard@42: "comment" : "SVGUI Notebook", lbessard@43: "generate" : generate_svgui_block, "initialise" : initialise_block}, etisserant@37: {"name" : "RotatingCtrl", "type" : "functionBlock", "extensible" : False, lbessard@138: "inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("SetAngle","REAL","none")], lbessard@138: "outputs" : [("Angle","REAL","none")], lbessard@42: "comment" : "SVGUI Rotating Control", lbessard@43: "generate" : generate_svgui_block, "initialise" : initialise_block}, etisserant@37: {"name" : "Transform", "type" : "functionBlock", "extensible" : False, lbessard@138: "inputs" : [("Show","BOOL","none"),("Enable","BOOL","none"),("SetX","REAL","none"),("SetY","REAL","none"),("SetXScale","REAL","none"),("SetYScale","REAL","none"),("SetAngle","REAL","none")], lbessard@138: "outputs" : [("X","REAL","none"),("Y","REAL","none")], lbessard@42: "comment" : "SVGUI Transform", lbessard@43: "generate" : generate_svgui_block, "initialise" : initialise_block}, etisserant@37: ]} lbessard@201: ]) lbessard@201: lbessard@201: return SVGUIBlock_Types lbessard@147: lbessard@147: lbessard@147: class _SVGUICGenerator(SVGUICGenerator): lbessard@147: lbessard@201: def __init__(self, controler, elements, svgfile, xmlfile, current_location): lbessard@147: SVGUICGenerator.__init__(self, elements, svgfile, xmlfile) lbessard@147: lbessard@147: self.CurrentLocation = current_location lbessard@201: self.Controler = controler lbessard@147: lbessard@147: def GenerateProgramHeadersPublicVars(self): etisserant@203: text = """ etisserant@203: void OnPlcOutEvent(wxEvent& event); lbessard@147: lbessard@147: void Retrieve(); lbessard@147: void Publish(); lbessard@147: void Initialize(); lbessard@147: """ lbessard@147: # text += " void Print();\n" lbessard@147: return text lbessard@147: lbessard@147: def GenerateIECVars(self): lbessard@147: text = "" lbessard@147: for element in self.Elements: lbessard@147: text += "STATE_TYPE out_state_%d;\n"%element.getid() lbessard@147: text += "STATE_TYPE in_state_%d;\n"%element.getid() lbessard@147: text +="\n" lbessard@147: current_location = "_".join(map(str, self.CurrentLocation)) lbessard@147: #Declaration des variables lbessard@147: for element in self.Elements: lbessard@201: block_infos = self.Controler.GetSVGUIBlockType(SVGUIFB_Types[GetElementType(element)]) lbessard@147: block_id = element.getid() lbessard@147: for i, input in enumerate(block_infos["inputs"]): lbessard@147: element_c_type = CTYPECONVERSION[input[1]] lbessard@147: variable = "__Q%s%s_%d_%d"%(TYPECONVERSION[input[1]], current_location, block_id, i + 1) lbessard@165: text += "%s beremiz%s;\n"%(element_c_type, variable) lbessard@165: text += "%s* %s = &beremiz%s;\n"%(element_c_type, variable, variable) lbessard@147: text += "%s _copy%s;\n"%(element_c_type, variable) lbessard@147: for i, output in enumerate(block_infos["outputs"]): lbessard@147: element_c_type = CTYPECONVERSION[output[1]] lbessard@147: variable = "__I%s%s_%d_%d"%(TYPECONVERSION[output[1]], current_location, block_id, i + 1) lbessard@165: text += "%s beremiz%s;\n"%(element_c_type, variable) lbessard@165: text += "%s* %s = &beremiz%s;\n"%(element_c_type, variable, variable) lbessard@147: text += "%s _copy%s;\n"%(element_c_type, variable) lbessard@147: text +="\n" lbessard@147: return text lbessard@147: lbessard@147: def GenerateGlobalVarsAndFuncs(self, size): etisserant@181: text = """#include "iec_types.h" lbessard@147: #ifdef __WXMSW__ lbessard@147: #define COMPARE_AND_SWAP_VAL(Destination, comparand, exchange) InterlockedCompareExchange(Destination, exchange, comparand) lbessard@147: #define THREAD_RETURN_TYPE DWORD WINAPI lbessard@147: #define STATE_TYPE long int lbessard@147: #else lbessard@147: #define COMPARE_AND_SWAP_VAL(Destination, comparand, exchange) __sync_val_compare_and_swap(Destination, comparand, exchange) lbessard@147: #define THREAD_RETURN_TYPE void* lbessard@147: #define STATE_TYPE volatile int lbessard@147: #endif lbessard@147: lbessard@147: """ lbessard@147: lbessard@147: text += self.GenerateIECVars() lbessard@147: lbessard@147: text += """IMPLEMENT_APP_NO_MAIN(SVGViewApp); lbessard@147: SVGViewApp *myapp = NULL; etisserant@181: wxSemaphore MyInitSem; lbessard@147: lbessard@147: #ifdef __WXMSW__ lbessard@147: HANDLE wxMainLoop; lbessard@147: DWORD wxMainLoopId; lbessard@147: #else lbessard@147: pthread_t wxMainLoop; lbessard@147: #endif lbessard@147: lbessard@147: """ lbessard@147: lbessard@147: text += """int myargc = 0; lbessard@147: char** myargv = NULL; lbessard@147: lbessard@147: #define UNCHANGED 1 lbessard@147: #define PLC_BUSY 2 lbessard@147: #define CHANGED 3 lbessard@147: #define GUI_BUSY 4 lbessard@147: #ifdef __WXMSW__ lbessard@147: #else lbessard@147: #endif lbessard@147: lbessard@147: bool refresh = false; lbessard@147: bool refreshing = false; lbessard@147: lbessard@147: THREAD_RETURN_TYPE InitWxEntry(void* args) lbessard@147: { lbessard@147: wxEntry(myargc,myargv); etisserant@203: MyInitSem.Post(); lbessard@147: return 0; lbessard@147: } lbessard@147: lbessard@147: """ lbessard@189: etisserant@203: text += """ etisserant@203: bool SVGViewApp::OnInit() lbessard@147: { lbessard@147: #ifndef __WXMSW__ lbessard@147: setlocale(LC_NUMERIC, "C"); lbessard@147: #endif lbessard@147: """ lbessard@189: lbessard@189: text += """ frame = new MainFrame(NULL, wxT("Program"),wxDefaultPosition, wxSize(%d, %d)); lbessard@147: frame->Show(); lbessard@147: myapp = this; lbessard@189: """%size lbessard@147: text += """ return true; lbessard@147: } lbessard@147: lbessard@147: extern "C" { lbessard@147: lbessard@147: int __init_%(location)s(int argc, char** argv) lbessard@147: { lbessard@147: myargc = argc; lbessard@147: myargv = argv; lbessard@147: #ifdef __WXMSW__ lbessard@147: wxMainLoop = CreateThread(NULL, 0, InitWxEntry, 0, 0, &wxMainLoopId); lbessard@147: #else lbessard@147: pthread_create(&wxMainLoop, NULL, InitWxEntry, NULL); lbessard@147: #endif etisserant@181: MyInitSem.Wait(); lbessard@147: return 0; lbessard@147: } lbessard@147: lbessard@147: void __cleanup_%(location)s() lbessard@147: { etisserant@203: if(myapp){ etisserant@203: wxCloseEvent event(wxEVT_CLOSE_WINDOW); etisserant@203: myapp->frame->AddPendingEvent(event); etisserant@203: myapp = NULL; etisserant@203: } etisserant@203: MyInitSem.Wait(); lbessard@147: } lbessard@147: lbessard@147: void __retrieve_%(location)s() lbessard@147: { lbessard@147: if(myapp){ lbessard@147: myapp->frame->m_svgCtrl->Retrieve(); lbessard@147: } lbessard@147: } lbessard@147: lbessard@147: void __publish_%(location)s() lbessard@147: { lbessard@147: if(myapp){ lbessard@147: myapp->frame->m_svgCtrl->Publish(); lbessard@147: } lbessard@147: } lbessard@147: lbessard@147: } lbessard@147: lbessard@147: IEC_STRING wxStringToIEC_STRING(wxString s) lbessard@147: { lbessard@147: IEC_STRING res = {0,""}; lbessard@147: int i; lbessard@147: for(i = 0; iargv[1], wxT("%s")); etisserant@203: wxFileName xmlfilepath(wxTheApp->argv[1], wxT("%s")); lbessard@192: lbessard@147: m_svgCtrl = new Program(this); lbessard@192: if (m_svgCtrl->LoadFiles(svgfilepath.GetFullPath(), xmlfilepath.GetFullPath())) lbessard@147: { lbessard@147: Show(true); lbessard@147: m_svgCtrl->SetFocus(); lbessard@147: m_svgCtrl->SetFitToFrame(true); lbessard@147: m_svgCtrl->InitScrollBars(); lbessard@147: m_svgCtrl->Initialize(); lbessard@147: m_svgCtrl->Update(); lbessard@147: } lbessard@147: else lbessard@147: { etisserant@203: printf("Error while opening SVGUI files\\n"); lbessard@147: } lbessard@147: } lbessard@147: lbessard@147: lbessard@147: """%(self.SVGFilePath, self.XMLFilePath) lbessard@147: lbessard@147: return text lbessard@147: lbessard@147: def GenerateProgramInitProgram(self): lbessard@147: text = "Program::Program(wxWindow* parent):SVGUIWindow(parent)\n{\n" lbessard@147: for element in self.Elements: lbessard@147: text += " out_state_%d = UNCHANGED;\n"%element.getid() lbessard@147: text += " in_state_%d = UNCHANGED;\n"%element.getid() lbessard@147: text += "}\n\n" lbessard@147: return text lbessard@147: lbessard@147: def GenerateProgramEventFunctions(self): lbessard@147: text = "" lbessard@147: current_location = "_".join(map(str, self.CurrentLocation)) lbessard@147: for element in self.Elements: lbessard@147: element_type = GetElementType(element) etisserant@203: element_lock = """ etisserant@203: if (COMPARE_AND_SWAP_VAL(&in_state_%d, CHANGED, GUI_BUSY) == CHANGED || lbessard@147: COMPARE_AND_SWAP_VAL(&in_state_%d, UNCHANGED, GUI_BUSY) == UNCHANGED) { lbessard@147: """%(element.getid(), element.getid()) etisserant@203: element_unlock = """ etisserant@203: COMPARE_AND_SWAP_VAL(&in_state_%d, GUI_BUSY, CHANGED); etisserant@203: event.Skip(); etisserant@203: }else{ etisserant@203: /* re post event for idle */ etisserant@203: AddPendingEvent(event); lbessard@147: } etisserant@203: } etisserant@203: lbessard@147: """%element.getid() lbessard@147: element_name = element.getname() lbessard@147: lbessard@147: if element_type == ITEM_BUTTON: lbessard@147: text += """void Program::On%sClick(wxCommandEvent& event) lbessard@147: { lbessard@147: SVGUIButton* button = (SVGUIButton*)GetElementByName(wxT("%s"));\n"""%(element_name, element_name) lbessard@147: text += element_lock lbessard@147: text += " _copy__IX%s_%d_1 = button->GetToggle();\n"%(current_location, element.getid()) lbessard@147: text += element_unlock lbessard@147: elif element_type == ITEM_ROTATING: lbessard@147: text += """void Program::On%sChanging(wxScrollEvent& event) lbessard@147: { lbessard@147: SVGUIRotatingCtrl* rotating = (SVGUIRotatingCtrl*)GetElementByName(wxT("%s")); lbessard@147: """%(element_name, element_name) lbessard@147: text += element_lock lbessard@147: text += " _copy__ID%s_%d_1 = rotating->GetAngle();\n"%(current_location, element.getid()) lbessard@147: text += element_unlock lbessard@147: elif element_type == ITEM_NOTEBOOK: lbessard@147: text += """void Program::On%sTabChanged(wxNotebookEvent& event) lbessard@147: { lbessard@147: SVGUINoteBook* notebook = (SVGUINoteBook*)GetElementByName(wxT("%s")); lbessard@147: """%(element_name, element_name) lbessard@147: text += element_lock lbessard@147: text += " _copy__IB%s_%d_1 = notebook->GetCurrentPage();\n"%(current_location, element.getid()) lbessard@147: text += element_unlock lbessard@147: elif element_type == ITEM_TRANSFORM: lbessard@147: text += """void Program::On%sChanging(wxScrollEvent& event) lbessard@147: { lbessard@147: SVGUITransform* transform = (SVGUITransform*)GetElementByName(wxT("%s")); lbessard@147: """%(element_name, element_name) lbessard@147: text += element_lock lbessard@147: text += " _copy__ID%s_%d_1 = transform->GetX();\n"%(current_location, element.getid()) lbessard@147: text += " _copy__ID%s_%d_2 = transform->GetY();\n"%(current_location, element.getid()) lbessard@147: text += element_unlock lbessard@147: lbessard@147: text += "/* OnPlcOutEvent update GUI with provided IEC __Q* PLC output variables */\n" lbessard@147: text += """void Program::OnPlcOutEvent(wxEvent& event) lbessard@147: { lbessard@147: SVGUIElement* element; lbessard@147: lbessard@147: refreshing = true; lbessard@147: etisserant@203: lbessard@147: """ lbessard@147: for element in self.Elements: lbessard@147: element_type = GetElementType(element) lbessard@147: texts = {"location" : current_location, "id" : element.getid()} lbessard@147: lbessard@147: text += """ if (COMPARE_AND_SWAP_VAL(&out_state_%(id)d, CHANGED, GUI_BUSY) == CHANGED) lbessard@147: { lbessard@147: element = (SVGUIElement*)GetElementById(wxT("%(id)d")); lbessard@147: lbessard@147: if (_copy__QX%(location)s_%(id)d_1 != element->IsVisible()) { lbessard@147: if (_copy__QX%(location)s_%(id)d_1) lbessard@147: element->Show(); lbessard@147: else lbessard@147: element->Hide(); lbessard@147: } lbessard@147: if (_copy__QX%(location)s_%(id)d_2 != element->IsEnabled()) { lbessard@147: if (_copy__QX%(location)s_%(id)d_2) lbessard@147: element->Enable(); lbessard@147: else lbessard@147: element->Disable(); lbessard@147: } lbessard@147: """%texts lbessard@147: if element_type == ITEM_BUTTON: lbessard@147: text += """ if (_copy__QX%(location)s_%(id)d_3 != ((SVGUIButton*)element)->GetToggle()) lbessard@147: ((SVGUIButton*)element)->SetToggle(_copy__QX%(location)s_%(id)d_3); lbessard@147: """%texts lbessard@147: elif element_type == ITEM_TEXT: lbessard@147: text += """ if (((SVGUITextCtrl*)element)->GetValue().compare(_copy__QX%(location)s_%(id)d_3)) lbessard@147: { lbessard@147: wxString str = wxString::FromAscii(_copy__QB%(location)s_%(id)d_3); lbessard@147: ((SVGUITextCtrl*)element)->SetText(str); lbessard@147: } lbessard@147: """%texts lbessard@147: elif element_type == ITEM_SCROLLBAR: lbessard@147: text += """ if (_copy__QW%(location)s_%(id)d_3 != ((SVGUIScrollBar*)element)->GetThumbPosition() || lbessard@147: _copy__QW%(location)s_%(id)d_4 != ((SVGUIScrollBar*)element)->GetThumbSize() || lbessard@147: _copy__QW%(location)s_%(id)d_5 != ((SVGUIScrollBar*)element)->GetRange()) lbessard@147: ((SVGUIScrollBar*)element)->Init_ScrollBar(_copy__QW%(location)s_%(id)d_3, _copy__QW%(location)s_%(id)d_4, _copy__QW%(location)s_%(id)d_5); lbessard@147: """%texts lbessard@147: elif element_type == ITEM_ROTATING: lbessard@147: text += """ if (_copy__QD%(location)s_%(id)d_3 != ((SVGUIRotatingCtrl*)element)->GetAngle()) lbessard@147: ((SVGUIRotatingCtrl*)element)->SetAngle(_copy__QD%(location)s_%(id)d_3); lbessard@147: """%texts lbessard@147: elif element_type == ITEM_NOTEBOOK: lbessard@147: text += """ if (_copy__QB%(location)s_%(id)d_3 != ((SVGUINoteBook*)element)->GetCurrentPage()) lbessard@147: ((SVGUINoteBook*)element)->SetCurrentPage(_copy__QB%(location)s_%(id)d_3); lbessard@147: """%texts lbessard@147: elif element_type == ITEM_TRANSFORM: lbessard@147: text += """ if (_copy__QD%(location)s_%(id)d_3 != ((SVGUITransform*)element)->GetX() || etisserant@181: _copy__QD%(location)s_%(id)d_4 != ((SVGUITransform*)element)->GetY()) etisserant@181: ((SVGUITransform*)element)->Move(_copy__QD%(location)s_%(id)d_3, _copy__QD%(location)s_%(id)d_4); lbessard@147: if (_copy__QD%(location)s_%(id)d_5 != ((SVGUITransform*)element)->GetXScale() || etisserant@181: _copy__QD%(location)s_%(id)d_6 != ((SVGUITransform*)element)->GetYScale()) etisserant@181: ((SVGUITransform*)element)->Scale(_copy__QD%(location)s_%(id)d_5, _copy__QD%(location)s_%(id)d_6); lbessard@147: if (_copy__QD%(location)s_%(id)d_7 != ((SVGUITransform*)element)->GetAngle()) etisserant@181: ((SVGUITransform*)element)->Rotate(_copy__QD%(location)s_%(id)d_7); lbessard@147: """%texts lbessard@147: text += " COMPARE_AND_SWAP_VAL(&out_state_%(id)d, GUI_BUSY, UNCHANGED);\n }\n"%texts lbessard@147: etisserant@203: text += """ lbessard@147: lbessard@147: refreshing = false; lbessard@147: lbessard@147: event.Skip(); lbessard@147: } lbessard@147: lbessard@147: """ lbessard@147: return text lbessard@147: lbessard@147: def GenerateProgramPrivateFunctions(self): lbessard@147: current_location = "_".join(map(str, self.CurrentLocation)) lbessard@147: lbessard@147: text = "void Program::Retrieve()\n{\n" lbessard@147: for element in self.Elements: lbessard@147: element_type = GetElementType(element) lbessard@147: texts = {"location" : current_location, "id" : element.getid()} lbessard@201: block_infos = self.Controler.GetSVGUIBlockType(SVGUIFB_Types[GetElementType(element)]) lbessard@147: if len(block_infos["outputs"]) > 0: lbessard@147: text += """ if (COMPARE_AND_SWAP_VAL(&in_state_%(id)d, CHANGED, PLC_BUSY) == CHANGED) { lbessard@147: """%texts lbessard@147: for i, output in enumerate(block_infos["outputs"]): lbessard@147: texts["type"] = TYPECONVERSION[output[1]] lbessard@147: texts["pin"] = i + 1 lbessard@147: lbessard@147: variable = "__I%(type)s%(location)s_%(id)d_%(pin)d"%texts lbessard@165: text +=" beremiz%s = _copy%s;\n"%(variable, variable) lbessard@147: lbessard@147: text += """ COMPARE_AND_SWAP_VAL(&in_state_%(id)d, PLC_BUSY, UNCHANGED); lbessard@147: } lbessard@147: """%texts lbessard@147: text += "}\n\n" lbessard@147: lbessard@147: text += "void Program::Publish()\n{\n STATE_TYPE new_state;\n\n" lbessard@147: for element in self.Elements: lbessard@147: element_type = GetElementType(element) lbessard@147: texts = {"location" : current_location, "id" : element.getid()} lbessard@201: block_infos = self.Controler.GetSVGUIBlockType(SVGUIFB_Types[GetElementType(element)]) lbessard@147: lbessard@147: text += """ if ((new_state = COMPARE_AND_SWAP_VAL(&out_state_%(id)d, UNCHANGED, PLC_BUSY)) == UNCHANGED || lbessard@147: (new_state = COMPARE_AND_SWAP_VAL(&out_state_%(id)d, CHANGED, PLC_BUSY)) == CHANGED) { lbessard@147: """%texts lbessard@147: for i, input in enumerate(block_infos["inputs"]): lbessard@147: texts["type"] = TYPECONVERSION[input[1]] lbessard@147: texts["pin"] = i + 1 lbessard@147: variable = "__Q%(type)s%(location)s_%(id)d_%(pin)d"%texts lbessard@165: text += " if (_copy%s != beremiz%s) {\n"%(variable, variable) lbessard@165: text += " _copy%s = beremiz%s;\n"%(variable, variable) lbessard@147: text += " new_state = CHANGED;\n }\n"%texts lbessard@147: text += """ COMPARE_AND_SWAP_VAL(&out_state_%(id)d, PLC_BUSY, new_state); lbessard@147: refresh |= new_state == CHANGED; lbessard@147: } lbessard@147: """%texts lbessard@147: lbessard@147: text += """ /* Replace this with determinist signal if called from RT */ lbessard@147: if (refresh && !refreshing) { lbessard@147: wxCommandEvent event( EVT_PLC ); etisserant@203: AddPendingEvent(event); lbessard@147: refresh = false; lbessard@147: } lbessard@147: }; lbessard@147: lbessard@147: """ lbessard@147: lbessard@147: text += """void Program::Initialize() lbessard@147: { lbessard@147: SVGUIElement* element; lbessard@147: """ lbessard@147: for element in self.Elements: lbessard@147: element_type = GetElementType(element) lbessard@147: texts = {"location" : current_location, "id" : element.getid()} lbessard@147: lbessard@147: text += """ lbessard@147: element = (SVGUIElement*)GetElementById(wxT("%(id)d")); lbessard@192: beremiz__QX%(location)s_%(id)d_1 = _copy__QX%(location)s_%(id)d_1 = element->IsVisible(); lbessard@192: beremiz__QX%(location)s_%(id)d_2 = _copy__QX%(location)s_%(id)d_2 = element->IsEnabled(); lbessard@147: """%texts lbessard@147: if element_type == ITEM_BUTTON: lbessard@192: text += " beremiz__QX%(location)s_%(id)d_3 = _copy__QX%(location)s_%(id)d_3 = ((SVGUIButton*)element)->GetToggle();\n"%texts etisserant@181: text += " beremiz__IX%(location)s_%(id)d_1 = _copy__IX%(location)s_%(id)d_1 = ((SVGUIButton*)element)->GetToggle();\n"%texts lbessard@147: elif element_type == ITEM_TEXT: lbessard@192: text += " beremiz__QB%(location)s_%(id)d_3 = _copy__QB%(location)s_%(id)d_3 = ((SVGUITextCtrl*)element)->GetValue();\n"%texts etisserant@181: text += " beremiz__IB%(location)s_%(id)d_1 = _copy__IB%(location)s_%(id)d_1 = ((SVGUITextCtrl*)element)->GetValue();\n"%texts lbessard@147: elif element_type == ITEM_SCROLLBAR: lbessard@192: text += " beremiz__QW%(location)s_%(id)d_3 = _copy__QW%(location)s_%(id)d_3 = ((SVGUIScrollBar*)element)->GetThumbSize();\n"%texts lbessard@192: text += " beremiz__QW%(location)s_%(id)d_4 = _copy__QW%(location)s_%(id)d_4 = ((SVGUIScrollBar*)element)->GetRange();\n"%texts lbessard@192: text += " beremiz__QW%(location)s_%(id)d_5 = _copy__QW%(location)s_%(id)d_5 = ((SVGUIScrollBar*)element)->GetThumbPosition();\n"%texts etisserant@181: text += " beremiz__IW%(location)s_%(id)d_1 = _copy__IW%(location)s_%(id)d_1 = ((SVGUIScrollBar*)element)->GetThumbPosition();\n"%texts lbessard@147: elif element_type == ITEM_ROTATING: lbessard@192: text += " beremiz__QD%(location)s_%(id)d_3 = _copy__QD%(location)s_%(id)d_3 = ((SVGUIRotatingCtrl*)element)->GetAngle();\n"%texts lbessard@186: text += " beremiz__ID%(location)s_%(id)d_1 = _copy__ID%(location)s_%(id)d_1 = ((SVGUIRotatingCtrl*)element)->GetAngle();\n"%texts lbessard@147: elif element_type == ITEM_NOTEBOOK: lbessard@192: text += " beremiz__QB%(location)s_%(id)d_3 = _copy__QB%(location)s_%(id)d_3 = ((SVGUINoteBook*)element)->GetCurrentPage();\n"%texts etisserant@181: text += " beremiz__IB%(location)s_%(id)d_1 = _copy__IB%(location)s_%(id)d_1 = ((SVGUINoteBook*)element)->GetCurrentPage();\n"%texts lbessard@147: elif element_type == ITEM_TRANSFORM: etisserant@181: text += " beremiz__QD%(location)s_%(id)d_3 = _copy__QD%(location)s_%(id)d_3 = ((SVGUITransform*)element)->GetX();\n"%texts etisserant@181: text += " beremiz__QD%(location)s_%(id)d_4 = _copy__QD%(location)s_%(id)d_4 = ((SVGUITransform*)element)->GetY();\n"%texts etisserant@181: text += " beremiz__QD%(location)s_%(id)d_5 = _copy__QD%(location)s_%(id)d_5 = ((SVGUITransform*)element)->GetXScale();\n"%texts etisserant@181: text += " beremiz__QD%(location)s_%(id)d_6 = _copy__QD%(location)s_%(id)d_6 = ((SVGUITransform*)element)->GetYScale();\n"%texts etisserant@181: text += " beremiz__QD%(location)s_%(id)d_7 = _copy__QD%(location)s_%(id)d_7 = ((SVGUITransform*)element)->GetAngle();\n"%texts etisserant@181: text += " beremiz__ID%(location)s_%(id)d_1 = _copy__ID%(location)s_%(id)d_1 = ((SVGUITransform*)element)->GetX();\n"%texts etisserant@181: text += " beremiz__ID%(location)s_%(id)d_2 = _copy__ID%(location)s_%(id)d_2 = ((SVGUITransform*)element)->GetY();\n"%texts lbessard@186: lbessard@186: text += "\n MyInitSem.Post();\n}\n\n" lbessard@147: return text