laurent@371: #!/usr/bin/python laurent@371: # -*- coding: utf-8 -*- laurent@371: laurent@371: import os laurent@371: laurent@371: from nevow import rend, appserver, inevow, tags, loaders, athena laurent@371: import simplejson as json laurent@371: laurent@371: svgfile = '%(svgfile)s' laurent@371: laurent@381: svguiWidgets = {} laurent@381: laurent@381: currentId = 0 laurent@381: def getNewId(): laurent@381: global currentId laurent@381: currentId += 1 laurent@381: return currentId laurent@371: laurent@371: class SvguiWidget: laurent@371: laurent@381: def __init__(self, classname, id, **kwargs): laurent@371: self.classname = classname laurent@381: self.id = id laurent@371: self.attrs = kwargs.copy() laurent@381: self.inputs = {} laurent@381: self.outputs = {} laurent@371: self.inhibit = False laurent@371: self.changed = False laurent@371: laurent@381: def setinput(self, attrname, value): laurent@381: self.inputs[attrname] = value laurent@371: laurent@381: def getinput(self, attrname, default=None): laurent@381: if not self.inputs.has_key(attrname): laurent@381: self.inputs[attrname] = default laurent@381: return self.inputs[attrname] laurent@371: laurent@381: def setoutput(self, attrname, value): laurent@381: if self.outputs.get(attrname) != value: laurent@381: self.outputs[attrname] = value laurent@381: self.changed = True laurent@381: self.RefreshInterface() laurent@381: laurent@381: def updateoutputs(self, **kwargs): laurent@371: for attrname, value in kwargs.iteritems(): laurent@381: if self.outputs.get(attrname) != value: laurent@381: self.outputs[attrname] = value laurent@371: self.changed = True laurent@381: self.RefreshInterface() laurent@381: laurent@381: def RefreshInterface(self): laurent@371: interface = website.getHMI() laurent@381: if isinstance(interface, SVGUI_HMI) and self.changed and not self.inhibit: laurent@371: self.changed = False laurent@381: d = interface.sendData(self) laurent@381: if d is not None: laurent@381: self.inhibit = True laurent@381: d.addCallback(self.InterfaceRefreshed) laurent@381: laurent@381: def InterfaceRefreshed(self, result): laurent@381: self.inhibit = False laurent@381: if self.changed: laurent@381: self.RefreshInterface() laurent@371: laurent@381: def get_object_init_state(obj): laurent@371: # Convert objects to a dictionary of their representation laurent@381: attrs = obj.attrs.copy() laurent@381: attrs.update(obj.inputs) laurent@381: d = { '__class__': obj.classname, laurent@381: 'id': obj.id, laurent@381: 'kwargs': json.dumps(attrs), laurent@371: } laurent@371: return d laurent@371: laurent@381: def get_object_current_state(obj): laurent@381: # Convert objects to a dictionary of their representation laurent@381: d = { '__class__': obj.classname, laurent@381: 'id': obj.id, laurent@381: 'kwargs': json.dumps(obj.outputs), laurent@381: } laurent@381: return d laurent@371: laurent@381: class SVGUI_HMI(website.PLCHMI): laurent@371: jsClass = u"LiveSVGPage.LiveSVGWidget" laurent@371: laurent@371: docFactory = loaders.stan(tags.div(render=tags.directive('liveElement'))[ laurent@371: tags.xml(loaders.xmlfile(os.path.join(WorkingDir, svgfile))), laurent@371: ]) laurent@381: laurent@381: def HMIinitialisation(self): laurent@381: gadgets = [] laurent@381: for gadget in svguiWidgets.values(): laurent@381: gadgets.append(unicode(json.dumps(gadget, default=get_object_init_state, indent=2), 'ascii')) laurent@381: d = self.callRemote('init', gadgets) laurent@381: d.addCallback(self.HMIinitialised) laurent@381: laurent@381: def sendData(self,data): laurent@381: if self.initialised: laurent@381: return self.callRemote('receiveData',unicode(json.dumps(data, default=get_object_current_state, indent=2), 'ascii')) laurent@381: return None laurent@381: laurent@381: def setattr(self, id, attrname, value): laurent@381: svguiWidgets[id].setinput(attrname, value) laurent@371: laurent@381: def createSVGUIControl(*args, **kwargs): laurent@381: id = getNewId() laurent@381: gad = SvguiWidget(args[0], id, **kwargs) laurent@381: svguiWidgets[id] = gad laurent@381: gadget = [unicode(json.dumps(gad, default=get_object_init_state, indent=2), 'ascii')] laurent@381: interface = website.getHMI() laurent@381: if isinstance(interface, SVGUI_HMI) and interface.initialised: laurent@381: interface.callRemote('init', gadget) laurent@381: return id laurent@371: laurent@381: def setAttr(id, attrname, value): laurent@381: gad = svguiWidgets.get(id, None) laurent@381: if gad is not None: laurent@381: gad.setoutput(attrname, value) laurent@371: laurent@381: def updateAttr(id, **kwargs): laurent@381: gad = svguiWidgets.get(id, None) laurent@381: if gad is not None: laurent@381: gad.updateoutput(**kwargs) laurent@371: laurent@381: def getAttr(id, attrname, default=None): laurent@381: gad = svguiWidgets.get(id, None) laurent@381: if gad is not None: laurent@381: return gad.getinput(attrname, default) laurent@381: return default laurent@381: