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