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