changeset 1323:ffbbd3aa218d

Make a component from a group. User can translate a group into a component from context menu.
author Thinker K.F. Li <thinker@codemud.net>
date Sun, 30 Jan 2011 19:15:17 +0800
parents 7f25abbc1b61
children 740b3239030e
files pyink/MBScene.py pyink/comp_dock.py pyink/domview.py pyink/domview_ui.py pyink/pyink.py
diffstat 5 files changed, 171 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/pyink/MBScene.py	Sun Jan 23 09:24:01 2011 +0800
+++ b/pyink/MBScene.py	Sun Jan 30 19:15:17 2011 +0800
@@ -388,6 +388,26 @@
 	self.last_update = None
 	return False
 
+    ## \brief To handle context menu event.
+    #
+    def do_make_component_from_group(self, node):
+	comp_name = 'Component ' + node.getAttribute('id')
+	self._domviewui.add_component_from_group(comp_name, node)
+	pass
+
+    def context_menu(self, spitem, menu_factory):
+	node = spitem.repr
+	if node.name() != 'svg:g':
+	    return		# not a group
+
+	if self._domviewui.is_graph_node(node):
+	    menu_item_handler = \
+		lambda *args: self.do_make_component_from_group(node)
+	    menu_factory.add_item_label('Make a component',
+					menu_item_handler)
+	    pass
+	pass
+
     def show(self):
 	self.do_show()
 	pass
--- a/pyink/comp_dock.py	Sun Jan 23 09:24:01 2011 +0800
+++ b/pyink/comp_dock.py	Sun Jan 30 19:15:17 2011 +0800
@@ -260,6 +260,10 @@
         
         comp_name = self._current_component()
         domview_ui.switch_component(comp_name)
+        
+        group = domview_ui.get_layer_group(0)
+        desktop = self._desktop # from comp_dock_base
+        desktop.setCurrentLayer(group.spitem)
         pass
     
     def on_cellrenderer_comp_edited(self, renderer, path,
--- a/pyink/domview.py	Sun Jan 23 09:24:01 2011 +0800
+++ b/pyink/domview.py	Sun Jan 30 19:15:17 2011 +0800
@@ -272,7 +272,6 @@
         group = doc.createElement('svg:g')
         gid = self.new_id()
         group.setAttribute('id', gid)
-        group.setAttribute('component_group', 'true')
         
         self._components_group.appendChild(group)
         return group
@@ -312,8 +311,19 @@
         layer_group = doc.createElement('svg:g')
         layer_group.setAttribute('id', gid)
         layer_group.setAttribute('inkscape:label', layer_name)
+        layer_group.setAttribute('inkscape:groupmode', 'layer')
         comp_group.appendChild(layer_group)
-        pass
+        return layer_group
+    
+    ## \brief Return group of specified layer in a component.
+    #
+    # This is here for getting layer group without switch current
+    # component.
+    #
+    def _get_group_of_component_layer(self, comp_name, layer_idx):
+        comp = self._get_component(comp_name)
+        layer = comp.layers[layer_idx]
+        return layer.group
     
     def all_comp_names(self):
         return [comp.name() for comp in self._components]
@@ -322,6 +332,8 @@
         return name in self._comp_names
 
     def switch_component(self, comp_name):
+        old_comp = self._cur_comp
+        
         comp = self._get_component(comp_name)
         self._cur_comp = comp
         self._layers = comp.layers
@@ -331,6 +343,18 @@
         
         first_name = comp.all_timeline_names()[0]
         self.switch_timeline(first_name)
+
+        # Hide layers in old component
+        for layer in old_comp.layers:
+            group = layer.group
+            group.setAttribute('style', 'display: none')
+            pass
+        
+        # Show layers in new component
+        for layer in comp.layers:
+            group = layer.group
+            group.setAttribute('style', '')
+            pass
         pass
 
     def add_component(self, comp_name):
@@ -342,10 +366,14 @@
         comp_group_id = comp_group.getAttribute('id')
         comp_node = self._create_component_node(comp_name, comp_group_id)
 
-        self._create_comp_layer_group(comp_group, comp_name + ' Layer1')
+        layer_group = self._create_comp_layer_group(comp_group, 'Layer1')
+        layer_group.setAttribute('style', 'display: none')
         
         comp = Component(self, comp_node)
         comp.parse_timelines()
+
+        layer = Layer(layer_group)
+        comp.layers.append(layer)
         
         self._components.append(comp)
         self._comp_names.add(comp_name)
@@ -416,6 +444,21 @@
 
     def get_current_timeline(self):
         return self._cur_timeline.name()
+
+    ## \brief Add a new component from a group node.
+    #
+    # The group node is reparented to the group of first layer of
+    # specified component.
+    #
+    def mv_group_to_component(self, group, comp_name):
+        group_parent = group.parent()
+        if group_parent:
+            group_parent.removeChild(group)
+            pass
+        
+        layer_group = self._get_group_of_component_layer(comp_name, 0)
+        layer_group.appendChild(group)
+        pass
     pass
 
 
@@ -738,6 +781,7 @@
         #
         self._scenes_node = None
         self._layers_parent = None
+        self._layers = []
 	pass
 
     ## \brief Create a scenes node if not existed.
@@ -800,7 +844,7 @@
     def handle_doc_root(self, doc, root):
 	self._doc = doc
 	self._root = root
-	self._layers = []
+        self._layers[:] = []
 	
 	self._init_metadata()
 	self._start_monitor()	# from domview_monitor
@@ -810,7 +854,7 @@
 
     def reset(self):
         self._monitor_reparse() # from domview_monitor
-        self._layers = []
+        self._layers[:] = []
         self._parse_all_layers()
 	pass
    
@@ -1223,5 +1267,38 @@
             dst_group.appendChild(dst_child)
             pass
         pass
+
+    ## \brief To test a graphic node.
+    #
+    # A graphic node is a SVG node that is not layer group, scene
+    # group, ... etc.  It is only a normal node in a layer group or a
+    # scene group.
+    def is_graph_node(self, node):
+        try:
+            mode = node.getAttribute('inkscape:groupmode')
+        except:
+            pass
+        else:
+            if mode == 'layer':
+                return False
+            pass
+
+        try:
+            label = node.geteAttribute('inkscape:label')
+        except:
+            pass
+        else:
+            return False
+        
+        try:
+            scene_group = node.geteAttribute('scene_group')
+        except:
+            pass
+        else:
+            if scene_group == 'true':
+                return False
+            pass
+        
+        return True
     pass
 
--- a/pyink/domview_ui.py	Sun Jan 23 09:24:01 2011 +0800
+++ b/pyink/domview_ui.py	Sun Jan 30 19:15:17 2011 +0800
@@ -455,6 +455,16 @@
 
     def get_current_timeline(self):
         return self._dom.get_current_timeline()
+
+    ## \brief Add a new component from a group node.
+    #
+    # The group node is reparented to the group of first layer of
+    # specified component.
+    #
+    def add_component_from_group(self, comp_name, group):
+        self.add_component(comp_name)
+        self._dom.mv_group_to_component(group, comp_name)
+        pass
     pass
 
 
@@ -757,6 +767,14 @@
         self._dom.clone_group_children(src_group, dst_group)
         pass
 
+    ## \brief To test a graphic node.
+    #
+    # A graphic node is a SVG node that is not layer group, scene
+    # group, ... etc.  It is only a normal node in a layer group or a
+    # scene group.
+    def is_graph_node(self, node):
+        return self._dom.is_graph_node(node)
+
     ## \brief Return widget showing frames and layers.
     #
     def get_frame_ui_widget(self):
@@ -906,6 +924,12 @@
             pass
         self._fl_stack.set_layer_label(layer_idx, label)
         pass
+
+    ## \brief Get layer group.
+    #
+    def get_layer_group(self, layer_idx):
+        layer_group = self._dom.get_layer_group(layer_idx)
+        return layer_group
     pass
 
 
--- a/pyink/pyink.py	Sun Jan 23 09:24:01 2011 +0800
+++ b/pyink/pyink.py	Sun Jan 30 19:15:17 2011 +0800
@@ -13,24 +13,50 @@
 import pygtk
 import gtk
 from MBScene import *
-global ink_inited
-ink_inited=0
-def start_desktop(inkscape,ptr):
-    global ink_inited
-    if ink_inited == 1:
-    	desktop = pybInkscape.GPointer_2_PYSPDesktop(ptr)
-	top = desktop.getToplevel()
-    	#dock = desktop.getDock()
-    	#item = dock.new_item("scene", "scene", "feBlend-icon", dock.ITEM_ST_DOCKED_STATE)
-    	scene = MBScene(desktop,top)
-    	scene.show()
+
+all_desktop_mbscenes = {}
+
+def _init_mbscene(inkscape, ptr):
+    global all_desktop_mbscenes
+    
+    desktop = pybInkscape.GPointer_2_PYSPDesktop(ptr)
+
+    top = desktop.getToplevel()
+    mbscene = MBScene(desktop,top)
+    mbscene.show()
+
+    all_desktop_mbscenes[desktop] = mbscene
+
+    print hash(desktop)
+    pass
+
+
+## \brief Handler for events of activating a desktop.
+#
+def act_desktop(inkscape, ptr):
+    # Get Python wrapper of SPDesktop passed by ptr.
+    desktop = pybInkscape.GPointer_2_PYSPDesktop(ptr)
+    
+    top = desktop.getToplevel()
+    if not top:                 # has not top window.
         return
-        
 
-    ink_inited = 1
+    if desktop in all_desktop_mbscenes:
+        return                  # already initialized
+    
+    _init_mbscene(inkscape, ptr)
+    pass
 
 
 def pyink_start():
-    print 'pyink_start()'
-    pybInkscape.inkscape.connect('activate_desktop', start_desktop)
+    pybInkscape.inkscape.connect('activate_desktop', act_desktop)
     pass
+
+
+def pyink_context_menu(view, item, menu_factory):
+    print hash(view)
+    if view in all_desktop_mbscenes:
+        mbscene = all_desktop_mbscenes[view]
+        mbscene.context_menu(item, menu_factory)
+        pass
+    pass