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