comparison pyink/MBScene.py @ 1191:6442fb198418

Refactory insertKeyScene() and fix bug of ObjectWatcher
author Thinker K.F. Li <thinker@codemud.net>
date Sun, 02 Jan 2011 13:53:38 +0800
parents a4df892fb4e5
children 79a3f82edaac
comparison
equal deleted inserted replaced
1190:a4df892fb4e5 1191:6442fb198418
70 self.obj = obj 70 self.obj = obj
71 self.type = type 71 self.type = type
72 self.func = func 72 self.func = func
73 self.arg = arg 73 self.arg = arg
74 74
75 def notifyChildAdded(self,node,child,prev): 75 def notifyChildAdded(self, node, child, prev):
76 if self.type == 'DOMNodeInserted': 76 if self.type == 'DOMNodeInserted':
77 self.func(node) 77 self.func(node, child)
78 def notifyChildRemoved(self,node,child,prev): 78 def notifyChildRemoved(self, node, child, prev):
79 if self.type == 'DOMNodeRemoved': 79 if self.type == 'DOMNodeRemoved':
80 self.func(node) 80 self.func(node, child)
81 def notifyChildOrderChanged(self,node,child,prev): 81 def notifyChildOrderChanged(self,node,child,prev):
82 pass 82 pass
83 def notifyContentChanged(self,node,old_content,new_content): 83 def notifyContentChanged(self,node,old_content,new_content):
84 if self.type == 'DOMSubtreeModified': 84 if self.type == 'DOMSubtreeModified':
85 self.func(node) 85 self.func(node)
86 def notifyAttributeChanged(self,node, name, old_value, new_value): 86 def notifyAttributeChanged(self,node, name, old_value, new_value):
87 # print 'attr',node,name,old_value,new_value
88 if self.type == 'DOMAttrModified': 87 if self.type == 'DOMAttrModified':
89 self.func(node, name, old_value, new_value) 88 self.func(node, name, old_value, new_value)
90 89
91 def addEventListener(obj, type, func,arg): 90 def addEventListener(obj, type, func,arg):
92 obs = ObjectWatcher(obj,type,func,arg) 91 obs = ObjectWatcher(obj,type,func,arg)
170 addEventListener(doc,'DOMNodeInserted', self._on_insert_node, None) 169 addEventListener(doc,'DOMNodeInserted', self._on_insert_node, None)
171 addEventListener(doc,'DOMNodeRemoved', self._on_remove_node, None) 170 addEventListener(doc,'DOMNodeRemoved', self._on_remove_node, None)
172 addEventListener(doc, 'DOMAttrModified', self._on_attr_modified, None) 171 addEventListener(doc, 'DOMAttrModified', self._on_attr_modified, None)
173 pass 172 pass
174 173
175 def _on_insert_node(self, node): 174 def _on_insert_node(self, node, child):
176 try: 175 try:
177 node_id = node.getAttribute('id') 176 child_id = child.getAttribute('id')
178 except: 177 except:
179 pass 178 pass
180 else: 179 else:
181 if node_id not in self._id2node: 180 if child_id not in self._id2node:
182 self._id2node[node_id] = node 181 self._id2node[child_id] = child
183 pass 182 pass
184 pass 183 pass
185 184
186 if node.name() == 'ns0:scene': 185 if child.name() == 'ns0:scene':
187 try: 186 try:
188 ref = node.getAttribute('ref') 187 ref = child.getAttribute('ref')
189 except: 188 except:
190 pass 189 pass
191 else: 190 else:
192 print 'scene %s' % (ref)
193 if ref not in self._group2scene: 191 if ref not in self._group2scene:
194 self._group2scene[ref] = node 192 self._group2scene[ref] = child
195 pass 193 pass
196 pass 194 pass
197 pass 195 pass
198 pass 196 pass
199 197
200 def _on_remove_node(self, node): 198 def _on_remove_node(self, node, child):
201 try: 199 try:
202 node_id = node.getAttribute('id') 200 child_id = child.getAttribute('id')
203 except: 201 except:
204 pass 202 pass
205 else: 203 else:
206 if node_id not in self._id2node: 204 if child_id not in self._id2node:
207 raise ValueError, \ 205 raise ValueError, \
208 'remove a node that is never known (%s)' % (node_id) 206 'remove a node that is never known (%s)' % (child_id)
209 del self._id2node[node_id] 207 del self._id2node[child_id]
210 pass 208 pass
211 209
212 if node.name() == 'ns0:scene': 210 if child.name() == 'ns0:scene':
213 try: 211 try:
214 ref = node.getAttribute('ref') 212 ref = child.getAttribute('ref')
215 except: 213 except:
216 pass 214 pass
217 else: 215 else:
218 del self._group2scene[ref] 216 del self._group2scene[ref]
219 pass 217 pass
220 pass 218 pass
221 pass 219 pass
222 220
223 def _on_attr_modified(self, node, name, old_value, new_value): 221 def _on_attr_modified(self, node, name, old_value, new_value):
224 print 'chg attr %s' % (name)
225 if name == 'id' and old_value != new_value: 222 if name == 'id' and old_value != new_value:
226 if old_value and (old_value not in self._id2node): 223 if old_value and (old_value not in self._id2node):
227 raise ValueError, \ 224 raise ValueError, \
228 'old ID value of passed node is valid one (%s)' % \ 225 'old ID value of passed node is valid one (%s)' % \
229 (old_value) 226 (old_value)
236 del self._id2node[old_value] 233 del self._id2node[old_value]
237 pass 234 pass
238 self._id2node[new_value] = node 235 self._id2node[new_value] = node
239 pass 236 pass
240 elif name == 'ref' and node.name() == 'ns0:scene': 237 elif name == 'ref' and node.name() == 'ns0:scene':
241 print 'change ref %s' % (new_value)
242 if old_value == new_value: 238 if old_value == new_value:
243 return 239 return
244 if old_value: 240 if old_value:
245 node = self._group2scene[old_value] # use old node. Binding 241 node = self._group2scene[old_value] # use old node. Binding
246 # may generate a new 242 # may generate a new
275 271
276 def get_node(self, node_id): 272 def get_node(self, node_id):
277 return self._id2node[node_id] 273 return self._id2node[node_id]
278 274
279 def get_scene(self, group_id): 275 def get_scene(self, group_id):
280 print 'get_scene %s' % (group_id)
281 return self._group2scene[group_id] 276 return self._group2scene[group_id]
282 277
283 def new_id(self): 278 def new_id(self):
284 while True: 279 while True:
285 candidate = 's%d' % int(random.random()*100000) 280 candidate = 's%d' % int(random.random()*100000)
291 286
292 287
293 ## \brief Layer of MBScene to manipulate DOM tree. 288 ## \brief Layer of MBScene to manipulate DOM tree.
294 # 289 #
295 class MBScene_dom(MBScene_dom_monitor): 290 class MBScene_dom(MBScene_dom_monitor):
291 # Declare variables, here, for keeping tracking
292 _doc = None
293 _root = None
294 _scenes_group = None
295
296 def __init__(self, *args, **kws): 296 def __init__(self, *args, **kws):
297 super(MBScene_dom, self).__init__() 297 super(MBScene_dom, self).__init__()
298 pass 298 pass
299 299
300 def handle_doc_root(self, doc, root): 300 def handle_doc_root(self, doc, root):
380 raise RuntimeError, \ 380 raise RuntimeError, \
381 'can not find <svg:metadata> node in the document' 381 'can not find <svg:metadata> node in the document'
382 382
383 for n in node.childList(): 383 for n in node.childList():
384 if n.name() == 'ns0:scenes': 384 if n.name() == 'ns0:scenes':
385 self._scenes_node = n
385 break 386 break
386 pass 387 pass
387 else: 388 else:
388 ns = "http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd" 389 ns = "http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd"
389 self._root.setAttribute("xmlns:ns0", ns) 390 self._root.setAttribute("xmlns:ns0", ns)
390 scenes_node = self._doc.createElement("ns0:scenes") 391 scenes_node = self._doc.createElement("ns0:scenes")
391 node.appendChild(scenes_node) 392 node.appendChild(scenes_node)
392 pass 393 self._scenes_node = scenes_node
393 pass 394 pass
394 395 pass
396
397 ## \brief Create and add a ns0:scene node under ns0:scenes subtree.
398 #
399 def _add_scene_node(self, start, end,
400 frame_type=TweenObject.TWEEN_TYPE_NORMAL,
401 ref=None):
402 type_names = ('normal', 'scale')
403 scenes_node = self._scenes_node
404 doc = self._doc
405
406 scene_node = doc.createElement('ns0:scene')
407 scene_node.setAttribute('start', str(start))
408 if start != end:
409 scene_node.setAttribute('end', str(end))
410 pass
411 type_name = type_names[frame_type]
412 scene_node.setAttribute('type', type_name)
413 if ref:
414 scene_node.setAttribute('ref', ref)
415 pass
416
417 scenes_node.appendChild(scene_node)
418
419 return scene_node
420
421 ## \brief Create and add a svg:g for a scene under a group for a layer.
422 #
423 def _add_scene_group(self, layer_idx):
424 layer = self.layers[layer_idx]
425 doc = self._doc
426
427 scene_group = doc.createElement('svg:g')
428 gid = self.new_id()
429 scene_group.setAttribute("id", gid)
430 scene_group.setAttribute("inkscape:groupmode", "layer")
431
432 layer.group.appendChild(scene_group)
433
434 return scene_group
435
395 def insertKeyScene(self, line, frame): 436 def insertKeyScene(self, line, frame):
396 """ 437 """
397 Insert a new key scene into the stage. If the nth is always a 438 Insert a new key scene into the stage. If the nth is always a
398 key scene, we will return without changing anything. If the 439 key scene, we will return without changing anything. If the
399 nth is a filled scene, we will break the original scene into 440 nth is a filled scene, we will break the original scene into
400 two parts. If the nth is out of any scene, we will append a 441 two parts. If the nth is out of any scene, we will append a
401 new scene. 442 new scene.
402 443
403 """ 444 """
404 rdoc = self._doc 445 doc = self._doc
405 scene_group = rdoc.createElement("svg:g") 446 layer_idx = self._framelines.index(line)
406 found = False 447
407 for node in line.layer_group.childList(): 448 scene_group = self._add_scene_group(layer_idx)
449 scene_group_id = scene_group.getAttribute('id')
450 scene_node = self._add_scene_node(frame, frame, ref=scene_group_id)
451 line.add_keyframe(frame, scene_node)
452
453 for node in self.layers[layer_idx].group.childList():
408 try: 454 try:
409 label = node.getAttribute("inkscape:label") 455 label = node.getAttribute('inkscape:label')
410 except: 456 except:
411 continue 457 continue
412 if label == "dup": 458 if label == 'dup':
413 #FIXME: The duplication here is not perfect. We should 459 node.setAttribute('style', 'display: none')
414 # get the element inside the group and apply the 460 pass
415 # transformation matrix to it directly. 461 pass
416 for n in node.childList(): 462 pass
417 scene_group.appendChild(n.duplicate(self._doc)) 463
418 found = True
419 node.setAttribute("style","display:none")
420 break
421 pass
422 pass
423
424 if found == False:
425 txt = rdoc.createElement("svg:rect")
426 txt.setAttribute("x","0")
427 txt.setAttribute("y","0")
428 txt.setAttribute("width","100")
429 txt.setAttribute("height","100")
430 txt.setAttribute("style","fill:#ff00")
431 scene_group.appendChild(txt)
432
433 gid = line.layer_group.getAttribute('inkscape:label')+self.new_id()
434 scene_group.setAttribute("id",gid)
435 scene_group.setAttribute("inkscape:groupmode","layer")
436 line.layer_group.appendChild(scene_group)
437 line.add_keyframe(frame, scene_group)
438 self.update_scenes_of_dom()
439 pass
440
441 def add_scene_on_dom(self, frameline, scenes_node): 464 def add_scene_on_dom(self, frameline, scenes_node):
442 doc = self._doc 465 doc = self._doc
443 for start_idx, stop_idx, tween_type in frameline.get_frame_blocks(): 466 for start_idx, stop_idx, tween_type in frameline.get_frame_blocks():
444 scene_node = frameline.get_frame_data(start_idx) 467 scene_node = frameline.get_frame_data(start_idx)
445 tween_type_idx = self._frameline_tween_types.index(tween_type) 468 tween_type_idx = self._frameline_tween_types.index(tween_type)
786 pass 809 pass
787 pass 810 pass
788 pass 811 pass
789 pass 812 pass
790 813
791 def enterGroup(self,obj): 814 def enterGroup(self, obj):
792 for l in self.layers: 815 for l in self.layers:
793 for s in l.group.childList(): 816 for s in l.group.childList():
794 if s.getAttribute('id') == obj.getAttribute("id"): 817 if s.getAttribute('id') == obj.getAttribute("id"):
795 self.desktop.setCurrentLayer(s.spitem) 818 self.desktop.setCurrentLayer(s.spitem)
796 pass 819 pass
803 start, stop, tween_type = frameline.get_frame_block(frame_idx) 826 start, stop, tween_type = frameline.get_frame_block(frame_idx)
804 except: 827 except:
805 return 828 return
806 829
807 scene_node = frameline.get_frame_data(start) 830 scene_node = frameline.get_frame_data(start)
808 self.enterGroup(scene_node) 831 scene_group_id = scene_node.getAttribute('ref')
832 scene_group = self.get_node(scene_group_id)
833 self.enterGroup(scene_group)
809 self.setTweenType(tween_type) 834 self.setTweenType(tween_type)
810 pass 835 pass
811 836
812 def setTweenType(self, tween_type): 837 def setTweenType(self, tween_type):
813 sel_type = MBScene._frameline_tween_types.index(tween_type) 838 sel_type = MBScene._frameline_tween_types.index(tween_type)
896 line.connect('motion-notify-event', self._remove_active_frame) 921 line.connect('motion-notify-event', self._remove_active_frame)
897 pass 922 pass
898 vbox.show_all() 923 vbox.show_all()
899 pass 924 pass
900 925
901 ## \brief Update conetent of frameliens according layers. 926 ## \brief Update conetent of framelines according layers.
902 # 927 #
903 def _update_framelines(self): 928 def _update_framelines(self):
904 for frameline in self._framelines: 929 for frameline in self._framelines:
905 layer = frameline.layer 930 layer = frameline.layer
906 if frameline.layer_group.getAttribute("inkscape:label")==None: 931 if frameline.layer_group.getAttribute("inkscape:label")==None:
1153 def onOK(self,event): 1178 def onOK(self,event):
1154 self.OK = True 1179 self.OK = True
1155 gtk.main_quit() 1180 gtk.main_quit()
1156 pass 1181 pass
1157 1182
1158 def updateUI(self,node=None,arg=None): 1183 def updateUI(self, node=None, child=None, arg=None):
1159 if self._lockui: return 1184 if self._lockui: return
1160 1185
1161 if self.last_update!= None: 1186 if self.last_update!= None:
1162 glib.source_remove(self.last_update) 1187 glib.source_remove(self.last_update)
1163 self.last_update = glib.timeout_add(300,self._updateUI) 1188 self.last_update = glib.timeout_add(300,self._updateUI)