Mercurial > MadButterfly
changeset 1188:45e3a9273af2
Move code about monitoring DOM-tree to MBScene_dom_monitor
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Fri, 31 Dec 2010 21:40:35 +0800 |
parents | 9d784a987d87 |
children | 9cf183faf89f |
files | pyink/MBScene.py |
diffstat | 1 files changed, 163 insertions(+), 102 deletions(-) [+] |
line wrap: on
line diff
--- a/pyink/MBScene.py Fri Dec 31 13:37:45 2010 +0800 +++ b/pyink/MBScene.py Fri Dec 31 21:40:35 2010 +0800 @@ -87,7 +87,7 @@ def notifyAttributeChanged(self,node, name, old_value, new_value): # print 'attr',node,name,old_value,new_value if self.type == 'DOMAttrModified': - self.func(node,name) + self.func(node, name, old_value, new_value) def addEventListener(obj, type, func,arg): obs = ObjectWatcher(obj,type,func,arg) @@ -153,23 +153,108 @@ pass pass -## \brief Layer of MBScene to manipulate DOM tree. + +## \brief Monitor changes of DOM-tree. # -class MBScene_dom(object): - def newID(self): - while True: - n = 's%d' % int(random.random()*10000) - #print "try %s" % n - if self.ID.has_key(n) == False: - return n +class MBScene_dom_monitor(object): + def __init__(self, *args, **kws): + super(MBScene_dom_monitor, self).__init__() + + self._id2node = {} # map ID to the node in the DOM tree. + pass + + def _start_monitor(self): + self._collect_node_ids() + + doc = self._doc + addEventListener(doc,'DOMNodeInserted', self._on_insert_node, None) + addEventListener(doc,'DOMNodeRemoved', self._on_remove_node, None) + addEventListener(doc, 'DOMAttrModified', self._on_attr_modified, None) + pass + + def _on_insert_node(self, node): + try: + node_id = node.getAttribute('id') + except: + return + self._id2node[node_id] = node + pass + + def _on_remove_node(self, node): + try: + node_id = node.getAttribute('id') + except: + return + if node_id not in self._id2node: + raise ValueError, \ + 'remove a node that is never known (%s)' % (node_id) + del self._id2node[node_id] + pass + + def _on_attr_modified(self, node, name, old_value, new_value): + if name != 'id' or old_value == new_value: + return + + if old_value and (old_value not in self._id2node): + raise ValueError, \ + 'old ID value of passed node is valid one (%s)' % (old_value) + if (new_value in self._id2node): + raise ValueError, \ + 'new ID value of passed node is valid one (%s)' % (new_value) + + if old_value: + del self._id2node[old_value] + pass + self._id2node[new_value] = node + pass + + def _collect_node_ids(self): + self._id2node = {} + root = self._root + for n in root.childList(): + self._collect_node_ids_recursive(n) pass pass - def dumpID(self): - for a,v in self.ID.items(): + def _collect_node_ids_recursive(self, node): + try: + node_id = node.getAttribute('id') + except: + return + + self._id2node[node_id] = node + for n in node.childList(): + self._collect_node_ids_recursive(n) pass pass + def get_node(self, node_id): + return self._id2node[node_id] + + def new_id(self): + while True: + candidate = 's%d' % int(random.random()*100000) + if candidate not in self._id2node: + return candidate + pass + pass + pass + + +## \brief Layer of MBScene to manipulate DOM tree. +# +class MBScene_dom(MBScene_dom_monitor): + def __init__(self, *args, **kws): + super(MBScene_dom, self).__init__() + pass + + def handle_doc_root(self, doc, root): + self._doc = doc + self._root = root + + self._start_monitor() # start MBScene_dom_monitor + pass + def dumpattr(self, n): s = "" for a,v in n.attrib.items(): @@ -237,8 +322,8 @@ pass else: ns = "http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd" - self.root.setAttribute("xmlns:ns0", ns) - scenes = self.document.createElement("ns0:scenes") + self._root.setAttribute("xmlns:ns0", ns) + scenes = self._doc.createElement("ns0:scenes") node.appendChild(scenes) pass pass @@ -252,7 +337,7 @@ new scene. """ - rdoc = self.document + rdoc = self._doc ns = rdoc.createElement("svg:g") found = False for node in line.node.childList(): @@ -265,7 +350,7 @@ # get the element inside the group and apply the # transformation matrix to it directly. for n in node.childList(): - ns.appendChild(n.duplicate(self.document)) + ns.appendChild(n.duplicate(self._doc)) found = True node.setAttribute("style","display:none") break @@ -281,8 +366,7 @@ txt.setAttribute("style","fill:#ff00") ns.appendChild(txt) - gid = line.node.getAttribute('inkscape:label')+self.newID() - self.ID[gid]=1 + gid = line.node.getAttribute('inkscape:label')+self.new_id() ns.setAttribute("id",gid) ns.setAttribute("inkscape:groupmode","layer") line.node.appendChild(ns) @@ -291,7 +375,7 @@ pass def add_scene_on_dom(self, frameline, scenes_node): - doc = self.document + doc = self._doc for start_idx, stop_idx, tween_type in frameline.get_frame_blocks(): ref = frameline.get_frame_data(start_idx) tween_type_idx = self._frameline_tween_types.index(tween_type) @@ -309,8 +393,8 @@ pass def update_scenes_of_dom(self): - doc = self.root - rdoc = self.document + doc = self._root + rdoc = self._doc for node in doc.childList(): if node.name() == 'svg:metadata': for t in node.childList(): @@ -327,61 +411,6 @@ pass pass pass - pass - -class MBScene(MBScene_dom): - _frameline_tween_types = (frameline.TWEEN_TYPE_NONE, - frameline.TWEEN_TYPE_SHAPE) - _tween_obj_tween_types = (TweenObject.TWEEN_TYPE_NORMAL, - TweenObject.TWEEN_TYPE_SCALE) - _tween_type_names = ('normal', 'scale') - - def __init__(self, desktop, win, root=None): - self.desktop = desktop - self.window = win - self.layers = [] - self.layers.append(Layer(None)) - self.scenemap = None - self.top = None - self.last_update = None - pybInkscape.inkscape.connect('change_selection', self.show_selection) - self.last_select = None - self.lockui=False - self.tween=None - self.document = None - self.root = root - self.framerate=12 - self.maxframe=0 - self._disable_tween_type_selector = False - pass - - def show_selection(self,w,obj): - objs = self.desktop.selection.list() - try: - o = objs[0] - print o.getCenter() - if o == self.last_select: - return - except: - self.nameEditor.set_text('') - self.last_select = None - return - self.last_select = o - try: - self.nameEditor.set_text(o.getAttribute("inkscape:label")) - except: - self.nameEditor.set_text('') - pass - pass - - def confirm(self,msg): - vbox = gtk.VBox() - vbox.pack_start(gtk.Label(msg)) - self.button = gtk.Button('OK') - vbox.pack_start(self.button) - self.button.connect("clicked", self.onQuit) - self.window.add(vbox) - pass def parseScene(self): """ @@ -391,7 +420,7 @@ """ self.layers = [] self.scenemap = None - doc = self.root + doc = self._root # TODO: Remove following code sicne this function is for parsing. # Why do this here? @@ -445,37 +474,71 @@ pass pass pass - - # TODO: Remove following code, too. It is unreasonable. - self.collectID() - self.dumpID() pass - def collectID(self): - self.ID = {} - root = self.root - for n in root.childList(): - self.collectID_recursive(n) - pass - pass - - def collectID_recursive(self,node): - try: - self.ID[node.getAttribute('id')] = 1 - except: - pass - for n in node.childList(): - self.collectID_recursive(n) - pass - pass - def getLayer(self, layer): for l in self.layers: if l.node.getAttribute('id') == layer: return l pass return None + pass + +class MBScene(MBScene_dom): + _frameline_tween_types = (frameline.TWEEN_TYPE_NONE, + frameline.TWEEN_TYPE_SHAPE) + _tween_obj_tween_types = (TweenObject.TWEEN_TYPE_NORMAL, + TweenObject.TWEEN_TYPE_SCALE) + _tween_type_names = ('normal', 'scale') + def __init__(self, desktop, win, root=None): + super(MBScene, self).__init__() + + self.desktop = desktop + self.window = win + self.layers = [] + self.layers.append(Layer(None)) + self.scenemap = None + self.top = None + self.last_update = None + pybInkscape.inkscape.connect('change_selection', self.show_selection) + self.last_select = None + self.lockui=False + self.tween=None + self.document = None + self.root = root + self.framerate=12 + self.maxframe=0 + self._disable_tween_type_selector = False + pass + + def show_selection(self,w,obj): + objs = self.desktop.selection.list() + try: + o = objs[0] + print o.getCenter() + if o == self.last_select: + return + except: + self.nameEditor.set_text('') + self.last_select = None + return + self.last_select = o + try: + self.nameEditor.set_text(o.getAttribute("inkscape:label")) + except: + self.nameEditor.set_text('') + pass + pass + + def confirm(self,msg): + vbox = gtk.VBox() + vbox.pack_start(gtk.Label(msg)) + self.button = gtk.Button('OK') + vbox.pack_start(self.button) + self.button.connect("clicked", self.onQuit) + self.window.add(vbox) + pass def removeKeyScene(self): nth = self.last_frame @@ -584,8 +647,6 @@ pass pass pass - - def setCurrentScene(self,nth): """ @@ -866,8 +927,7 @@ new_node.setAttribute('ns0:duplicate-src', old_node_id) pass - gid = self.last_line.node.getAttribute("inkscape:label")+self.newID() - self.ID[gid]=1 + gid = self.last_line.node.getAttribute("inkscape:label")+self.new_id() ns.setAttribute("id",gid) ns.setAttribute("inkscape:groupmode","layer") self.last_line.node.appendChild(ns) @@ -1059,6 +1119,7 @@ pass self.document = self.desktop.doc().rdoc + self.handle_doc_root(self.document, self.root) self.tween = TweenObject(self.document, self.root) self._updateUI() if self.top == None: