Mercurial > MadButterfly
comparison inkscape/MB_Frame.py @ 236:55f86e2f8d40
Modify the format according to the new design.
author | wycc |
---|---|
date | Sat, 27 Dec 2008 10:18:33 +0800 |
parents | 889cdc5f23c5 |
children | db7f22ecd3ad |
comparison
equal
deleted
inserted
replaced
234:889cdc5f23c5 | 236:55f86e2f8d40 |
---|---|
4 import gtk | 4 import gtk |
5 from copy import deepcopy | 5 from copy import deepcopy |
6 from lxml import etree | 6 from lxml import etree |
7 import random | 7 import random |
8 | 8 |
9 # In the inkscape, the top layer group are treated as layer. The Mad butter fly add another structure under the layer as frame. It means that each layer can has multiple frame. | 9 # Please refer to http://www.assembla.com/wiki/show/MadButterfly/Inkscape_extention for the designed document. |
10 # Like the layer, the frames are represented by special groups. All groups directly under a layer will be treated as frames. However, a group may be spanned for more than one | |
11 # frame. For example | |
12 # <g id="layer1"> | |
13 # <g id="g1222"> | |
14 # </g> | |
15 # <g id="g1234" scene="1"> | |
16 # </g> | |
17 # <g id="g1235" scene="2-7" current="3"> | |
18 # </g> | |
19 # <g id="g1333"/> | |
20 # </g> | |
21 # This will stand for 7 scenes. Scene 1 and scene 2 are key scenes. 3,4,5,6,7 are filled scenes. The current scene is defined by the 'current' attribute. In the above example, it is 3. | |
22 # All elements without scene attributes are items in the current scene. | |
23 # Therefore, when we switch scene, we will move all items into the current scene and then move items out from the new scene. | |
24 # | |
25 # In the inkscape extention, we will provide an grid for users to select the current scene or change the scene structure. Users are allowed to | |
26 # Insert a new key scene | |
27 # Delete a key scene | |
28 # Insert a filled scene | |
29 # Delete a filled scene | |
30 # Select a scene for edit. | |
31 # | |
32 # When user select a scene to edit, we will hide all scenes which is not in the selected scene. For example, if we select scene 4, g1234 will be hidden and g1235 and g1236 will | |
33 # be displayed. | |
34 | |
35 | 10 |
36 | 11 |
37 # Algorithm: | 12 # Algorithm: |
38 # | 13 # |
39 # We will parse the first two level of the SVG DOM. collect a table of layer and scene. | 14 # We will parse the first two level of the SVG DOM. collect a table of layer and scene. |
75 def dump(self,node,l=0): | 50 def dump(self,node,l=0): |
76 print " " * l*2,"<", node.tag, self.dumpattr(node),">" | 51 print " " * l*2,"<", node.tag, self.dumpattr(node),">" |
77 for n in node: | 52 for n in node: |
78 self.dump(n,l+1) | 53 self.dump(n,l+1) |
79 print " " * l * 2,"/>" | 54 print " " * l * 2,"/>" |
55 def parseMetadata(self,node): | |
56 for n in node: | |
57 if n.tag == '{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scenes': | |
58 self.scenemap={} | |
59 cur = int(n.get("current")) | |
60 self.current = cur | |
61 | |
62 for s in n: | |
63 if s.tag == '{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scene': | |
64 try: | |
65 start = int(s.get("start")) | |
66 except: | |
67 continue | |
68 try: | |
69 end = s.get("end") | |
70 if end == None: | |
71 end = start | |
72 except: | |
73 end = start | |
74 link = s.get("ref") | |
75 self.scenemap[link] = [int(start),int(end)] | |
76 if cur >= start and cur <= end: | |
77 self.currentscene = link | |
78 | |
79 pass | |
80 pass | |
81 pass | |
82 pass | |
83 | |
84 | |
80 | 85 |
81 def parseScene(self): | 86 def parseScene(self): |
82 """ | 87 """ |
83 In this function, we will collect all items for the current scene and then relocate them back to the appropriate scene object. | 88 In this function, we will collect all items for the current scene and then relocate them back to the appropriate scene object. |
84 """ | 89 """ |
85 self.layer = [] | 90 self.layer = [] |
86 current_scene = [] | |
87 oldscene = None | |
88 for node in self.document.getroot(): | 91 for node in self.document.getroot(): |
89 if node.tag == '{http://www.w3.org/2000/svg}g': | 92 if node.tag == '{http://www.w3.org/2000/svg}metadata': |
93 self.parseMetadata(node) | |
94 elif node.tag == '{http://www.w3.org/2000/svg}g': | |
95 oldscene = None | |
90 #print layer.attrib.get("id") | 96 #print layer.attrib.get("id") |
91 lyobj = Layer(node) | 97 lyobj = Layer(node) |
92 self.layer.append(lyobj) | 98 self.layer.append(lyobj) |
99 lyobj.current_scene = [] | |
93 for scene in node: | 100 for scene in node: |
94 if scene.tag == '{http://www.w3.org/2000/svg}g': | 101 if scene.tag == '{http://www.w3.org/2000/svg}g': |
95 s = scene.get("scene") | 102 try: |
96 if s == None: | 103 scmap = self.scenemap[scene.get("id")] |
97 # group without scene is part of the current scene | 104 if scmap == None: |
98 current_scene.append(scene) | 105 lyobj.current_scene.append(scene) |
106 continue | |
107 if self.current <= scmap[1] and self.current >= scmap[0]: | |
108 oldscene = scene | |
109 except: | |
110 lyobj.current_scene.append(scene) | |
99 continue | 111 continue |
100 range = s.split('-') | 112 |
101 | 113 lyobj.scene.append(Scene(scene,scmap[0],scmap[1])) |
102 cur = scene.get("current") | |
103 try: | |
104 self.current_scene = int(cur) | |
105 del scene.attrib["current"] | |
106 oldscene = scene | |
107 except: | |
108 pass | |
109 if len(range) == 1: | |
110 #print " scene %d" % int(range[0]) | |
111 lyobj.scene.append(Scene(scene,range[0],range[0])) | |
112 elif len(range) == 2: | |
113 #print " scene%d-%d" % (int(range[0]),int(range[1])) | |
114 lyobj.scene.append(Scene(scene,range[0],range[1])) | |
115 else: | 114 else: |
116 current_scene.append(scene) | 115 lyobj.current_scene.append(scene) |
116 pass | |
117 pass | |
118 | |
119 if oldscene != None: | |
120 # Put the objects back to the current scene | |
121 for o in lyobj.current_scene: | |
122 #print o.tag | |
123 oldscene.append(o) | |
117 pass | 124 pass |
118 pass | 125 pass |
119 pass | 126 pass |
120 pass | 127 pass |
121 | |
122 if oldscene != None: | |
123 # Put the objects back to the current scene | |
124 #print "Add elements back" | |
125 for o in current_scene: | |
126 #print o.tag | |
127 oldscene.append(o) | |
128 | 128 |
129 self.collectID() | 129 self.collectID() |
130 #self.dumpID() | 130 #self.dumpID() |
131 def collectID(self): | 131 def collectID(self): |
132 self.ID = {} | 132 self.ID = {} |
181 btn.nLayer = y | 181 btn.nLayer = y |
182 self.grid.remove(self.last_cell) | 182 self.grid.remove(self.last_cell) |
183 self.grid.attach(btn, x,x+1,y,y+1,0,0,0,0) | 183 self.grid.attach(btn, x,x+1,y,y+1,0,0,0,0) |
184 return | 184 return |
185 if len(layer.scene) > 0: | 185 if len(layer.scene) > 0: |
186 last = layer.scene[len(layer.scene)-1] | 186 last = nth |
187 for x in range(last.end+1, nth): | 187 lastscene = None |
188 for s in layer.scene: | |
189 if s.end < nth and last < s.end: | |
190 last = s.end | |
191 lastscene = s | |
192 for x in range(last+1, nth): | |
188 btn = self.newCell('fill.png') | 193 btn = self.newCell('fill.png') |
189 btn.nScene = x | 194 btn.nScene = x |
190 btn.layer = layer | 195 btn.layer = layer.node.get('id') |
191 btn.nLayer = y | 196 btn.nLayer = y |
192 self.grid.attach(btn, x, x+1, y , y+1,0,0,0,0) | 197 self.grid.attach(btn, x, x+1, y , y+1,0,0,0,0) |
193 last.end = nth-1 | 198 if lastscene == None: |
194 newscene = Scene(deepcopy(s.node),nth,nth) | 199 node = etree.Element('{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scene') |
195 newscene.node.set("id",self.newID()) | 200 node.set("id", self.newID()) |
201 newscene = Scene(node,nth,nth) | |
202 else: | |
203 lastscene.end = nth-1 | |
204 newscene = Scene(deepcopy(lastscene.node),nth,nth) | |
205 newscene.node.set("id",self.newID()) | |
196 layer.scene.append(newscene) | 206 layer.scene.append(newscene) |
197 btn = self.newCell('start.png') | 207 btn = self.newCell('start.png') |
198 x = self.last_cell.nScene | 208 x = self.last_cell.nScene |
199 y = self.last_cell.nLayer | 209 y = self.last_cell.nLayer |
200 btn.nScene = nth | 210 btn.nScene = nth |
211 btn.layer = layer.node.get('id') | |
212 btn.nLayer = y | |
213 self.grid.attach(btn, x, x+1, y, y+1,0,0,0,0) | |
214 else: | |
215 # This is the first scene in the layer | |
216 node = etree.Element('{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scene') | |
217 node.set("id", self.newID()) | |
218 newscene = Scene(node,nth,nth) | |
219 layer.scene.append(newscene) | |
220 btn = self.newCell('start.png') | |
221 btn.nScene = nth | |
201 btn.layer = layer | 222 btn.layer = layer |
202 btn.nLayer = y | 223 btn.nLayer = y |
203 self.grid.attach(btn, x, x+1, y, y+1,0,0,0,0) | 224 self.grid.attach(btn, x, x+1, y, y+1,0,0,0,0) |
204 | 225 |
205 | 226 |
227 | |
228 | |
206 def removeKeyScene(self): | 229 def removeKeyScene(self): |
207 nth = self.last_cell.nScene | 230 nth = self.last_cell.nScene |
208 layer = self.getLayer(self.last_cell.layer) | 231 try: |
232 layer = self.getLayer(self.last_cell.layer.node.get('id')) | |
233 except: | |
234 return | |
209 x = self.last_cell.nScene | 235 x = self.last_cell.nScene |
210 y = self.last_cell.nLayer | 236 y = self.last_cell.nLayer |
211 # We can not remove the key scene at the first scene | |
212 if nth == 1: return | |
213 for i in range(0,len(layer.scene)): | 237 for i in range(0,len(layer.scene)): |
214 s = layer.scene[i] | 238 s = layer.scene[i] |
215 if nth == s.start: | 239 if nth == s.start: |
216 layer.scene[i-1].end = s.end | 240 if i == 0: |
217 layer.scene.remove(s) | 241 for j in range(s.start,s.end+1): |
218 btn = self.newCell('fill.png') | 242 btn = self.newCell('empty.png') |
219 btn.nScene = nth | 243 btn.nScene = nth |
220 btn.layer = layer | 244 btn.layer = layer |
221 btn.nLayer = y | 245 btn.nLayer = y |
222 self.grid.attach(btn, x,x+1,y,y+1,0,0,0,0) | 246 self.grid.attach(btn, j,j+1,y,y+1,0,0,0,0) |
247 layer.scene.remove(s) | |
248 else: | |
249 if s.start == layer.scene[i-1].end+1: | |
250 # If the start of the delete scene segment is the end of the last scene segmenet, convert all scenes in the deleted | |
251 # scene segmenet to the last one | |
252 layer.scene[i-1].end = s.end | |
253 layer.scene.remove(s) | |
254 btn = self.newCell('fill.png') | |
255 | |
256 btn.nScene = nth | |
257 btn.layer = layer | |
258 btn.nLayer = y | |
259 self.grid.attach(btn, x,x+1,y,y+1,0,0,0,0) | |
260 else: | |
261 # Convert all scenes into empty cell | |
262 layer.scene.remove(s) | |
263 for j in range(s.start,s.end+1): | |
264 btn = self.newCell('empty.png') | |
265 btn.nScene = nth | |
266 btn.layer = layer | |
267 btn.nLayer = y | |
268 self.grid.attach(btn, j,j+1,y,y+1,0,0,0,0) | |
269 | |
270 | |
223 return | 271 return |
224 | 272 |
225 def extendScene(self,layer,nth): | 273 def extendScene(self,layer,nth): |
226 layer = self.getLayer(layer) | 274 layer = self.getLayer(layer) |
227 if layer == None: return | 275 if layer == None: return |
230 if nth >= layer.scene[i].start and nth < layer.scene[i+1].start: | 278 if nth >= layer.scene[i].start and nth < layer.scene[i+1].start: |
231 layer.scene[i].end = nth | 279 layer.scene[i].end = nth |
232 if len(layer.scene) > 0: | 280 if len(layer.scene) > 0: |
233 layer.scene[len(layer.scene)-1].end = nth | 281 layer.scene[len(layer.scene)-1].end = nth |
234 def setCurrentScene(self,nth): | 282 def setCurrentScene(self,nth): |
283 self.current = nth | |
235 for layer in self.layer: | 284 for layer in self.layer: |
236 for s in layer.scene: | 285 for s in layer.scene: |
237 if nth >= s.start and nth <= s.end: | 286 if nth >= s.start and nth <= s.end: |
238 s.node.set("style","") | 287 s.node.set("style","") |
239 s.node.set("current","%d"%nth) | |
240 #print "Put the elemenets out" | 288 #print "Put the elemenets out" |
241 layer.nodes = [] | 289 layer.nodes = [] |
242 | 290 |
243 for o in s.node: | 291 for o in s.node: |
244 #print " ",o.tag | 292 #print " ",o.tag |
248 else: | 296 else: |
249 s.node.set("style","display:none") | 297 s.node.set("style","display:none") |
250 def generate(self): | 298 def generate(self): |
251 newdoc = deepcopy(self.document) | 299 newdoc = deepcopy(self.document) |
252 root = newdoc.getroot() | 300 root = newdoc.getroot() |
301 has_scene = False | |
253 for n in root: | 302 for n in root: |
303 if n.tag == '{http://www.w3.org/2000/svg}metadata': | |
304 for nn in n: | |
305 if nn.tag == '{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scenes': | |
306 nn.clear() | |
307 nn.set("current", "%d" % self.current) | |
308 scenes = [] | |
309 for l in self.layer: | |
310 for s in l.scene: | |
311 id = s.node.get("id") | |
312 scene = etree.Element('{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scene') | |
313 scene.set("ref", id) | |
314 if s.start == s.end: | |
315 scene.set("start", "%d" % s.start) | |
316 else: | |
317 scene.set("start", "%d" % s.start) | |
318 scene.set("end", "%d" % s.end) | |
319 | |
320 scenes.append(scene) | |
321 for s in scenes: | |
322 nn.append(s) | |
323 has_scene = True | |
324 if has_scene == False: | |
325 scenes = etree.Element('{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scenes') | |
326 scenes.set("current","%d" % self.current) | |
327 for l in self.layer: | |
328 for s in l.scene: | |
329 scene = etree.Element('{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scene') | |
330 scene.set("ref", s.node.get("id")) | |
331 if s.start == s.end: | |
332 scene.set("start", "%d" % s.start) | |
333 else: | |
334 scene.set("start", "%d" % s.start) | |
335 scene.set("end", "%d" % s.end) | |
336 scenes.append(scene) | |
337 n.append(scenes) | |
254 if n.tag == '{http://www.w3.org/2000/svg}g': | 338 if n.tag == '{http://www.w3.org/2000/svg}g': |
255 root.remove(n) | 339 root.remove(n) |
256 | 340 |
257 for l in self.layer: | 341 for l in self.layer: |
258 # Duplicate all attribute of the layer | 342 # Duplicate all attribute of the layer |
264 root.append(lnode) | 348 root.append(lnode) |
265 for s in l.scene: | 349 for s in l.scene: |
266 snode = etree.Element("{http://www.w3.org/2000/svg}g") | 350 snode = etree.Element("{http://www.w3.org/2000/svg}g") |
267 for a,v in s.node.attrib.items(): | 351 for a,v in s.node.attrib.items(): |
268 snode.set(a,v) | 352 snode.set(a,v) |
269 if s.start == s.end: | |
270 snode.set("scene", "%d" % s.start) | |
271 else: | |
272 snode.set("scene","%d-%d" % (s.start,s.end)) | |
273 for n in s.node: | 353 for n in s.node: |
274 snode.append(deepcopy(n)) | 354 snode.append(deepcopy(n)) |
275 lnode.append(snode) | 355 lnode.append(snode) |
276 self.document = newdoc | 356 self.document = newdoc |
277 def newCell(self,file): | 357 def newCell(self,file): |