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: