etisserant@20: import os, sys etisserant@20: base_folder = os.path.split(sys.path[0])[0] etisserant@20: sys.path.append(os.path.join(base_folder, "wxsvg", "defeditor")) etisserant@20: etisserant@37: from DEFControler import * etisserant@37: from defeditor import * etisserant@37: from FBD_Objects import * lbessard@11: etisserant@13: class _EditorFramePlug(EditorFrame): etisserant@37: """ etisserant@37: This Class add IEC specific features to the SVGUI DEFEditor : etisserant@37: - FDB preview etisserant@37: - FBD begin drag etisserant@37: """ etisserant@37: def __init__(self,controller): etisserant@38: EditorFrame.__init__(self,controller, solo_mode=False) etisserant@37: self.FbdWindow = wx.Panel(name='fbdwindow',parent=self.EditorPanel, etisserant@37: pos=wx.Point(300, 355),size=wx.Size(240, 240), etisserant@37: style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER) etisserant@37: self.FbdWindow.SetBackgroundColour(wxColour(255,255,255)) etisserant@37: self.FbdWindow.Bind(wx.EVT_LEFT_DOWN, self.OnFbdClick) etisserant@37: wx.EVT_PAINT(self.FbdWindow,self.OnPaintFBD) etisserant@37: etisserant@37: self.FbdData = None etisserant@37: self.RefreshProjectTree() etisserant@37: if (controller.SvgFilepath): etisserant@37: self.OpenSVGFile(controller.filepath) etisserant@37: self.mySVGctrl.Refresh() etisserant@37: self.OnNewFile() etisserant@37: self.RefreshFBD() etisserant@37: etisserant@37: def SetFbdDragData(self,selected_type): etisserant@37: self.FbdBlock = FBD_Block(parent=self.FbdWindow,type=selected_type,name='') etisserant@37: name = self.Controler.GetSelectedElementName() etisserant@37: self.FbdData = str((selected_type,"functionBlock", name)) etisserant@37: etisserant@37: def RefreshFBD(self): etisserant@37: dc = wx.ClientDC(self.FbdWindow) etisserant@37: dc.Clear() etisserant@37: if self.Controler.HasOpenedProject(): etisserant@37: selected_type = self.Controler.GetSelectedElementType() etisserant@37: if selected_type: etisserant@37: self.SetFbdDragData(selected_type) etisserant@37: self.FbdBlock = FBD_Block(parent=self.FbdWindow,type=selected_type,name='') etisserant@37: width,height = self.FbdBlock.GetMinSize() etisserant@37: self.FbdBlock.SetSize(width,height) etisserant@37: clientsize = self.FbdWindow.GetClientSize() etisserant@37: x = (clientsize.width - width) / 2 etisserant@37: y = (clientsize.height - height) / 2 etisserant@37: self.FbdBlock.SetPosition(x, y) etisserant@37: self.FbdBlock.Draw(dc) etisserant@37: etisserant@37: def OnPaintFBD(self,event): etisserant@37: self.RefreshFBD() etisserant@37: event.Skip() etisserant@37: etisserant@37: def OnFbdClick(self,event): etisserant@37: if self.FbdData: etisserant@37: data = wx.TextDataObject(self.FbdData) etisserant@37: DropSrc = wx.DropSource(self.FbdWindow) etisserant@37: DropSrc.SetData(data) etisserant@37: DropSrc.DoDragDrop() etisserant@37: etisserant@37: def OnProjectTreeItemSelected(self,event): etisserant@37: EditorFrame.OnProjectTreeItemSelected(self,event) etisserant@37: self.RefreshFBD() etisserant@37: etisserant@37: def OnNew(self,event): etisserant@37: EditorFrame.OnNew(self,event) etisserant@37: self.RefreshFBD() etisserant@37: etisserant@37: def OnOpen(self,event): etisserant@37: EditorFrame.OnOpen(self,event) etisserant@37: self.RefreshFBD() etisserant@37: 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@12: def OnClose(self, event): etisserant@38: self._onclose() etisserant@12: event.Skip() etisserant@37: 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"} etisserant@37: """ etisserant@37: TYPECONVERSION = {"BOOL" : "X", "UINT" : "W","REAL" : "D","STRING" : "B"} 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"} etisserant@37: class RootClass(DEFControler): etisserant@37: etisserant@38: def __init__(self): etisserant@37: DEFControler.__init__(self) etisserant@37: filepath = os.path.join(self.PlugPath(), "gui.def") 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: etisserant@12: self.CreateRootElement() etisserant@12: self.SetFilePath(filepath) etisserant@12: 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() etisserant@38: self._View = _EditorFramePlug(self) etisserant@38: self._View._onclose = _onclose etisserant@38: self._View._onsave = _onsave etisserant@38: filepath = os.path.join(self.PlugPath(), "gui.def") etisserant@38: self._View.OpenSVGFile(filepath) etisserant@38: self._View.Show() etisserant@38: etisserant@38: PluginMethods = [("HMI Editor",_OpenView), ("Import SVG",_OpenView), ("Import DEF",_OpenView)] etisserant@38: etisserant@37: def OnPlugSave(self): etisserant@12: self.SaveXMLFile() etisserant@12: return True etisserant@37: etisserant@37: def GenerateProgramHeadersPublicVars(self): etisserant@37: fct = "" etisserant@37: fct += " void OnPlcOutEvent(wxEvent& event);\n\n" etisserant@44: fct += " void Retrive();\n" etisserant@44: fct += " void Publish();\n" etisserant@37: fct += " void Initialize();\n" etisserant@44: # fct += " void Print();\n" etisserant@37: return fct etisserant@37: etisserant@38: def GenerateIECVars(self): etisserant@37: text = "" etisserant@37: elementsTab = self.GetElementsTab() etisserant@37: for element in elementsTab: etisserant@37: infos = element.getElementAttributes() etisserant@37: for info in infos: etisserant@37: if info["name"] == "id": etisserant@37: element_id = str(info["value"]) etisserant@39: text += "volatile int out_state_"+element_id+";\n" etisserant@39: text += "volatile int in_state_"+element_id+";\n" etisserant@37: text +="\n" etisserant@37: #Declaration des variables etisserant@37: for element in elementsTab: etisserant@37: infos = element.getElementAttributes() etisserant@37: for info in infos: etisserant@37: if info["name"] == "id": etisserant@37: element_id = str(info["value"]) etisserant@37: type = element.GetElementInfos()["type"] etisserant@37: FbdBlock = self.GetBlockType(type) etisserant@37: element_num_patte = 1 etisserant@37: for input in FbdBlock["inputs"]: etisserant@37: element_type = TYPECONVERSION[input[1]] etisserant@37: element_c_type = CTYPECONVERSION[input[1]] etisserant@38: line = "__Q"+element_type+self.BusNumber+"_"+element_id+"_"+str(element_num_patte)+";\n" etisserant@38: text += element_c_type+" "+line etisserant@38: text += element_c_type+" _copy"+line etisserant@37: element_num_patte +=1 etisserant@37: element_num_patte = 1 etisserant@37: for output in FbdBlock["outputs"]: etisserant@37: element_type = TYPECONVERSION[output[1]] etisserant@37: element_c_type = CTYPECONVERSION[output[1]] etisserant@37: etisserant@38: line = "__I"+element_type+self.BusNumber+"_"+element_id+"_"+str(element_num_patte)+";\n" etisserant@38: text += element_c_type+" "+line etisserant@38: text += element_c_type+" _copy"+line etisserant@37: element_num_patte +=1 etisserant@37: text +="\n" etisserant@37: return text etisserant@37: etisserant@37: def GenerateGlobalVarsAndFuncs(self): etisserant@44: text = "#include \"iec_types.h\"\n\n" etisserant@38: pri_vars = self.GenerateIECVars() etisserant@38: if (pri_vars): etisserant@38: text += pri_vars etisserant@38: etisserant@37: text += "IMPLEMENT_APP_NO_MAIN(SVGViewApp);\n" etisserant@37: text += "IMPLEMENT_WX_THEME_SUPPORT;\n" etisserant@39: text += "SVGViewApp *myapp = NULL;\n" etisserant@47: text += "pthread_t wxMainLoop;\n" etisserant@47: # text += "pthread_t wxMainLoop,automate;\n" etisserant@39: text += "int myargc = 0;\n" etisserant@39: text += "char** myargv = NULL;\n\n" etisserant@39: etisserant@39: text += "#define UNCHANGED 1 \n" etisserant@37: text += "#define PLC_BUSY 2 \n" etisserant@39: text += "#define CHANGED 3 \n" etisserant@39: text += "#define GUI_BUSY 4 \n\n" etisserant@37: etisserant@37: etisserant@37: text += "void* InitWxEntry(void* args)\n{\n" etisserant@37: text += " wxEntry(myargc,myargv);\n" etisserant@37: text += " return args;\n" etisserant@37: text += "}\n\n" etisserant@37: etisserant@39: # text += "void* SimulAutomate(void* args)\n{\n" etisserant@39: # text += " while(1){\n" etisserant@39: # text += " myapp->frame->m_svgCtrl->IN_"+self.BusNumber+"();\n" etisserant@39: # text += " //printf(\"AUTOMATE\\n\");\n" etisserant@39: # text += " myapp->frame->m_svgCtrl->OUT_"+self.BusNumber+"();\n" etisserant@39: # text += " sleep(1);\n" etisserant@39: # text += " }\n" etisserant@39: # text += " return args;\n" etisserant@39: # text += "}\n\n" etisserant@37: etisserant@47: # if (self.SVGUIRootElement): etisserant@47: # width = self.SVGUIRootElement.GetBBox().GetWidth() etisserant@47: # height = self.SVGUIRootElement.GetBBox().GetHeight() etisserant@47: # else : etisserant@47: # width = 250 etisserant@47: # height = 350 etisserant@37: text += "bool SVGViewApp::OnInit()\n{\n" etisserant@37: text += " #ifndef __WXMSW__\n" etisserant@37: text += " setlocale(LC_NUMERIC, \"C\");\n" etisserant@37: text += " #endif\n" etisserant@47: #text += " frame = new MainFrame(NULL, wxT(\"Program\"),wxDefaultPosition, wxSize((int)"+str(width)+", (int)"+str(height)+"));\n" etisserant@47: text += " frame = new MainFrame(NULL, wxT(\"Program\"),wxDefaultPosition, wxDefaultSize);\n" etisserant@37: text += " myapp = this;\n" etisserant@39: # text += " pthread_create(&automate, NULL, SimulAutomate, NULL);\n" etisserant@37: text += " return true;\n" etisserant@37: text += "}\n\n" etisserant@37: etisserant@39: text += "int __init_"+self.BusNumber+"(int argc, char** argv)\n{\n" etisserant@37: text += " myargc = argc;\n" etisserant@37: text += " myargv = argv;\n" etisserant@37: text += " pthread_create(&wxMainLoop, NULL, InitWxEntry, NULL);\n" etisserant@47: text += "}\n\n" etisserant@47: etisserant@47: text += "int __cleanup_"+self.BusNumber+"()\n{\n" etisserant@37: text += "}\n\n" etisserant@39: etisserant@39: text += "int __retrive_"+self.BusNumber+"()\n{\n" etisserant@39: text += " if(myapp){" etisserant@39: text += " myapp->Retrive()" etisserant@39: text += " }" etisserant@39: text += "}\n\n" etisserant@39: etisserant@39: text += "int __publish_"+self.BusNumber+"()\n{\n" etisserant@39: text += " if(myapp){" etisserant@39: text += " myapp->Publish()" etisserant@39: text += " }" etisserant@39: text += "}\n\n" etisserant@44: etisserant@44: text += "IEC_STRING wxStringToIEC_STRING(wxString s)\n" etisserant@44: text += "{\n" etisserant@44: text += " STRING res = {0,""};\n" etisserant@44: text += " for(int i=0; iGetX();\n" etisserant@39: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_6 = true;\n" etisserant@39: fct += " }\n" etisserant@37: elif element_num_patte == 2: etisserant@39: fct += " if (transform->GetY() != _copy__ID"+self.BusNumber+"_"+element_id+"_2)\n" etisserant@39: fct += " {\n" etisserant@39: fct += " _copy__ID"+self.BusNumber+"_"+element_id+"_2 = transform->GetY();\n" etisserant@39: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_6 = true;\n" etisserant@39: fct += " }\n" etisserant@37: elif element_num_patte == 3: etisserant@39: fct += " if (transform->GetXScale() != _copy__ID"+self.BusNumber+"_"+element_id+"_3)\n" etisserant@39: fct += " {\n" etisserant@39: fct += " _copy__ID"+self.BusNumber+"_"+element_id+"_3 = transform->GetXScale();\n" etisserant@39: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_6 = true;\n" etisserant@39: fct += " }\n" etisserant@37: elif element_num_patte == 4: etisserant@39: fct += " if (transform->GetYScale() != _copy__ID"+self.BusNumber+"_"+element_id+"_4)\n" etisserant@39: fct += " {\n" etisserant@39: fct += " _copy__ID"+self.BusNumber+"_"+element_id+"_4 = transform->GetYScale();\n" etisserant@39: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_6 = true;\n" etisserant@39: fct += " }\n" etisserant@37: elif element_num_patte == 5: etisserant@39: fct += " if (transform->GetAngle() != _copy__ID"+self.BusNumber+"_"+element_id+"_5)\n" etisserant@39: fct += " {\n" etisserant@39: fct += " _copy__ID"+self.BusNumber+"_"+element_id+"_5 = transform->GetAngle();\n" etisserant@39: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_6 = true;\n" etisserant@39: fct += " }\n" etisserant@37: element_num_patte +=1 etisserant@39: fct += _unlock etisserant@37: fct += " event.Skip();\n" etisserant@37: fct += "}\n\n" etisserant@37: elif type == "Container": etisserant@37: fct += "void Program::On"+element_name+"Paint(wxPaintEvent& event)\n{\n" etisserant@37: fct += " SVGUIContainer* container = (SVGUIContainer*)GetElementById(wxT(\""+element_id+"\"));\n" etisserant@39: fct += " bool isvisible = container->IsVisible();\n" etisserant@39: fct += _lock etisserant@39: fct += " if (isvisible != _copy__IX"+self.BusNumber+"_"+element_id+"_1)\n" etisserant@37: fct += " {\n" etisserant@38: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_1 = container->IsVisible();\n" etisserant@38: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_2 = true;\n" etisserant@37: fct += " }\n" etisserant@39: fct += _unlock etisserant@37: fct += " event.Skip();\n" etisserant@37: fct += "}\n\n" etisserant@37: etisserant@37: fct += "void Program::OnChar(wxKeyEvent& event)\n{\n" etisserant@37: fct += " SVGUIContainer* container = GetSVGUIRootElement();\n" etisserant@37: fct += " if (container->GetFocusedElementName() == wxT(\"TextCtrl\"))\n" etisserant@37: fct += " {\n" etisserant@37: fct += " wxString focusedId = container->GetFocusedElement();\n" etisserant@37: fct += " SVGUITextCtrl* text = (SVGUITextCtrl*)GetElementById(container->GetFocusedElement());\n" etisserant@37: fct += " text->SendKeyEvent(event);\n" etisserant@37: for element in elementsTab: etisserant@37: infos = element.getElementAttributes() etisserant@37: for info in infos: etisserant@37: if info["name"] == "id": etisserant@37: element_id = str(info["value"]) etisserant@39: _lock = " in_state_"+element_id+" = GUI_BUSY;\n" etisserant@39: _unlock = " in_state_"+element_id+" = CHANGED;\n" etisserant@37: type = element.GetElementInfos()["type"] etisserant@37: FbdBlock = self.GetBlockType(type) etisserant@37: if type == "TextCtrl": etisserant@39: fct += " if (focusedId == wxT(\""+element_id+"\"))\n" etisserant@37: fct += " {\n" etisserant@39: fct += _lock etisserant@44: fct += " _copy__IB"+self.BusNumber+"_"+element_id+"_1 = wxStringToIEC_STRING(text->GetValue());\n" etisserant@38: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_2 = true;\n" etisserant@39: fct += _unlock etisserant@37: fct += " }\n" etisserant@37: fct += " }\n" etisserant@37: fct += "}\n" etisserant@37: etisserant@37: etisserant@37: etisserant@37: fct += "void Program::OnClick(wxMouseEvent& event)\n{\n" etisserant@37: fct += " SVGUIContainer* container = GetSVGUIRootElement();\n" etisserant@37: fct += " if (container->GetFocusedElementName() == wxT(\"ScrollBar\"))\n" etisserant@37: fct += " {\n" etisserant@37: fct += " wxString focusedId = container->GetFocusedElement();\n" etisserant@37: fct += " SVGUIScrollBar* scrollbar = (SVGUIScrollBar*)GetElementById(focusedId);\n" etisserant@37: fct += " scrollbar->SendMouseEvent(event);\n" etisserant@37: for element in elementsTab: etisserant@37: infos = element.getElementAttributes() etisserant@37: for info in infos: etisserant@37: if info["name"] == "id": etisserant@37: element_id = str(info["value"]) etisserant@37: type = element.GetElementInfos()["type"] etisserant@37: FbdBlock = self.GetBlockType(type) etisserant@37: if type == "ScrollBar": etisserant@39: fct += " if (focusedId == wxT(\""+element_id+"\"))\n" etisserant@37: fct += " {\n" etisserant@37: fct += " unsigned int scrollPos = scrollbar->GetThumbPosition();\n" etisserant@38: fct += " _copy__IW"+self.BusNumber+"_"+element_id+"_1 = scrollPos;\n" etisserant@38: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_2 = true;\n" etisserant@37: fct += " }\n" etisserant@37: fct += " }\n" etisserant@37: fct += " event.Skip();\n" etisserant@37: fct += "}\n" etisserant@37: etisserant@37: etisserant@37: etisserant@37: etisserant@39: fct += "/* OnPlcOutEvent updatde GUI with provided IEC __Q* PLC output variables */\n" etisserant@37: fct += "void Program::OnPlcOutEvent(wxEvent& event)\n{\n" etisserant@39: for element in elementsTab: etisserant@39: infos = element.getElementAttributes() etisserant@39: for info in infos: etisserant@39: if info["name"] == "id": etisserant@39: element_id = str(info["value"]) etisserant@39: _lock = " if (__sync_val_compare_and_swap (&out_state_"+element_id+", CHANGED, GUI_BUSY) == CHANGED)" etisserant@39: _lock += " {\n" etisserant@39: _unlock = " __sync_val_compare_and_swap (&out_state_"+element_id+", GUI_BUSY, UNCHANGED);\n" etisserant@39: _unlock +=" }\n" etisserant@37: type = element.GetElementInfos()["type"] etisserant@37: FbdBlock = self.GetBlockType(type) etisserant@37: if type == "Button": etisserant@39: fct += _lock etisserant@39: fct += " if (_copy__QX"+self.BusNumber+"_"+element_id+"_2)\n" etisserant@37: fct += " {\n" etisserant@37: fct += " SVGUIButton* button = (SVGUIButton*)GetElementById(wxT(\""+element_id+"\"));\n" etisserant@38: fct += " if (_copy__QX"+self.BusNumber+"_"+element_id+"_1)\n" etisserant@37: fct += " button->Show();\n" etisserant@37: fct += " else\n" etisserant@37: fct += " button->Hide();\n" etisserant@37: fct += " }\n" etisserant@39: fct += _unlock etisserant@37: elif type == "Container": etisserant@39: fct += _lock etisserant@39: fct += " if (_copy__QX"+self.BusNumber+"_"+element_id+"_2)\n" etisserant@37: fct += " {\n" etisserant@37: fct += " SVGUIContainer* container = (SVGUIContainer*)GetElementById(wxT(\""+element_id+"\"));\n" etisserant@38: fct += " if (_copy__QX"+self.BusNumber+"_"+element_id+"_1)\n" etisserant@37: fct += " container->Show();\n" etisserant@37: fct += " else\n" etisserant@37: fct += " container->Hide();\n" etisserant@37: fct += " }\n" etisserant@39: fct += _unlock etisserant@37: elif type == "TextCtrl": etisserant@39: fct += _lock etisserant@39: fct += " if (_copy__QX"+self.BusNumber+"_"+element_id+"_2)\n" etisserant@37: fct += " {\n" etisserant@37: fct += " SVGUITextCtrl* text = (SVGUITextCtrl*)GetElementById(wxT(\""+element_id+"\"));\n" etisserant@38: fct += " wxString str = wxString::FromAscii(_copy__QB"+self.BusNumber+"_"+element_id+"_1);\n" etisserant@37: fct += " text->SetText(str);\n" etisserant@37: fct += " }\n" etisserant@39: fct += _unlock etisserant@37: elif type == "ScrollBar": etisserant@39: fct += _lock etisserant@39: fct += " if (_copy__QX"+self.BusNumber+"_"+element_id+"_2)\n" etisserant@37: fct += " {\n" etisserant@37: fct += " SVGUIScrollBar* scrollbar = (SVGUIScrollBar*)GetElementById(wxT(\""+element_id+"\"));\n" etisserant@38: fct += " scrollbar->SetThumbPosition(_copy__QW"+self.BusNumber+"_"+element_id+"_1);\n" etisserant@37: fct += " }\n" etisserant@39: fct += _unlock etisserant@37: elif type == "RotatingCtrl": etisserant@39: fct += _lock etisserant@39: fct += " if (_copy__QX"+self.BusNumber+"_"+element_id+"_2)\n" etisserant@37: fct += " {\n" etisserant@37: fct += " SVGUIRotatingCtrl* rotating = (SVGUIRotatingCtrl*)GetElementById(wxT(\""+element_id+"\"));\n" etisserant@38: fct += " rotating->SetAngle(_copy__QD"+self.BusNumber+"_"+element_id+"_1);\n" etisserant@37: fct += " }\n" etisserant@39: fct += _unlock etisserant@37: elif type == "NoteBook": etisserant@39: fct += _lock etisserant@39: fct += " if (copy__QX"+self.BusNumber+"_"+element_id+"_2)\n" etisserant@37: fct += " {\n" etisserant@37: fct += " SVGUINoteBook* notebook = (SVGUINoteBook*)GetElementById(wxT(\""+element_id+"\"));\n" etisserant@38: fct += " notebook->SetCurrentPage(_copy__QB"+self.BusNumber+"_"+element_id+"_1);\n" etisserant@37: fct += " }\n" etisserant@39: fct += _unlock etisserant@37: elif type == "Transform": etisserant@39: fct += _lock etisserant@39: fct += " if (copy__QX"+self.BusNumber+"_"+element_id+"_6)\n" etisserant@37: fct += " {\n" etisserant@37: fct += " SVGUITransform* transform = (SVGUITransform*)GetElementById(wxT(\""+element_id+"\"));\n" etisserant@38: fct += " transform->Move(_copy__QD"+self.BusNumber+"_"+element_id+"_1,_copy__QD"+self.BusNumber+"_"+element_id+"_2);\n" etisserant@38: fct += " transform->Scale(_copy__QD"+self.BusNumber+"_"+element_id+"_3,_copy__QD"+self.BusNumber+"_"+element_id+"_4);\n" etisserant@38: fct += " transform->Rotate(_copy__QD"+self.BusNumber+"_"+element_id+"_5);\n" etisserant@37: fct += " }\n" etisserant@39: fct += _unlock etisserant@37: fct += " Update_Elements();\n" etisserant@37: fct += " Refresh();\n" etisserant@37: fct += " event.Skip();\n" etisserant@37: fct += "}\n\n" etisserant@37: return fct etisserant@37: etisserant@37: def GenerateProgramPrivateFunctions(self): etisserant@37: elementsTab = self.GetElementsTab() etisserant@39: fct = "void Program::Retrive()\n{\n" etisserant@37: for element in elementsTab: etisserant@37: infos = element.getElementAttributes() etisserant@37: for info in infos: etisserant@37: if info["name"] == "id": etisserant@37: element_id = str(info["value"]) etisserant@37: type = element.GetElementInfos()["type"] etisserant@37: FbdBlock = self.GetBlockType(type) etisserant@39: fct += " if ( __sync_val_compare_and_swap (&out_state_"+element_id+", UNCHANGED, PLC_BUSY) == UNCHANGED ||\n" etisserant@39: fct += " __sync_val_compare_and_swap (&out_state_"+element_id+", CHANGED, PLC_BUSY) == CHANGED){\n" etisserant@39: fct += " bool diff = False;\n" etisserant@37: element_num_patte = 1 etisserant@37: for input in FbdBlock["inputs"]: etisserant@37: element_type = TYPECONVERSION[input[1]] etisserant@38: var = "__Q"+element_type+self.BusNumber+"_"+element_id+"_"+str(element_num_patte) etisserant@39: fct +=" diff |= _copy"+var+ " != "+var+";\n" etisserant@37: fct +=" _copy"+var+ " = "+var+";\n" etisserant@37: element_num_patte +=1 etisserant@39: fct += " if(diff) out_state_"+element_id+" = CHANGED;\n" etisserant@37: fct += " }\n" etisserant@39: fct +=" /*Replace this with determinist signal if called from RT*/;\n" etisserant@37: fct +=" wxCommandEvent event( EVT_PLC );\n" etisserant@37: fct +=" ProcessEvent(event);\n" etisserant@37: fct +="};\n\n" etisserant@37: etisserant@39: fct += "void Program::Publish()\n{\n" etisserant@37: etisserant@37: for element in elementsTab: etisserant@37: infos = element.getElementAttributes() etisserant@37: for info in infos: etisserant@37: if info["name"] == "id": etisserant@37: element_id = str(info["value"]) etisserant@37: type = element.GetElementInfos()["type"] etisserant@37: FbdBlock = self.GetBlockType(type) etisserant@39: fct += " do{\n" etisserant@39: fct += " if ( __sync_val_compare_and_swap (&in_state_"+element_id+", CHANGED, PLC_BUSY) == CHANGED){\n" etisserant@37: element_num_patte = 1 etisserant@37: for output in FbdBlock["outputs"]: etisserant@37: element_type = TYPECONVERSION[output[1]] etisserant@38: var = "__I"+element_type+self.BusNumber+"_"+element_id+"_"+str(element_num_patte) etisserant@39: fct +=" "+var+ " = _copy"+var+";\n" etisserant@37: element_num_patte +=1 etisserant@39: fct += " /* reset change status pin */\n" etisserant@39: if type == "Button": etisserant@39: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_2 = false;\n" etisserant@39: elif type == "Container": etisserant@39: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_2 = false;\n" etisserant@39: elif type == "TextCtrl": etisserant@39: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_2 = false;\n" etisserant@39: elif type == "ScrollBar": etisserant@39: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_2 = false;\n" etisserant@39: elif type == "RotatingCtrl": etisserant@39: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_2 = false;\n" etisserant@39: elif type == "NoteBook": etisserant@39: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_2 = false;\n" etisserant@39: elif type == "Transform": etisserant@39: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_6 = false;\n" etisserant@39: fct += " }else{\n" etisserant@39: fct += " break;\n" etisserant@39: fct += " }\n" etisserant@39: #If GUI did change data while publishing, do it again (in real-time this should be avoided with priority stuff) etisserant@39: fct += " }while(__sync_val_compare_and_swap (&in_state_"+element_id+", PLC_BUSY, UNCHANGED) != PLC_BUSY)\n" etisserant@37: fct +="};\n\n" etisserant@37: etisserant@37: fct += "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 etisserant@37: for element in elementsTab: etisserant@37: infos = element.getElementAttributes() etisserant@37: for info in infos: etisserant@37: if info["name"] == "id": etisserant@37: element_id = str(info["value"]) etisserant@37: type = element.GetElementInfos()["type"] etisserant@37: FbdBlock = self.GetBlockType(type) etisserant@37: if type == "Button": etisserant@37: if (not button): etisserant@37: fct += " SVGUIButton* button;\n" etisserant@37: fct += " button = (SVGUIButton*)GetElementById(wxT(\""+element_id+"\"));\n" etisserant@37: fct += " if (button->IsVisible())\n" etisserant@38: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_1 = true;\n" etisserant@37: fct += " else\n" etisserant@38: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_1 = false;\n" etisserant@38: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_2 = true;\n\n" etisserant@37: button = True etisserant@37: elif type == "Container": etisserant@37: if (not container): etisserant@37: fct += " SVGUIContainer* container;\n" etisserant@37: fct += " container = (SVGUIContainer*)GetElementById(wxT(\""+element_id+"\"));\n" etisserant@37: fct += " if (container->IsVisible())\n" etisserant@38: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_1 = true;\n" etisserant@37: fct += " else\n" etisserant@38: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_1 = false;\n" etisserant@38: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_2 = true;\n\n" etisserant@37: container = True etisserant@37: elif type == "TextCtrl": etisserant@37: if (not textctrl): etisserant@37: fct += " SVGUITextCtrl* text;\n" etisserant@37: fct += " text = (SVGUITextCtrl*)GetElementById(wxT(\""+element_id+"\"));\n" etisserant@44: fct += " _copy__IB"+self.BusNumber+"_"+element_id+"_1 = wxStringToIEC_STRING(text->GetValue());\n" etisserant@38: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_2 = true;\n\n" etisserant@37: textctrl = True etisserant@37: elif type == "ScrollBar": etisserant@37: if (not scrollbar): etisserant@37: fct += " SVGUIScrollBar* scrollbar;\n" etisserant@37: fct += " scrollbar = (SVGUIScrollBar*)GetElementById(wxT(\""+element_id+"\"));\n" etisserant@38: fct += " _copy__IW"+self.BusNumber+"_"+element_id+"_1 = scrollbar->GetThumbPosition();\n" etisserant@38: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_2 = true;\n\n" etisserant@37: scrollbar = True etisserant@37: elif type == "RotatingCtrl": etisserant@37: if (not rotatingctrl): etisserant@37: fct += " SVGUIRotatingCtrl* rotating;\n" etisserant@37: fct += " rotating = (SVGUIRotatingCtrl*)GetElementById(wxT(\""+element_id+"\"));\n" etisserant@38: fct += " _copy__ID"+self.BusNumber+"_"+element_id+"_1 = rotating->GetAngle();\n" etisserant@38: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_2 = true;\n\n" etisserant@37: rotatingctrl = True etisserant@37: elif type == "NoteBook": etisserant@37: if (not notebook): etisserant@37: fct += " SVGUINoteBook* notebook;\n" etisserant@37: fct += " notebook = (SVGUINoteBook*)GetElementById(wxT(\""+element_id+"\"));\n" etisserant@38: fct += " _copy__IB"+self.BusNumber+"_"+element_id+"_1 = notebook->GetCurrentPage();\n" etisserant@38: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_2 = true;\n\n" etisserant@37: notebook = True etisserant@37: elif type == "Transform": etisserant@37: if (not transform): etisserant@37: fct += " SVGUITransform* transform;\n" etisserant@37: fct += " transform = (SVGUITransform*)GetElementById(wxT(\""+element_id+"\"));\n" etisserant@38: fct += " _copy__ID"+self.BusNumber+"_"+element_id+"_1 = transform->GetX();\n" etisserant@38: fct += " _copy__ID"+self.BusNumber+"_"+element_id+"_2 = transform->GetY();\n" etisserant@38: fct += " _copy__ID"+self.BusNumber+"_"+element_id+"_3 = transform->GetXScale();\n" etisserant@38: fct += " _copy__ID"+self.BusNumber+"_"+element_id+"_4 = transform->GetYScale();\n" etisserant@38: fct += " _copy__ID"+self.BusNumber+"_"+element_id+"_5 = transform->GetAngle();\n" etisserant@38: fct += " _copy__IX"+self.BusNumber+"_"+element_id+"_6 = true;\n\n" etisserant@37: transform = True etisserant@37: fct += "}\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" etisserant@37: return fct etisserant@37: etisserant@37: def PlugGenerate_C(self, buildpath, locations, logger): etisserant@37: current_location = self.GetCurrentLocation() etisserant@37: self.BusNumber = "_".join(map(lambda x:str(x), current_location)) etisserant@49: progname = "SVGUI_" + self.BusNumber etisserant@47: self.GenerateProgram(buildpath, progname) etisserant@47: Gen_C_file = os.path.join(buildpath, progname+".cpp" ) etisserant@55: return [(Gen_C_file,"")],"",True etisserant@13: etisserant@12: def BlockTypesFactory(self): etisserant@12: def generate_svgui_block(generator, block, body, link): etisserant@12: 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@43: type = block.getTypeName() lbessard@43: block_infos = self.GetBlockType(type) lbessard@43: current_location = ".".join(map(str, self.GetCurrentLocation())) etisserant@12: if not generator.ComputedBlocks.get(name, False): etisserant@12: for num, variable in enumerate(block.inputVariables.getVariable()): etisserant@12: 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))) etisserant@12: generator.ComputedBlocks[name] = True etisserant@12: if link: etisserant@12: connectionPoint = link.getPosition()[-1] etisserant@12: for num, variable in enumerate(block.outputVariables.getVariable()): etisserant@12: blockPointx, blockPointy = variable.connectionPointOut.getRelPosition() etisserant@12: 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@43: block_infos = self.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" : etisserant@12: [{"name" : "Container", "type" : "functionBlock", "extensible" : False, etisserant@37: "inputs" : [("Show","BOOL","none"),("Set State","BOOL","none")], etisserant@37: "outputs" : [("Show","BOOL","none"),("State Changed","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, etisserant@37: "inputs" : [("Text","STRING","none"),("Set Text","BOOL","none")], etisserant@37: "outputs" : [("Text","STRING","none"),("Text Changed","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, etisserant@37: "inputs" : [("Position","UINT","none"),("Set Position","BOOL","none")], etisserant@37: "outputs" : [("Position","UINT","none"),("Position Changed","BOOL","none")], lbessard@42: "comment" : "SVGUI ScrollBar", lbessard@43: "generate" : generate_svgui_block, "initialise" : initialise_block}, etisserant@37: {"name" : "NoteBook", "type" : "functionBlock", "extensible" : False, etisserant@37: "inputs" : [("Selected","UINT","none"),("Set Selected","BOOL","none")], etisserant@37: "outputs" : [("Selected","UINT","none"),("Selected Changed","BOOL","none")], lbessard@42: "comment" : "SVGUI Notebook", lbessard@43: "generate" : generate_svgui_block, "initialise" : initialise_block}, etisserant@37: {"name" : "RotatingCtrl", "type" : "functionBlock", "extensible" : False, etisserant@37: "inputs" : [("Angle","REAL","none"),("Set Angle","BOOL","none")], etisserant@37: "outputs" : [("Angle","REAL","none"),("Angle changed","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, etisserant@37: "inputs" : [("X","REAL","none"),("Y","REAL","none"),("Scale X","REAL","none"),("Scale Y","REAL","none"),("Angle","REAL","none"),("Set","BOOL","none")], etisserant@37: "outputs" : [("X","REAL","none"),("Y","REAL","none"),("Scale X","REAL","none"),("Scale Y","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: ] etisserant@37: etisserant@37: def GetBlockType(self,type): etisserant@37: for category in self.BlockTypesFactory(): etisserant@37: for blocktype in category["list"]: etisserant@37: if blocktype["name"] == type: etisserant@37: return blocktype etisserant@37: return None etisserant@37: etisserant@37: #DEBUG etisserant@37: if __name__ == '__main__': etisserant@37: app = wxPySimpleApp() etisserant@37: wxInitAllImageHandlers() etisserant@37: etisserant@37: # Install a exception handle for bug reports etisserant@37: #wxAddExceptHook(os.getcwd(),__version__) etisserant@37: etisserant@37: cont = RootClass(sys.path[0]) etisserant@37: frame = _EditorFramePlug(cont) etisserant@37: etisserant@37: frame.Show() etisserant@37: app.MainLoop() etisserant@37: #DEBUG etisserant@37: etisserant@37: etisserant@37: etisserant@37: etisserant@37: