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