comparison pyink/domview.py @ 1352:9164a0782ba7

Refactory layer_parser out from domview
author Thinker K.F. Li <thinker@codemud.net>
date Sun, 13 Feb 2011 12:33:31 +0800
parents 17fa5d78200b
children f92be354ad24
comparison
equal deleted inserted replaced
1351:1a4d15fe2c62 1352:9164a0782ba7
236 # special case with slightly different in structure. It should be 236 # special case with slightly different in structure. It should be
237 # removed and normalized to normal components. 237 # removed and normalized to normal components.
238 # 238 #
239 @trait 239 @trait
240 class component_manager(component_manager_ui_update): 240 class component_manager(component_manager_ui_update):
241 _layers = require
242 _scenes_node = require 241 _scenes_node = require
243 _metadata_node = require 242 _metadata_node = require
244 _doc = require 243 _doc = require
245 _root = require 244 _root = require
246 _layers = require 245 _layers = require
987 yield node 986 yield node
988 pass 987 pass
989 pass 988 pass
990 989
991 990
992 ## \brief This layer provide a data view to the DOM-tree. 991 @trait
993 # 992 class layers_parser(object):
994 # This class maintains layers information, and provides functions to create, 993 _layers = require
995 # change and destroy scene node and scene group. A scene node is a 'ns0:scene' 994 _layers_parent = require
996 # in 'ns0:scenes' tag. A scene group is respective 'svg:g' for a scene. 995 get_scene = require
997 # 996
998 @composite 997 def parse_all_layers(self):
999 class domview(domview_monitor):
1000 use_traits = (component_manager,)
1001
1002 method_map_traits = {component_manager._start_component_manager:
1003 '_start_component_manager'}
1004
1005 # Declare variables, here, for keeping tracking
1006 _doc = None
1007 _root = None
1008
1009 def __init__(self, *args, **kws):
1010 super(domview, self).__init__()
1011 self._metadata_node = None
1012 #
1013 # Following two variables would be changed by class
1014 # component_manager to switch components and timelines.
1015 #
1016 self._scenes_node = None
1017 self._layers_parent = None
1018 self._layers = []
1019 pass
1020
1021 ## \brief Create a scenes node if not existed.
1022 #
1023 def _init_metadata(self):
1024 self._layers_parent = self._root
1025
1026 for node in self._root.childList():
1027 if node.name() == 'svg:metadata':
1028 break
1029 pass
1030 else:
1031 raise RuntimeError, \
1032 'can not find <svg:metadata> node in the document'
1033
1034 self._metadata_node = node
1035
1036 for n in node.childList():
1037 if n.name() == 'ns0:scenes':
1038 self._scenes_node = n
1039 break
1040 pass
1041 else:
1042 ns = "http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd"
1043 self._root.setAttribute("xmlns:ns0", ns)
1044 scenes_node = self._doc.createElement("ns0:scenes")
1045 scenes_node_id = 'main_default_scenes'
1046 scenes_node.setAttribute('id', scenes_node_id)
1047 scenes_node.setAttribute('name', 'default')
1048 node.appendChild(scenes_node)
1049 self._scenes_node = scenes_node
1050 pass
1051 pass
1052
1053 def _parse_all_layers(self):
1054 layers = self._layers 998 layers = self._layers
1055 layers_parent = self._layers_parent 999 layers_parent = self._layers_parent
1056 1000
1057 for child in layers_parent.childList(): 1001 for child in layers_parent.childList():
1058 if child.name() != 'svg:g': 1002 if child.name() != 'svg:g':
1072 layer.idx = len(layers) 1016 layer.idx = len(layers)
1073 layers.append(layer) 1017 layers.append(layer)
1074 self.parse_layer(layer.idx) 1018 self.parse_layer(layer.idx)
1075 pass 1019 pass
1076 pass 1020 pass
1077
1078 def handle_doc_root(self, doc, root):
1079 self._doc = doc
1080 self._root = root
1081 self._layers[:] = []
1082
1083 self._init_metadata()
1084 self._start_monitor() # from domview_monitor
1085 self._start_component_manager()
1086 self._parse_all_layers()
1087 pass
1088
1089 def reset(self):
1090 self._monitor_reparse() # from domview_monitor
1091 self._layers[:] = []
1092 self._parse_all_layers()
1093 pass
1094
1095 def dumpattr(self, n):
1096 s = ""
1097 for a,v in n.attrib.items():
1098 s = s + ("%s=%s" % (a,v))
1099 pass
1100 return s
1101
1102 def dump(self, node, l=0):
1103 print " " * l*2,"<", node.tag, self.dumpattr(node),">"
1104 for n in node:
1105 self.dump(n, l+1)
1106 pass
1107 print " " * l * 2,"/>"
1108 pass
1109
1110 ## \brief Create and add a ns0:scene node under ns0:scenes subtree.
1111 #
1112 def add_scene_node(self, layer_idx, start, end,
1113 frame_type=TweenObject.TWEEN_TYPE_NORMAL,
1114 ref=None):
1115 type_names = ('normal', 'scale')
1116 scenes_node = self._scenes_node
1117 doc = self._doc
1118
1119 scene_node = doc.createElement('ns0:scene')
1120 self.chg_scene_node(scene_node, start=start)
1121 if start != end:
1122 self.chg_scene_node(scene_node, end=end)
1123 pass
1124 type_name = type_names[frame_type]
1125 self.chg_scene_node(scene_node, tween_type=type_name)
1126 if ref:
1127 self.chg_scene_node(scene_node, ref=ref)
1128 pass
1129
1130 scenes_node.appendChild(scene_node)
1131
1132 self._layers[layer_idx].scenes.append(scene_node)
1133
1134 return scene_node
1135
1136 ## \brief Manage a existed scene node at given layer.
1137 #
1138 def manage_scene_node(self, layer_idx, scene_node):
1139 self._layers[layer_idx].scenes.append(scene_node)
1140 pass
1141
1142 ## \brief Change attributes of a scene node.
1143 #
1144 # This is here to monitor changes of scene node.
1145 def chg_scene_node(self, scene_node, start=None, end=None,
1146 tween_type=None, ref=None):
1147 if start is not None:
1148 scene_node.setAttribute('start', str(start))
1149 pass
1150 if end is not None:
1151 scene_node.setAttribute('end', str(end))
1152 pass
1153 if tween_type is not None:
1154 scene_node.setAttribute('type', tween_type)
1155 pass
1156 if ref is not None:
1157 scene_node.setAttribute('ref', ref)
1158 pass
1159 pass
1160
1161 ## \brief Remove scene node from DOM-tree.
1162 #
1163 def rm_scene_node(self, scene_node):
1164 if not scene_node.parent():
1165 return # without this, may crash the Inkscape.
1166
1167 self._scenes_node.removeChild(scene_node)
1168 for layer in self._layers:
1169 try:
1170 layer.scenes.remove(scene_node)
1171 except ValueError: # not in the list
1172 pass
1173 else:
1174 break
1175 pass
1176 pass
1177
1178 ## \brief Remove scene node and asssociated scene group from DOM.
1179 #
1180 # It will remove as many as possible. Does not complain about
1181 # error in the procedure of removing.
1182 #
1183 def rm_scene_node_n_group(self, scene_node):
1184 scene_group_id = scene_node.getAttribute('ref')
1185 try:
1186 scene_group_node = self.get_node(scene_group_id)
1187 if scene_group_node.parent(): # Check it, or crash the
1188 # Inkscape.
1189 scene_group_node.parent().removeChild(scene_group_node)
1190 pass
1191 except:
1192 pass
1193
1194 try:
1195 self.rm_scene_node(scene_node)
1196 except:
1197 pass
1198 pass
1199
1200 ## \brief Create and add a svg:g for a scene under a group for a layer.
1201 #
1202 def add_scene_group(self, layer_idx):
1203 layer = self._layers[layer_idx]
1204 doc = self._doc
1205
1206 scene_group = doc.createElement('svg:g')
1207 gid = self.new_id()
1208 scene_group.setAttribute("id", gid)
1209 scene_group.setAttribute("inkscape:groupmode", "layer")
1210 scene_group.setAttribute('scene_group', 'true')
1211
1212 layer.group.appendChild(scene_group)
1213
1214 return scene_group
1215 1021
1216 def parse_layer(self, layer_idx): 1022 def parse_layer(self, layer_idx):
1217 layer = self._layers[layer_idx] 1023 layer = self._layers[layer_idx]
1218 layer_group = layer.group 1024 layer_group = layer.group
1219 1025
1227 continue 1033 continue
1228 1034
1229 layer.scenes.append(scene_node) 1035 layer.scenes.append(scene_node)
1230 pass 1036 pass
1231 pass 1037 pass
1232 1038 pass
1039
1040 ## \brief This layer provide a data view to the DOM-tree.
1041 #
1042 # This class maintains layers information, and provides functions to create,
1043 # change and destroy scene node and scene group. A scene node is a 'ns0:scene'
1044 # in 'ns0:scenes' tag. A scene group is respective 'svg:g' for a scene.
1045 #
1046 @composite
1047 class domview(domview_monitor):
1048 use_traits = (component_manager, layers_parser)
1049
1050 method_map_traits = {component_manager._start_component_manager:
1051 '_start_component_manager'}
1052
1053 # Declare variables, here, for keeping tracking
1054 _doc = None
1055 _root = None
1056
1057 def __init__(self, *args, **kws):
1058 super(domview, self).__init__()
1059 self._metadata_node = None
1060 #
1061 # Following two variables would be changed by class
1062 # component_manager to switch components and timelines.
1063 #
1064 self._scenes_node = None
1065 self._layers_parent = None
1066 self._layers = []
1067 pass
1068
1069 ## \brief Create a scenes node if not existed.
1070 #
1071 def _init_metadata(self):
1072 self._layers_parent = self._root
1073
1074 for node in self._root.childList():
1075 if node.name() == 'svg:metadata':
1076 break
1077 pass
1078 else:
1079 raise RuntimeError, \
1080 'can not find <svg:metadata> node in the document'
1081
1082 self._metadata_node = node
1083
1084 for n in node.childList():
1085 if n.name() == 'ns0:scenes':
1086 self._scenes_node = n
1087 break
1088 pass
1089 else:
1090 ns = "http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd"
1091 self._root.setAttribute("xmlns:ns0", ns)
1092 scenes_node = self._doc.createElement("ns0:scenes")
1093 scenes_node_id = 'main_default_scenes'
1094 scenes_node.setAttribute('id', scenes_node_id)
1095 scenes_node.setAttribute('name', 'default')
1096 node.appendChild(scenes_node)
1097 self._scenes_node = scenes_node
1098 pass
1099 pass
1100
1101 def handle_doc_root(self, doc, root):
1102 self._doc = doc
1103 self._root = root
1104 self._layers[:] = []
1105
1106 self._init_metadata()
1107 self._start_monitor() # from domview_monitor
1108 self._start_component_manager()
1109 self.parse_all_layers()
1110 pass
1111
1112 def reset(self):
1113 self._monitor_reparse() # from domview_monitor
1114 self._layers[:] = []
1115 self.parse_all_layers()
1116 pass
1117
1118 def dumpattr(self, n):
1119 s = ""
1120 for a,v in n.attrib.items():
1121 s = s + ("%s=%s" % (a,v))
1122 pass
1123 return s
1124
1125 def dump(self, node, l=0):
1126 print " " * l*2,"<", node.tag, self.dumpattr(node),">"
1127 for n in node:
1128 self.dump(n, l+1)
1129 pass
1130 print " " * l * 2,"/>"
1131 pass
1132
1133 ## \brief Create and add a ns0:scene node under ns0:scenes subtree.
1134 #
1135 def add_scene_node(self, layer_idx, start, end,
1136 frame_type=TweenObject.TWEEN_TYPE_NORMAL,
1137 ref=None):
1138 type_names = ('normal', 'scale')
1139 scenes_node = self._scenes_node
1140 doc = self._doc
1141
1142 scene_node = doc.createElement('ns0:scene')
1143 self.chg_scene_node(scene_node, start=start)
1144 if start != end:
1145 self.chg_scene_node(scene_node, end=end)
1146 pass
1147 type_name = type_names[frame_type]
1148 self.chg_scene_node(scene_node, tween_type=type_name)
1149 if ref:
1150 self.chg_scene_node(scene_node, ref=ref)
1151 pass
1152
1153 scenes_node.appendChild(scene_node)
1154
1155 self._layers[layer_idx].scenes.append(scene_node)
1156
1157 return scene_node
1158
1159 ## \brief Manage a existed scene node at given layer.
1160 #
1161 def manage_scene_node(self, layer_idx, scene_node):
1162 self._layers[layer_idx].scenes.append(scene_node)
1163 pass
1164
1165 ## \brief Change attributes of a scene node.
1166 #
1167 # This is here to monitor changes of scene node.
1168 def chg_scene_node(self, scene_node, start=None, end=None,
1169 tween_type=None, ref=None):
1170 if start is not None:
1171 scene_node.setAttribute('start', str(start))
1172 pass
1173 if end is not None:
1174 scene_node.setAttribute('end', str(end))
1175 pass
1176 if tween_type is not None:
1177 scene_node.setAttribute('type', tween_type)
1178 pass
1179 if ref is not None:
1180 scene_node.setAttribute('ref', ref)
1181 pass
1182 pass
1183
1184 ## \brief Remove scene node from DOM-tree.
1185 #
1186 def rm_scene_node(self, scene_node):
1187 if not scene_node.parent():
1188 return # without this, may crash the Inkscape.
1189
1190 self._scenes_node.removeChild(scene_node)
1191 for layer in self._layers:
1192 try:
1193 layer.scenes.remove(scene_node)
1194 except ValueError: # not in the list
1195 pass
1196 else:
1197 break
1198 pass
1199 pass
1200
1201 ## \brief Remove scene node and asssociated scene group from DOM.
1202 #
1203 # It will remove as many as possible. Does not complain about
1204 # error in the procedure of removing.
1205 #
1206 def rm_scene_node_n_group(self, scene_node):
1207 scene_group_id = scene_node.getAttribute('ref')
1208 try:
1209 scene_group_node = self.get_node(scene_group_id)
1210 if scene_group_node.parent(): # Check it, or crash the
1211 # Inkscape.
1212 scene_group_node.parent().removeChild(scene_group_node)
1213 pass
1214 except:
1215 pass
1216
1217 try:
1218 self.rm_scene_node(scene_node)
1219 except:
1220 pass
1221 pass
1222
1223 ## \brief Create and add a svg:g for a scene under a group for a layer.
1224 #
1225 def add_scene_group(self, layer_idx):
1226 layer = self._layers[layer_idx]
1227 doc = self._doc
1228
1229 scene_group = doc.createElement('svg:g')
1230 gid = self.new_id()
1231 scene_group.setAttribute("id", gid)
1232 scene_group.setAttribute("inkscape:groupmode", "layer")
1233 scene_group.setAttribute('scene_group', 'true')
1234
1235 layer.group.appendChild(scene_group)
1236
1237 return scene_group
1238
1233 ## \brief Add/insert a layer at given position. 1239 ## \brief Add/insert a layer at given position.
1234 # 1240 #
1235 # \param layer_idx is the position in the layer list. 1241 # \param layer_idx is the position in the layer list.
1236 # 1242 #
1237 def insert_layer(self, layer_idx, layer_group): 1243 def insert_layer(self, layer_idx, layer_group):