Mercurial > MadButterfly
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) |