Mercurial > MadButterfly
comparison pyink/tween.py @ 1245:ccbf0c5d01d1
Move code of setCurrentScene to tween.py.
- setCurrentScene() is removed from MBScene.
- Add a new class scenes_director in tween.py.
- scenes_director.show_scene() replaces setCurrentScene().
- MBScene instantiates a scenes_director, and calls
scenes_director.show_scene() to switch scenes.
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Mon, 10 Jan 2011 19:07:26 +0800 |
parents | 447cd3359cf2 |
children | cbcb91b196fa |
comparison
equal
deleted
inserted
replaced
1244:b241f9768833 | 1245:ccbf0c5d01d1 |
---|---|
34 else: | 34 else: |
35 s = s +';'+ a | 35 s = s +';'+ a |
36 obj.setAttribute("style",s) | 36 obj.setAttribute("style",s) |
37 | 37 |
38 | 38 |
39 class TweenObject: | 39 class TweenObject(object): |
40 TWEEN_TYPE_NORMAL = 0 | 40 TWEEN_TYPE_NORMAL = 0 |
41 #TWEEN_TYPE_RELOCATE = 1 | 41 #TWEEN_TYPE_RELOCATE = 1 |
42 TWEEN_TYPE_SCALE = 1 | 42 TWEEN_TYPE_SCALE = 1 |
43 | 43 |
44 def __init__(self,doc,dom): | 44 def __init__(self, doc, root): |
45 self.document = doc | 45 super(TweenObject, self).__init__() |
46 self.dom = dom | 46 self._doc = doc |
47 self._root = root | |
47 try: | 48 try: |
48 self.width = float(dom.getAttribute("width")) | 49 self.width = float(root.getAttribute("width")) |
49 self.height = float(dom.getAttribute("height")) | 50 self.height = float(root.getAttribute("height")) |
50 except: | 51 except: |
51 self.width = 640 | 52 self.width = 640 |
52 self.height = 480 | 53 self.height = 480 |
53 | 54 pass |
54 def updateMapping(self): | 55 pass |
55 self.nodeToItem={} | 56 |
56 root = self.dom | |
57 self.updateMappingNode(root) | |
58 def updateMappingNode(self,node): | |
59 for c in node.childList(): | |
60 self.updateMappingNode(c) | |
61 try: | |
62 self.nodeToItem[c.getAttribute("id")] = c | |
63 except: | |
64 pass | |
65 def updateTweenContent(self, duplicate_group, tween_type, | 57 def updateTweenContent(self, duplicate_group, tween_type, |
66 start_scene_group, stop_scene_group, percent): | 58 start_scene_group, stop_scene_group, percent): |
67 """ | 59 """ |
68 Update the content of the duplicate scene group. We will | 60 Update the content of the duplicate scene group. We will |
69 use precent, start_scene_group, stop_scene_group to | 61 use precent, start_scene_group, stop_scene_group to |
217 if typ == self.TWEEN_TYPE_SCALE: | 209 if typ == self.TWEEN_TYPE_SCALE: |
218 self.updateTweenObjectScale(obj,s,d,p,newobj) | 210 self.updateTweenObjectScale(obj,s,d,p,newobj) |
219 pass | 211 pass |
220 elif typ == self.TWEEN_TYPE_NORMAL: | 212 elif typ == self.TWEEN_TYPE_NORMAL: |
221 if newobj == None: | 213 if newobj == None: |
222 newobj = s.duplicate(self.document) | 214 newobj = s.duplicate(self._doc) |
223 newobj.setAttribute("ref", s.getAttribute("id")) | 215 newobj.setAttribute("ref", s.getAttribute("id")) |
224 obj.appendChild(newobj) | 216 obj.appendChild(newobj) |
225 pass | 217 pass |
226 | 218 |
227 def updateTweenObjectScale(self,obj,s,d,p,newobj): | 219 def updateTweenObjectScale(self,obj,s,d,p,newobj): |
242 newobj.parent().removeChild(newobj) | 234 newobj.parent().removeChild(newobj) |
243 newobj = None | 235 newobj = None |
244 pass | 236 pass |
245 | 237 |
246 if newobj == None: | 238 if newobj == None: |
247 newobj = s.duplicate(self.document) | 239 newobj = s.duplicate(self._doc) |
248 top = self.document.createElement("svg:g") | 240 top = self._doc.createElement("svg:g") |
249 top.setAttribute("ref",s.getAttribute("id")) | 241 top.setAttribute("ref",s.getAttribute("id")) |
250 top.appendChild(newobj) | 242 top.appendChild(newobj) |
251 obj.appendChild(top) | 243 obj.appendChild(top) |
252 else: | 244 else: |
253 top = newobj | 245 top = newobj |
257 if s.name() == 'svg:g': | 249 if s.name() == 'svg:g': |
258 # Parse the translate or matrix | 250 # Parse the translate or matrix |
259 # | 251 # |
260 # D = B inv(A) | 252 # D = B inv(A) |
261 try: | 253 try: |
262 item = self.nodeToItem[s.getAttribute("id")] | 254 (ox,oy) = s.spitem.getCenter() |
263 (ox,oy) = item.getCenter() | |
264 except: | 255 except: |
265 ox = 0 | 256 ox = 0 |
266 oy = 0 | 257 oy = 0 |
267 try: | 258 try: |
268 item = self.nodeToItem[d.getAttribute("id")] | 259 (dx,dy) = d.spitem.getCenter() |
269 (dx,dy) = item.getCenter() | |
270 except: | 260 except: |
271 dx = 0 | 261 dx = 0 |
272 dy = 0 | 262 dy = 0 |
273 try: | 263 try: |
274 start_opacity = parse_opacity(s) | 264 start_opacity = parse_opacity(s) |
327 end_opacity = 1 | 317 end_opacity = 1 |
328 cur_opacity = start_opacity*(1-p)+end_opacity*p | 318 cur_opacity = start_opacity*(1-p)+end_opacity*p |
329 change_opacity(newobj,cur_opacity) | 319 change_opacity(newobj,cur_opacity) |
330 | 320 |
331 try: | 321 try: |
332 item = self.nodeToItem[s.getAttribute("id")] | 322 (ox,oy) = s.spitem.getCenter() |
333 (ox,oy) = item.getCenter() | |
334 except: | 323 except: |
335 ox = 0 | 324 ox = 0 |
336 oy = 0 | 325 oy = 0 |
337 try: | 326 try: |
338 item = self.nodeToItem[d.getAttribute("id")] | 327 (dx,dy) = d.spitem.getCenter() |
339 (dx,dy) = item.getCenter() | |
340 except: | 328 except: |
341 dx = 0 | 329 dx = 0 |
342 dy = 0 | 330 dy = 0 |
343 try: | 331 try: |
344 sm = self.parseTransform(s) | 332 sm = self.parseTransform(s) |
364 m = self.mulA([1,0,0,1,tx,self.height-ty],m) | 352 m = self.mulA([1,0,0,1,tx,self.height-ty],m) |
365 | 353 |
366 top.setAttribute("transform","matrix(%g,%g,%g,%g,%g,%g)" % (m[0],m[2],m[1],m[3],m[4],m[5])) | 354 top.setAttribute("transform","matrix(%g,%g,%g,%g,%g,%g)" % (m[0],m[2],m[1],m[3],m[4],m[5])) |
367 except: | 355 except: |
368 traceback.print_exc() | 356 traceback.print_exc() |
357 pass | |
358 pass | |
359 pass | |
360 pass | |
361 | |
362 ## \brief Providing capability of showing scenes. | |
363 # | |
364 # This class computes and shows scenes for a \ref domview_ui. The | |
365 # content of layers and frames are read from domview_ui to generate | |
366 # scenes properly. When caller requests to show a scene 'n', this | |
367 # class compute content of frame 'n' for every layer of the | |
368 # domview_ui. | |
369 # | |
370 class scenes_director(object): | |
371 _tween_obj_tween_types = (TweenObject.TWEEN_TYPE_NORMAL, | |
372 TweenObject.TWEEN_TYPE_SCALE) | |
373 | |
374 def __init__(self, domview_ui): | |
375 super(scenes_director, self).__init__() | |
376 self._domview = domview_ui | |
377 self._tween_obj = TweenObject(domview_ui.doc, domview_ui.root) | |
378 pass | |
379 | |
380 def show_scene(self, idx): | |
381 """ | |
382 Update the scene group according to the curretn scene | |
383 data. There are a couple of cases. | |
384 1. If the type of the scene is normal, we display it when | |
385 it contains the current frame. Otherwise hide it. | |
386 2. If the type of the scene is relocate or scale, we need | |
387 to duplicate the scene group and then modify its | |
388 transform matrix according to the definition of the | |
389 scene. Then, hide the original scenr group and display | |
390 the duplciate scene group. In addition, we may need to | |
391 delete the old duplicated scene group as well. | |
392 | |
393 For each layer, we will always use the duplicated scene | |
394 group whose name as dup. | |
395 We will put the duplicated scene group inside it. We will | |
396 create this group if it is not | |
397 available. | |
398 """ | |
399 for layer_idx in range(self._domview.get_layer_num()): | |
400 dup_group = self._domview.get_layer_dup_group(layer_idx) | |
401 dup_group.setAttribute('style', 'display: none') | |
402 | |
403 all_key_tweens = self._domview.get_layer_keys(layer_idx) | |
404 for start, end, tween_type in all_key_tweens: | |
405 if start == idx: # at key frame | |
406 scene_group = \ | |
407 self._domview.get_key_group(layer_idx, start) | |
408 scene_group.setAttribute('style', '') | |
409 elif start < idx and end >= idx: # in Tween | |
410 dup_group.setAttribute('style', '') | |
411 scene_group = \ | |
412 self._domview.get_key_group(layer_idx, start) | |
413 scene_group.setAttribute('style', 'display: none') | |
414 | |
415 try: | |
416 next_scene_group = \ | |
417 self._domview.get_key_group(layer_idx, end + 1) | |
418 except: # no next key frame | |
419 next_scene_group = scene_group | |
420 pass | |
421 | |
422 tween_obj_type = self._tween_obj_tween_types[tween_type] | |
423 nframes = end - start + 1 | |
424 percent = float(idx - start) / nframes | |
425 self._tween_obj.updateTweenContent(dup_group, | |
426 tween_obj_type, | |
427 scene_group, | |
428 next_scene_group, | |
429 percent) | |
430 pass | |
431 else: # this scene should not be showed. | |
432 scene_group = \ | |
433 self._domview.get_key_group(layer_idx, start) | |
434 scene_group.setAttribute('style', 'display: none') | |
435 pass | |
436 pass | |
437 pass | |
438 pass | |
439 pass |