comparison pyink/MBScene.py @ 1128:b65ac686a7c5

Switch to the DOM-like API. The SPObject become the base of the DOM-like API.
author wycc
date Sat, 18 Dec 2010 09:00:55 +0800
parents 5b2394f67ad0
children 37a0f6ab2f91
comparison
equal deleted inserted replaced
1127:baf4c4d48cff 1128:b65ac686a7c5
8 from lxml import etree 8 from lxml import etree
9 import random 9 import random
10 import traceback 10 import traceback
11 import time 11 import time
12 import pybInkscape 12 import pybInkscape
13 import math
13 14
14 # Please refer to 15 # Please refer to
15 # http://www.assembla.com/wiki/show/MadButterfly/Inkscape_extention 16 # http://www.assembla.com/wiki/show/MadButterfly/Inkscape_extention
16 # for the designed document. 17 # for the designed document.
17 18
53 self.start = int(start) 54 self.start = int(start)
54 self.end = int(end) 55 self.end = int(end)
55 self.type = typ 56 self.type = typ
56 pass 57 pass
57 pass 58 pass
59 class DOM(pybInkscape.PYSPObject):
60 def __init__(self,obj=None):
61 self.proxy = obj
62 pass
63 def duplicate(self,doc):
64 return DOM(self.repr.duplicate(doc))
65
66 class ObjectWatcher(pybInkscape.PYNodeObserver):
67 def __init__(self,obj,type,func,arg):
68 self.obj = obj
69 self.type = type
70 self.func = func
71 self.arg = arg
72
73 def notifyChildAdded(self,node,child,prev):
74 if self.type == 'DOMNodeInserted':
75 self.func(node)
76 def notifyChildRemoved(self,node,child,prev):
77 if self.type == 'DOMNodeRemoved':
78 self.func(node)
79 def notifyChildOrderChanged(self,node,child,prev):
80 pass
81 def notifyContentChanged(self,node,old_content,new_content):
82 print 'cont'
83 if self.type == 'DOMSubtreeModified':
84 self.func(node)
85 def notifyAttributeChanged(self,node, name, old_value, new_value):
86 print 'attr'
87 if self.type == 'DOMAttrModified':
88 self.func(node,name)
89
90 def addEventListener(obj, type, func,arg):
91 obs = ObjectWatcher(obj,type,func,arg)
92 obj.addSubtreeObserver(obs)
93
58 94
59 _scenes = '{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scenes' 95 _scenes = '{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scenes'
60 _scene = '{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scene' 96 _scene = '{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scene'
61 class LayerAttributeWatcher(pybInkscape.PYNodeObserver): 97 class LayerAttributeWatcher(pybInkscape.PYNodeObserver):
62 def __init__(self,ui): 98 def __init__(self,ui):
91 self.layers = [] 127 self.layers = []
92 self.layers.append(Layer(None)) 128 self.layers.append(Layer(None))
93 self.scenemap = None 129 self.scenemap = None
94 self.top = None 130 self.top = None
95 self.last_update = None 131 self.last_update = None
96 self.startPolling() 132 pybInkscape.inkscape.connect('change_selection', self.show_selection)
97 self.last_select = None 133 self.last_select = None
98 pass 134 pass
99 135
100 def startPolling(self): 136 def startPolling(self):
101 objs = self.desktop.selection.list() 137 objs = self.desktop.selection.list()
116 self.nameEditor.set_text(o.repr.attribute("inkscape:label")) 152 self.nameEditor.set_text(o.repr.attribute("inkscape:label"))
117 except: 153 except:
118 self.nameEditor.set_text('') 154 self.nameEditor.set_text('')
119 pass 155 pass
120 glib.timeout_add(500,self.startPolling) 156 glib.timeout_add(500,self.startPolling)
157 def show_selection(self,w,obj):
158 objs = self.desktop.selection.list()
159 try:
160 o = objs[0]
161 print o.getCenter()
162 if o == self.last_select:
163 return
164 except:
165 self.nameEditor.set_text('')
166 self.last_select = None
167 return
168 self.last_select = o
169 try:
170 self.nameEditor.set_text(o.repr.attribute("inkscape:label"))
171 except:
172 self.nameEditor.set_text('')
173 pass
121 174
122 def confirm(self,msg): 175 def confirm(self,msg):
123 vbox = gtk.VBox() 176 vbox = gtk.VBox()
124 vbox.pack_start(gtk.Label(msg)) 177 vbox.pack_start(gtk.Label(msg))
125 self.button = gtk.Button('OK') 178 self.button = gtk.Button('OK')
144 pass 197 pass
145 198
146 def parseMetadata(self,node): 199 def parseMetadata(self,node):
147 self.current = 1 200 self.current = 1
148 for n in node.childList(): 201 for n in node.childList():
149 if n.repr.name() == 'ns0:scenes': 202 if n.name() == 'ns0:scenes':
150 self.scenemap={} 203 self.scenemap={}
151 try: 204 try:
152 cur = int(n.repr.attribute("current")) 205 cur = int(n.attribute("current"))
153 except: 206 except:
154 cur = 1 207 cur = 1
155 self.current = cur 208 self.current = cur
156 209
157 for s in n.childList(): 210 for s in n.childList():
158 if s.repr.name() == 'ns0:scene': 211 if s.name() == 'ns0:scene':
159 try: 212 try:
160 start = int(s.repr.attribute("start")) 213 start = int(s.attribute("start"))
161 except: 214 except:
162 traceback.print_exc() 215 traceback.print_exc()
163 continue 216 continue
164 try: 217 try:
165 end = s.repr.attribute("end") 218 end = s.attribute("end")
166 if end == None: 219 if end == None:
167 end = start 220 end = start
168 pass 221 pass
169 except: 222 except:
170 end = start 223 end = start
171 pass 224 pass
172 try: 225 try:
173 typ = s.repr.attribute('type') 226 typ = s.attribute('type')
174 if typ == None: 227 if typ == None:
175 typ = 'normal' 228 typ = 'normal'
176 except: 229 except:
177 traceback.print_exc() 230 traceback.print_exc()
178 typ = 'normal' 231 typ = 'normal'
179 link = s.repr.attribute("ref") 232 link = s.attribute("ref")
180 self.scenemap[link] = [int(start),int(end),typ] 233 self.scenemap[link] = [int(start),int(end),typ]
181 if cur >= start and cur <= end: 234 if cur >= start and cur <= end:
182 self.currentscene = link 235 self.currentscene = link
183 pass 236 pass
184 pass 237 pass
185 pass 238 pass
186 pass 239 pass
187 pass 240 pass
188 pass 241 pass
189 if self.scenemap==None: 242 if self.scenemap==None:
190 self.desktop.doc().root().repr.setAttribute("xmlns:ns0","http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd",True) 243 #self.desktop.doc().root().repr.setAttribute("xmlns:ns0","http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd")
191 scenes = self.desktop.doc().rdoc.createElement("ns0:scenes") 244 self.dom.setAttribute("xmlns:ns0","http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd")
192 node.repr.appendChild(scenes) 245 scenes = self.document.createElement("ns0:scenes")
246 node.appendChild(scenes)
193 def update(self): 247 def update(self):
194 doc = self.desktop.doc().root() 248 doc = self.dom
195 rdoc = self.desktop.doc().rdoc 249 rdoc = self.document
196 for node in doc.childList(): 250 for node in doc.childList():
197 if node.repr.name() == 'svg:metadata': 251 if node.name() == 'svg:metadata':
198 for t in node.childList(): 252 for t in node.childList():
199 if t.repr.name() == "ns0:scenes": 253 if t.name() == "ns0:scenes":
200 node.repr.removeChild(t.repr) 254 node.removeChild(t)
201 ns = rdoc.createElement("ns0:scenes") 255 ns = rdoc.createElement("ns0:scenes")
202 node.repr.appendChild(ns) 256 node.appendChild(ns)
203 for layer in range(0,len(self._framelines)): 257 for layer in range(0,len(self._framelines)):
204 lobj = self._framelines[layer] 258 lobj = self._framelines[layer]
205 lobj.addScenes(rdoc,ns) 259 lobj.addScenes(rdoc,ns)
206 260
207 261
211 scene and then relocate them back to the appropriate scene 265 scene and then relocate them back to the appropriate scene
212 object. 266 object.
213 """ 267 """
214 self.layers = [] 268 self.layers = []
215 self.scenemap = None 269 self.scenemap = None
216 doc = self.desktop.doc().root() 270 doc = self.dom
217 271
218 #obs = pybInkscape.PYNodeObserver() 272 #obs = pybInkscape.PYNodeObserver()
219 obs = LayerAddRemoveWatcher(self) 273 #obs = LayerAddRemoveWatcher(self)
220 doc.repr.addObserver(obs) 274 #doc.addObserver(obs)
275 addEventListener(doc,'DOMNodeInserted',self.updateUI,None)
276 addEventListener(doc,'DOMNodeRemoved',self.updateUI,None)
277 doc.childList()
221 for node in doc.childList(): 278 for node in doc.childList():
222 if node.repr.name() == 'svg:metadata': 279 print node.name()
280 if node.name() == 'svg:metadata':
223 self.parseMetadata(node) 281 self.parseMetadata(node)
224 pass 282 pass
225 elif node.repr.name() == 'svg:g': 283 elif node.name() == 'svg:g':
226 oldscene = None 284 oldscene = None
227 obs = LayerAttributeWatcher(self) 285 #obs = LayerAttributeWatcher(self)
228 node.repr.addObserver(obs) 286 addEventListener(doc,'DOMAttrModified',self.updateUI,None)
287 #node.addObserver(obs)
229 lyobj = Layer(node) 288 lyobj = Layer(node)
230 self.layers.append(lyobj) 289 self.layers.append(lyobj)
231 lyobj.current_scene = [] 290 lyobj.current_scene = []
232 for scene in node.childList(): 291 for scene in node.childList():
233 if scene.repr.name() == 'svg:g': 292 print scene.getCenter()
293 if scene.name() == 'svg:g':
294 try:
295 label = scene.attribute('inkscape:label')
296 if label == 'dup':
297 node.removeChild(scene)
298 except:
299 pass
300
234 try: 301 try:
235 scmap = self.scenemap[scene.getId()] 302 scmap = self.scenemap[scene.getId()]
236 if scmap == None: 303 if scmap == None:
237 lyobj.current_scene.append(scene) 304 lyobj.current_scene.append(scene)
238 continue 305 continue
254 self.dumpID() 321 self.dumpID()
255 pass 322 pass
256 323
257 def collectID(self): 324 def collectID(self):
258 self.ID = {} 325 self.ID = {}
259 root = self.desktop.doc().root() 326 root = self.dom
260 for n in root.childList(): 327 for n in root.childList():
261 self.collectID_recursive(n) 328 self.collectID_recursive(n)
262 pass 329 pass
263 pass 330 pass
264 331
300 new scene. 367 new scene.
301 368
302 """ 369 """
303 x = self.last_frame 370 x = self.last_frame
304 y = self.last_line 371 y = self.last_line
305 rdoc = self.desktop.doc().rdoc 372 rdoc = self.document
306 ns = rdoc.createElement("svg:g") 373 ns = rdoc.createElement("svg:g")
307 txt = rdoc.createElement("svg:rect") 374 txt = rdoc.createElement("svg:rect")
308 txt.setAttribute("x","0",True) 375 txt.setAttribute("x","0")
309 txt.setAttribute("y","0",True) 376 txt.setAttribute("y","0")
310 txt.setAttribute("width","100",True) 377 txt.setAttribute("width","100")
311 txt.setAttribute("height","100",True) 378 txt.setAttribute("height","100")
312 txt.setAttribute("style","fill:#ff00",True) 379 txt.setAttribute("style","fill:#ff00")
313 ns.appendChild(txt) 380 ns.appendChild(txt)
314 gid = self.last_line.node.label()+self.newID() 381 gid = self.last_line.node.label()+self.newID()
315 self.ID[gid]=1 382 self.ID[gid]=1
316 ns.setAttribute("id",gid,True) 383 ns.setAttribute("id",gid)
317 ns.setAttribute("inkscape:groupmode","layer",True) 384 ns.setAttribute("inkscape:groupmode","layer")
318 self.last_line.node.repr.appendChild(ns) 385 self.last_line.node.appendChild(ns)
319 print 'Add key ', x 386 print 'Add key ', x
320 self.last_line.add_keyframe(x,ns) 387 self.last_line.add_keyframe(x,ns)
321 self.update() 388 self.update()
322 self.last_line.update() 389 self.last_line.update()
323 390
324 391
325 def removeKeyScene(self): 392 def removeKeyScene(self):
326 nth = self.last_frame 393 nth = self.last_frame
327 y = self.last_line 394 y = self.last_line
328 rdoc = self.desktop.doc().rdoc 395 rdoc = self.document
329 i = 0 396 i = 0
330 layer = self.last_line 397 layer = self.last_line
331 while i < len(layer._keys): 398 while i < len(layer._keys):
332 s = layer._keys[i] 399 s = layer._keys[i]
333 print "nth:%d idx %d" % (nth,s.idx) 400 print "nth:%d idx %d" % (nth,s.idx)
425 return 492 return
426 pass 493 pass
427 pass 494 pass
428 pass 495 pass
429 496
497 def updateMapping(self):
498 self.nodeToItem={}
499 root = self.dom
500 self.updateMappingNode(root)
501 def updateMappingNode(self,node):
502 for c in node.childList():
503 self.updateMappingNode(c)
504 self.nodeToItem[c.getId()] = c
505 print "Add",c.getId()
506
430 507
431 def setCurrentScene(self,nth): 508 def setCurrentScene(self,nth):
432 """ 509 """
433 Update the scene group according to the curretn scene data. There are a couple of cases. 510 Update the scene group according to the curretn scene data. There are a couple of cases.
434 1. If the type of the scene is normal, we display it when it contains the current 511 1. If the type of the scene is normal, we display it when it contains the current
441 For each layer, we will always use the duplicated scene group whose name as dup. 518 For each layer, we will always use the duplicated scene group whose name as dup.
442 We will put the duplicated scene group inside it. We will create this group if it is not 519 We will put the duplicated scene group inside it. We will create this group if it is not
443 available. 520 available.
444 """ 521 """
445 self.current = nth 522 self.current = nth
523 self.updateMapping()
446 for layer in self._framelines: 524 for layer in self._framelines:
447 i=0 525 i=0
448 526
449 # Check the duplicated scene group and create it if it is not available 527 # Check the duplicated scene group and create it if it is not available
450 try: 528 try:
461 while i < len(layer._keys): 539 while i < len(layer._keys):
462 s = layer._keys[i] 540 s = layer._keys[i]
463 print s.ref.attribute("id"),s.idx,s.left_tween,s.right_tween 541 print s.ref.attribute("id"),s.idx,s.left_tween,s.right_tween
464 if s.right_tween is False: 542 if s.right_tween is False:
465 if nth == s.idx+1: 543 if nth == s.idx+1:
466 s.ref.setAttribute("style","",True) 544 s.ref.setAttribute("style","")
467 else: 545 else:
468 s.ref.setAttribute("style","display:none",True) 546 s.ref.setAttribute("style","display:none")
469 i = i + 1 547 i = i + 1
470 continue 548 continue
471 if nth == s.idx + 1: 549 if nth == s.idx + 1:
472 s.ref.setAttribute("style","",True) 550 s.ref.setAttribute("style","")
473 else: 551 else:
474 if nth > (s.idx+1) and nth <= (layer._keys[i+1].idx+1): 552 if nth > (s.idx+1) and nth <= (layer._keys[i+1].idx+1):
475 if i+2 < len(layer._keys): 553 if i+2 < len(layer._keys):
476 layer.duplicateGroup = self.desktop.doc().rdoc.createElement("svg:g") 554 layer.duplicateGroup = self.document.createElement("svg:g")
477 layer.duplicateGroup.setAttribute("inkscape:label","dup",True) 555 layer.duplicateGroup.setAttribute("inkscape:label","dup")
478 s.ref.setAttribute("style","display:none",True) 556 s.ref.setAttribute("style","display:none")
479 s.ref.parent().appendChild(layer.duplicateGroup) 557 s.ref.parent().appendChild(layer.duplicateGroup)
480 self.updateTweenContent(layer.duplicateGroup, layer.get_tween_type(s.idx),s, layer._keys[i+2], nth) 558 self.updateTweenContent(layer.duplicateGroup, layer.get_tween_type(s.idx),s, layer._keys[i+2], nth)
481 else: 559 else:
482 s.ref.setAttribute("style","display:none",True) 560 s.ref.setAttribute("style","display:none")
483 i = i + 2 561 i = i + 2
484 pass 562 pass
485 pass 563 pass
486 pass 564 pass
487 def updateTweenContent(self,obj, typ, source,dest,cur): 565 def updateTweenContent(self,obj, typ, source,dest,cur):
496 i = 0 574 i = 0
497 s = source.ref.firstChild() 575 s = source.ref.firstChild()
498 d = dest.ref.firstChild() 576 d = dest.ref.firstChild()
499 sources={} 577 sources={}
500 dests={} 578 dests={}
579
501 # Collect all objects 580 # Collect all objects
502 while d: 581 while d:
503 try: 582 try:
504 label = d.attribute("inkscape:label") 583 label = d.attribute("inkscape:label")
505 except: 584 except:
506 d = d.next() 585 d = d.getNext()
507 continue 586 continue
508 dests[label.value()] = d 587 dests[label] = d
509 d = d.next() 588 d = d.getNext()
510 # Check if the object in the source exists in the destination 589 # Check if the object in the source exists in the destination
511 s = source.ref.firstChild() 590 s = source.ref.firstChild()
512 d = dest.ref.firstChild() 591 d = dest.ref.firstChild()
513 while s: 592 while s:
514 print s,d 593 print s,d
516 label = s.attribute("inkscape:label") 595 label = s.attribute("inkscape:label")
517 # Use i8nkscape:label to identidy the equipvalent objects 596 # Use i8nkscape:label to identidy the equipvalent objects
518 if label: 597 if label:
519 if dests.hasattr(label.value()): 598 if dests.hasattr(label.value()):
520 self.updateTweenObject(obj,typ,s,dests[label.value()],percent) 599 self.updateTweenObject(obj,typ,s,dests[label.value()],percent)
521 s = s.next() 600 s = s.getNext()
522 continue 601 continue
523 except: 602 except:
524 pass 603 pass
525 # Search obejcts in the destination 604 # Search obejcts in the destination
526 while d: 605 while d:
527 try: 606 try:
528 d.attribute("inkscape:label") 607 d.attribute("inkscape:label")
529 d = d.next() 608 d = d.getNext()
530 continue 609 continue
531 except: 610 except:
532 pass 611 pass
533 if s.name() == d.name(): 612 if s.name() == d.name():
534 self.updateTweenObject(obj,typ,s,d,percent) 613 self.updateTweenObject(obj,typ,s,d,percent)
535 d = d.next() 614 d = d.getNext()
536 break 615 break
537 d = d.next() 616 d = d.getNext()
538 s = s.next() 617 s = s.getNext()
539 def parseTransform(self,obj): 618 def parseTransform(self,obj):
540 """ 619 """
541 Return the transform matrix of an object 620 Return the transform matrix of an object
542 """ 621 """
543 try: 622 try:
559 #traceback.print_exc() 638 #traceback.print_exc()
560 return [1,0,0,1,0,0] 639 return [1,0,0,1,0,0]
561 640
562 def invA(self,m): 641 def invA(self,m):
563 d = m[0]*m[3]-m[2]*m[1] 642 d = m[0]*m[3]-m[2]*m[1]
564 return [m[3]/d, m[1]/d, -m[2]/d, m[0]/d, (m[1]*m[5]-m[4]*m[3])/d, (m[4]*m[2]-m[0]*m[5])/d] 643 return [m[3]/d, -m[1]/d, -m[2]/d, m[0]/d, (m[1]*m[5]-m[4]*m[3])/d, (m[4]*m[2]-m[0]*m[5])/d]
565 def mulA(self,a,b): 644 def mulA(self,a,b):
566 return [a[0]*b[0]+a[1]*b[2], 645 return [a[0]*b[0]+a[1]*b[2],
567 a[0]*b[1]+a[1]*b[3], 646 a[0]*b[1]+a[1]*b[3],
568 a[2]*b[0]+a[3]*b[2], 647 a[2]*b[0]+a[3]*b[2],
569 a[2]*b[1]+a[3]*b[3], 648 a[2]*b[1]+a[3]*b[3],
570 a[0]*b[4]+a[1]*b[5]+a[4], 649 a[0]*b[4]+a[1]*b[5]+a[4],
571 a[2]*b[4]+a[3]*b[5]+a[5]] 650 a[2]*b[4]+a[3]*b[5]+a[5]]
651 def parseMatrix(self,m):
652 d = (1-m[0])*(1-m[3])-m[1]*m[2]
653 if d == 0:
654 return [1,0,0,1,m[4],m[5]]
655 else:
656 return [m[0],m[1],m[2],m[3],(m[4]-m[3]*m[4]+m[1]*m[5])/d,(m[5]-m[0]*m[5]+m[2]*m[4])/d]
657
658 def decomposition(self,m):
659 if m[0]*m[3] == m[1]*m[2]:
660 print "The affine matrix is singular"
661 return [1,0,0,1,0,0]
662 A=m[0]
663 B=m[2]
664 C=m[1]
665 D=m[3]
666 E=m[4]
667 F=m[5]
668 sx = math.sqrt(m[0]*m[0]+m[2]*m[2])
669 A = A/sx
670 B = B/sx
671 shear = m[0]*m[1]+m[2]*m[3]
672 C = C - A*shear
673 D = D - B*shear
674 sy = math.sqrt(C*C+D*D)
675 C = C/sy
676 D = D/sy
677 r = A*D-B*C
678 if r == -1:
679 shear = -shear
680 sy = -sy
681 R = math.atan2(B,A)
682 return [sx,sy, R, E,F]
572 683
573 684
574 def updateTweenObject(self,obj,typ,s,d,p): 685 def updateTweenObject(self,obj,typ,s,d,p):
575 """ 686 """
576 Generate tweened object in the @obj by using s and d in the @p percent 687 Generate tweened object in the @obj by using s and d in the @p percent
688 http://lists.w3.org/Archives/Public/www-style/2010Jun/0602.html
577 """ 689 """
578 print 'compare',s,d 690 print 'compare',s,d
579 if typ == 'relocate': 691 if typ == 'relocate':
580 print "percent",p 692 print "percent",p
581 newobj = s.duplicate(self.desktop.doc().rdoc) 693 newobj = s.duplicate(self.document)
582 top = self.desktop.doc().rdoc.createElement("svg:g") 694 newobj.setAttribute("ref", s.getId())
695 top = self.document.createElement("svg:g")
583 top.appendChild(newobj) 696 top.appendChild(newobj)
584 obj.appendChild(top) 697 obj.appendChild(top)
585 print s.name() 698 print s.name()
586 if s.name() == 'svg:g': 699 if s.name() == 'svg:g':
587 # Parse the translate or matrix 700 # Parse the translate or matrix
588 sm = self.parseTransform(s) 701 sm = self.parseTransform(s)
589 dm = self.parseTransform(d) 702 dm = self.parseTransform(d)
590 print "g", (dm[2]-sm[2])*p,(dm[5]-sm[5])*p 703 top.setAttribute("transform","translate(%g,%g)" % ((dm[2]-sm[2])*p,(dm[5]-sm[5])*p))
591 top.setAttribute("transform","translate(%g,%g)" % ((dm[2]-sm[2])*p,(dm[5]-sm[5])*p),True)
592 else: 704 else:
593 try: 705 try:
594 sx = float(s.attribute("x")) 706 sx = float(s.attribute("x"))
595 sy = float(s.attribute("y")) 707 sy = float(s.attribute("y"))
596 dx = float(d.attribute("x")) 708 dx = float(d.attribute("x"))
597 dy = float(d.attribute("y")) 709 dy = float(d.attribute("y"))
598 tx = (dx-sx)*p 710 tx = (dx-sx)*p
599 ty = (dy-sy)*p 711 ty = (dy-sy)*p
600 print tx,ty 712 print tx,ty
601 top.setAttribute("transform","translate(%g,%g)" % (tx,ty),True) 713 top.setAttribute("transform","translate(%g,%g)" % (tx,ty))
602 except: 714 except:
603 #traceback.print_exc() 715 #traceback.print_exc()
604 pass 716 pass
605 pass 717 pass
606 elif typ == 'scale': 718 elif typ == 'scale':
607 newobj = s.duplicate(self.desktop.doc().rdoc) 719 newobj = s.duplicate(self.document)
608 top = self.desktop.doc().rdoc.createElement("svg:g") 720 top = self.document.createElement("svg:g")
609 top.appendChild(newobj) 721 top.appendChild(newobj)
610 obj.appendChild(top) 722 obj.appendChild(top)
723
724 print s,d
611 if s.name() == 'svg:g': 725 if s.name() == 'svg:g':
612 # Parse the translate or matrix 726 # Parse the translate or matrix
727 #
728 # D = B inv(A)
729 try:
730 item = self.nodeToItem[s.attribute("id")]
731 (ox,oy) = item.getCenter()
732 except:
733 ox = 0
734 oy = 0
735 try:
736 item = self.nodeToItem[d.attribute("id")]
737 (dx,dy) = item.getCenter()
738 except:
739 dx = 0
740 dy = 0
741
613 sm = self.parseTransform(s) 742 sm = self.parseTransform(s)
743 ss = self.decomposition(sm)
614 dm = self.parseTransform(d) 744 dm = self.parseTransform(d)
615 # r(1)*A = B 745 dd = self.decomposition(dm)
616 # ==> r(1) = B * inv(A) 746 sx = ss[0]*(1-p)+dd[0]*p
617 r1 = self.mulA(dm,self.invA(sm)) 747 sy = ss[1]*(1-p)+dd[1]*p
618 t0 = 1+ (r1[0]-1)*p 748 a = ss[2]*(1-p)+dd[2]*p
619 t1 = r1[1]*p 749 tx = sx*(1-p)+dx*p
620 t2 = r1[2]*p 750 ty = sy*(1-p)+dy*p
621 t3 = 1+(r1[3]-1)*p 751 #m = self.mulA([math.cos(a),-math.sin(a),math.sin(a),math.cos(a),0,0],[sx,0,0,sy,0,0])
622 t4 = r1[4]*p 752 m = [sx,0,0,sy,0,0]
623 t5 = r1[5]*p 753 m = self.mulA(m,[1,0,0,1,-ox,-oy])
624 754 m = [1,0,0,1,-ox,-oy]
625 print "scale: %g %g %g %g %g %g" % (t0,t1,t2,t3,t4,t5) 755 if dd[0] != ss[0]:
626 top.setAttribute("transform","matrix(%g,%g,%g,%g,%g,%g)" % (t0,t1,t2,t3,t4,t5),True) 756 top.setAttribute("transform","matrix(%g,%g,%g,%g,%g,%g)" % (m[0],m[1],m[2],m[3],m[4],m[5]))
627 else: 757 else:
628 try: 758 try:
629 sw = float(s.attribute("width")) 759 sw = float(s.attribute("width"))
630 sh = float(s.attribute("height")) 760 sh = float(s.attribute("height"))
631 dw = float(d.attribute("width")) 761 dw = float(d.attribute("width"))
632 dh = float(d.attribute("height")) 762 dh = float(d.attribute("height"))
633 tx = (dw-sw)*p+sw 763 tx = (dw-sw)*p+sw
634 ty = (dh-sh)*p+sh 764 ty = (dh-sh)*p+sh
635 print tx,ty 765 print tx,ty
636 top.setAttribute("transform","matrix(%g,0,0,%g,0,0)" % (tx,ty),True) 766 top.setAttribute("transform","matrix(%g,0,0,%g,0,0)" % (tx,ty))
637 except: 767 except:
638 traceback.print_exc() 768 traceback.print_exc()
639 pass 769 pass
640 pass 770 pass
641 771
757 if frameline.node.label()==None: 887 if frameline.node.label()==None:
758 frameline.label.set_text('???') 888 frameline.label.set_text('???')
759 else: 889 else:
760 frameline.label.set_text(frameline.node.label()) 890 frameline.label.set_text(frameline.node.label())
761 for scene in layer.scenes: 891 for scene in layer.scenes:
762 frameline.add_keyframe(scene.start-1,scene.node.repr) 892 frameline.add_keyframe(scene.start-1,scene.node)
763 if scene.start != scene.end: 893 if scene.start != scene.end:
764 frameline.add_keyframe(scene.end-1,scene.node.repr) 894 frameline.add_keyframe(scene.end-1,scene.node)
765 frameline.tween(scene.start-1,scene.type) 895 frameline.tween(scene.start-1,scene.type)
766 pass 896 pass
767 pass 897 pass
768 pass 898 pass
769 899
796 return 926 return
797 last_key = key 927 last_key = key
798 i = i + 1 928 i = i + 1
799 def duplicateSceneGroup(self,gid): 929 def duplicateSceneGroup(self,gid):
800 # Search for the duplicated group 930 # Search for the duplicated group
801 doc = self.desktop.doc().root() 931 doc = self.dom
802 rdoc = self.desktop.doc().rdoc 932 rdoc = self.document
803 orig = None 933 orig = None
804 for node in doc.childList(): 934 for node in doc.childList():
805 if node.repr.name() == 'svg:g': 935 if node.name() == 'svg:g':
806 for t in node.childList(): 936 for t in node.childList():
807 if t.repr.name() == "svg:g": 937 if t.name() == "svg:g":
808 if t.repr.attribute("id") == gid: 938 if t.attribute("id") == gid:
809 orig = t.repr 939 orig = t
810 break 940 break
811 if orig == None: 941 if orig == None:
812 return None 942 return None
813 ns = orig.duplicate(rdoc) 943 ns = orig.duplicate(rdoc)
814 gid = self.last_line.node.label()+self.newID() 944 gid = self.last_line.node.label()+self.newID()
815 self.ID[gid]=1 945 self.ID[gid]=1
816 ns.setAttribute("id",gid,True) 946 ns.setAttribute("id",gid)
817 ns.setAttribute("inkscape:groupmode","layer",True) 947 ns.setAttribute("inkscape:groupmode","layer")
818 self.last_line.node.repr.appendChild(ns) 948 self.last_line.node.appendChild(ns)
819 return ns 949 return ns
820 950
821 def doEditScene(self,w): 951 def doEditScene(self,w):
822 self.setCurrentScene(self.last_frame+1) 952 self.setCurrentScene(self.last_frame+1)
823 self.selectSceneObject(self.last_line,self.last_frame+1) 953 self.selectSceneObject(self.last_line,self.last_frame+1)
839 self.extendScene() 969 self.extendScene()
840 #self.grid.show_all() 970 #self.grid.show_all()
841 pass 971 pass
842 def changeObjectLabel(self,w): 972 def changeObjectLabel(self,w):
843 o = self.desktop.selection.list()[0] 973 o = self.desktop.selection.list()[0]
844 o.repr.setAttribute("inkscape:label", self.nameEditor.get_text(), True) 974 o.setAttribute("inkscape:label", self.nameEditor.get_text())
845 def addNameEditor(self,hbox): 975 def addNameEditor(self,hbox):
846 self.nameEditor = gtk.Entry(max=40) 976 self.nameEditor = gtk.Entry(max=40)
847 hbox.pack_start(self.nameEditor,expand=False,fill=False) 977 hbox.pack_start(self.nameEditor,expand=False,fill=False)
848 self.editDone = gtk.Button('Set') 978 self.editDone = gtk.Button('Set')
849 hbox.pack_start(self.editDone,expand=False,fill=False) 979 hbox.pack_start(self.editDone,expand=False,fill=False)
921 def onOK(self,event): 1051 def onOK(self,event):
922 self.OK = True 1052 self.OK = True
923 gtk.main_quit() 1053 gtk.main_quit()
924 pass 1054 pass
925 1055
926 def updateUI(self): 1056 def updateUI(self,node=None,arg=None):
927 if self.last_update!= None: 1057 if self.last_update!= None:
928 glib.source_remove(self.last_update) 1058 glib.source_remove(self.last_update)
929 self.last_update = glib.timeout_add(300,self.show) 1059 self.last_update = glib.timeout_add(300,self.show)
930 def show(self): 1060 def show(self):
931 self.OK = True 1061 self.OK = True
1062 self.dom = self.desktop.doc().root()
1063 self.document = self.desktop.doc().rdoc
932 self.parseScene() 1064 self.parseScene()
933 self._create_framelines() 1065 self._create_framelines()
934 self._update_framelines() 1066 self._update_framelines()
935 if self.top == None: 1067 if self.top == None:
936 self.top = gtk.VBox(False,0) 1068 self.top = gtk.VBox(False,0)