comparison pyink/domview.py @ 1301:18af917cf855

Add component_manager as a mix-in of domview
author Thinker K.F. Li <thinker@codemud.net>
date Wed, 19 Jan 2011 01:28:43 +0800
parents 6949e2b6cae2
children c53331c55a23
comparison
equal deleted inserted replaced
1300:2a35a1cb6cdf 1301:18af917cf855
1 import random 1 import random
2 import dom_event 2 import dom_event
3 from tween import TweenObject 3 from tween import TweenObject
4
4 5
5 class Layer: 6 class Layer:
6 def __init__(self, node): 7 def __init__(self, node):
7 self.scenes = [] 8 self.scenes = []
8 self.group = node 9 self.group = node
9 pass 10 pass
10 pass 11 pass
12
13
14 class Timeline(object):
15 def __init__(self, scenes_node):
16 self.scenes_node = scenes_node
17 pass
18
19 def name(self):
20 name = self.node.getAttribute('name')
21 return name
22 pass
23
24
25 class Component(object):
26 #
27 # \param comp_node is None for main component.
28 #
29 def __init__(self, comp_mgr, comp_node):
30 self._comp_mgr = comp_mgr
31 self.node = comp_node
32 self.layers = []
33 self.timelines = []
34
35 if comp_node:
36 self._initialize_comp()
37 pass
38 pass
39
40 def _initialize_comp(self):
41 comp_node = self.node
42 for child in comp_node.childList():
43 if child.name() == 'ns0:scenes':
44 break
45 pass
46 else: # no any ns0:scenes
47 scenes_node = doc.createElementById('ns0:scenes')
48 scenes_node.setAttribute('name', 'default')
49 node_id = self._comp_mgr.new_id()
50 scenes_node.setAttribute('id', node_id)
51 comp_node.appendChild(scenes_node)
52 pass
53 pass
54
55 def name(self):
56 if self.node:
57 name = self.node.getAttribute('name')
58 else:
59 name = 'main'
60 pass
61 return name
62
63 def all_timeline_names(self):
64 names = [tl.name() for tl in self.timelines]
65 return names
66
67 def parse_timelines(self):
68 if self.node:
69 assert self.node.name() == 'ns0:component'
70 pass
71
72 comp_node = self.node
73 for child in comp_node.childList:
74 if child.name() == 'ns0:scenes':
75 tl = Timeline(child)
76 self.timelines.append(tl)
77 pass
78 pass
79 pass
80
81 def get_timeline(self, name):
82 for tl in self.timelines:
83 if tl.name() == name:
84 return tl
85 pass
86 raise Value, 'invalid timeline name - %s' % (name)
87
88 def has_timeline(self, name):
89 for tl in self.timelines:
90 if tl.name() == name:
91 return True
92 pass
93 return False
94
95 def add_timeline(self, name):
96 if self.has_timeline(name):
97 raise ValueError, \
98 'try add a timeline with duplicated name - %s' % (name)
99
100 doc = self._comp_mgr._doc
101 comp_node = self.node
102
103 scenes_node = doc.createElementById('ns0:scenes')
104 scenes_node.setAttribute('name', name)
105 node_id = self._comp_mgr.new_id()
106 scenes_node.setAttribute('id', node_id)
107
108 comp_node.appendChild(scenes_node)
109 pass
110
111 ## \brief Add a timeline for an existed scenes node.
112 #
113 def add_timeline_scenes(self, scenes_node):
114 tl = Timeline(scenes_node)
115 name = tl.name()
116 if self.has_timeline(name):
117 raise ValueError, \
118 'name of scenes node of a timeline is duplicated'
119 pass
120
121 def rm_timeline(self, name):
122 for i, tl in enumerate(self.timelines):
123 if tl.name() == name:
124 del self.timelines[i]
125 return
126 pass
127 raise ValueError, 'try to remove a non-existed timeline - %s' % (name)
128 pass
129
130
131 ## \brief A mix-in for class domview for management of components.
132 #
133 class component_manager(object):
134 def __init__(self):
135 self._components = []
136 self._comp_names = set()
137 self._main_comp = None
138 self._cur_comp = None
139 self._cur_timeline = None
140 pass
141
142 def _set_main_component(self):
143 comp = Component(self, None)
144 comp.layers = self._layers
145 scenes_node = self._scenes_node
146 timeline = Timeline(scenes_node)
147 comp.timelines = [timeline]
148
149 self._components.append(comp)
150 self._comp_names.add('main')
151
152 self._main_comp = comp
153 self._cur_comp = comp
154 pass
155
156 def _parse_components(self):
157 comp_names = self._comp_names
158 components_node = self._components_node
159 for child in components_node.childList():
160 child_name = child.name()
161 if child_name != 'ns0:component':
162 continue
163 if child_name in comp_names:
164 raise ValueError, 'duplicate component name %s' % (child_name)
165
166 comp = Component(self, child)
167 comp.parse_timelines()
168
169 self._components.append(comp)
170 comp_names.add(child_name)
171 pass
172 pass
173
174 def all_comp_names(self):
175 return list(self._comp_names)
176
177 def has_component(self, name):
178 return name in self._comp_names
179
180 def switch_component(self, comp_name):
181 for comp in self._components:
182 if comp.name() == comp_name:
183 self._cu_comp = comp
184 self._layers = comp.layers
185
186 first_name = comp.all_timeline_names()[0]
187 self.switch_timeline(self, first_name)
188 return
189 pass
190 raise ValueError, 'not such component %s' % (comp_name)
191
192 def add_component(self, comp_name):
193 if self.has_component(comp_name):
194 raise ValueError, \
195 'try add a component with existed name %s' % (comp_name)
196
197 comp_node = self._doc.createElementById('ns0:component')
198 comp_id = self.new_id()
199 comp_node.setAttribute('id', comp_id)
200 comp_node.setAttribute('name', comp_name)
201 self._components_node.appendChild(comp_node)
202
203 comp = Component(self, comp_node)
204 comp.parse_timelines()
205
206 self._components.append(comp)
207 self._comp_names.add(comp_name)
208 pass
209
210 def add_component_node(self, comp_node):
211 comp = Component(self, comp_node)
212 comp_name = comp.name()
213 if self.has_component(comp_name):
214 raise ValueError, \
215 'the name of a ns0:component is duplicated'
216
217 self._components.append(comp)
218 self._comp_names.add(comp_name)
219 pass
220
221 def rm_component(self, comp_name):
222 if not self.has_component(comp_name):
223 raise ValueError, 'try to remove a non-existed component'
224
225 self._comp_names.remove(comp_name)
226 for i, comp in enumerate(self._components):
227 if comp.name() == comp_name:
228 del self._components[i]
229 self._comp_names.remove(comp_name)
230 break
231 pass
232 pass
233
234 def switch_timeline(self, timeline_name):
235 tl = self._cur_comp.get_timeline(timeline_name)
236 self._cur_timeline = tl
237 self._scenes_node = tl.scenes_node # of class domview
238
239 self._monitor_rescan() # from domview_monitor
240 pass
241
242 def add_timeline(self, timeline_name):
243 self._cur_comp.add_timeline(timeline_name)
244 pass
245
246 def rm_timeline(self, timeline_name):
247 self._cur_comp.rm_timeline(timeline_name)
248 pass
249 pass
250
11 251
12 ## \brief Monitor changes of DOM-tree. 252 ## \brief Monitor changes of DOM-tree.
13 # 253 #
14 # This class monitors DOM-tree to maintain _maxframe and maps for node ID to 254 # This class monitors DOM-tree to maintain _maxframe and maps for node ID to
15 # node and scene group ID to scene node. 255 # node and scene group ID to scene node.
32 dom_event.addEventListener(doc, 'DOMNodeRemoved', 272 dom_event.addEventListener(doc, 'DOMNodeRemoved',
33 self._on_remove_node, None) 273 self._on_remove_node, None)
34 dom_event.addEventListener(doc, 'DOMAttrModified', 274 dom_event.addEventListener(doc, 'DOMAttrModified',
35 self._on_attr_modified, None) 275 self._on_attr_modified, None)
36 pass 276 pass
277
278 ## \brief Rescan the tree.
279 #
280 def _monitor_rescan(self):
281 self._maxframe = 0
282 self._id2node = {}
283 self._group2scene = {}
284
285 self._collect_node_ids()
286 self._collect_all_scenes()
287 pass
37 288
38 def _on_insert_node(self, node, child): 289 def _on_insert_node(self, node, child):
39 for cchild in child.childList(): 290 for cchild in child.childList():
40 self._on_insert_node(child, cchild) 291 self._on_insert_node(child, cchild)
41 pass 292 pass
333 ns = "http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd" 584 ns = "http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd"
334 self._root.setAttribute("xmlns:ns0", ns) 585 self._root.setAttribute("xmlns:ns0", ns)
335 scenes_node = self._doc.createElement("ns0:scenes") 586 scenes_node = self._doc.createElement("ns0:scenes")
336 node.appendChild(scenes_node) 587 node.appendChild(scenes_node)
337 self._scenes_node = scenes_node 588 self._scenes_node = scenes_node
589 pass
590
591 for n in node.childList():
592 if n.name() == 'ns0:components':
593 self._components_node = n
594 break
595 pass
596 else:
597 components_node = self._doc.createElement("ns0:components")
598 node.appendChild(components_node)
599 self._components_node = components_node
338 pass 600 pass
339 pass 601 pass
340 602
341 def _parse_all_layers(self): 603 def _parse_all_layers(self):
342 root = self._root 604 root = self._root