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@137: from SVGUIControler import * lbessard@137: from SVGUIEditor import * etisserant@37: from FBD_Objects import * lbessard@11: lbessard@137: from wxPopen import ProcessLogger 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@38: def _OpenView(self, logger): 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: lbessard@137: def _ImportSVG(self, logger): 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: lbessard@137: logger.write_error("No such SVG file: %s\n"%svgpath) lbessard@137: dialog.Destroy() lbessard@137: lbessard@137: def _ImportXML(self, logger): 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: lbessard@137: 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", lbessard@137: "method" : "_InportXML"}, lbessard@65: ] etisserant@38: etisserant@37: def OnPlugSave(self): etisserant@12: self.SaveXMLFile() etisserant@12: return True etisserant@37: lbessard@137: def GenerateProgramHeadersPublicVars(self, elements): lbessard@137: text = """ void OnPlcOutEvent(wxEvent& event); lbessard@137: lbessard@137: void Retrieve(); lbessard@137: void Publish(); lbessard@137: void Initialize(); lbessard@137: """ lbessard@137: # text += " void Print();\n" lbessard@137: return text lbessard@137: lbessard@137: def GenerateIECVars(self, elements): etisserant@37: text = "" lbessard@137: for element in elements: lbessard@137: text += "volatile int out_state_%d;\n"%element.getid() lbessard@137: text += "volatile int in_state_%d;\n"%element.getid() etisserant@37: text +="\n" lbessard@137: current_location = "_".join(map(str, self.GetCurrentLocation())) etisserant@37: #Declaration des variables lbessard@137: for element in elements: lbessard@137: block_infos = GetBlockType(SVGUIFB_Types[GetElementType(element)]) lbessard@137: block_id = element.getid() lbessard@137: for i, input in enumerate(block_infos["inputs"]): etisserant@37: element_c_type = CTYPECONVERSION[input[1]] lbessard@137: variable = "__Q%s%s_%d_%d"%(TYPECONVERSION[input[1]], current_location, block_id, i + 1) lbessard@137: text += "%s %s;\n"%(element_c_type, variable) lbessard@137: text += "%s _copy%s;\n"%(element_c_type, variable) lbessard@137: for i, output in enumerate(block_infos["outputs"]): etisserant@37: element_c_type = CTYPECONVERSION[output[1]] lbessard@137: variable = "__I%s%s_%d_%d"%(TYPECONVERSION[output[1]], current_location, block_id, i + 1) lbessard@137: text += "%s %s;\n"%(element_c_type, variable) lbessard@137: text += "%s _copy%s;\n"%(element_c_type, variable) etisserant@37: text +="\n" etisserant@37: return text etisserant@37: lbessard@137: def GenerateGlobalVarsAndFuncs(self, elements, size): lbessard@137: text = "#include \"iec_std_lib.h\"\n\n" lbessard@137: lbessard@137: text += self.GenerateIECVars(elements) lbessard@137: lbessard@137: text += """IMPLEMENT_APP_NO_MAIN(SVGViewApp); lbessard@137: IMPLEMENT_WX_THEME_SUPPORT; lbessard@137: SVGViewApp *myapp = NULL; lbessard@137: pthread_t wxMainLoop; lbessard@137: """ etisserant@47: # text += "pthread_t wxMainLoop,automate;\n" lbessard@137: text += """int myargc = 0; lbessard@137: char** myargv = NULL; lbessard@137: lbessard@137: #define UNCHANGED 1 lbessard@137: #define PLC_BUSY 2 lbessard@137: #define CHANGED 3 lbessard@137: #define GUI_BUSY 4 lbessard@137: lbessard@137: void* InitWxEntry(void* args) lbessard@137: { lbessard@137: wxEntry(myargc,myargv); lbessard@137: return args; lbessard@137: } lbessard@137: lbessard@137: """ lbessard@137: # text += """void* SimulAutomate(void* args) lbessard@137: #{ lbessard@137: # while(1){ lbessard@137: # myapp->frame->m_svgCtrl->IN_"+self.BusNumber+"(); lbessard@137: # //printf(\"AUTOMATE\\n\"); lbessard@137: # myapp->frame->m_svgCtrl->OUT_"+self.BusNumber+"(); lbessard@137: # sleep(1); lbessard@137: # } lbessard@137: # return args; lbessard@137: #} lbessard@137: # lbessard@137: #""" lbessard@137: lbessard@137: text += """bool SVGViewApp::OnInit() lbessard@137: { lbessard@137: #ifndef __WXMSW__ lbessard@137: setlocale(LC_NUMERIC, "C"); lbessard@137: #endif lbessard@137: """ lbessard@137: #text += " frame = new MainFrame(NULL, wxT(\"Program\"),wxDefaultPosition, wxSize(%d, %d));\n"%size lbessard@137: text += """ frame = new MainFrame(NULL, wxT("Program"),wxDefaultPosition, wxDefaultSize); lbessard@137: myapp = this; lbessard@137: """ etisserant@39: # text += " pthread_create(&automate, NULL, SimulAutomate, NULL);\n" lbessard@137: text += """ return true; lbessard@137: } lbessard@137: lbessard@137: extern "C" { lbessard@137: lbessard@137: int __init_%(location)s(int argc, char** argv) lbessard@137: { lbessard@137: myargc = argc; lbessard@137: myargv = argv; lbessard@137: pthread_create(&wxMainLoop, NULL, InitWxEntry, NULL); lbessard@137: } lbessard@137: lbessard@137: void __cleanup_%(location)s() lbessard@137: { lbessard@137: } lbessard@137: lbessard@137: void __retrieve_%(location)s() lbessard@137: { lbessard@137: if(myapp){ lbessard@137: myapp->frame->m_svgCtrl->Retrieve(); lbessard@137: } lbessard@137: } lbessard@137: lbessard@137: void __publish_%(location)s() lbessard@137: { lbessard@137: if(myapp){ lbessard@137: myapp->frame->m_svgCtrl->Publish(); lbessard@137: } lbessard@137: } lbessard@137: lbessard@137: } lbessard@137: lbessard@137: IEC_STRING wxStringToIEC_STRING(wxString s) lbessard@137: { lbessard@137: STRING res = {0,""}; lbessard@137: int i; lbessard@137: for(i = 0; iLoadFiles(wxT("%s"), wxT("%s"))) lbessard@137: { lbessard@137: Show(true); lbessard@137: m_svgCtrl->SetFocus(); lbessard@137: m_svgCtrl->SetFitToFrame(true); lbessard@137: m_svgCtrl->RefreshScale(); lbessard@137: m_svgCtrl->InitScrollBars(); lbessard@137: m_svgCtrl->Initialize(); lbessard@137: m_svgCtrl->Update(); lbessard@137: //m_svgCtrl->Print(); lbessard@137: } lbessard@137: else lbessard@137: { lbessard@137: printf("Error while opening files\\n"); lbessard@137: exit(0); lbessard@137: } lbessard@137: } lbessard@137: lbessard@137: lbessard@137: """%(self.GetSVGFilePath(), self.GetFilePath()) lbessard@137: lbessard@137: return text lbessard@137: lbessard@137: def GenerateProgramInitProgram(self, elements): etisserant@37: text = "Program::Program(wxWindow* parent):SVGUIWindow(parent)\n{\n" lbessard@137: for element in elements: lbessard@137: text += " out_state_%d = UNCHANGED;\n"%element.getid() lbessard@137: text += " in_state_%d = UNCHANGED;\n"%element.getid() etisserant@37: text += "}\n\n" etisserant@37: return text etisserant@37: lbessard@137: def GenerateProgramEventFunctions(self, elements): lbessard@137: text = "" lbessard@137: current_location = "_".join(map(str, self.GetCurrentLocation())) lbessard@137: for element in elements: lbessard@137: element_type = GetElementType(element) lbessard@137: element_state = " in_state_%d = %s;\n"%(element.getid(), "%s") lbessard@137: element_name = element.getname() lbessard@137: lbessard@137: block_infos = GetBlockType(SVGUIFB_Types[element_type]) lbessard@137: if element_type == ITEM_BUTTON: lbessard@137: text += """void Program::On%sClick(wxCommandEvent& event) lbessard@137: { lbessard@137: SVGUIButton* button = (SVGUIButton*)GetElementByName(wxT("%s"));\n"""%(element_name, element_name) lbessard@137: text += element_state%"GUI_BUSY" lbessard@137: for i, output in enumerate(block_infos["outputs"]): etisserant@37: element_type = TYPECONVERSION[output[1]] lbessard@137: if i == 0: lbessard@137: value = "button->IsVisible()" lbessard@137: elif i == 1: lbessard@137: value = "button->GetToggle()" lbessard@137: else: lbessard@137: value = "0" lbessard@137: text += " _copy__I%s%s_%d_%d = %s;\n"%(TYPECONVERSION[output[1]], current_location, element.getid(), i + 1, value) lbessard@137: text += element_state%"CHANGED" lbessard@137: text += " event.Skip();\n}\n\n" lbessard@137: elif element_type == ITEM_ROTATING: lbessard@137: text += """void Program::On%sChanged(wxScrollEvent& event) lbessard@137: { lbessard@137: SVGUIRotatingCtrl* rotating = (SVGUIRotatingCtrl*)GetElementByName(wxT("%s")); lbessard@137: rotating->SendScrollEvent(event); lbessard@137: double angle = rotating->GetAngle(); lbessard@137: """%(element_name, element_name) lbessard@137: text += element_state%"GUI_BUSY" lbessard@137: for i, output in enumerate(block_infos["outputs"]): lbessard@137: text += " _copy__I%s%s_%d_%d = %s;\n"%(TYPECONVERSION[output[1]], current_location, element.getid(), i + 1, ["angle", "true"][value]) lbessard@137: text += element_state%"CHANGED" lbessard@137: text += " event.Skip();\n}\n\n" lbessard@137: elif element_type == ITEM_NOTEBOOK: lbessard@137: text += """void Program::On%sTabChanged(wxNotebookEvent& event) lbessard@137: { lbessard@137: SVGUINoteBook* notebook = (SVGUINoteBook*)GetElementByName(wxT("%s")); lbessard@137: notebook->SendNotebookEvent(event); lbessard@137: unsigned int selected = notebook->GetCurrentPage(); lbessard@137: """%(element_name, element_name) lbessard@137: text += element_state%"GUI_BUSY" lbessard@137: for i, output in enumerate(block_infos["outputs"]): lbessard@137: text += " _copy__I%s%s_%d_%d = %s;\n"%(TYPECONVERSION[output[1]], current_location, element.getid(), i + 1, ["selected", "true"][value]) lbessard@137: text += element_state%"CHANGED" lbessard@137: text += " event.Skip();\n}\n\n" lbessard@137: elif element_type == ITEM_TRANSFORM: lbessard@137: text += """void Program::On%sPaint(wxPaintEvent& event) lbessard@137: { lbessard@137: SVGUITransform* transform = (SVGUITransform*)GetElementByName(wxT("%s")); lbessard@137: """%(element_name, element_name) lbessard@137: text += element_state%"GUI_BUSY" lbessard@137: for i, output in enumerate(block_infos["outputs"]): lbessard@137: if i < 5: lbessard@137: texts = {"location" : current_location, "id" : element.getid(), lbessard@137: "pin" : i + 1, "param" : ["X", "Y", "XScale", "YScale", "Angle"][i]} lbessard@137: lbessard@137: text += """ if (transform->Get%(param)s() != _copy__ID%(location)s_%(id)d_%(pin)d) lbessard@137: { lbessard@137: _copy__ID%(location)s_%(id)d_%(pin)d = transform->Get%(param)s(); lbessard@137: _copy__IX%(location)s_%(id)d_6 = true; lbessard@137: } lbessard@137: """%texts lbessard@137: text += element_state%"CHANGED" lbessard@137: text += " event.Skip();\n}\n\n" lbessard@137: elif element_type == ITEM_CONTAINER: lbessard@137: text += """void Program::On%sPaint(wxPaintEvent& event) lbessard@137: { lbessard@137: SVGUIContainer* container = (SVGUIContainer*)GetElementByName(wxT("%s")); lbessard@137: bool isvisible = container->IsVisible(); lbessard@137: """%(element_name, element_name) lbessard@137: text += element_state%"GUI_BUSY" lbessard@137: texts = {"location" : current_location, "id" : element.getid()} etisserant@37: lbessard@137: text += """ if (isvisible != _copy__IX%(location)s_%(id)d_1) lbessard@137: { lbessard@137: _copy__IX%(location)s_%(id)d_1 = container->IsVisible(); lbessard@137: _copy__IX%(location)s_%(id)d_2 = true; lbessard@137: """%texts lbessard@137: text += " %s }\n else {\n %s }\n"%(element_state%"CHANGED", element_state%"UNCHANGED") lbessard@137: text += " event.Skip();\n}\n\n" lbessard@137: lbessard@137: lbessard@137: text += """void Program::OnChar(wxKeyEvent& event) lbessard@137: { lbessard@137: SVGUIContainer* container = GetSVGUIRootElement(); lbessard@137: if (container->GetFocusedElementName() == wxT("TextCtrl")) lbessard@137: { lbessard@137: wxString focusedId = container->GetFocusedElement(); lbessard@137: SVGUITextCtrl* text = (SVGUITextCtrl*)GetElementById(focusedId); lbessard@137: text->SendKeyEvent(event); lbessard@137: """ lbessard@137: for element in elements: lbessard@137: element_type = GetElementType(element) lbessard@137: if element_type == ITEM_TEXT: lbessard@137: texts = {"location" : current_location, "id" : element.getid()} lbessard@137: lbessard@137: text += """ if (focusedId == wxT("%(id)d")) lbessard@137: { lbessard@137: in_state_%(id)d = GUI_BUSY; lbessard@137: _copy__IB%(location)s_%(id)d_1 = wxStringToIEC_STRING(text->GetValue()); lbessard@137: _copy__IX%(location)s_%(id)d_2 = true; lbessard@137: in_state_%(id)d = CHANGED; lbessard@137: } lbessard@137: """%texts lbessard@137: lbessard@137: text += " }\n event.Skip();\n}\n\n" lbessard@137: lbessard@137: lbessard@137: text += """void Program::OnClick(wxMouseEvent& event) lbessard@137: { lbessard@137: SVGUIContainer* container = GetSVGUIRootElement(); lbessard@137: if (container->GetFocusedElementName() == wxT("ScrollBar")) lbessard@137: { lbessard@137: wxString focusedId = container->GetFocusedElement(); lbessard@137: SVGUIScrollBar* scrollbar = (SVGUIScrollBar*)GetElementById(focusedId); lbessard@137: scrollbar->SendMouseEvent(event); lbessard@137: """ lbessard@137: for element in elements: lbessard@137: element_type = GetElementType(element) lbessard@137: if element_type == ITEM_SCROLLBAR: lbessard@137: texts = {"location" : current_location, "id" : element.getid()} lbessard@137: lbessard@137: text += """ if (focusedId == wxT("%(id)d")) lbessard@137: { lbessard@137: unsigned int scrollPos = scrollbar->GetThumbPosition(); lbessard@137: _copy__IW%(location)s_%(id)d_1 = scrollPos; lbessard@137: _copy__IX%(location)s_%(id)d_2 = true;\n" lbessard@137: } lbessard@137: """%texts lbessard@137: lbessard@137: text += " }\n event.Skip();\n}\n\n" lbessard@137: lbessard@137: lbessard@137: text += "/* OnPlcOutEvent update GUI with provided IEC __Q* PLC output variables */\n" lbessard@137: text += "void Program::OnPlcOutEvent(wxEvent& event)\n{\n wxMutexGuiEnter();" lbessard@137: for element in elements: lbessard@137: element_type = GetElementType(element) lbessard@137: texts = {"location" : current_location, "id" : element.getid()} lbessard@137: lbessard@137: element_lock = " if (__sync_val_compare_and_swap (&out_state_%(id)d, CHANGED, GUI_BUSY) == CHANGED)\n {\n"%texts lbessard@137: element_unlock = " __sync_val_compare_and_swap (&out_state_%(id)d, GUI_BUSY, UNCHANGED);\n }\n"%texts lbessard@137: if element_type == ITEM_BUTTON: lbessard@137: text += element_lock lbessard@137: text += """ SVGUIButton* button = (SVGUIButton*)GetElementById(wxT("%(id)d")); lbessard@137: //if (_copy__QX%(location)s_%(id)d_1) lbessard@137: // button->Show(); lbessard@137: //else lbessard@137: // button->Hide(); lbessard@137: if (_copy__QX%(location)s_%(id)d_2 != button->GetToggle()) { lbessard@137: button->SetToggle(_copy__QX%(location)s_%(id)d_2); lbessard@137: } lbessard@137: """%texts lbessard@137: text += element_unlock lbessard@137: elif element_type == ITEM_CONTAINER: lbessard@137: text += element_lock lbessard@137: text += """ if (_copy__QX%(location)s_%(id)d_2) lbessard@137: { lbessard@137: SVGUIContainer* container = (SVGUIContainer*)GetElementById(wxT("%(id)d")); lbessard@137: //if (_copy__QX%(location)s_%(id)d_1) lbessard@137: // container->Show(); lbessard@137: //else lbessard@137: // container->Hide(); lbessard@137: } lbessard@137: """%texts lbessard@137: text += element_unlock lbessard@137: elif element_type == ITEM_TEXT: lbessard@137: text += element_lock lbessard@137: text += """ if (_copy__QX%(location)s_%(id)d_2) lbessard@137: { lbessard@137: SVGUITextCtrl* text = (SVGUITextCtrl*)GetElementById(wxT("%(id)d")); lbessard@137: wxString str = wxString::FromAscii(_copy__QB%(location)s_%(id)d_1); lbessard@137: text->SetText(str); lbessard@137: } lbessard@137: """%texts lbessard@137: text += element_unlock lbessard@137: elif element_type == ITEM_SCROLLBAR: lbessard@137: text += element_lock lbessard@137: text += """ if (_copy__QX%(location)s_%(id)d_2) lbessard@137: { lbessard@137: SVGUIScrollBar* scrollbar = (SVGUIScrollBar*)GetElementById(wxT("%(id)d")); lbessard@137: scrollbar->SetThumbPosition(_copy__QW%(location)s_%(id)d_1);\n" lbessard@137: } lbessard@137: """%texts lbessard@137: text += element_unlock lbessard@137: elif element_type == ITEM_ROTATING: lbessard@137: text += element_lock lbessard@137: text += """ if (_copy__QX%(location)s_%(id)d_2) lbessard@137: { lbessard@137: SVGUIRotatingCtrl* rotating = (SVGUIRotatingCtrl*)GetElementById(wxT("%(id)d")); lbessard@137: rotating->SetAngle(_copy__QD%(location)s_%(id)d_1);\n" lbessard@137: } lbessard@137: """%texts lbessard@137: text += element_unlock lbessard@137: elif elment_type == ITEM_NOTEBOOK: lbessard@137: text += element_lock lbessard@137: text += """ if (copy__QX%(location)s_%(id)d_2) lbessard@137: { lbessard@137: SVGUINoteBook* notebook = (SVGUINoteBook*)GetElementById(wxT("%(id)d")); lbessard@137: notebook->SetCurrentPage(_copy__QB%(location)s_%(id)d_1); lbessard@137: } lbessard@137: """%texts lbessard@137: text += element_unlock lbessard@137: elif elment_type == ITEM_TRANSFORM: lbessard@137: text += element_lock lbessard@137: text += """ if (copy__QX%(location)s_%(id)d_6) lbessard@137: { lbessard@137: SVGUITransform* transform = (SVGUITransform*)GetElementById(wxT("%(id)d")); lbessard@137: transform->Move(_copy__QD%(location)s_%(id)d_1, _copy__QD%(location)s_%(id)d_2); lbessard@137: transform->Scale(_copy__QD%(location)s_%(id)d_3, _copy__QD%(location)s_%(id)d_4); lbessard@137: transform->Rotate(_copy__QD%(location)s_%(id)d_5); lbessard@137: } lbessard@137: """%texts lbessard@137: text += element_unlock lbessard@137: text += """ wxMutexGuiLeave(); lbessard@137: event.Skip(); lbessard@137: } lbessard@137: lbessard@137: """ lbessard@137: return text lbessard@137: lbessard@137: def GenerateProgramPrivateFunctions(self, elements): lbessard@137: current_location = "_".join(map(str, self.GetCurrentLocation())) lbessard@137: lbessard@137: text = "void Program::Retrieve()\n{\n" lbessard@137: for element in elements: lbessard@137: element_type = GetElementType(element) lbessard@137: texts = {"location" : current_location, "id" : element.getid()} lbessard@137: block_infos = GetBlockType(SVGUIFB_Types[GetElementType(element)]) lbessard@137: lbessard@137: text += """ do{ lbessard@137: if ( __sync_val_compare_and_swap (&in_state_%(id)d, CHANGED, PLC_BUSY) == CHANGED){ lbessard@137: """%texts lbessard@137: for i, output in enumerate(block_infos["outputs"]): lbessard@137: texts["type"] = TYPECONVERSION[output[1]] lbessard@137: texts["pin"] = i + 1 lbessard@137: lbessard@137: variable = "__I%(type)s%(location)s_%(id)d_%(pin)d"%texts lbessard@137: text +=" %s = _copy%s;\n"%(variable, variable) lbessard@137: lbessard@137: text += " /* reset change status pin */\n" lbessard@137: if element_type in [ITEM_BUTTON, ITEM_CONTAINER, ITEM_TEXT, ITEM_SCROLLBAR, ITEM_ROTATING, ITEM_NOTEBOOK]: lbessard@137: text += " _copy__IX%(location)s_%(id)d_2 = false;\n"%texts lbessard@137: elif element_type == ITEM_TRANSFORM: lbessard@137: text += " _copy__IX%(location)s_%(id)d_6 = false;\n"%texts lbessard@137: text += """ } lbessard@137: else { lbessard@137: break; lbessard@137: } lbessard@137: """ etisserant@39: #If GUI did change data while publishing, do it again (in real-time this should be avoided with priority stuff) lbessard@137: text += " }while(__sync_val_compare_and_swap (&in_state_%(id)s, PLC_BUSY, UNCHANGED) != PLC_BUSY);\n"%texts lbessard@137: text += "}\n\n" lbessard@137: lbessard@137: text += """void Program::Publish() lbessard@137: { lbessard@137: bool refresh = false; lbessard@137: """ lbessard@137: for element in elements: lbessard@137: element_type = GetElementType(element) lbessard@137: texts = {"location" : current_location, "id" : element.getid()} lbessard@137: block_infos = GetBlockType(SVGUIFB_Types[GetElementType(element)]) lbessard@137: lbessard@137: text += """ if ( __sync_bool_compare_and_swap (&out_state_%(id)d, UNCHANGED, PLC_BUSY) || lbessard@137: __sync_bool_compare_and_swap (&out_state_%(id)d, CHANGED, PLC_BUSY)) { lbessard@137: """%texts lbessard@137: for i, input in enumerate(block_infos["inputs"]): lbessard@137: texts["type"] = TYPECONVERSION[input[1]] lbessard@137: texts["pin"] = i + 1 lbessard@137: variable = "__Q%(type)s%(location)s_%(id)d_%(pin)d"%texts lbessard@137: text += " if (_copy%s != %s) {\n"%(variable, variable) lbessard@137: text += " _copy%s = %s;\n"%(variable, variable) lbessard@137: text += " out_state_%(id)d = CHANGED;\n }\n"%texts lbessard@137: text += """ if (out_state_%(id)d == CHANGED) { lbessard@137: refresh = true; lbessard@137: } lbessard@137: else { lbessard@137: out_state_%(id)d = UNCHANGED; lbessard@137: } lbessard@137: } lbessard@137: """%texts lbessard@137: lbessard@137: text += """ /*Replace this with determinist signal if called from RT*/; lbessard@137: if (refresh) { lbessard@137: wxCommandEvent event( EVT_PLC ); lbessard@137: ProcessEvent(event); lbessard@137: } lbessard@137: }; lbessard@137: lbessard@137: """ lbessard@137: lbessard@137: text += "void Program::Initialize()\n{\n" etisserant@37: button = False etisserant@37: container = False etisserant@37: textctrl = False etisserant@37: scrollbar = False etisserant@37: rotatingctrl = False etisserant@37: notebook = False etisserant@37: transform = False lbessard@137: for element in elements: lbessard@137: element_type = GetElementType(element) lbessard@137: texts = {"location" : current_location, "id" : element.getid()} lbessard@137: lbessard@137: if element_type == ITEM_BUTTON: etisserant@37: if (not button): lbessard@137: text += " SVGUIButton* button;\n" lbessard@137: text += """ button = (SVGUIButton*)GetElementById(wxT("%(id)d")); lbessard@137: if (button->IsVisible()) lbessard@137: _copy__IX%(location)s_%(id)d_1 = true; lbessard@137: else lbessard@137: _copy__IX%(location)s_%(id)d_1 = false; lbessard@137: _copy__IX%(location)s_%(id)d_2 = false; lbessard@137: lbessard@137: """%texts etisserant@37: button = True lbessard@137: elif element_type == ITEM_CONTAINER: etisserant@37: if (not container): lbessard@137: text += " SVGUIContainer* container;\n" lbessard@137: text += """ container = (SVGUIContainer*)GetElementById(wxT("%(id)d")); lbessard@137: if (container->IsVisible()) lbessard@137: _copy__IX%(location)s_%(id)d_1 = true; lbessard@137: else lbessard@137: _copy__IX%(location)s_%(id)d_1 = false; lbessard@137: _copy__IX%(location)s_%(id)d_2 = true; lbessard@137: lbessard@137: """%texts etisserant@37: container = True lbessard@137: elif element_type == ITEM_TEXT: etisserant@37: if (not textctrl): lbessard@137: text += " SVGUITextCtrl* text;\n" lbessard@137: text += """ text = (SVGUITextCtrl*)GetElementById(wxT("%(id)d")); lbessard@137: _copy__IB%(location)s_%(id)d_1 = wxStringToIEC_STRING(text->GetValue()); lbessard@137: _copy__IX%(location)s_%(id)d_2 = true; lbessard@137: lbessard@137: """%texts etisserant@37: textctrl = True lbessard@137: elif element_type == ITEM_SCROLLBAR: etisserant@37: if (not scrollbar): lbessard@137: text += " SVGUIScrollBar* scrollbar;\n" lbessard@137: text += """ scrollbar = (SVGUIScrollBar*)GetElementById(wxT("%(id)d")); lbessard@137: _copy__IW%(location)s_%(id)d_1 = scrollbar->GetThumbPosition(); lbessard@137: _copy__IX%(location)s_%(id)d_2 = true; lbessard@137: lbessard@137: """%texts etisserant@37: scrollbar = True lbessard@137: elif element_type == ITEM_ROTATING: etisserant@37: if (not rotatingctrl): lbessard@137: text += " SVGUIRotatingCtrl* rotating;\n" lbessard@137: text += """ rotating = (SVGUIRotatingCtrl*)GetElementById(wxT("%(id)d")); lbessard@137: _copy__ID%(location)s_%(id)d_1 = rotating->GetAngle(); lbessard@137: _copy__IX%(location)s_%(id)d_2 = true; lbessard@137: lbessard@137: """%texts etisserant@37: rotatingctrl = True lbessard@137: elif element_type == ITEM_NOTEBOOK: etisserant@37: if (not notebook): lbessard@137: text += " SVGUINoteBook* notebook;\n" lbessard@137: text += """ notebook = (SVGUINoteBook*)GetElementById(wxT("%(id)d")); lbessard@137: _copy__IB%(location)s_%(id)d_1 = notebook->GetCurrentPage(); lbessard@137: _copy__IX%(location)s_%(id)d_2 = true; lbessard@137: lbessard@137: """%texts etisserant@37: notebook = True lbessard@137: elif element_type == ITEM_TRANSFORM: etisserant@37: if (not transform): lbessard@137: text += " SVGUITransform* transform;\n" lbessard@137: text += """ transform = (SVGUITransform*)GetElementById(wxT("%(id)d")); lbessard@137: _copy__ID%(location)s_%(id)d_1 = transform->GetX(); lbessard@137: _copy__ID%(location)s_%(id)d_2 = transform->GetY(); lbessard@137: _copy__ID%(location)s_%(id)d_3 = transform->GetXScale(); lbessard@137: _copy__ID%(location)s_%(id)d_4 = transform->GetYScale(); lbessard@137: _copy__ID%(location)s_%(id)d_5 = transform->GetAngle(); lbessard@137: _copy__IX%(location)s_%(id)d_6 = true; lbessard@137: lbessard@137: """%texts etisserant@37: transform = True lbessard@137: text += "}\n\n" etisserant@37: etisserant@37: #DEBUG Fonction d'affichage etisserant@44: # fct += "void Program::Print()\n{\n" etisserant@44: # for element in elementsTab: etisserant@44: # infos = element.getElementAttributes() etisserant@44: # for info in infos: etisserant@44: # if info["name"] == "id": etisserant@44: # element_id = str(info["value"]) etisserant@44: # type = element.GetElementInfos()["type"] etisserant@44: # FbdBlock = self.GetBlockType(type) etisserant@44: # element_num_patte = 1 etisserant@44: # for input in FbdBlock["inputs"]: etisserant@44: # element_type = TYPECONVERSION[input[1]] etisserant@44: # c_type = CPRINTTYPECONVERSION[input[1]] etisserant@44: # var = "_copy__Q"+element_type+self.BusNumber+"_"+element_id+"_"+str(element_num_patte) etisserant@44: # fct +=" printf(\""+var+": %"+c_type+"\\n\","+var+");\n" etisserant@44: # element_num_patte +=1 etisserant@44: # element_num_patte = 1 etisserant@44: # for output in FbdBlock["outputs"]: etisserant@44: # element_type = TYPECONVERSION[output[1]] etisserant@44: # c_type = CPRINTTYPECONVERSION[output[1]] etisserant@44: # var = "_copy__I"+element_type+self.BusNumber+"_"+element_id+"_"+str(element_num_patte) etisserant@44: # fct +=" printf(\""+var+": %"+c_type+"\\n\","+var+");\n" etisserant@44: # element_num_patte +=1 etisserant@37: #fct +=" wxPostEvent(Program,wxEVT_PLCOUT);\n" etisserant@44: # fct +="};\n\n" lbessard@137: return text etisserant@37: etisserant@37: def PlugGenerate_C(self, buildpath, locations, logger): lbessard@137: progname = "SVGUI_%s"%"_".join(map(str, self.GetCurrentLocation())) lbessard@137: self.GenerateProgram((0, 0), buildpath, progname) etisserant@47: Gen_C_file = os.path.join(buildpath, progname+".cpp" ) lbessard@137: lbessard@137: status, result, err_result = ProcessLogger(logger, "wx-config --cxxflags", no_stdout=True).spin() lbessard@137: if status: lbessard@137: logger.write_error("Unable to get wx cxxflags\n") lbessard@137: cxx_flags = result.strip() + " -I../matiec/lib" lbessard@137: lbessard@137: status, result, err_result = ProcessLogger(logger, "wx-config --libs", no_stdout=True).spin() lbessard@137: if status: lbessard@137: logger.write_error("Unable to get wx libs\n") lbessard@137: libs = result.strip() + " -lwxsvg" lbessard@137: lbessard@137: return [(Gen_C_file, cxx_flags)],libs,True etisserant@13: etisserant@12: def BlockTypesFactory(self): 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@137: block_infos = GetBlockType(type) lbessard@43: current_location = ".".join(map(str, self.GetCurrentLocation())) lbessard@73: if not generator.ComputedBlocks.get(name, False) and not order: lbessard@137: for num, variable in enumerate(block.inputVariables.getvariable()): lbessard@137: connections = variable.connectionPointIn.getconnections() 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]) etisserant@12: generator.Program += (" %s := %s;\n"%(parameter, generator.ExtractModifier(variable, value))) lbessard@73: generator.ComputedBlocks[block] = True 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@137: if block.getx() + blockPointx == connectionPoint.getx() and block.gety() + blockPointy == connectionPoint.gety(): etisserant@47: return "%sI%s%s.%d.%d"%("%", TYPECONVERSION[block_infos["outputs"][num][1]], current_location, block_id, num+1) etisserant@12: raise ValueError, "No output variable found" etisserant@12: else: etisserant@12: return None lbessard@11: lbessard@43: def initialise_block(type, name): lbessard@43: block_id = self.GetElementIdFromName(name) lbessard@43: if block_id == None: lbessard@43: raise ValueError, "No corresponding block found" lbessard@137: block_infos = GetBlockType(type) lbessard@43: current_location = ".".join(map(str, self.GetCurrentLocation())) lbessard@43: variables = [] lbessard@43: for num, (input_name, input_type, input_modifier) in enumerate(block_infos["inputs"]): etisserant@47: 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: etisserant@12: return [{"name" : "SVGUI function blocks", "list" : lbessard@137: [{"name" : "Container", "type" : "functionBlock", "extensible" : False, lbessard@137: "inputs" : [("Show","BOOL","none"),("SetState","BOOL","none")], lbessard@137: "outputs" : [("Visible","BOOL","none"),("StateChanged","BOOL","none")], lbessard@42: "comment" : "SVGUI Container", lbessard@43: "generate" : generate_svgui_block, "initialise" : initialise_block}, etisserant@37: {"name" : "Button", "type" : "functionBlock", "extensible" : False, etisserant@37: "inputs" : [("Show","BOOL","none"),("Toggle","BOOL","none")], etisserant@37: "outputs" : [("Visible","BOOL","none"),("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@137: "inputs" : [("Text","STRING","none"),("SetText","BOOL","none")], lbessard@137: "outputs" : [("Text","STRING","none"),("TextChanged","BOOL","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@137: "inputs" : [("Position","UINT","none"),("SetPosition","BOOL","none")], lbessard@137: "outputs" : [("Position","UINT","none"),("PositionChanged","BOOL","none")], lbessard@42: "comment" : "SVGUI ScrollBar", lbessard@43: "generate" : generate_svgui_block, "initialise" : initialise_block}, etisserant@37: {"name" : "NoteBook", "type" : "functionBlock", "extensible" : False, lbessard@137: "inputs" : [("Selected","UINT","none"),("SetSelected","BOOL","none")], lbessard@137: "outputs" : [("Selected","UINT","none"),("SelectedChanged","BOOL","none")], lbessard@42: "comment" : "SVGUI Notebook", lbessard@43: "generate" : generate_svgui_block, "initialise" : initialise_block}, etisserant@37: {"name" : "RotatingCtrl", "type" : "functionBlock", "extensible" : False, lbessard@137: "inputs" : [("Angle","REAL","none"),("SetAngle","BOOL","none")], lbessard@137: "outputs" : [("Angle","REAL","none"),("AngleChanged","BOOL","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@137: "inputs" : [("X","REAL","none"),("Y","REAL","none"),("XScale","REAL","none"),("YScale","REAL","none"),("Angle","REAL","none"),("Set","BOOL","none")], lbessard@137: "outputs" : [("X","REAL","none"),("Y","REAL","none"),("XScale","REAL","none"),("YScale","REAL","none"),("Angle","REAL","none"),("Changed","BOOL","none")], lbessard@42: "comment" : "SVGUI Transform", lbessard@43: "generate" : generate_svgui_block, "initialise" : initialise_block}, etisserant@37: ]} etisserant@37: ] lbessard@137: