comparison pyink/domview.py @ 1356:ac61d86987af

Move more code to layers_parser
author Thinker K.F. Li <thinker@codemud.net>
date Sun, 13 Feb 2011 14:41:42 +0800
parents f92be354ad24
children f19121bd6a6c
comparison
equal deleted inserted replaced
1355:f1fa284fc9c9 1356:ac61d86987af
988 pass 988 pass
989 989
990 990
991 @trait 991 @trait
992 class layers_parser(object): 992 class layers_parser(object):
993 _doc = require
993 _layers = require 994 _layers = require
994 _layers_parent = require 995 _layers_parent = require
995 get_scene = require 996 get_scene = require
997 get_node = require
998 new_id = require
996 999
997 def parse_all_layers(self): 1000 def parse_all_layers(self):
998 layers = self._layers 1001 layers = self._layers
999 layers_parent = self._layers_parent 1002 layers_parent = self._layers_parent
1000 1003
1037 pass 1040 pass
1038 1041
1039 def get_layer_num(self): 1042 def get_layer_num(self):
1040 return len(self._layers) 1043 return len(self._layers)
1041 1044
1042 def reset_layers(self):
1043 self._layers[:] = []
1044 self.parse_all_layers()
1045 pass
1046 pass
1047
1048 ## \brief This layer provide a data view to the DOM-tree.
1049 #
1050 # This class maintains layers information, and provides functions to create,
1051 # change and destroy scene node and scene group. A scene node is a 'ns0:scene'
1052 # in 'ns0:scenes' tag. A scene group is respective 'svg:g' for a scene.
1053 #
1054 @composite
1055 class domview(domview_monitor):
1056 use_traits = (component_manager, layers_parser)
1057
1058 method_map_traits = {component_manager._start_component_manager:
1059 '_start_component_manager'}
1060
1061 # Declare variables, here, for keeping tracking
1062 _doc = None
1063 _root = None
1064
1065 def __init__(self, *args, **kws):
1066 super(domview, self).__init__()
1067 self._metadata_node = None
1068 #
1069 # Following two variables would be changed by class
1070 # component_manager to switch components and timelines.
1071 #
1072 self._scenes_node = None
1073 self._layers_parent = None
1074 self._layers = []
1075 pass
1076
1077 ## \brief Create a scenes node if not existed.
1078 #
1079 def _init_metadata(self):
1080 self._layers_parent = self._root
1081
1082 for node in self._root.childList():
1083 if node.name() == 'svg:metadata':
1084 break
1085 pass
1086 else:
1087 raise RuntimeError, \
1088 'can not find <svg:metadata> node in the document'
1089
1090 self._metadata_node = node
1091
1092 for n in node.childList():
1093 if n.name() == 'ns0:scenes':
1094 self._scenes_node = n
1095 break
1096 pass
1097 else:
1098 ns = "http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd"
1099 self._root.setAttribute("xmlns:ns0", ns)
1100 scenes_node = self._doc.createElement("ns0:scenes")
1101 scenes_node_id = 'main_default_scenes'
1102 scenes_node.setAttribute('id', scenes_node_id)
1103 scenes_node.setAttribute('name', 'default')
1104 node.appendChild(scenes_node)
1105 self._scenes_node = scenes_node
1106 pass
1107 pass
1108
1109 def handle_doc_root(self, doc, root):
1110 self._doc = doc
1111 self._root = root
1112
1113 self._init_metadata()
1114 self._start_monitor() # from domview_monitor
1115 self._start_component_manager()
1116 self.reset_layers()
1117 pass
1118
1119 def reset(self):
1120 self._monitor_reparse() # from domview_monitor
1121 self.reset_layers()
1122 pass
1123
1124 def dumpattr(self, n):
1125 s = ""
1126 for a,v in n.attrib.items():
1127 s = s + ("%s=%s" % (a,v))
1128 pass
1129 return s
1130
1131 def dump(self, node, l=0):
1132 print " " * l*2,"<", node.tag, self.dumpattr(node),">"
1133 for n in node:
1134 self.dump(n, l+1)
1135 pass
1136 print " " * l * 2,"/>"
1137 pass
1138
1139 ## \brief Create and add a ns0:scene node under ns0:scenes subtree.
1140 #
1141 def add_scene_node(self, layer_idx, start, end,
1142 frame_type=TweenObject.TWEEN_TYPE_NORMAL,
1143 ref=None):
1144 type_names = ('normal', 'scale')
1145 scenes_node = self._scenes_node
1146 doc = self._doc
1147
1148 scene_node = doc.createElement('ns0:scene')
1149 self.chg_scene_node(scene_node, start=start)
1150 if start != end:
1151 self.chg_scene_node(scene_node, end=end)
1152 pass
1153 type_name = type_names[frame_type]
1154 self.chg_scene_node(scene_node, tween_type=type_name)
1155 if ref:
1156 self.chg_scene_node(scene_node, ref=ref)
1157 pass
1158
1159 scenes_node.appendChild(scene_node)
1160
1161 self._layers[layer_idx].scenes.append(scene_node)
1162
1163 return scene_node
1164
1165 ## \brief Manage a existed scene node at given layer.
1166 #
1167 def manage_scene_node(self, layer_idx, scene_node):
1168 self._layers[layer_idx].scenes.append(scene_node)
1169 pass
1170
1171 ## \brief Change attributes of a scene node.
1172 #
1173 # This is here to monitor changes of scene node.
1174 def chg_scene_node(self, scene_node, start=None, end=None,
1175 tween_type=None, ref=None):
1176 if start is not None:
1177 scene_node.setAttribute('start', str(start))
1178 pass
1179 if end is not None:
1180 scene_node.setAttribute('end', str(end))
1181 pass
1182 if tween_type is not None:
1183 scene_node.setAttribute('type', tween_type)
1184 pass
1185 if ref is not None:
1186 scene_node.setAttribute('ref', ref)
1187 pass
1188 pass
1189
1190 ## \brief Remove scene node from DOM-tree.
1191 #
1192 def rm_scene_node(self, scene_node):
1193 if not scene_node.parent():
1194 return # without this, may crash the Inkscape.
1195
1196 self._scenes_node.removeChild(scene_node)
1197 for layer in self._layers:
1198 try:
1199 layer.scenes.remove(scene_node)
1200 except ValueError: # not in the list
1201 pass
1202 else:
1203 break
1204 pass
1205 pass
1206
1207 ## \brief Remove scene node and asssociated scene group from DOM.
1208 #
1209 # It will remove as many as possible. Does not complain about
1210 # error in the procedure of removing.
1211 #
1212 def rm_scene_node_n_group(self, scene_node):
1213 scene_group_id = scene_node.getAttribute('ref')
1214 try:
1215 scene_group_node = self.get_node(scene_group_id)
1216 if scene_group_node.parent(): # Check it, or crash the
1217 # Inkscape.
1218 scene_group_node.parent().removeChild(scene_group_node)
1219 pass
1220 except:
1221 pass
1222
1223 try:
1224 self.rm_scene_node(scene_node)
1225 except:
1226 pass
1227 pass
1228
1229 ## \brief Create and add a svg:g for a scene under a group for a layer.
1230 #
1231 def add_scene_group(self, layer_idx):
1232 layer = self._layers[layer_idx]
1233 doc = self._doc
1234
1235 scene_group = doc.createElement('svg:g')
1236 gid = self.new_id()
1237 scene_group.setAttribute("id", gid)
1238 scene_group.setAttribute("inkscape:groupmode", "layer")
1239 scene_group.setAttribute('scene_group', 'true')
1240
1241 layer.group.appendChild(scene_group)
1242
1243 return scene_group
1244
1245 ## \brief Add/insert a layer at given position. 1045 ## \brief Add/insert a layer at given position.
1246 # 1046 #
1247 # \param layer_idx is the position in the layer list. 1047 # \param layer_idx is the position in the layer list.
1248 # 1048 #
1249 def insert_layer(self, layer_idx, layer_group): 1049 def insert_layer(self, layer_idx, layer_group):
1342 for idx in range(layer_idx, len(layers)): 1142 for idx in range(layer_idx, len(layers)):
1343 layers[idx].idx = idx 1143 layers[idx].idx = idx
1344 pass 1144 pass
1345 pass 1145 pass
1346 1146
1347 ## \brief Find layer index and scene info for a given scene node.
1348 #
1349 # \return (-1, None) for error.
1350 #
1351 def find_layer_n_scene_of_node(self, node_id):
1352 for layer_idx, layer in enumerate(self._layers):
1353 for scene_node in layer.scenes:
1354 scene_group_id = scene_node.getAttribute('ref')
1355 if scene_group_id == node_id:
1356 return layer_idx, scene_node
1357 pass
1358 pass
1359 return -1, None
1360
1361 def get_layer_group(self, layer_idx): 1147 def get_layer_group(self, layer_idx):
1362 layer = self._layers[layer_idx] 1148 layer = self._layers[layer_idx]
1363 return layer.group 1149 return layer.group
1364 1150
1365 def get_all_scene_node_of_layer(self, layer_idx): 1151 def get_all_scene_node_of_layer(self, layer_idx):
1401 for layer_idx, layer in enumerate(self._layers): 1187 for layer_idx, layer in enumerate(self._layers):
1402 if layer.group.getAttribute('id') == group_id: 1188 if layer.group.getAttribute('id') == group_id:
1403 return layer_idx 1189 return layer_idx
1404 pass 1190 pass
1405 return -1 1191 return -1
1192
1193 def reset_layers(self):
1194 self._layers[:] = []
1195 self.parse_all_layers()
1196 pass
1197 pass
1198
1199 ## \brief This layer provide a data view to the DOM-tree.
1200 #
1201 # This class maintains layers information, and provides functions to create,
1202 # change and destroy scene node and scene group. A scene node is a 'ns0:scene'
1203 # in 'ns0:scenes' tag. A scene group is respective 'svg:g' for a scene.
1204 #
1205 @composite
1206 class domview(domview_monitor):
1207 use_traits = (component_manager, layers_parser)
1208
1209 method_map_traits = {component_manager._start_component_manager:
1210 '_start_component_manager'}
1211
1212 # Declare variables, here, for keeping tracking
1213 _doc = None
1214 _root = None
1215
1216 def __init__(self, *args, **kws):
1217 super(domview, self).__init__()
1218 self._metadata_node = None
1219 #
1220 # Following two variables would be changed by class
1221 # component_manager to switch components and timelines.
1222 #
1223 self._scenes_node = None
1224 self._layers_parent = None
1225 self._layers = []
1226 pass
1227
1228 ## \brief Create a scenes node if not existed.
1229 #
1230 def _init_metadata(self):
1231 self._layers_parent = self._root
1232
1233 for node in self._root.childList():
1234 if node.name() == 'svg:metadata':
1235 break
1236 pass
1237 else:
1238 raise RuntimeError, \
1239 'can not find <svg:metadata> node in the document'
1240
1241 self._metadata_node = node
1242
1243 for n in node.childList():
1244 if n.name() == 'ns0:scenes':
1245 self._scenes_node = n
1246 break
1247 pass
1248 else:
1249 ns = "http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd"
1250 self._root.setAttribute("xmlns:ns0", ns)
1251 scenes_node = self._doc.createElement("ns0:scenes")
1252 scenes_node_id = 'main_default_scenes'
1253 scenes_node.setAttribute('id', scenes_node_id)
1254 scenes_node.setAttribute('name', 'default')
1255 node.appendChild(scenes_node)
1256 self._scenes_node = scenes_node
1257 pass
1258 pass
1259
1260 def handle_doc_root(self, doc, root):
1261 self._doc = doc
1262 self._root = root
1263
1264 self._init_metadata()
1265 self._start_monitor() # from domview_monitor
1266 self._start_component_manager()
1267 self.reset_layers()
1268 pass
1269
1270 def reset(self):
1271 self._monitor_reparse() # from domview_monitor
1272 self.reset_layers()
1273 pass
1274
1275 def dumpattr(self, n):
1276 s = ""
1277 for a,v in n.attrib.items():
1278 s = s + ("%s=%s" % (a,v))
1279 pass
1280 return s
1281
1282 def dump(self, node, l=0):
1283 print " " * l*2,"<", node.tag, self.dumpattr(node),">"
1284 for n in node:
1285 self.dump(n, l+1)
1286 pass
1287 print " " * l * 2,"/>"
1288 pass
1289
1290 ## \brief Create and add a ns0:scene node under ns0:scenes subtree.
1291 #
1292 def add_scene_node(self, layer_idx, start, end,
1293 frame_type=TweenObject.TWEEN_TYPE_NORMAL,
1294 ref=None):
1295 type_names = ('normal', 'scale')
1296 scenes_node = self._scenes_node
1297 doc = self._doc
1298
1299 scene_node = doc.createElement('ns0:scene')
1300 self.chg_scene_node(scene_node, start=start)
1301 if start != end:
1302 self.chg_scene_node(scene_node, end=end)
1303 pass
1304 type_name = type_names[frame_type]
1305 self.chg_scene_node(scene_node, tween_type=type_name)
1306 if ref:
1307 self.chg_scene_node(scene_node, ref=ref)
1308 pass
1309
1310 scenes_node.appendChild(scene_node)
1311
1312 self._layers[layer_idx].scenes.append(scene_node)
1313
1314 return scene_node
1315
1316 ## \brief Manage a existed scene node at given layer.
1317 #
1318 def manage_scene_node(self, layer_idx, scene_node):
1319 self._layers[layer_idx].scenes.append(scene_node)
1320 pass
1321
1322 ## \brief Change attributes of a scene node.
1323 #
1324 # This is here to monitor changes of scene node.
1325 def chg_scene_node(self, scene_node, start=None, end=None,
1326 tween_type=None, ref=None):
1327 if start is not None:
1328 scene_node.setAttribute('start', str(start))
1329 pass
1330 if end is not None:
1331 scene_node.setAttribute('end', str(end))
1332 pass
1333 if tween_type is not None:
1334 scene_node.setAttribute('type', tween_type)
1335 pass
1336 if ref is not None:
1337 scene_node.setAttribute('ref', ref)
1338 pass
1339 pass
1340
1341 ## \brief Remove scene node from DOM-tree.
1342 #
1343 def rm_scene_node(self, scene_node):
1344 if not scene_node.parent():
1345 return # without this, may crash the Inkscape.
1346
1347 self._scenes_node.removeChild(scene_node)
1348 for layer in self._layers:
1349 try:
1350 layer.scenes.remove(scene_node)
1351 except ValueError: # not in the list
1352 pass
1353 else:
1354 break
1355 pass
1356 pass
1357
1358 ## \brief Remove scene node and asssociated scene group from DOM.
1359 #
1360 # It will remove as many as possible. Does not complain about
1361 # error in the procedure of removing.
1362 #
1363 def rm_scene_node_n_group(self, scene_node):
1364 scene_group_id = scene_node.getAttribute('ref')
1365 try:
1366 scene_group_node = self.get_node(scene_group_id)
1367 if scene_group_node.parent(): # Check it, or crash the
1368 # Inkscape.
1369 scene_group_node.parent().removeChild(scene_group_node)
1370 pass
1371 except:
1372 pass
1373
1374 try:
1375 self.rm_scene_node(scene_node)
1376 except:
1377 pass
1378 pass
1379
1380 ## \brief Create and add a svg:g for a scene under a group for a layer.
1381 #
1382 def add_scene_group(self, layer_idx):
1383 layer = self._layers[layer_idx]
1384 doc = self._doc
1385
1386 scene_group = doc.createElement('svg:g')
1387 gid = self.new_id()
1388 scene_group.setAttribute("id", gid)
1389 scene_group.setAttribute("inkscape:groupmode", "layer")
1390 scene_group.setAttribute('scene_group', 'true')
1391
1392 layer.group.appendChild(scene_group)
1393
1394 return scene_group
1395
1396 ## \brief Find layer index and scene info for a given scene node.
1397 #
1398 # \return (-1, None) for error.
1399 #
1400 def find_layer_n_scene_of_node(self, node_id):
1401 for layer_idx, layer in enumerate(self._layers):
1402 for scene_node in layer.scenes:
1403 scene_group_id = scene_node.getAttribute('ref')
1404 if scene_group_id == node_id:
1405 return layer_idx, scene_node
1406 pass
1407 pass
1408 return -1, None
1406 1409
1407 def insert_frames(self, layer_idx, frame_idx, num): 1410 def insert_frames(self, layer_idx, frame_idx, num):
1408 layer = self._layers[layer_idx] 1411 layer = self._layers[layer_idx]
1409 for scene_node in layer.scenes: 1412 for scene_node in layer.scenes:
1410 start, end, tween_type = self.parse_one_scene(scene_node) 1413 start, end, tween_type = self.parse_one_scene(scene_node)