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