Mercurial > MadButterfly
comparison pyink/domview.py @ 1342:972d749b9656
Move component_manager to a separated object.
- component_manager is a mixin for domview.
- domview inherit component_manager to mixing-in component_manager.
- There is no boundary between component_manager and domview, hard
to be managed and reused.
- component_manager is a separated object that hold a reference to
corresponding domview.
- domview delegate attribute accessing to component_manager object to
expose attributes and methods of component_manager. (__getattr__())
- component_manager is still a mix-in of domview.
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Tue, 08 Feb 2011 13:05:07 +0800 |
parents | 10d5f06f7566 |
children | c2fbae4f0adc |
comparison
equal
deleted
inserted
replaced
1341:599b606c4669 | 1342:972d749b9656 |
---|---|
46 | 46 |
47 class Component(object): | 47 class Component(object): |
48 # | 48 # |
49 # \param comp_node is None for main component. | 49 # \param comp_node is None for main component. |
50 # | 50 # |
51 def __init__(self, comp_mgr, comp_node): | 51 def __init__(self, domview, comp_node): |
52 self._comp_mgr = comp_mgr | 52 self._domview = domview |
53 self.node = comp_node | 53 self.node = comp_node |
54 self.layers = [] | 54 self.layers = [] |
55 self.timelines = [] | 55 self.timelines = [] |
56 | 56 |
57 if comp_node: | 57 if comp_node: |
64 for child in comp_node.childList(): | 64 for child in comp_node.childList(): |
65 if child.name() == 'ns0:scenes': | 65 if child.name() == 'ns0:scenes': |
66 break | 66 break |
67 pass | 67 pass |
68 else: # no any ns0:scenes | 68 else: # no any ns0:scenes |
69 doc = self._comp_mgr._doc | 69 doc = self._domview._doc |
70 scenes_node = doc.createElement('ns0:scenes') | 70 scenes_node = doc.createElement('ns0:scenes') |
71 scenes_node.setAttribute('name', 'default') | 71 scenes_node.setAttribute('name', 'default') |
72 | 72 |
73 node_id = self._comp_mgr.new_id() | 73 node_id = self._domview.new_id() |
74 scenes_node.setAttribute('id', node_id) | 74 scenes_node.setAttribute('id', node_id) |
75 | 75 |
76 comp_node.appendChild(scenes_node) | 76 comp_node.appendChild(scenes_node) |
77 pass | 77 pass |
78 pass | 78 pass |
124 def add_timeline(self, name): | 124 def add_timeline(self, name): |
125 if self.has_timeline(name): | 125 if self.has_timeline(name): |
126 raise ValueError, \ | 126 raise ValueError, \ |
127 'try add a timeline with duplicated name - %s' % (name) | 127 'try add a timeline with duplicated name - %s' % (name) |
128 | 128 |
129 doc = self._comp_mgr._doc | 129 doc = self._domview._doc |
130 comp_node = self.node | 130 comp_node = self.node |
131 | 131 |
132 scenes_node = doc.createElement('ns0:scenes') | 132 scenes_node = doc.createElement('ns0:scenes') |
133 scenes_node.setAttribute('name', name) | 133 scenes_node.setAttribute('name', name) |
134 node_id = self._comp_mgr.new_id() | 134 node_id = self._domview.new_id() |
135 scenes_node.setAttribute('id', node_id) | 135 scenes_node.setAttribute('id', node_id) |
136 | 136 |
137 comp_node.appendChild(scenes_node) | 137 comp_node.appendChild(scenes_node) |
138 | 138 |
139 tl = Timeline(scenes_node) | 139 tl = Timeline(scenes_node) |
234 # FIXME: The root node is always the 'main' component. It is a | 234 # FIXME: The root node is always the 'main' component. It is a |
235 # special case with slightly different in structure. It should be | 235 # special case with slightly different in structure. It should be |
236 # removed and normalized to normal components. | 236 # removed and normalized to normal components. |
237 # | 237 # |
238 class component_manager(component_manager_ui_update): | 238 class component_manager(component_manager_ui_update): |
239 def __init__(self): | 239 def __init__(self, domview): |
240 super(component_manager, self).__init__() | |
240 self._components_node = None | 241 self._components_node = None |
241 self._components = [] | 242 self._components = [] |
242 self._comp_names = set() | 243 self._comp_names = set() |
243 self._main_comp = None | 244 self._main_comp = None |
244 self._cur_comp = None | 245 self._cur_comp = None |
245 self._cur_timeline = None | 246 self._cur_timeline = None |
246 self._components_group = None | 247 self._components_group = None |
248 | |
249 self._domview = domview | |
247 pass | 250 pass |
248 | 251 |
249 def _set_main_component(self): | 252 def _set_main_component(self): |
250 comp = Component(self, None) | 253 comp = Component(self._domview, None) |
251 comp.layers = self._layers | 254 comp.layers = self._domview._layers |
252 scenes_node = self._scenes_node | 255 scenes_node = self._domview._scenes_node |
253 timeline = Timeline(scenes_node) | 256 timeline = Timeline(scenes_node) |
254 comp.timelines = [timeline] | 257 comp.timelines = [timeline] |
255 | 258 |
256 self._components.append(comp) | 259 self._components.append(comp) |
257 self._comp_names.add('main') | 260 self._comp_names.add('main') |
267 if child_name != 'ns0:component': | 270 if child_name != 'ns0:component': |
268 continue | 271 continue |
269 if child_name in comp_names: | 272 if child_name in comp_names: |
270 raise ValueError, 'duplicate component name %s' % (child_name) | 273 raise ValueError, 'duplicate component name %s' % (child_name) |
271 | 274 |
272 comp = Component(self, child) | 275 comp = Component(self._domview, child) |
273 comp.parse_timelines() | 276 comp.parse_timelines() |
274 | 277 |
275 self._components.append(comp) | 278 self._components.append(comp) |
276 comp_names.add(child_name) | 279 comp_names.add(child_name) |
277 pass | 280 pass |
280 ## \brief To initialize subtree of metadata. | 283 ## \brief To initialize subtree of metadata. |
281 # | 284 # |
282 # This method is called by domview._init_metadata(). | 285 # This method is called by domview._init_metadata(). |
283 # | 286 # |
284 def _component_manager_init_metadata(self): | 287 def _component_manager_init_metadata(self): |
285 metadata_node = self._metadata_node | 288 metadata_node = self._domview._metadata_node |
286 | 289 |
287 # Make sure ns0:components in metadata | 290 # Make sure ns0:components in metadata |
288 for n in metadata_node.childList(): | 291 for n in metadata_node.childList(): |
289 if n.name() == 'ns0:components': | 292 if n.name() == 'ns0:components': |
290 self._components_node = n | 293 self._components_node = n |
291 break | 294 break |
292 pass | 295 pass |
293 else: | 296 else: |
294 components_node = self._doc.createElement("ns0:components") | 297 components_node = \ |
298 self._domview._doc.createElement("ns0:components") | |
295 metadata_node.appendChild(components_node) | 299 metadata_node.appendChild(components_node) |
296 self._components_node = components_node | 300 self._components_node = components_node |
297 pass | 301 pass |
298 | 302 |
299 # Make sure the group for containing components. | 303 # Make sure the group for containing components. |
300 for n in self._root.childList(): | 304 for n in self._domview._root.childList(): |
301 if n.name() != 'svg:g': | 305 if n.name() != 'svg:g': |
302 continue | 306 continue |
303 try: | 307 try: |
304 nlabel = n.getAttribute('inkscape:label') | 308 nlabel = n.getAttribute('inkscape:label') |
305 except: | 309 except: |
307 if nlabel == 'components': | 311 if nlabel == 'components': |
308 self._components_group | 312 self._components_group |
309 break | 313 break |
310 pass | 314 pass |
311 else: # no components group | 315 else: # no components group |
312 components_group = self._doc.createElement('svg:g') | 316 components_group = self._domview._doc.createElement('svg:g') |
313 components_group.setAttribute('inkscape:label', 'components') | 317 components_group.setAttribute('inkscape:label', 'components') |
314 gid = self.new_id() | 318 gid = self._domview.new_id() |
315 components_group.setAttribute('id', gid) | 319 components_group.setAttribute('id', gid) |
316 | 320 |
317 self._root.appendChild(components_group) | 321 self._domview._root.appendChild(components_group) |
318 self._components_group = components_group | 322 self._components_group = components_group |
319 pass | 323 pass |
320 pass | 324 pass |
321 | 325 |
322 def _start_component_manager(self): | 326 def _start_component_manager(self): |
325 self._parse_components() | 329 self._parse_components() |
326 | 330 |
327 self._cur_comp = self._main_comp | 331 self._cur_comp = self._main_comp |
328 tl = self._main_comp.get_timeline('default') | 332 tl = self._main_comp.get_timeline('default') |
329 self._cur_timeline = tl | 333 self._cur_timeline = tl |
330 self._scenes_node = tl.scenes_node | 334 self._domview._scenes_node = tl.scenes_node |
331 pass | 335 pass |
332 | 336 |
333 ## \brief Create component group | 337 ## \brief Create component group |
334 # | 338 # |
335 # A component group is a group with a layers group as child. | 339 # A component group is a group with a layers group as child. |
336 # The layers group is where layer groups is in. | 340 # The layers group is where layer groups is in. |
337 # | 341 # |
338 def _create_component_group(self): | 342 def _create_component_group(self): |
339 doc = self._doc | 343 doc = self._domview._doc |
340 group = doc.createElement('svg:g') | 344 group = doc.createElement('svg:g') |
341 gid = self.new_id() | 345 gid = self._domview.new_id() |
342 group.setAttribute('id', gid) | 346 group.setAttribute('id', gid) |
343 | 347 |
344 self._components_group.appendChild(group) | 348 self._components_group.appendChild(group) |
345 | 349 |
346 # Create layers group | 350 # Create layers group |
347 layers_group = doc.createElement('svg:g') | 351 layers_group = doc.createElement('svg:g') |
348 gid = self.new_id() | 352 gid = self._domview.new_id() |
349 layers_group.setAttribute('id', gid) | 353 layers_group.setAttribute('id', gid) |
350 layers_group.setAttribute('inkscape:label', 'layers') | 354 layers_group.setAttribute('inkscape:label', 'layers') |
351 group.appendChild(layers_group) | 355 group.appendChild(layers_group) |
352 | 356 |
353 return group | 357 return group |
357 # \param comp_name is the name of the created component. | 361 # \param comp_name is the name of the created component. |
358 # \param comp_group_id is the component group. | 362 # \param comp_group_id is the component group. |
359 # \return a ns0:component node. | 363 # \return a ns0:component node. |
360 # | 364 # |
361 def _create_component_node(self, comp_name, comp_group_id): | 365 def _create_component_node(self, comp_name, comp_group_id): |
362 comp_node = self._doc.createElement('ns0:component') | 366 comp_node = self._domview._doc.createElement('ns0:component') |
363 comp_id = self.new_id() | 367 comp_id = self._domview.new_id() |
364 comp_node.setAttribute('id', comp_id) | 368 comp_node.setAttribute('id', comp_id) |
365 comp_node.setAttribute('name', comp_name) | 369 comp_node.setAttribute('name', comp_name) |
366 comp_node.setAttribute('ref', comp_group_id) | 370 comp_node.setAttribute('ref', comp_group_id) |
367 self._components_node.appendChild(comp_node) | 371 self._components_node.appendChild(comp_node) |
368 return comp_node | 372 return comp_node |
379 raise ValueError, 'can not find component node - %s' % (comp_name) | 383 raise ValueError, 'can not find component node - %s' % (comp_name) |
380 | 384 |
381 ## \brief Create a layer group for give layer of a component. | 385 ## \brief Create a layer group for give layer of a component. |
382 # | 386 # |
383 def _create_comp_layer_group(self, layers_group, layer_name): | 387 def _create_comp_layer_group(self, layers_group, layer_name): |
384 doc = self._doc | 388 doc = self._domview._doc |
385 gid = self.new_id() | 389 gid = self._domview.new_id() |
386 | 390 |
387 layer_group = doc.createElement('svg:g') | 391 layer_group = doc.createElement('svg:g') |
388 layer_group.setAttribute('id', gid) | 392 layer_group.setAttribute('id', gid) |
389 layer_group.setAttribute('inkscape:label', layer_name) | 393 layer_group.setAttribute('inkscape:label', layer_name) |
390 layer_group.setAttribute('inkscape:groupmode', 'layer') | 394 layer_group.setAttribute('inkscape:groupmode', 'layer') |
402 layer = comp.layers[layer_idx] | 406 layer = comp.layers[layer_idx] |
403 return layer.group | 407 return layer.group |
404 | 408 |
405 def _get_layers_group_of_component(self, comp_name): | 409 def _get_layers_group_of_component(self, comp_name): |
406 if comp_name == 'main': | 410 if comp_name == 'main': |
407 return self._root | 411 return self._domview._root |
408 | 412 |
409 comp_group = self.get_component_group(comp_name) | 413 comp_group = self.get_component_group(comp_name) |
410 layers_group = comp_group.firstChild() | 414 layers_group = comp_group.firstChild() |
411 assert layers_group.getAttribute('inkscape:label') == 'layers' | 415 assert layers_group.getAttribute('inkscape:label') == 'layers' |
412 | 416 |
447 def switch_component(self, comp_name): | 451 def switch_component(self, comp_name): |
448 old_comp = self._cur_comp | 452 old_comp = self._cur_comp |
449 | 453 |
450 comp = self._get_component(comp_name) | 454 comp = self._get_component(comp_name) |
451 self._cur_comp = comp | 455 self._cur_comp = comp |
452 self._layers = comp.layers | 456 self._domview._layers = comp.layers |
453 comp_name = self._cur_comp.name() | 457 comp_name = self._cur_comp.name() |
454 # for domview | 458 # for domview |
455 self._layers_parent = self._get_layers_group_of_component(comp_name) | 459 self._domview._layers_parent = \ |
460 self._get_layers_group_of_component(comp_name) | |
456 | 461 |
457 first_name = comp.all_timeline_names()[0] | 462 first_name = comp.all_timeline_names()[0] |
458 self.switch_timeline(first_name) | 463 self.switch_timeline(first_name) |
459 | 464 |
460 self.hide_component(old_comp.name()) | 465 self.hide_component(old_comp.name()) |
468 | 473 |
469 comp_group = self._create_component_group() | 474 comp_group = self._create_component_group() |
470 comp_group_id = comp_group.getAttribute('id') | 475 comp_group_id = comp_group.getAttribute('id') |
471 comp_node = self._create_component_node(comp_name, comp_group_id) | 476 comp_node = self._create_component_node(comp_name, comp_group_id) |
472 | 477 |
473 comp = Component(self, comp_node) | 478 comp = Component(self._domview, comp_node) |
474 comp.parse_timelines() | 479 comp.parse_timelines() |
475 | 480 |
476 self._components.append(comp) | 481 self._components.append(comp) |
477 self._comp_names.add(comp_name) | 482 self._comp_names.add(comp_name) |
478 | 483 |
484 | 489 |
485 self.hide_component(comp_name) | 490 self.hide_component(comp_name) |
486 pass | 491 pass |
487 | 492 |
488 def add_component_node(self, comp_node): | 493 def add_component_node(self, comp_node): |
489 comp = Component(self, comp_node) | 494 comp = Component(self._domview, comp_node) |
490 comp_name = comp.name() | 495 comp_name = comp.name() |
491 if self.has_component(comp_name): | 496 if self.has_component(comp_name): |
492 raise ValueError, \ | 497 raise ValueError, \ |
493 'the name of a ns0:component is duplicated' | 498 'the name of a ns0:component is duplicated' |
494 | 499 |
516 def get_component_group(self, comp_name): | 521 def get_component_group(self, comp_name): |
517 comp = self._get_component(comp_name) | 522 comp = self._get_component(comp_name) |
518 | 523 |
519 comp_name = comp.name() | 524 comp_name = comp.name() |
520 if comp_name == 'main': | 525 if comp_name == 'main': |
521 return self._root | 526 return self._domview._root |
522 | 527 |
523 comp_node = comp.node | 528 comp_node = comp.node |
524 gid = comp_node.getAttribute('ref') | 529 gid = comp_node.getAttribute('ref') |
525 comp_group = self.get_node(gid) | 530 comp_group = self._domview.get_node(gid) |
526 return comp_group | 531 return comp_group |
527 | 532 |
528 def get_current_component(self): | 533 def get_current_component(self): |
529 return self._cur_comp.name() | 534 return self._cur_comp.name() |
530 | 535 |
531 def switch_timeline(self, timeline_name): | 536 def switch_timeline(self, timeline_name): |
532 tl = self._cur_comp.get_timeline(timeline_name) | 537 tl = self._cur_comp.get_timeline(timeline_name) |
533 self._cur_timeline = tl | 538 self._cur_timeline = tl |
534 self._scenes_node = tl.scenes_node # of class domview | 539 self._domview._scenes_node = tl.scenes_node # of class domview |
535 | 540 |
536 # Make domview to rescan layers and scenes. | 541 # Make domview to rescan layers and scenes. |
537 self.reset() # from domview | 542 self._domview.reset() # from domview |
538 pass | 543 pass |
539 | 544 |
540 def add_timeline(self, timeline_name): | 545 def add_timeline(self, timeline_name): |
541 self._cur_comp.add_timeline(timeline_name) | 546 self._cur_comp.add_timeline(timeline_name) |
542 pass | 547 pass |
587 # \return link node. | 592 # \return link node. |
588 # | 593 # |
589 def link_to_component(self, comp_name, parent_group): | 594 def link_to_component(self, comp_name, parent_group): |
590 layers_group = self._get_layers_group_of_component(comp_name) | 595 layers_group = self._get_layers_group_of_component(comp_name) |
591 | 596 |
592 use_node = self._doc.createElement('svg:use') | 597 use_node = self._domview._doc.createElement('svg:use') |
593 layers_group_id = layers_group.getAttribute('id') | 598 layers_group_id = layers_group.getAttribute('id') |
594 use_node.setAttribute('xlink:href', '#' + layers_group_id) | 599 use_node.setAttribute('xlink:href', '#' + layers_group_id) |
595 use_node_id = self.new_id() | 600 use_node_id = self._domview.new_id() |
596 use_node.setAttribute('id', use_node_id) | 601 use_node.setAttribute('id', use_node_id) |
597 use_node.setAttribute('use_component', 'true') | 602 use_node.setAttribute('use_component', 'true') |
598 | 603 |
599 parent_group.appendChild(use_node) | 604 parent_group.appendChild(use_node) |
600 | 605 |
935 # | 940 # |
936 # This class maintains layers information, and provides functions to create, | 941 # This class maintains layers information, and provides functions to create, |
937 # change and destroy scene node and scene group. A scene node is a 'ns0:scene' | 942 # change and destroy scene node and scene group. A scene node is a 'ns0:scene' |
938 # in 'ns0:scenes' tag. A scene group is respective 'svg:g' for a scene. | 943 # in 'ns0:scenes' tag. A scene group is respective 'svg:g' for a scene. |
939 # | 944 # |
940 class domview(domview_monitor, component_manager): | 945 class domview(domview_monitor): |
941 # Declare variables, here, for keeping tracking | 946 # Declare variables, here, for keeping tracking |
942 _doc = None | 947 _doc = None |
943 _root = None | 948 _root = None |
944 | 949 |
945 def __init__(self, *args, **kws): | 950 def __init__(self, *args, **kws): |
950 # component_manager to switch components and timelines. | 955 # component_manager to switch components and timelines. |
951 # | 956 # |
952 self._scenes_node = None | 957 self._scenes_node = None |
953 self._layers_parent = None | 958 self._layers_parent = None |
954 self._layers = [] | 959 self._layers = [] |
955 pass | 960 |
961 self._comp_mgr = component_manager(self) | |
962 pass | |
963 | |
964 ## \brief Special method to get attribute. | |
965 # | |
966 # This method is here for delegating attribute accessing for | |
967 # mix-in. | |
968 # | |
969 def __getattr__(self, name): | |
970 val = getattr(self._comp_mgr, name) | |
971 return val | |
956 | 972 |
957 ## \brief Create a scenes node if not existed. | 973 ## \brief Create a scenes node if not existed. |
958 # | 974 # |
959 def _init_metadata(self): | 975 def _init_metadata(self): |
960 self._layers_parent = self._root | 976 self._layers_parent = self._root |
1016 self._root = root | 1032 self._root = root |
1017 self._layers[:] = [] | 1033 self._layers[:] = [] |
1018 | 1034 |
1019 self._init_metadata() | 1035 self._init_metadata() |
1020 self._start_monitor() # from domview_monitor | 1036 self._start_monitor() # from domview_monitor |
1021 self._start_component_manager() # from component_manager | 1037 self._comp_mgr._start_component_manager() |
1022 self._parse_all_layers() | 1038 self._parse_all_layers() |
1023 pass | 1039 pass |
1024 | 1040 |
1025 def reset(self): | 1041 def reset(self): |
1026 self._monitor_reparse() # from domview_monitor | 1042 self._monitor_reparse() # from domview_monitor |