comparison pyink/MBScene.py @ 1206:1d476b35dc79

Merge and move code of tracking max frame number to MBScene_dom_monitor
author Thinker K.F. Li <thinker@codemud.net>
date Tue, 04 Jan 2011 10:08:02 +0800
parents 1af64bcdfd7d ca4e89cc464b
children 489e6e474fdf
comparison
equal deleted inserted replaced
1205:1af64bcdfd7d 1206:1d476b35dc79
156 # 156 #
157 class MBScene_dom_monitor(object): 157 class MBScene_dom_monitor(object):
158 def __init__(self, *args, **kws): 158 def __init__(self, *args, **kws):
159 super(MBScene_dom_monitor, self).__init__() 159 super(MBScene_dom_monitor, self).__init__()
160 160
161 self._maxframe = 0
161 self._id2node = {} # map ID to the node in the DOM tree. 162 self._id2node = {} # map ID to the node in the DOM tree.
162 self._group2scene = {} # map ID of a group to associated scene node. 163 self._group2scene = {} # map ID of a group to associated scene node.
163 pass 164 pass
164 165
165 def _start_monitor(self): 166 def _start_monitor(self):
166 self._collect_node_ids() 167 self._collect_node_ids()
168 self._collect_all_scenes()
167 169
168 doc = self._doc 170 doc = self._doc
169 addEventListener(doc,'DOMNodeInserted', self._on_insert_node, None) 171 addEventListener(doc,'DOMNodeInserted', self._on_insert_node, None)
170 addEventListener(doc,'DOMNodeRemoved', self._on_remove_node, None) 172 addEventListener(doc,'DOMNodeRemoved', self._on_remove_node, None)
171 addEventListener(doc, 'DOMAttrModified', self._on_attr_modified, None) 173 addEventListener(doc, 'DOMAttrModified', self._on_attr_modified, None)
190 else: 192 else:
191 if ref not in self._group2scene: 193 if ref not in self._group2scene:
192 self._group2scene[ref] = child 194 self._group2scene[ref] = child
193 pass 195 pass
194 pass 196 pass
195 pass 197
196 pass 198 try:
199 start = child.getAttribute('start')
200 self._maxframe = max(int(start), self._maxframe)
201 except:
202 pass
203 try:
204 start = child.getAttribute('end')
205 self._maxframe = max(int(start), self._maxframe)
206 except:
207 pass
208 pass
209 pass
210
211 def _find_maxframe(self, scenes_node):
212 maxframe = 0
213 for child in scenes_node.childList():
214 if child.name() != 'ns0:scene':
215 continue
216
217 try:
218 start = child.getAttribute('start')
219 maxframe = max(int(start), maxframe)
220 except:
221 pass
222 try:
223 end = child.getAttribute('end')
224 maxframe = max(int(end), maxframe)
225 except:
226 pass
227 pass
228 return maxframe
197 229
198 def _on_remove_node(self, node, child): 230 def _on_remove_node(self, node, child):
199 try: 231 try:
200 child_id = child.getAttribute('id') 232 child_id = child.getAttribute('id')
201 except: 233 except:
212 ref = child.getAttribute('ref') 244 ref = child.getAttribute('ref')
213 except: 245 except:
214 pass 246 pass
215 else: 247 else:
216 del self._group2scene[ref] 248 del self._group2scene[ref]
249 pass
250
251 try:
252 if node.name() == 'ns0:scenes' and \
253 (int(child.getAttribute('start')) == self._maxframe or
254 int(child.getAttribute('end')) == self._maxframe):
255 self._maxframe = self._find_maxframe(node)
256 pass
257 except:
217 pass 258 pass
218 pass 259 pass
219 pass 260 pass
220 261
221 def _on_attr_modified(self, node, name, old_value, new_value): 262 def _on_attr_modified(self, node, name, old_value, new_value):
244 del self._group2scene[old_value] 285 del self._group2scene[old_value]
245 pass 286 pass
246 if new_value: 287 if new_value:
247 self._group2scene[new_value] = node 288 self._group2scene[new_value] = node
248 pass 289 pass
249 return 290 pass
291 elif (name in ('start', 'end')) and node.name() == 'ns0:scene':
292 self._maxframe = max(int(new_value), self._maxframe)
293 pass
250 pass 294 pass
251 295
252 ## \brief Collect ID of nodes in the document. 296 ## \brief Collect ID of nodes in the document.
253 # 297 #
254 # It is used to implement a fast mapping from an ID to the respective node. 298 # It is used to implement a fast mapping from an ID to the respective node.
268 return 312 return
269 313
270 self._id2node[node_id] = node 314 self._id2node[node_id] = node
271 for n in node.childList(): 315 for n in node.childList():
272 self._collect_node_ids_recursive(n) 316 self._collect_node_ids_recursive(n)
317 pass
318 pass
319
320 def _parse_one_scene(self, scene_node):
321 assert scene_node.name() == 'ns0:scene'
322
323 start = int(scene_node.getAttribute("start"))
324 try:
325 end = int(scene_node.getAttribute("end"))
326 except:
327 end = start
328 pass
329
330 try:
331 scene_type = scene_node.getAttribute('type')
332 if scene_type == None:
333 scene_type = 'normal'
334 pass
335 except:
336 scene_type = 'normal'
337 pass
338
339 return start, end, scene_type
340
341 def _parse_one_scenes(self, scenes_node):
342 try:
343 cur = int(n.getAttribute("current"))
344 except:
345 cur = 0
346 pass
347 self.current = cur
348
349 for scene_node in scenes_node.childList():
350 if scene_node.name() != 'ns0:scene':
351 continue
352
353 try:
354 start, end, scene_type = self._parse_one_scene(scene_node)
355 except:
356 continue
357
358 group_id = scene_node.getAttribute("ref")
359 self._group2scene[group_id] = (start, end, scene_type)
360 pass
361 pass
362
363 ## \brief Parse all scenes node in svg:metadata subtree.
364 #
365 def _collect_all_scenes(self):
366 root = self._root
367 for child in root.childList():
368 if child.name() != 'svg:metadata':
369 continue
370
371 metadata_node = child
372 for metachild in metadata_node.childList():
373 if metachild.name() == 'ns0:scenes':
374 self._parse_one_scenes(metachild)
375 self._maxframe = self._find_maxframe(metachild)
376 pass
377 pass
273 pass 378 pass
274 pass 379 pass
275 380
276 ## \brief Return the node with given ID. 381 ## \brief Return the node with given ID.
277 # 382 #
309 self._root = root 414 self._root = root
310 self._layers = [] 415 self._layers = []
311 416
312 self._start_monitor() # start MBScene_dom_monitor 417 self._start_monitor() # start MBScene_dom_monitor
313 self._init_metadata() 418 self._init_metadata()
314 self._parse_all_scenes()
315 self._parse_all_layers() 419 self._parse_all_layers()
316 pass 420 pass
317 421
318 def dumpattr(self, n): 422 def dumpattr(self, n):
319 s = "" 423 s = ""
328 self.dump(n, l+1) 432 self.dump(n, l+1)
329 pass 433 pass
330 print " " * l * 2,"/>" 434 print " " * l * 2,"/>"
331 pass 435 pass
332 436
333 def _parse_one_scene(self, scene_node):
334 assert scene_node.name() == 'ns0:scene'
335
336 start = int(scene_node.getAttribute("start"))
337 try:
338 end = int(scene_node.getAttribute("end"))
339 except:
340 end = start
341 pass
342
343 try:
344 scene_type = scene_node.getAttribute('type')
345 if scene_type == None:
346 scene_type = 'normal'
347 pass
348 except:
349 scene_type = 'normal'
350 pass
351
352 return start, end, scene_type
353
354 def _parse_one_scenes(self, scenes_node):
355 self.scenemap = {}
356 try:
357 cur = int(n.getAttribute("current"))
358 except:
359 cur = 0
360 pass
361 self.current = cur
362
363 for scene_node in scenes_node.childList():
364 if scene_node.name() != 'ns0:scene':
365 continue
366
367 try:
368 start, end, scene_type = self._parse_one_scene(scene_node)
369 except:
370 continue
371
372 if end > self.maxframe:
373 self.maxframe = end
374 pass
375
376 link = scene_node.getAttribute("ref")
377 self.scenemap[link] = (start, end, scene_type)
378 if cur >= start and cur <= end:
379 self.currentscene = link
380 pass
381 pass
382 pass
383
384 ## \brief Parse all scenes node in svg:metadata subtree.
385 #
386 def _parse_all_scenes(self):
387 root = self._root
388 for child in root.childList():
389 if child.name() != 'svg:metadata':
390 continue
391
392 metadata_node = child
393 for metachild in metadata_node.childList():
394 if metachild.name() == 'ns0:scenes':
395 self._parse_one_scenes(metachild)
396 pass
397 pass
398 pass
399 pass
400
401 ## \brief Create a scenes node if not existed. 437 ## \brief Create a scenes node if not existed.
402 # 438 #
403 def _init_metadata(self): 439 def _init_metadata(self):
404 for node in self._root.childList(): 440 for node in self._root.childList():
405 if node.name() == 'svg:metadata': 441 if node.name() == 'svg:metadata':
431 type_names = ('normal', 'scale') 467 type_names = ('normal', 'scale')
432 scenes_node = self._scenes_node 468 scenes_node = self._scenes_node
433 doc = self._doc 469 doc = self._doc
434 470
435 scene_node = doc.createElement('ns0:scene') 471 scene_node = doc.createElement('ns0:scene')
436 scene_node.setAttribute('start', str(start)) 472 self._chg_scene_node(scene_node, start=start)
437 if start != end: 473 if start != end:
438 self._chg_scene_node(scene_node, end=end) 474 self._chg_scene_node(scene_node, end=end)
439 pass 475 pass
440 type_name = type_names[frame_type] 476 type_name = type_names[frame_type]
441 scene_node.setAttribute('type', type_name) 477 self._chg_scene_node(scene_node, tween_type=type_name)
442 if ref: 478 if ref:
443 scene_node.setAttribute('ref', ref) 479 self._chg_scene_node(scene_node, ref=ref)
444 pass 480 pass
445 481
446 scenes_node.appendChild(scene_node) 482 scenes_node.appendChild(scene_node)
447 483
448 return scene_node 484 return scene_node
449 485
486 ## \brief Change attributes of a scene node.
487 #
488 # This is here to monitor changes of scene node.
450 def _chg_scene_node(self, scene_node, start=None, end=None, 489 def _chg_scene_node(self, scene_node, start=None, end=None,
451 tween_type=None, ref=None): 490 tween_type=None, ref=None):
452 if start: 491 if start:
453 scene_node.setAttribute('start', str(start)) 492 scene_node.setAttribute('start', str(start))
454 pass 493 pass
455 if end: 494 if end:
456 scene_node.setAttribute('end', str(end)) 495 scene_node.setAttribute('end', str(end))
457 if int(end) > self.maxframe:
458 self.maxframe = int(end)
459 pass
460 pass 496 pass
461 if tween_type: 497 if tween_type:
462 scene_node.setAttribute('type', tween_type) 498 scene_node.setAttribute('type', tween_type)
463 pass 499 pass
464 if ref: 500 if ref:
591 self.window = win 627 self.window = win
592 self.top = None 628 self.top = None
593 self.last_update = None 629 self.last_update = None
594 pybInkscape.inkscape.connect('change_selection', self.show_selection) 630 pybInkscape.inkscape.connect('change_selection', self.show_selection)
595 self.last_select = None 631 self.last_select = None
596 self._lockui=False 632 self._lockui = False
597 self.tween=None 633 self.tween = None
598 self.document = None 634 self.document = None
599 self.root = root 635 self.root = root
600 self.framerate=12 636 self.framerate = 12
601 self.maxframe=0
602 self._disable_tween_type_selector = False 637 self._disable_tween_type_selector = False
603 pass 638 pass
604 639
605 def show_selection(self,w,obj): 640 def show_selection(self,w,obj):
606 objs = self.desktop.selection.list() 641 objs = self.desktop.selection.list()
1077 Execute the current animation till the last frame. 1112 Execute the current animation till the last frame.
1078 """ 1113 """
1079 if self.btnRun.get_label() == "Run": 1114 if self.btnRun.get_label() == "Run":
1080 self.btnRun.set_label("Stop") 1115 self.btnRun.set_label("Stop")
1081 self._lockui = True 1116 self._lockui = True
1082 self.last_update = glib.timeout_add(1000/self.framerate,self.doRunNext) 1117 tmout = 1000 / self.framerate
1118 self.last_update = glib.timeout_add(tmout, self.doRunNext)
1083 else: 1119 else:
1084 self.btnRun.set_label("Run") 1120 self.btnRun.set_label("Run")
1085 glib.source_remove(self.last_update) 1121 glib.source_remove(self.last_update)
1086 self._lockui = False 1122 self._lockui = False
1087 pass 1123 pass
1124 pass
1088 1125
1089 def doRunNext(self): 1126 def doRunNext(self):
1090 if self.current > self.maxframe: 1127 if self.current > self._maxframe:
1091 self.current = 0 1128 self.current = 0
1129 pass
1092 try: 1130 try:
1093 self.setCurrentScene(self.current) 1131 self.setCurrentScene(self.current)
1094 except: 1132 except:
1095 traceback.print_exc() 1133 traceback.print_exc()
1096 raise 1134 raise
1097 self.current = self.current + 1 1135 self.current = self.current + 1
1098 self.last_update = glib.timeout_add(1000/self.framerate,self.doRunNext) 1136 tmout = 1000 / self.framerate
1137 self.last_update = glib.timeout_add(tmout, self.doRunNext)
1138 pass
1099 1139
1100 def addButtons(self,hbox): 1140 def addButtons(self,hbox):
1101 btn = gtk.Button('Insert Key') 1141 btn = gtk.Button('Insert Key')
1102 btn.connect('clicked',self.doInsertKeyScene) 1142 btn.connect('clicked',self.doInsertKeyScene)
1103 hbox.pack_start(btn,expand=False,fill=False) 1143 hbox.pack_start(btn,expand=False,fill=False)
1191 self.document = self.desktop.doc().rdoc 1231 self.document = self.desktop.doc().rdoc
1192 self.handle_doc_root(self.document, self.root) 1232 self.handle_doc_root(self.document, self.root)
1193 self.tween = TweenObject(self.document, self.root) 1233 self.tween = TweenObject(self.document, self.root)
1194 self._init_framelines() 1234 self._init_framelines()
1195 self._add_frameline_for_layers() 1235 self._add_frameline_for_layers()
1196 # self._updateUI()
1197 1236
1198 if self.top == None: 1237 if self.top == None:
1199 self.top = gtk.VBox(False,0) 1238 self.top = gtk.VBox(False,0)
1200 self.desktop.getToplevel().child.child.pack_end(self.top,expand=False) 1239 toplevel = self.desktop.getToplevel()
1240 toplevel.child.child.pack_end(self.top,expand=False)
1201 else: 1241 else:
1202 self.top.remove(self.startWindow) 1242 self.top.remove(self.startWindow)
1203 pass 1243 pass
1204 1244
1205 vbox = gtk.VBox(False,0) 1245 vbox = gtk.VBox(False,0)