Mercurial > MadButterfly
comparison pyink/MBScene.py @ 1231:d28b1b840bfc
Integrate MBDOM_UI to MBScene
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Mon, 10 Jan 2011 11:45:12 +0800 |
parents | f0864d7177e3 |
children | 6d4de488389e |
comparison
equal
deleted
inserted
replaced
1230:f0864d7177e3 | 1231:d28b1b840bfc |
---|---|
74 def addEventListener(obj, type, func, arg): | 74 def addEventListener(obj, type, func, arg): |
75 obs = ObjectWatcher(obj, type, func, arg) | 75 obs = ObjectWatcher(obj, type, func, arg) |
76 obj.addSubtreeObserver(obs) | 76 obj.addSubtreeObserver(obs) |
77 pass | 77 pass |
78 | 78 |
79 def _travel_DOM(node): | 79 ## \brief Iterator to travel a sub-tree of DOM. |
80 # | |
81 def _DOM_iterator(node): | |
80 nodes = [node] | 82 nodes = [node] |
81 while nodes: | 83 while nodes: |
82 node = nodes.pop(0) | 84 node = nodes.pop(0) |
83 child = node.firstChild() | 85 child = node.firstChild() |
84 while child: | 86 while child: |
544 for idx in range(layer_idx, len(layers)): | 546 for idx in range(layer_idx, len(layers)): |
545 layers[idx].idx = idx | 547 layers[idx].idx = idx |
546 pass | 548 pass |
547 pass | 549 pass |
548 | 550 |
551 def get_layer_num(self): | |
552 return len(self._layers) | |
553 | |
549 def find_layer_n_scene_of_node(self, node_id): | 554 def find_layer_n_scene_of_node(self, node_id): |
550 for layer_idx, layer in enumerate(self._layers): | 555 for layer_idx, layer in enumerate(self._layers): |
551 for scene_node in layer.scenes: | 556 for scene_node in layer.scenes: |
552 scene_group_id = scene_node.getAttribute('ref') | 557 scene_group_id = scene_node.getAttribute('ref') |
553 if scene_group_id == node_id: | 558 if scene_group_id == node_id: |
554 return layer_idx, scene_node | 559 return layer_idx, scene_node |
555 pass | 560 pass |
556 pass | 561 pass |
557 pass | 562 return -1, None |
558 | 563 |
559 def get_layer_group(self, layer_idx): | 564 def get_layer_group(self, layer_idx): |
560 layer = self._layers[layer_idx] | 565 layer = self._layers[layer_idx] |
561 return layer.group | 566 return layer.group |
562 | 567 |
563 def get_all_scene_node_of_layer(self, layer_idx): | 568 def get_all_scene_node_of_layer(self, layer_idx): |
564 layer = self._layers[layer_idx] | 569 layer = self._layers[layer_idx] |
565 return layer.scenes | 570 return layer.scenes |
571 | |
572 def add_frames(self, layer_idx, frame_idx, num): | |
573 layer = self._layers[layer_idx] | |
574 for scene_node in layer.scenes: | |
575 start, end, tween_type = self._parse_one_scene(scene_node) | |
576 if start >= frame_idx: | |
577 self.chg_scene_node(scene_node, start=(start + num)) | |
578 pass | |
579 if end >= frame_idx: | |
580 self.chg_scene_node(scene_node, end=(end + num)) | |
581 pass | |
582 pass | |
583 pass | |
584 | |
585 ## \brief Remove frames | |
586 # | |
587 # - Scenes covered by removing range were removed. | |
588 # - Scenes after removing range were shifted left. | |
589 # | |
590 def rm_frames(self, layer_idx, frame_idx, num): | |
591 layer = self._layers[layer_idx] | |
592 | |
593 last_rm = frame_idx + num - 1 # last removed frame | |
594 for scene_node in layer.scenes: | |
595 start, end, tween_type = \ | |
596 self._dom._parse_one_scene(scene_node) | |
597 | |
598 if end < frame_idx: | |
599 continue | |
600 | |
601 if start > last_rm: # this scene is at right side | |
602 self.chg_scene_node(scene_node, | |
603 start=(start - num), | |
604 end=(end - num)) | |
605 else: # this scene is covered by removing range | |
606 self.rm_scene_node_n_group(scene_node) | |
607 pass | |
608 pass | |
609 pass | |
566 pass | 610 pass |
567 | 611 |
568 ## \brief Maintain frameline list for MBScene. | 612 ## \brief Maintain frameline list for MBScene. |
569 # | 613 # |
570 class MBScene_framelines(object): | 614 class MBScene_framelines(object): |
576 def __init__(self, *args, **kws): | 620 def __init__(self, *args, **kws): |
577 super(MBScene_framelines, self).__init__(*args, **kws) | 621 super(MBScene_framelines, self).__init__(*args, **kws) |
578 | 622 |
579 self._last_mouse_over_frameline = None | 623 self._last_mouse_over_frameline = None |
580 self._last_active_frameline = None | 624 self._last_active_frameline = None |
625 self._active_frame_callback = None | |
581 pass | 626 pass |
582 | 627 |
583 def _change_hover_frameline(self, widget, event): | 628 def _change_hover_frameline(self, widget, event): |
584 """ | 629 """ |
585 Hide all hover frames. This is a hack. We should use the lost focus | 630 Hide all hover frames. This is a hack. We should use the lost focus |
590 self._last_mouse_over_frameline.mouse_leave() | 635 self._last_mouse_over_frameline.mouse_leave() |
591 pass | 636 pass |
592 self._last_mouse_over_frameline = widget | 637 self._last_mouse_over_frameline = widget |
593 pass | 638 pass |
594 | 639 |
640 ## \brief Switch to new active frameline. | |
641 # | |
642 # Hide active frame mark for the active frame of old active frameline. It | |
643 # always shows at most one active frame mark. When a frame is activated, | |
644 # all active frame mark of other frameline should be hidden. | |
645 # | |
595 def _active_frameline(self, frameline): | 646 def _active_frameline(self, frameline): |
596 last = self._last_active_frameline | 647 last = self._last_active_frameline |
597 | 648 |
598 if last and last != frameline: | 649 if last and last != frameline: |
599 last.deactive() | 650 last.deactive() |
604 | 655 |
605 ## \brief Called for changing of active frame. | 656 ## \brief Called for changing of active frame. |
606 # | 657 # |
607 # This handle deactive previous frameline that owns an active frame when a | 658 # This handle deactive previous frameline that owns an active frame when a |
608 # frame in another frameline is activated. | 659 # frame in another frameline is activated. |
609 def _change_active_frame(self, widget, frame, button): | 660 # |
610 self._active_frameline(widget) | 661 def _change_active_frame(self, frameline, frame_idx, button): |
662 frameline.active_frame(frame_idx) | |
663 self._active_frameline(frameline) | |
664 | |
665 if self._active_frame_callback: | |
666 layer_idx = frameline.layer_idx | |
667 self._active_frame_callback(layer_idx, frame_idx) | |
668 pass | |
611 pass | 669 pass |
612 | 670 |
613 ## \brief Add a frameline into the frameline box for the given layer. | 671 ## \brief Add a frameline into the frameline box for the given layer. |
614 # | 672 # |
615 def _add_frameline(self, layer_idx): | 673 def _add_frameline(self, layer_idx): |
637 for idx in range(layer_idx, len(self._framelines)): | 695 for idx in range(layer_idx, len(self._framelines)): |
638 self._framelines[idx].layer_idx = idx | 696 self._framelines[idx].layer_idx = idx |
639 pass | 697 pass |
640 | 698 |
641 line.label = label | 699 line.label = label |
642 # TODO: The following line of code should be moved to MBScene. | |
643 line.connect(line.FRAME_BUT_PRESS, self.onCellClick) | |
644 line.connect('motion-notify-event', self._change_hover_frameline) | 700 line.connect('motion-notify-event', self._change_hover_frameline) |
645 line.connect(frameline.FRAME_BUT_PRESS, self._change_active_frame) | 701 line.connect(frameline.FRAME_BUT_PRESS, self._change_active_frame) |
646 pass | 702 pass |
647 | 703 |
648 ## \brief Remove the given frameline from the frameline box. | 704 ## \brief Remove the given frameline from the frameline box. |
706 | 762 |
707 ## \brief Get layer and frame index of current active frame. | 763 ## \brief Get layer and frame index of current active frame. |
708 # | 764 # |
709 # \return (-1, -1) for no active, (layer_idx, frame_idx) for current | 765 # \return (-1, -1) for no active, (layer_idx, frame_idx) for current |
710 # active. | 766 # active. |
711 def get_active_frame(self): | 767 def get_active_layer_frame(self): |
712 if self._active_frameline: | 768 if self._active_frameline: |
713 layer_idx = self._active_frameline.layer_idx | 769 layer_idx = self._active_frameline.layer_idx |
714 frame_idx = self._active_frameline.get_active_frame() | 770 frame_idx = self._active_frameline.get_active_frame() |
715 if frame_idx != -1: | 771 if frame_idx != -1: |
716 return layer_idx, frame_idx | 772 return layer_idx, frame_idx |
794 def set_keyframe_data(self, layer_idx, frame_idx, data): | 850 def set_keyframe_data(self, layer_idx, frame_idx, data): |
795 frameline = self._framelines[layer_idx] | 851 frameline = self._framelines[layer_idx] |
796 frameline.set_frame_data(frame_idx, data) | 852 frameline.set_frame_data(frame_idx, data) |
797 pass | 853 pass |
798 | 854 |
799 def insert_frames(self, layer_idx, frame_idx, num): | 855 def add_frames(self, layer_idx, frame_idx, num): |
800 assert num > 0 | 856 assert num > 0 |
801 assert frame_idx >= 0 | 857 assert frame_idx >= 0 |
802 frameline = self._framelines[layer_idx] | 858 frameline = self._framelines[layer_idx] |
803 for i in range(num): | 859 for i in range(num): |
804 frameline.insert_frame(frame_idx) | 860 frameline.add_frame(frame_idx) |
861 pass | |
862 pass | |
863 | |
864 ## \brief Remove a number of frames from the frameline. | |
865 # | |
866 # All key frames and tweens covered by removing range would be removed. | |
867 # | |
868 def rm_frames(self, layer_idx, frame_idx, num): | |
869 assert num > 0 | |
870 assert frame_idx >= 0 | |
871 | |
872 frameline = self._framelines[layer_idx] | |
873 | |
874 # | |
875 # Remove right key frame of last tween which left one will be removed. | |
876 # | |
877 last_rm = frame_idx + num - 1 # last removed frame | |
878 try: | |
879 start, end, tween_type = frameline.get_frame_block(last_rm) | |
880 except ValueError: # last removed frame is not in any tween | |
881 pass | |
882 else: | |
883 if start >= frame_idx and end > last_rm: | |
884 # Left key frame of the tween was removed, but not right one. | |
885 frameline.untween(start) | |
886 frameline.rm_keyframe(end) | |
887 pass | |
888 pass | |
889 | |
890 # | |
891 # Remove left key of the tween that right key frame is in removing | |
892 # range. | |
893 # | |
894 try: | |
895 start, end, tween_type = frameline.get_frame_block(frame_idx) | |
896 except ValueError: | |
897 pass | |
898 else: | |
899 if start < frame_idx and end <= last_rm: | |
900 # right key frame is in removing range but left one. | |
901 frameline.untween(start) | |
902 frameline.rm_keyframe(start) | |
903 frameline.rm_keyframe(end) | |
904 pass | |
905 pass | |
906 | |
907 for i in range(num): | |
908 frameline.rm_frame(frame_idx) | |
805 pass | 909 pass |
806 pass | 910 pass |
807 | 911 |
808 ## \brief Set label of a layer. | 912 ## \brief Set label of a layer. |
809 # | 913 # |
810 def set_layer_label(self, layer_idx, txt): | 914 def set_layer_label(self, layer_idx, txt): |
811 frameline = self._framelines[layer_idx] | 915 frameline = self._framelines[layer_idx] |
812 frameline.label.set_text(txt) | 916 frameline.label.set_text(txt) |
917 pass | |
918 | |
919 def register_active_frame_callback(self, cb): | |
920 self._active_frame_callback = cb | |
813 pass | 921 pass |
814 pass | 922 pass |
815 | 923 |
816 ## \brief Gateway of DOM-tree to syncrhonize data-model and UI. | 924 ## \brief Gateway of DOM-tree to syncrhonize data-model and UI. |
817 # | 925 # |
846 # | 954 # |
847 # This method is called to create a frameline for every layer found when | 955 # This method is called to create a frameline for every layer found when |
848 # loading a document. | 956 # loading a document. |
849 # | 957 # |
850 def _add_frameline_for_every_layer(self): | 958 def _add_frameline_for_every_layer(self): |
851 for layer_idx in range(len(self._dom._layers)): | 959 for layer_idx in range(self._dom.get_layer_num()): |
852 layer_group_node = self._dom.get_layer_group(layer_idx) | 960 layer_group_node = self._dom.get_layer_group(layer_idx) |
853 label = layer_group_node.getAttribute('inkscape:label') | 961 label = layer_group_node.getAttribute('inkscape:label') |
854 | 962 |
855 self._fl_mgr._add_frameline(layer_idx) | 963 self._fl_mgr._add_frameline(layer_idx) |
856 self._fl_mgr.set_layer_label(layer_idx, label) | 964 self._fl_mgr.set_layer_label(layer_idx, label) |
920 self._dom.rm_scene_node_n_group(scene_node) | 1028 self._dom.rm_scene_node_n_group(scene_node) |
921 | 1029 |
922 self._fl_mgr.rm_key_n_tween(layer_idx, key_frame_idx) | 1030 self._fl_mgr.rm_key_n_tween(layer_idx, key_frame_idx) |
923 pass | 1031 pass |
924 | 1032 |
925 def insert_frames(self, layer_idx, frame_idx, num): | 1033 def add_frames(self, layer_idx, frame_idx, num): |
926 self._fl_mgr.insert_frames(layer_idx, frame_idx, num) | 1034 self._fl_mgr.add_frames(layer_idx, frame_idx, num) |
927 | 1035 self._dom.add_frames(layer_idx, frame_idx, num) |
928 key_tweens = self._fl_mgr.get_all_key_tween_of_layer(layer_idx) | 1036 pass |
929 for start, end, tween_type in key_tweens: | 1037 |
930 if frame_idx > end: | 1038 def rm_frames(self, layer_idx, frame_idx, num): |
931 continue | 1039 self._fl_mgr.add_frames(layer_idx, frame_idx, num) |
932 | 1040 self._dom.rm_frames(layer_idx, frame_idx, num) |
933 scene_node = self._fl_mgr.get_keyframe_data(start) | |
934 self._dom.chg_scene_node(scene_node, start=start, end=end) | |
935 pass | |
936 pass | 1041 pass |
937 | 1042 |
938 def add_layer(self, layer_idx): | 1043 def add_layer(self, layer_idx): |
939 self._dom.add_layer(layer_idx) | 1044 self._dom.add_layer(layer_idx) |
940 self._fl_mgr._add_frameline(layer_idx) | 1045 self._fl_mgr._add_frameline(layer_idx) |
948 ## \bref Return current active frame and its layer. | 1053 ## \bref Return current active frame and its layer. |
949 # | 1054 # |
950 # \return (layer_idx, frame_idx) of active frame, or (-1, -1) when no | 1055 # \return (layer_idx, frame_idx) of active frame, or (-1, -1) when no |
951 # active one. | 1056 # active one. |
952 def get_active_layer_frame(self): | 1057 def get_active_layer_frame(self): |
953 layer_idx, frame_idx = self._fl_mgr.get_active_frame() | 1058 layer_idx, frame_idx = self._fl_mgr.get_active_layer_frame() |
954 return layer_idx, frame_idx | 1059 return layer_idx, frame_idx |
955 | 1060 |
956 def rm_layer(self, layer_idx): | 1061 def rm_layer(self, layer_idx): |
957 self._dom.rm_layer(layer_idx) | 1062 self._dom.rm_layer(layer_idx) |
958 self._fl_mgr._remove_frameline(layer_idx) | 1063 self._fl_mgr._remove_frameline(layer_idx) |
959 self._fl_mgr._show_framelines() | 1064 self._fl_mgr._show_framelines() |
960 pass | 1065 pass |
961 | 1066 |
1067 def get_layer_num(self): | |
1068 return self._dom.get_layer_num() | |
1069 | |
962 ## \brief Return associated group node for a key frame. | 1070 ## \brief Return associated group node for a key frame. |
963 # | 1071 # |
964 def get_keyframe_group(self, layer_idx, frame_idx): | 1072 def get_keyframe_group(self, layer_idx, frame_idx): |
965 scene_node = self._fl_mgr.get_keyframe_data(frame_idx) | 1073 scene_node = self._fl_mgr.get_keyframe_data(frame_idx) |
966 scene_group_id = scene_node.getAttribute('ref') | 1074 scene_group_id = scene_node.getAttribute('ref') |
968 return scene_group_node | 1076 return scene_group_node |
969 | 1077 |
970 ## \brief Find an associated key frame and tween info for a group ID. | 1078 ## \brief Find an associated key frame and tween info for a group ID. |
971 # | 1079 # |
972 def find_keyframe_from_group(self, scene_group_id): | 1080 def find_keyframe_from_group(self, scene_group_id): |
973 scene_node = self._dom.get_scene(scene_group_id) | 1081 layer_idx, scene_node = \ |
1082 self._dom.find_layer_n_scene_of_node(scene_group_id) | |
974 start, end, tween_name = self._dom._parse_one_scene(scene_node) | 1083 start, end, tween_name = self._dom._parse_one_scene(scene_node) |
975 tween_type = self._tween_type_names.index(tween_name) | 1084 tween_type = self._tween_type_names.index(tween_name) |
1085 return layer_idx, (start, end, tween_type) | |
1086 | |
1087 ## \brief Return key and tween info for given frame index. | |
1088 # | |
1089 # The return key is at given frame, or its tween covers given frame. | |
1090 # | |
1091 def get_key(self, layer_idx, frame_idx): | |
1092 start, end, tween_type = \ | |
1093 self._fl_mgr.get_key_tween(layer_idx, frame_idx) | |
976 return start, end, tween_type | 1094 return start, end, tween_type |
977 | 1095 |
978 def get_left_key(self, layer_idx, frame_idx): | 1096 def get_left_key(self, layer_idx, frame_idx): |
979 start, end, tween_type = \ | 1097 start, end, tween_type = \ |
980 self._fl_mgr.get_left_key_tween(layer_idx, frame_idx) | 1098 self._fl_mgr.get_left_key_tween(layer_idx, frame_idx) |
981 return start, end, tween_type | 1099 return start, end, tween_type |
1100 | |
1101 ## \brief Return widget showing frames and layers. | |
1102 # | |
1103 def get_frame_ui_widget(self): | |
1104 return self._fl_mgr._frameline_box | |
1105 | |
1106 def register_active_frame_cb(self, cb): | |
1107 self._fl_mgr.register_active_frame_cb(cb) | |
1108 pass | |
1109 | |
1110 def set_layer_label(self, txt): | |
1111 self._fl_mgr.set_layer_label(txt) | |
1112 pass | |
982 pass | 1113 pass |
983 | 1114 |
984 ## \brief MBScene connect GUI and DOM-tree | 1115 ## \brief MBScene connect GUI and DOM-tree |
985 # | 1116 # |
986 # This class connect behavior of GUI to the DOM-tree. All about GUI is | 1117 # This class connect behavior of GUI to the DOM-tree. All about GUI is |
999 | 1130 |
1000 self.desktop = desktop | 1131 self.desktop = desktop |
1001 self.window = win | 1132 self.window = win |
1002 self.top = None | 1133 self.top = None |
1003 self.last_update = None | 1134 self.last_update = None |
1004 pybInkscape.inkscape.connect('change_selection', self.show_selection) | 1135 pybInkscape.inkscape.connect('change_selection', self.on_selection) |
1005 self.last_select = None | 1136 self.last_select = None |
1006 self._lockui = False | 1137 self._lockui = False |
1007 self.tween = None | 1138 self.tween = None |
1008 self.document = None | 1139 self.document = None |
1009 self.root = root | 1140 self.root = root |
1010 self.framerate = 12 | 1141 self.framerate = 12 |
1011 self._disable_tween_type_selector = False | 1142 self._disable_tween_type_selector = False |
1012 pass | 1143 |
1013 | 1144 self._dom = MBDOM_UI() |
1014 def show_selection(self,w,obj): | |
1015 objs = self.desktop.selection.list() | |
1016 try: | |
1017 o = objs[0] | |
1018 print o.getCenter() | |
1019 if o == self.last_select: | |
1020 return | |
1021 except: | |
1022 self.nameEditor.set_text('') | |
1023 self.last_select = None | |
1024 return | |
1025 self.last_select = o | |
1026 try: | |
1027 self.nameEditor.set_text(o.getAttribute("inkscape:label")) | |
1028 except: | |
1029 self.nameEditor.set_text('') | |
1030 pass | |
1031 | |
1032 # The selection is a PYSPObject. Convert it to be PYNode | |
1033 self.change_active_frame(self.last_select.repr.parent()) | |
1034 pass | 1145 pass |
1035 | 1146 |
1036 def change_active_frame(self, node): | 1147 def change_active_frame(self, node): |
1037 """ | 1148 """ |
1038 Change the active frame to the current selected node. This will | 1149 Change the active frame to the current selected node. This will |
1039 tell users where the current node is. | 1150 tell users where the current node is. |
1040 """ | 1151 """ |
1041 | |
1042 while node: | 1152 while node: |
1043 try: | 1153 try: |
1044 node_id = node.getAttribute('id') | 1154 node_id = node.getAttribute('id') |
1045 except: | 1155 except: |
1046 node = node.parent() | 1156 node = node.parent() |
1047 continue | 1157 continue |
1048 | 1158 |
1049 try: | 1159 try: |
1050 # Search for the frameline which use @node as one of its scene | 1160 layer_idx, (start, end, tween_type) = \ |
1051 # group. | 1161 self._dom.find_keyframe_from_group(node_id) |
1052 try: | |
1053 layer_idx, scene_node = \ | |
1054 self.find_layer_n_scene_of_node(node_id) | |
1055 except: | |
1056 pass | |
1057 else: | |
1058 start, end, tween_type_name = \ | |
1059 self._parse_one_scene(scene_node) | |
1060 self.active_frame(layer_idx, start) | |
1061 return | |
1062 except: | 1162 except: |
1063 traceback.print_exc() | 1163 pass |
1064 pass | 1164 else: |
1165 self._dom.set_active_layer_frame(layer_idx, start) | |
1166 break | |
1167 | |
1065 node = node.parent() | 1168 node = node.parent() |
1066 pass | 1169 pass |
1067 pass | 1170 pass |
1068 | 1171 |
1069 def insertKeyScene(self, line, frame): | 1172 def insertKeyScene(self, layer_idx, frame_idx): |
1070 """ | 1173 """ |
1071 Insert a new key scene into the stage. If the nth is always a | 1174 Insert a new key scene into the stage. If the nth is always a |
1072 key scene, we will return without changing anything. If the | 1175 key scene, we will return without changing anything. If the |
1073 nth is a filled scene, we will break the original scene into | 1176 nth is a filled scene, we will break the original scene into |
1074 two parts. If the nth is out of any scene, we will append a | 1177 two parts. If the nth is out of any scene, we will append a |
1075 new scene. | 1178 new scene. |
1076 | 1179 |
1077 """ | 1180 """ |
1078 doc = self._doc | |
1079 layer_idx = self._framelines.index(line) | |
1080 | |
1081 scene_group = self.add_scene_group(layer_idx) | |
1082 scene_group_id = scene_group.getAttribute('id') | |
1083 scene_node = self.add_scene_node(frame, frame, ref=scene_group_id) | |
1084 line.add_keyframe(frame, scene_node) | |
1085 | |
1086 for node in self._layers[layer_idx].group.childList(): | |
1087 try: | |
1088 label = node.getAttribute('inkscape:label') | |
1089 except: | |
1090 continue | |
1091 if label == 'dup': | |
1092 node.setAttribute('style', 'display: none') | |
1093 pass | |
1094 pass | |
1095 pass | |
1096 | |
1097 def removeKeyScene(self, frameline, frame_idx): | |
1098 start, end, scene_type = frameline.get_frame_block(frame_idx) | |
1099 scene_node = frameline.get_frame_data(start) | |
1100 | |
1101 frameline.rm_keyframe(start) | |
1102 if start != end: | |
1103 frameline.rm_keyframe(end) | |
1104 pass | |
1105 | |
1106 scene_group_id = scene_node.getAttribute('ref') | |
1107 scene_group = self.get_node(scene_group_id) | |
1108 scene_group.parent().removeChild(scene_group) | |
1109 scene_node.parent().removeChild(scene_node) | |
1110 | |
1111 try: | 1181 try: |
1112 frameline.duplicateGroup.setAttribute('style', 'display: none') | 1182 self._dom.add_key(layer_idx, frame_idx) |
1113 except AttributeError: | 1183 except ValueError: |
1114 pass | 1184 # existed key frame |
1185 pass | |
1186 pass | |
1187 | |
1188 def removeKeyScene(self, layer_idx, frame_idx): | |
1189 self._dom.rm_key_n_tween(layer_idx, frame_idx) | |
1190 self.setCurrentScene(frame_idx) | |
1115 pass | 1191 pass |
1116 | 1192 |
1117 def extendScene(self): | 1193 def extendScene(self): |
1118 frame_idx = self.last_frame | 1194 layer_idx, frame_idx = self._dom.get_active_layer_frame() |
1119 frameline = self.last_line | 1195 start, end, tween_type = \ |
1120 | 1196 self._dom.get_left_key(layer_idx, frame_idx) |
1121 start, end, scene_type = frameline.get_frame_block_floor(frame_idx) | 1197 tween_len = frame_idx - start |
1122 if frame_idx <= end: | 1198 self._dom.tween(layer_idx, start, tween_len, tween_type) |
1123 return | |
1124 | |
1125 if start < end: | |
1126 frameline.rm_keyframe(end) | |
1127 pass | |
1128 | |
1129 scene_node = frameline.get_frame_data(start) | |
1130 self.chg_scene_node(scene_node, end=frame_idx) | |
1131 frameline.add_keyframe(frame_idx) | |
1132 frameline.tween(start, scene_type) | |
1133 pass | 1199 pass |
1134 | 1200 |
1135 def setCurrentScene(self, idx): | 1201 def setCurrentScene(self, idx): |
1136 """ | 1202 """ |
1137 Update the scene group according to the curretn scene | 1203 Update the scene group according to the curretn scene |
1249 pass | 1315 pass |
1250 pass | 1316 pass |
1251 pass | 1317 pass |
1252 pass | 1318 pass |
1253 | 1319 |
1254 def selectSceneObject(self, frameline, frame_idx): | 1320 def setTweenType(self, tween_type): |
1321 tween_type_name = self._tween_type_names[tween_type] | |
1322 | |
1323 self._disable_tween_type_selector = True | |
1324 self.tweenTypeSelector.set_active(tween_type_name) | |
1325 self._disable_tween_type_selector = False | |
1326 pass | |
1327 | |
1328 def selectSceneObject(self, layer_idx, frame_idx): | |
1255 try: | 1329 try: |
1256 start, stop, tween_type = frameline.get_frame_block(frame_idx) | 1330 start, stop, tween_type = self._dom.get_key(frame_idx) |
1257 except: | 1331 except: |
1258 return | 1332 return |
1259 | 1333 |
1260 scene_node = frameline.get_frame_data(start) | 1334 scene_group = self._dom.get_keyframe_group(layer_idx, start) |
1261 scene_group_id = scene_node.getAttribute('ref') | |
1262 scene_group = self.get_node(scene_group_id) | |
1263 self.enterGroup(scene_group) | 1335 self.enterGroup(scene_group) |
1264 self.setTweenType(tween_type) | 1336 self.setTweenType(tween_type) |
1265 pass | 1337 pass |
1266 | 1338 |
1267 def setTweenType(self, tween_type): | |
1268 sel_type = self._frameline_tween_types.index(tween_type) | |
1269 self._disable_tween_type_selector = True | |
1270 self.tweenTypeSelector.set_active(sel_type) | |
1271 self._disable_tween_type_selector = False | |
1272 pass | |
1273 | |
1274 ## \brief Remove the layer that lost the layer group. | 1339 ## \brief Remove the layer that lost the layer group. |
1275 # | 1340 # |
1276 # This function is called when a layer group being removed from the | 1341 # This function is called when a layer group being removed from the |
1277 # DOM-tree. | 1342 # DOM-tree. |
1278 def _remove_lost_group_layer(self, layer_idx): | 1343 def _remove_lost_group_layer(self, layer_idx): |
1357 | 1422 |
1358 layer_idx = layer_idx + 1 | 1423 layer_idx = layer_idx + 1 |
1359 pass | 1424 pass |
1360 pass | 1425 pass |
1361 | 1426 |
1362 ## \brief Update content of a frameline from scenes of respective layer. | |
1363 # | |
1364 def _update_frameline_content(self, layer_idx): | |
1365 line = self._framelines[layer_idx] | |
1366 layer = self._layers[layer_idx] | |
1367 for scene_node in layer.scenes: | |
1368 start, end, tween_name = self._parse_one_scene(scene_node) | |
1369 | |
1370 line.add_keyframe(start) | |
1371 if start != end: | |
1372 line.add_keyframe(end) | |
1373 tween_type_idx = self._tween_type_names.index(tween_name) | |
1374 tween_type = self._frameline_tween_types[tween_type_idx] | |
1375 line.tween(start, tween_type) | |
1376 pass | |
1377 line.set_frame_data(start, scene_node) | |
1378 pass | |
1379 pass | |
1380 | |
1381 ## \brief Add a frameline for every found layer. | |
1382 # | |
1383 # This method is called to create a frameline for every layer found when | |
1384 # loading a document. | |
1385 # | |
1386 def _add_frameline_for_every_layer(self): | |
1387 for layer_idx in range(len(self._layers)): | |
1388 self._add_frameline(layer_idx) | |
1389 line = self._framelines[layer_idx] | |
1390 layer = self._layers[layer_idx] | |
1391 try: | |
1392 label = layer.group.getAttribute('inkscape:label') | |
1393 except: | |
1394 label = layer.group.getAttribute('id') | |
1395 pass | |
1396 line.label.set_text(label) | |
1397 | |
1398 self._update_frameline_content(layer_idx) | |
1399 pass | |
1400 pass | |
1401 | |
1402 def duplicateKeyScene(self): | 1427 def duplicateKeyScene(self): |
1403 # Search for the current scene | 1428 # Search for the current scene |
1404 frameline = self.last_line | 1429 layer_idx, frame_idx = self._dom.get_active_layer_frame() |
1405 frame_idx = self.last_frame | 1430 |
1406 | |
1407 try: | 1431 try: |
1408 start, end, scene_type = frameline.get_frame_block_floor(frame_idx) | 1432 left_start, left_end, left_tween_type = \ |
1433 self._dom.get_left_key(layer_idx, frame_idx) | |
1409 except: | 1434 except: |
1410 return | 1435 return |
1411 if end >= frame_idx: | 1436 if left_end >= frame_idx: |
1412 return | 1437 return |
1413 | 1438 |
1414 prev_scene_node = frameline.get_frame_data(start) | 1439 self._dom.add_key(layer_idx, frame_idx) |
1415 prev_scene_group_id = prev_scene_node.getAttribute('ref') | 1440 |
1416 | 1441 scene_group = self._dom.get_keyframe_group(layer_idx, frame_idx) |
1417 scene_group = self.duplicateSceneGroup(prev_scene_group_id) | 1442 left_scene_group = \ |
1418 scene_group_id = scene_group.getAttribute('id') | 1443 self._dom.get_keyframe_group(layer_idx, left_frame_idx) |
1419 scene_node = self.add_scene_node(frame_idx, frame_idx, | 1444 |
1420 ref=scene_group_id) | 1445 left_scene_group_id = left_scene_group.getAttribute('id') |
1421 | 1446 dup_group = self._duplicate_group(left_scene_group_id, scene_group) |
1422 frameline.add_keyframe(frame_idx, scene_node) | |
1423 | 1447 |
1424 self.setCurrentScene(frame_idx) | 1448 self.setCurrentScene(frame_idx) |
1425 pass | 1449 pass |
1426 | 1450 |
1427 def duplicateSceneGroup(self,gid): | 1451 ## \brief Duplicate children of a group. |
1452 # | |
1453 # Duplicate children of a group, and append them to another group. | |
1454 # | |
1455 def _duplicate_group(self, src_group, dst_group): | |
1428 # Search for the duplicated group | 1456 # Search for the duplicated group |
1429 root = self._root | 1457 root = self._root |
1430 doc = self._doc | 1458 doc = self._doc |
1431 orig = self.get_node(gid) | 1459 |
1432 scene_group = orig.duplicate(doc) | 1460 dup_group = orig.duplicate(doc) |
1433 | 1461 for child in dup_group.childList(): |
1434 old_nodes = _travel_DOM(orig) | 1462 dst_group.appendChild(child) |
1435 new_nodes = _travel_DOM(scene_group) | 1463 pass |
1464 | |
1465 old_nodes = _DOM_iterator(src_group) | |
1466 new_nodes = _DOM_iterator(dst_group) | |
1436 for old_node in old_nodes: | 1467 for old_node in old_nodes: |
1437 old_node_id = old_node.getAttribute('id') | 1468 old_node_id = old_node.getAttribute('id') |
1438 new_node = new_nodes.next() | 1469 new_node = new_nodes.next() |
1439 new_node.setAttribute('ns0:duplicate-src', old_node_id) | 1470 new_node.setAttribute('ns0:duplicate-src', old_node_id) |
1440 pass | 1471 pass |
1441 | 1472 pass |
1442 layer = self._layers[self.last_line.layer_idx] | |
1443 gid = layer.group.getAttribute("inkscape:label")+self.new_id() | |
1444 scene_group.setAttribute("id",gid) | |
1445 scene_group.setAttribute("inkscape:groupmode","layer") | |
1446 layer.group.appendChild(scene_group) | |
1447 return scene_group | |
1448 | 1473 |
1449 def changeObjectLabel(self,w): | 1474 def changeObjectLabel(self,w): |
1450 o = self.desktop.selection.list()[0] | 1475 o = self.desktop.selection.list()[0] |
1451 o.setAttribute("inkscape:label", self.nameEditor.get_text()) | 1476 o.setAttribute("inkscape:label", self.nameEditor.get_text()) |
1452 pass | 1477 pass |
1472 self._lockui = True | 1497 self._lockui = True |
1473 self._make_layers_integral() | 1498 self._make_layers_integral() |
1474 self._lockui = False | 1499 self._lockui = False |
1475 pass | 1500 pass |
1476 | 1501 |
1477 def onCellClick(self, line, frame, but): | 1502 def addTweenTypeSelector(self, hbox): |
1478 self.last_line = line | 1503 tweenbox = gtk.HBox() |
1479 self.last_frame = frame | 1504 label = gtk.Label('Tween Type') |
1480 self.last_line.active_frame(frame) | 1505 tweenbox.pack_start(label) |
1506 | |
1507 self.tweenTypeSelector = gtk.combo_box_new_text() | |
1508 self.tweenTypeSelector.append_text('normal') | |
1509 self.tweenTypeSelector.append_text('scale') | |
1510 self.tweenTypeSelector.set_active(0) | |
1511 tweenbox.pack_start(self.tweenTypeSelector, expand=False, fill=False) | |
1512 hbox.pack_start(tweenbox, expand=False, fill=False) | |
1513 self.tweenTypeSelector.connect('changed', self.onTweenTypeChange) | |
1514 pass | |
1515 | |
1516 def on_selection(self,w,obj): | |
1517 objs = self.desktop.selection.list() | |
1518 try: | |
1519 o = objs[0] | |
1520 print o.getCenter() | |
1521 if o == self.last_select: | |
1522 return | |
1523 except: | |
1524 self.nameEditor.set_text('') | |
1525 self.last_select = None | |
1526 return | |
1527 self.last_select = o | |
1528 try: | |
1529 self.nameEditor.set_text(o.getAttribute("inkscape:label")) | |
1530 except: | |
1531 self.nameEditor.set_text('') | |
1532 pass | |
1533 | |
1534 # The selection is a PYSPObject. Convert it to be PYNode | |
1535 self.change_active_frame(self.last_select.repr.parent()) | |
1536 pass | |
1537 | |
1538 def onCellClick(self, layer_idx, frame_idx): | |
1481 self._lockui = True | 1539 self._lockui = True |
1482 self.doEditScene(None) | 1540 |
1541 self.setCurrentScene(frame_idx) | |
1542 self.selectSceneObject(layer_idx, frame_idx) | |
1543 | |
1483 self._lockui = False | 1544 self._lockui = False |
1484 pass | 1545 pass |
1485 | |
1486 def doEditScene(self, w): | |
1487 self.setCurrentScene(self.last_frame) | |
1488 self.selectSceneObject(self.last_line, self.last_frame) | |
1489 pass | |
1490 | 1546 |
1491 def doInsertKeyScene(self,w): | 1547 def doInsertKeyScene(self,w): |
1492 self._lockui=True | 1548 self._lockui=True |
1493 self.insertKeyScene(self.last_line, self.last_frame) | 1549 layer_idx, frame_idx = self._dom.get_active_layer_frame() |
1494 self.selectSceneObject(self.last_line, self.last_frame) | 1550 self.insertKeyScene(layer_idx, frame_idx) |
1551 self.selectSceneObject(layer_idx, frame_idx) | |
1495 self._lockui=False | 1552 self._lockui=False |
1496 # self.grid.show_all() | |
1497 return | 1553 return |
1498 | 1554 |
1499 def doDuplicateKeyScene(self,w): | 1555 def doDuplicateKeyScene(self,w): |
1500 self._lockui = True | 1556 self._lockui = True |
1501 self.duplicateKeyScene() | 1557 self.duplicateKeyScene() |
1502 self._lockui = False | 1558 self._lockui = False |
1503 | 1559 |
1504 def doRemoveScene(self,w): | 1560 def doRemoveScene(self,w): |
1505 self._lockui = True | 1561 self._lockui = True |
1506 self.removeKeyScene(self.last_line, self.last_frame) | 1562 layer_idx, frame_idx = self._dom.get_active_layer_frame() |
1563 self.removeKeyScene(layer_idx, frame_idx) | |
1507 self._lockui = False | 1564 self._lockui = False |
1508 return | 1565 return |
1509 | 1566 |
1510 | 1567 |
1511 def doExtendScene(self,w): | 1568 def doExtendScene(self,w): |
1542 self.current = self.current + 1 | 1599 self.current = self.current + 1 |
1543 tmout = 1000 / self.framerate | 1600 tmout = 1000 / self.framerate |
1544 self.last_update = glib.timeout_add(tmout, self.doRunNext) | 1601 self.last_update = glib.timeout_add(tmout, self.doRunNext) |
1545 pass | 1602 pass |
1546 | 1603 |
1547 def remove_frame(self, line, frame): | |
1548 for start, end, tween_type in line.get_frame_blocks(): | |
1549 if frame > end: | |
1550 # Don't change the tween before the select frame | |
1551 continue | |
1552 elif frame == start: | |
1553 # Please use remove key frame ro remove the key frame instead | |
1554 return | |
1555 elif frame < start: | |
1556 # For all tweens after the frame, shift both key frames by one | |
1557 scene_node = line.get_frame_data(start) | |
1558 self.chg_scene_node(scene_node, start=start-1, end=end-1) | |
1559 line.rm_keyframe(start) | |
1560 | |
1561 if start != end: | |
1562 line.rm_keyframe(end) | |
1563 line.add_keyframe(start-1) | |
1564 line.set_frame_data(start-1, scene_node) | |
1565 if start != end: | |
1566 line.add_keyframe(end-1) | |
1567 line.tween(start-1, tween_type) | |
1568 pass | |
1569 else: | |
1570 # For the tween contain the frame, remove the end keyframe | |
1571 # and put it back one frame before. The tween is removed | |
1572 # if the tween has one frame only. In this case, keep only | |
1573 # the start key frame and remove the second one. | |
1574 scene_node = line.get_frame_data(start) | |
1575 self.chg_scene_node(scene_node, end=end-1) | |
1576 line.rm_keyframe(end) | |
1577 if start != end-1: | |
1578 line.add_keyframe(end-1) | |
1579 line.tween(start, tween_type) | |
1580 pass | |
1581 pass | |
1582 pass | |
1583 | |
1584 def insert_frame(self, line, frame): | |
1585 for start, end, tween_type in line.get_frame_blocks(): | |
1586 print "start=",start | |
1587 print "end=",end | |
1588 if frame > end: | |
1589 # Don't change the tween before the select frame | |
1590 continue | |
1591 elif frame <= start: | |
1592 # For all tweens after the frame, shift both key frames by one | |
1593 scene_node = line.get_frame_data(start) | |
1594 if scene_node==None: continue | |
1595 self.chg_scene_node(scene_node, start=start+1, end=end+1) | |
1596 line.rm_keyframe(start) | |
1597 if start != end: | |
1598 line.rm_keyframe(end) | |
1599 line.add_keyframe(start+1) | |
1600 line.set_frame_data(start+1,scene_node) | |
1601 if start != end: | |
1602 line.add_keyframe(end+1) | |
1603 line.tween(start+1,tween_type) | |
1604 pass | |
1605 else: | |
1606 # For the tween contain the frame, remove the end keyframe | |
1607 # and put it back one frame before. The tween is removed | |
1608 # if the tween has one frame only. In this case, keep only | |
1609 # the start key frame and remove the second one. | |
1610 scene_node = line.get_frame_data(start) | |
1611 self.chg_scene_node(scene_node, end=end+1) | |
1612 line.rm_keyframe(end) | |
1613 line.add_keyframe(end+1) | |
1614 line.tween(start, tween_type) | |
1615 pass | |
1616 pass | |
1617 pass | |
1618 | |
1619 | |
1620 def doInsertFrame(self, w): | 1604 def doInsertFrame(self, w): |
1621 self.lockui=True | 1605 self.lockui=True |
1622 self.insert_frame(self.last_line, self.last_frame) | 1606 layer_idx, frame_idx = self._dom.get_active_layer_frame() |
1607 self._dom.add_frames(layer_idx, frame_idx, 1) | |
1623 self.lockui=False | 1608 self.lockui=False |
1624 | 1609 |
1625 def doRemoveFrame(self, w): | 1610 def doRemoveFrame(self, w): |
1626 self.lockui=True | 1611 self.lockui=True |
1627 self.remove_frame(self.last_line, self.last_frame) | 1612 layer_idx, frame_idx = self._dom.get_active_layer_frame() |
1613 self._dom.rm_frames(layer_idx, frame_idx, 1) | |
1628 self.lockui=False | 1614 self.lockui=False |
1629 | 1615 |
1630 def addButtons(self, hbox): | 1616 def onTweenTypeChange(self, w): |
1617 if self._disable_tween_type_selector: | |
1618 return | |
1619 | |
1620 layer_idx, frame_idx = self._dom.get_active_layer_frame() | |
1621 tween_type = self.tweenTypeSelector.get_active() | |
1622 | |
1623 start, end, old_tween_type = \ | |
1624 self._dom.get_left_key(layer_idx, frame_idx) | |
1625 if end >= frame_idx and start != end: | |
1626 # Length of tween > 1 and cover this frame | |
1627 self._dom.chg_tween(tween_type) | |
1628 pass | |
1629 pass | |
1630 | |
1631 def onQuit(self, event): | |
1632 self.OK = False | |
1633 gtk.main_quit() | |
1634 pass | |
1635 | |
1636 def onOK(self, event): | |
1637 self.OK = True | |
1638 gtk.main_quit() | |
1639 pass | |
1640 | |
1641 def _add_buttons(self, hbox): | |
1631 btn = gtk.Button('Insert Key') | 1642 btn = gtk.Button('Insert Key') |
1632 btn.connect('clicked', self.doInsertKeyScene) | 1643 btn.connect('clicked', self.doInsertKeyScene) |
1633 hbox.pack_start(btn, expand=False, fill=False) | 1644 hbox.pack_start(btn, expand=False, fill=False) |
1634 | 1645 |
1635 btn=gtk.Button('Remove Key') | 1646 btn=gtk.Button('Remove Key') |
1659 | 1670 |
1660 self.addNameEditor(hbox) | 1671 self.addNameEditor(hbox) |
1661 self.addTweenTypeSelector(hbox) | 1672 self.addTweenTypeSelector(hbox) |
1662 pass | 1673 pass |
1663 | 1674 |
1664 def onTweenTypeChange(self, w): | |
1665 if self._disable_tween_type_selector: | |
1666 return | |
1667 | |
1668 if self.last_line == None: | |
1669 return | |
1670 frameline = self.last_line | |
1671 start, end, old_tween_type = frameline.get_frame_block(self.last_frame) | |
1672 | |
1673 type_idx = self.tweenTypeSelector.get_active() | |
1674 tween_type = self._frameline_tween_types[type_idx] | |
1675 type_name = self._tween_type_names[type_idx] | |
1676 | |
1677 frameline.tween(start, tween_type) | |
1678 | |
1679 scene_node = frameline.get_frame_data(start) | |
1680 self.chg_scene_node(scene_node, tween_type=type_name) | |
1681 pass | |
1682 | |
1683 def addTweenTypeSelector(self, hbox): | |
1684 tweenbox = gtk.HBox() | |
1685 label = gtk.Label('Tween Type') | |
1686 tweenbox.pack_start(label) | |
1687 | |
1688 self.tweenTypeSelector = gtk.combo_box_new_text() | |
1689 self.tweenTypeSelector.append_text('normal') | |
1690 #self.tweenTypeSelector.append_text('relocate') | |
1691 self.tweenTypeSelector.append_text('scale') | |
1692 self.tweenTypeSelector.set_active(0) | |
1693 tweenbox.pack_start(self.tweenTypeSelector, expand=False, fill=False) | |
1694 hbox.pack_start(tweenbox, expand=False, fill=False) | |
1695 self.tweenTypeSelector.connect('changed', self.onTweenTypeChange) | |
1696 pass | |
1697 | |
1698 def onQuit(self, event): | |
1699 self.OK = False | |
1700 gtk.main_quit() | |
1701 pass | |
1702 | |
1703 def onOK(self, event): | |
1704 self.OK = True | |
1705 gtk.main_quit() | |
1706 pass | |
1707 | |
1708 def show(self): | 1675 def show(self): |
1709 self.OK = True | 1676 self.OK = True |
1710 if not self.root: | 1677 if not self.root: |
1711 self.root = self.desktop.doc().root().repr | 1678 self.root = self.desktop.doc().root().repr |
1712 pass | 1679 pass |
1713 | 1680 |
1714 self.document = self.desktop.doc().rdoc | 1681 self.document = self.desktop.doc().rdoc |
1715 self.handle_doc_root(self.document, self.root) | |
1716 self.tween = TweenObject(self.document, self.root) | 1682 self.tween = TweenObject(self.document, self.root) |
1717 self._init_framelines() | 1683 self._dom.handle_doc_root(self.document, self.root) |
1718 self._add_frameline_for_every_layer() | 1684 self._dom.register_active_frame_cb(self.onCellClick) |
1719 self._show_framelines() | 1685 |
1720 | |
1721 if self.top == None: | 1686 if self.top == None: |
1722 self.top = gtk.VBox(False, 0) | 1687 self.top = gtk.VBox(False, 0) |
1723 toplevel = self.desktop.getToplevel() | 1688 toplevel = self.desktop.getToplevel() |
1724 toplevel.child.child.pack_end(self.top, expand=False) | 1689 toplevel.child.child.pack_end(self.top, expand=False) |
1725 else: | 1690 else: |
1727 pass | 1692 pass |
1728 | 1693 |
1729 vbox = gtk.VBox(False, 0) | 1694 vbox = gtk.VBox(False, 0) |
1730 self.startWindow = vbox | 1695 self.startWindow = vbox |
1731 self.top.pack_start(vbox, expand=False) | 1696 self.top.pack_start(vbox, expand=False) |
1732 vbox.pack_start(self._frameline_box, expand=False) | 1697 frame_ui = self._dom.get_frame_ui_widget() |
1698 vbox.pack_start(frame_ui, expand=False) | |
1733 hbox=gtk.HBox(False, 0) | 1699 hbox=gtk.HBox(False, 0) |
1734 self.addButtons(hbox) | 1700 self._add_buttons(hbox) |
1735 vbox.pack_start(hbox, expand=False) | 1701 vbox.pack_start(hbox, expand=False) |
1736 | 1702 |
1737 doc = self.document | 1703 doc = self.document |
1738 addEventListener(doc,'DOMNodeInserted', self.updateUI, None) | 1704 addEventListener(doc,'DOMNodeInserted', self.updateUI, None) |
1739 addEventListener(doc,'DOMNodeRemoved', self.updateUI, None) | 1705 addEventListener(doc,'DOMNodeRemoved', self.updateUI, None) |