Mercurial > MadButterfly
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) |