Mercurial > MadButterfly
view pyink/domview_ui.py @ 1532:4a92b639a1cd
Clear selection set when switching current scene.
To clear selection set after switching away from current to another scene.
It avoids Inkscape select on nodes they are not saw after switching.
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Fri, 30 Sep 2011 12:31:33 +0800 |
parents | b7d70341ee57 |
children |
line wrap: on
line source
import gtk from tween import TweenObject from frameline import frameline, frameruler from domview import domview import consistency import unlink_clone ## \brief Maintain a stack of frameline UI component. # # Every layer is assocated with a frameline. Framelines are showed/stacked in # virtical. Framelines of lower layers are placed at lower position on the # screen. This class provide a set of API to access framelines with layer and # frame index number. You access/set content of frameline by specifing layer # index and frame index. # class frameline_stack(object): _frameline_tween_types = (frameline.TWEEN_TYPE_NONE, frameline.TWEEN_TYPE_SHAPE) _num_frames_of_line = 100 _framelines = None def __init__(self, *args, **kws): super(frameline_stack, self).__init__(*args, **kws) self._last_mouse_over_frameline = None self._last_active_frameline = None self._active_frame_callback = None pass def _change_hover_frameline(self, widget, event): """ Hide all hover frames. This is a hack. We should use the lost focus event instead in the future to reduce the overhead. """ if self._last_mouse_over_frameline and \ widget != self._last_mouse_over_frameline: self._last_mouse_over_frameline.mouse_leave() pass self._last_mouse_over_frameline = widget pass ## \brief Switch to new active frameline. # # Hide active frame mark for the active frame of old active frameline. It # always shows at most one active frame mark. When a frame is activated, # all active frame mark of other frameline should be hidden. # def _active_frameline(self, frameline): last = self._last_active_frameline if last and last != frameline: last.deactive() pass self._last_active_frameline = frameline pass ## \brief Called for changing of active frame. # # This handle deactive previous frameline that owns an active frame when a # frame in another frameline is activated. # def _change_active_frame(self, frameline, frame_idx, button): frameline.active_frame(frame_idx) self._active_frameline(frameline) if self._active_frame_callback: layer_idx = frameline.layer_idx self._active_frame_callback(layer_idx, frame_idx) pass pass ## \brief Add a frameline into the frameline box for the given layer. # def add_frameline(self, layer_idx): if layer_idx > len(self._framelines): raise ValueError, 'layer number should be a consequence' vbox = self._frameline_vbox line = frameline(self._num_frames_of_line) line.set_size_request(self._num_frames_of_line * 10, 20) hbox = gtk.HBox() label = gtk.Label('') label.set_size_request(100,0) hbox.pack_start(label,expand=False, fill=True) hbox.pack_start(line) vbox.pack_start(hbox, False) # Put later one on the top of earier one, but after the ruler. position = len(self._framelines) - layer_idx + 1 vbox.reorder_child(hbox, position) self._framelines[layer_idx: layer_idx] = [line] for idx in range(layer_idx, len(self._framelines)): self._framelines[idx].layer_idx = idx pass line.label = label line.connect('motion-notify-event', self._change_hover_frameline) line.connect(frameline.FRAME_BUT_PRESS, self._change_active_frame) pass ## \brief Remove the given frameline from the frameline box. # def remove_frameline(self, layer_idx): vbox = self._frameline_vbox line = self._framelines[layer_idx] if self._last_active_frameline == line: self._last_active_frameline = None pass if self._last_mouse_over_frameline == line: self._last_mouse_over_frameline = None pass hbox = line.parent vbox.remove(hbox) del self._framelines[layer_idx] for idx in range(layer_idx, len(self._framelines)): self._framelines[idx].layer_idx = idx pass pass ## \brief Remove all framelines from the stack. # def remove_all_framelines(self): num = len(self._framelines) for idx in range(0, num): line = self._framelines[idx] hbox = line.parent self._frameline_vbox.remove(hbox) pass self._framelines = [] self._last_mouse_over_frameline = None self._last_active_frameline = None pass def init_framelines(self): if self._framelines!= None: return self._framelines = [] box = gtk.ScrolledWindow() self.frameline_box = box box.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) box.set_size_request(-1, 150) vbox = gtk.VBox() self._frameline_vbox = vbox box.add_with_viewport(vbox) nframes = self._num_frames_of_line # # Set up a ruler # ruler = frameruler(nframes) ruler.set_size_request(nframes * 10, 20) ruler.show() hbox = gtk.HBox() label=gtk.Label('') label.set_size_request(100,0) hbox.pack_start(label,expand=False,fill=True) hbox.pack_start(ruler) vbox.pack_start(hbox, False) pass ## \brief Show framelines on the screen. # # When a frameline was inserted or removed, it would not be showed # immediately. This function is used to notify toolkit to update the # screen and drawing framelines. def show_framelines(self): self._frameline_vbox.show_all() pass ## \brief Make given frame as current active frame. # def active_frame(self, layer_idx, frame_idx): frameline = self._framelines[layer_idx] self._active_frameline(frameline) frameline.active_frame(frame_idx) pass ## \brief Get layer and frame index of current active frame. # # \return (-1, -1) for no active, (layer_idx, frame_idx) for current # active. def get_active_layer_frame(self): if self._last_active_frameline: layer_idx = self._last_active_frameline.layer_idx frame_idx = self._last_active_frameline.get_active_frame() if frame_idx != -1: return layer_idx, frame_idx pass return -1, -1 ## \brief Get information of the key frame at left-side. # # The key frame, returned, is at the place of the give frame or its # left-side. def get_left_key_tween(self, layer_idx, frame_idx): frameline = self._framelines[layer_idx] start, end, fl_tween_type = frameline.get_frame_block_floor(frame_idx) tween_type = self._frameline_tween_types.index(fl_tween_type) return start, end, tween_type ## \brief Return information of a key frame and its tweening. # # This method return the key frame that the given frame is, or is in its # tween. # # \return (start, end, tween_type) def get_key_tween(self, layer_idx, frame_idx): frameline = self._framelines[layer_idx] start, end, fl_tween_type = frameline.get_frame_block(frame_idx) tween_type = self._frameline_tween_types.index(fl_tween_type) return start, end, tween_type def get_all_key_tween_of_layer(self, layer_idx): frameline = self._framelines[layer_idx] info = frameline.get_frame_blocks() tweens = [(tween[0], tween[1], self._frameline_tween_types.index(tween[2])) for tween in info] return tweens ## \brief Tweening key frame to a give size # # The tween can be changed by tweening it again. def tween(self, layer_idx, key_frame_idx, tween_len, tween_type=TweenObject.TWEEN_TYPE_NORMAL): assert tween_len > 1 frameline = self._framelines[layer_idx] right_frame_idx = key_frame_idx + tween_len - 1 fl_tween_type = self._frameline_tween_types[tween_type] start, end, old_fl_tween_type = \ frameline.get_frame_block(key_frame_idx) if start != key_frame_idx: ValueError, 'invalid key frame (%d)' % (key_frame_idx) if start < end: frameline.unmark_keyframe(end) pass frameline.mark_keyframe(right_frame_idx) frameline.tween(start, fl_tween_type) pass def untween(self, layer_idx, key_frame_idx): frameline = self._framelines[layer_idx] start, end, tween_type = \ frameline.get_frame_block(key_frame_idx) if start < end: frameline.untween(start) frameline.unmark_keyframe(end) pass pass ## \brief Unmark a key frame. # # Once a key frame was unmark, the associated tween was also removed # totally. # def unmark_keyframe(self, layer_idx, frame_idx): frameline = self._framelines[layer_idx] start, end, fl_tween_type = frameline.get_frame_block(frame_idx) if start != frame_idx: raise ValueError, 'no such key (%d, %d)' % (layer_idx, frame_idx) frameline.unmark_keyframe(frame_idx) if start < end: frameline.unmark_keyframe(end) pass pass ## \brief Makr a key frame. # # Make a frame as a key frame. # def mark_keyframe(self, layer_idx, frame_idx): frameline = self._framelines[layer_idx] frameline.mark_keyframe(frame_idx) pass ## \brief Get data associated with the given key frame. # # The given frame index must be exactly a key frame. # def get_keyframe_data(self, layer_idx, frame_idx): frameline = self._framelines[layer_idx] data = frameline.get_frame_data(frame_idx) return data ## \brief Set/associate data with the given key frame. # def set_keyframe_data(self, layer_idx, frame_idx, data): frameline = self._framelines[layer_idx] frameline.set_frame_data(frame_idx, data) pass ## \brief Insert frames before specified frame. # # Specified frame and frames after it are shift right for \ref num # positions to make a space for new frames. # def insert_frames(self, layer_idx, frame_idx, num): assert num > 0 assert frame_idx >= 0 frameline = self._framelines[layer_idx] for i in range(num): frameline.add_frame(frame_idx) pass pass ## \brief Remove a number of frames from the frameline. # # All key frames and associated tween info covered by removing range would # be removed. # def rm_frames(self, layer_idx, frame_idx, num): assert num > 0 assert frame_idx >= 0 frameline = self._framelines[layer_idx] # # Remove right key frame of last tween which left one will be removed. # last_rm = frame_idx + num - 1 # last removed frame try: start, end, tween_type = frameline.get_frame_block(last_rm) except ValueError: # last removed frame is not in any tween pass else: if start >= frame_idx and end > last_rm: # Left key frame of the tween was removed, but not right one. frameline.untween(start) frameline.unmark_keyframe(end) pass pass # # Remove left key of the tween that right key frame is in removing # range. # try: start, end, tween_type = frameline.get_frame_block(frame_idx) except ValueError: pass else: if start < frame_idx and end <= last_rm: # right key frame is in removing range but left one. frameline.untween(start) frameline.unmark_keyframe(start) frameline.unmark_keyframe(end) pass pass for i in range(num): frameline.rm_frame(frame_idx) pass pass ## \brief Set label for a layer. # def set_layer_label(self, layer_idx, txt): frameline = self._framelines[layer_idx] frameline.label.set_text(txt) pass ## \brief Register a callback for active frame event. # # The callback would be called when a frame is activated. # def register_active_frame_callback(self, cb): self._active_frame_callback = cb pass pass ## \biref Components and timelines management for domview. # # This is mix-in for domview_ui to provide components and timelines # management functions. This class expose a lot of methods from class # component_manager. # class domview_ui_comp(object): def __init__(self): from comp_dock import comp_dock self._comp_dock = comp_dock(self) pass def _ui_comp_refresh(self): self._comp_dock.refresh() pass ## \brief Setup desktop that the document will be serviced. # # This method must be called before handle_doc_root. # def set_desktop(self, desktop): self._desktop = desktop self._comp_dock.install_dock(desktop) pass def add_component(self, name): self._dom.add_component(name) self._comp_dock.dom_add_component(name) pass def rm_component(self, name): self._dom.rm_component(name) self._comp_dock.dom_rm_component(name) pass def switch_component(self, name): self._dom.switch_component(name) self._framelines_refresh() # from domview_ui self._comp_dock.refresh_timelines() cur_layer_idx, cur_frame_idx = self._dom.get_current_frame() self._fl_stack.active_frame(cur_layer_idx, cur_frame_idx) pass def all_comp_names(self): names = self._dom.all_comp_names() return names def has_component(self, name): r = self._dom.has_component(name) return r def get_current_component(self): return self._dom.get_current_component() def add_timeline(self, name): self._dom.add_timeline(name) self._comp_dock.dom_add_timeline(name) pass def rm_timeline(self, name): self._dom.rm_timeline(name) self._comp_dock.dom_rm_timeline(name) pass def switch_timeline(self, name): self._dom.switch_timeline(name) self._framelines_refresh() # from domview_ui cur_layer_idx, cur_frame_idx = self._dom.get_current_frame() self._fl_stack.active_frame(cur_layer_idx, cur_frame_idx) pass def all_timeline_names(self): names = self._dom.all_timeline_names() return names def has_timeline(self, name): r = self._dom.has_timeline(name) return r def get_current_timeline(self): return self._dom.get_current_timeline() ## \brief Add a new component from a group node. # # The group node is reparented to the group of first layer of # specified component. # def add_component_from_group(self, comp_name, group): self.add_component(comp_name) self._dom.mv_group_to_component(group, comp_name) pass def link_to_component(self, comp_name, parent_group): link_node = self._dom.link_to_component(comp_name, parent_group) return link_node def rename_component(self, comp_name, new_name): self._dom.rename_component(comp_name, new_name) pass def rename_timeline_of_component(self, timeline_name, new_name, comp_name): self._dom.rename_timeline_of_component(timeline_name, new_name, comp_name) pass def rename_timeline(self, timeline_name, new_name): self._dom.rename_timeline(timeline_name, new_name) pass def refresh_components(self): self._dom.reparse_components() dock = self._comp_dock dock.refresh_components() pass def refresh_timelines(self): self._dom.reparse_timelines() dock = self._comp_dock dock.refresh_timelines() pass pass ## \brief FSM management interface for domview_ui. # class domview_ui_FSM(object): def __init__(self): super(domview_ui_FSM, self).__init__() pass def all_state_names(self, comp_name): return self._dom.all_state_names(comp_name) def get_start_state_name(self, comp_name): return self._dom.get_start_state_name(comp_name) def rm_state(self, comp_name, state_name): self._dom.rm_state(comp_name, state_name) pass def add_state(self, comp_name, state_name): self._dom.add_state(comp_name, state_name) pass def rename_state(self, comp_name, state_name, new_name): self._dom.rename_state(comp_name, state_name, new_name) pass def set_start_state(self, comp_name, state_name): self._dom.set_start_state(comp_name, state_name) pass def set_state_entry_action(self, comp_name, state_name, entry_action): self._dom.set_state_entry_action(comp_name, state_name, entry_action) pass def set_state_r(self, comp_name, state_name, r): self._dom.set_state_r(comp_name, state_name, r) pass def set_state_xy(self, comp_name, state_name, x, y): self._dom.set_state_xy(comp_name, state_name, x, y) pass def get_state_entry_action(self, comp_name, state_name): action = self._dom.get_state_entry_action(comp_name, state_name) return action def get_state_r(self, comp_name, state_name): r = self._dom.get_state_r(comp_name, state_name) return r def get_state_xy(self, comp_name, state_name): xy = self._dom.get_state_xy(comp_name, state_name) return xy def all_transitions(self, comp_name, state_name): return self._dom.all_transitions(comp_name, state_name) def add_transition(self, comp_name, state_name, cond, target): self._dom.add_transition(comp_name, state_name, cond, target) pass def rm_transition(self, comp_name, state_name, cond): self._dom.rm_transition(comp_name, state_name, cond) pass def change_transition_cond(self, comp_name, state_name, old_cond, new_cond): self._dom.change_transition_cond(comp_name, state_name, old_cond, new_cond) pass def get_transition(self, comp_name, state_name, cond): return self._dom.get_transition(comp_name, state_name, cond) def set_transition_action(self, comp_name, state_name, cond, action): self._dom.set_transition_action(comp_name, state_name, cond, action) pass def set_transition_path(self, comp_name, state_name, cond, path): self._dom.set_transition_path(comp_name, state_name, cond, path) pass def chg_transition_cond(self, comp_name, state_name, cond, new_cond): self._dom.chg_transition_cond(comp_name, state_name, cond, new_cond) pass pass ## \brief Bridge of DOM-tree to syncrhonize data-model and UI. # # This class is a wrapper class domview_ui(object): _tween_type_names = ('normal', 'scale') def __init__(self): super(domview_ui, self).__init__() self._fl_stack = frameline_stack() self._dom = domview() self._desktop = None self._doc = None self._root = None self._lock = False pass ## \brief Update content of a frameline from scenes of respective layer. # def _update_frameline_content(self, layer_idx): fl_stack = self._fl_stack scene_nodes = self._dom.get_all_scene_node_of_layer(layer_idx) for scene_node in scene_nodes: start, end, tween_name = self._dom.parse_one_scene(scene_node) fl_stack.mark_keyframe(layer_idx, start) fl_stack.set_keyframe_data(layer_idx, start, scene_node) if start != end: tween_type = self._tween_type_names.index(tween_name) tween_len = end - start + 1 fl_stack.tween(layer_idx, start, tween_len, tween_type) pass pass pass ## \brief Add a frameline for every found layer. # # This method is called to create a frameline for every layer found when # loading a document. # def _add_frameline_for_every_layer(self): for layer_idx in range(self._dom.get_layer_num()): layer_group_node = self._dom.get_layer_group(layer_idx) label = layer_group_node.getAttribute('inkscape:label') self._fl_stack.add_frameline(layer_idx) self._fl_stack.set_layer_label(layer_idx, label) self._update_frameline_content(layer_idx) pass pass ## \brief This method is called to handle a new document. # def handle_doc_root(self, doc, root): self._dom.handle_doc_root(doc, root) self._fl_stack.init_framelines() self._add_frameline_for_every_layer() self._fl_stack.show_framelines() self._ui_comp_refresh() # from domview_ui_comp self._doc = doc self._root = root pass ## \brief Update framelines according domview. # def _framelines_refresh(self): self._fl_stack.remove_all_framelines() self._add_frameline_for_every_layer() self._fl_stack.show_framelines() pass ## \brief Parse the document from the scratch and update UI. # def reset(self): self._dom.reset() self._framelines_refresh() self._ui_comp_refresh() # from domview_ui_comp pass ## \brief Mark given frame as a key frame. # def mark_key(self, layer_idx, key_idx): scene_group = self._dom.add_scene_group(layer_idx) scene_group_id = scene_group.getAttribute('id') scene_node = self._dom.add_scene_node(layer_idx, key_idx, key_idx) self._dom.chg_scene_node(scene_node, ref=scene_group_id) self._fl_stack.mark_keyframe(layer_idx, key_idx) self._fl_stack.set_keyframe_data(layer_idx, key_idx, scene_node) pass ## \brief Tweening a key frame. # # To tween a key spanning several frames at right-side. # The tween of a key frame can be changed by tweening it again. # def tween(self, layer_idx, key_frame_idx, tween_len, tween_type=TweenObject.TWEEN_TYPE_NORMAL): self._fl_stack.tween(layer_idx, key_frame_idx, tween_len, tween_type) end_frame_idx = key_frame_idx + tween_len - 1 scene_node = self._fl_stack.get_keyframe_data(layer_idx, key_frame_idx) tween_name = self._tween_type_names[tween_type] self._dom.chg_scene_node(scene_node, end=end_frame_idx, tween_type=tween_name) pass ## \brief Change tween info of a key frame # def chg_tween(self, layer_idx, key_frame_idx, tween_len=None, tween_type=None): scene_node = self._fl_stack.get_keyframe_data(layer_idx, key_frame_idx) start, end, old_tween_type = \ self._fl_stack.get_key_tween(layer_idx, key_frame_idx) if tween_len is not None: end = start + tween_len - 1 self._dom.chg_scene_node(scene_node, end=end) pass if tween_type is not None: tween_name = self._tween_type_names[tween_type] self._dom.chg_scene_node(scene_node, tween_type=tween_name) pass if tween_type is None: tween_type = old_tween_type pass tween_len = end - start + 1 self._fl_stack.tween(layer_idx, start, tween_len, tween_type) pass ## \brief Unmark a frame from a key frame. # def unmark_key(self, layer_idx, key_frame_idx): scene_node = self._fl_stack.get_keyframe_data(layer_idx, key_frame_idx) self._dom.rm_scene_node_n_group(scene_node) self._fl_stack.unmark_keyframe(layer_idx, key_frame_idx) pass ## \brief Insert frames at specified position. # # All frame at and after given position will shift right. # def insert_frames(self, layer_idx, frame_idx, num): self._fl_stack.insert_frames(layer_idx, frame_idx, num) self._dom.insert_frames(layer_idx, frame_idx, num) pass ## \brief Insert frames at specified position. # # All frames at and after given position will shift left, except nearest # \ref num frames are removed. # # - For a tween that only right part is covered by removing # range, its tween length would be shrinked just before # removing range. # - For a tween that only left part is covered by removing range, # key and tween are fully removed. # - For a tween that only middle part is covered, tween length is # also shrinked according length of covered part. # def rm_frames(self, layer_idx, frame_idx, num): # # Check the key that is partially covered key tween, but not # include key frame. # last_rm_idx = frame_idx + num - 1 try: start, end, tween_type = \ self._fl_stack.get_left_key_tween(layer_idx, frame_idx) except ValueError: pass # no key at left else: if start < frame_idx and end >= frame_idx: # # Key frame is not covered, only part of a key tween # is covered. Shrink its tween length, size of the # covered part, or the key will be unmarked. # shrink_sz = min(end - frame_idx + 1, num) tween_len = end - start + 1 - shrink_sz if tween_len == 1: self._fl_stack.untween(layer_idx, start) else: self._fl_stack.tween(layer_idx, start, tween_len, tween_type) pass scene_end = end - shrink_sz scene_node = self._fl_stack.get_keyframe_data(layer_idx, start) self._dom.chg_scene_node(scene_node, end=scene_end) frame_idx = scene_end + 1 # to shift/remove keys at right side pass pass self._fl_stack.rm_frames(layer_idx, frame_idx, num) self._dom.rm_frames(layer_idx, frame_idx, num) pass ## \brief Insert a layer at given position. # # Original layer \ref layer_idx and later ones would be shifted to make a # space for the new layer. # def insert_layer(self, layer_idx): self._dom.insert_layer(layer_idx) layer_name = self._dom.get_layer_name(layer_idx) self._fl_stack.add_frameline(layer_idx) self._fl_stack.set_layer_label(layer_idx, layer_name) self._fl_stack.show_framelines() pass ## \brief Remove given layer. # def rm_layer(self, layer_idx): self._dom.rm_layer(layer_idx) self._fl_stack.remove_frameline(layer_idx) self._fl_stack.show_framelines() pass def set_active_layer_frame(self, layer_idx, frame_idx): self._fl_stack.active_frame(layer_idx, frame_idx) pass ## \bref Return current active frame and its layer. # # \return (layer_idx, frame_idx) of active frame, or (-1, -1) when no # active one. def get_active_layer_frame(self): layer_idx, frame_idx = self._fl_stack.get_active_layer_frame() return layer_idx, frame_idx def get_layer_num(self): return self._dom.get_layer_num() ## \brief Return associated group node for a key frame. # # The given frame index must be exactly a key frame. # def get_key_group(self, layer_idx, frame_idx): scene_node = self._fl_stack.get_keyframe_data(layer_idx, frame_idx) scene_group_id = scene_node.getAttribute('ref') scene_group_node = self._dom.get_node(scene_group_id) return scene_group_node ## \brief Find an associated key frame and tween info for a group ID. # def find_key_from_group(self, scene_group_id): layer_idx, scene_node = \ self._dom.find_layer_n_scene_of_node(scene_group_id) if layer_idx == -1: raise ValueError, \ 'can not find the key for group %s' % (scene_group_id) start, end, tween_name = self._dom.parse_one_scene(scene_node) tween_type = self._tween_type_names.index(tween_name) return layer_idx, (start, end, tween_type) ## \brief Return key and tween info for given frame index. # # The return key is at given frame, or its tween covers given frame. # def get_key(self, layer_idx, frame_idx): start, end, tween_type = \ self._fl_stack.get_key_tween(layer_idx, frame_idx) return start, end, tween_type def get_left_key(self, layer_idx, frame_idx): start, end, tween_type = \ self._fl_stack.get_left_key_tween(layer_idx, frame_idx) return start, end, tween_type ## \brief Return information of key frames in the given layer. # def get_layer_keys(self, layer_idx): key_tweens = self._fl_stack.get_all_key_tween_of_layer(layer_idx) return key_tweens ## \brief Copy content of a source key frame to a destinate. # # Copy content of the scene group of a source key frame to the # scene group of a destinate key frame. # def copy_key_group(self, layer_idx, src_frame_idx, dst_frame_idx): src_group = self.get_key_group(layer_idx, src_frame_idx) dst_group = self.get_key_group(layer_idx, dst_frame_idx) self._dom.copy_group_children(src_group, dst_group) pass def clone_key_group(self, layer_idx, src_frame_idx, dst_frame_idx): src_group = self.get_key_group(layer_idx, src_frame_idx) dst_group = self.get_key_group(layer_idx, dst_frame_idx) self._dom.clone_group_children(src_group, dst_group) pass ## \brief To test a graphic node. # # A graphic node is a SVG node that is not layer group, scene # group, ... etc. It is only a normal node in a layer group or a # scene group. def is_graph_node(self, node): return self._dom.is_graph_node(node) ## \brief Return widget showing frames and layers. # def get_frame_ui_widget(self): return self._fl_stack.frameline_box ## \brief Register a callback for activating a frame event. # # The callback function is called when a frame is activated. # def register_active_frame_callback(self, cb): self._fl_stack.register_active_frame_callback(cb) pass ## \brief Find the layer index associated with a given layer group. # def find_layer_from_group(self, group_id): layer_idx = self._dom.find_layer_of_group(group_id) if layer_idx == -1: raise ValueError, \ 'can not find the layer for group %s' % (group_id) return layer_idx ## \brief Get duplicate group of a layer. # def get_layer_dup_group(self, layer_idx): data = self._dom.get_layer_data(layer_idx) if not data: data = dict() self._dom.set_layer_data(layer_idx, data) pass dup_group = None if data.has_key('dup_group_id'): try: dup_group = self._dom.get_node(data['dup_group_id']) except KeyError: pass pass if not dup_group: # Search dup group from children of the layer group layer_group = self._dom.get_layer_group(layer_idx) for child in layer_group.childList(): try: label = child.getAttribute('inkscape:label') except: pass else: if label == 'dup': data['dup_group_id'] = child return child pass pass # Or create a new dup group for the layer dup_group = self._dom.create_layer_dup_group(layer_idx) data['dup_group_id'] = dup_group.getAttribute('id') pass return dup_group def get_max_frame(self): max_frame = self._dom.get_max_frame() return max_frame ## \brief Remember current frame and layer on the scenes node. # def remember_current_frame(self, layer_idx, frame_idx): self._dom.remember_current_frame(layer_idx, frame_idx) pass ## \brief Get current frame and layer from the scenes node. # def get_current_frame(self): return self._dom.get_current_frame() ## \brief add the current position to the undo buffer. # # The msg will be displayed in the UI to indicate the undo set. def mark_undo(self, msg): self._dom.mark_undo(msg) pass @property def doc(self): return self._doc @property def root(self): return self._root def lock(self): if self._lock: return False self._lock = True return True def unlock(self): self._lock = False return True pass ## \brief Expose some internal interface. # # This is a mix-in to provide API for internal using, for example, # consistency_checker. # class domview_internal(object): ## \brief Search a node by a ID. # def get_node(self, node_id): node = self._dom.get_node(node_id) return node ## \brief Search scene node by scene group ID. # def get_scene_by_group(self, scene_group_id): scene_node = self._dom.get_scene(scene_group_id) return scene_node ## \brief Manage a scene node that is unknown by domview_ui before. # def manage_scene_node(self, scene_node, scene_group): layer_group = scene_group.parent() layer_group_id = layer_group.getAttribute('id') layer_idx = self.find_layer_from_group(layer_group_id) self._dom.manage_scene_node(layer_idx, scene_node) start, end, tween_name = \ self._dom.parse_one_scene(scene_node) tween_type = self._tween_type_names.index(tween_name) tween_len = end - start + 1 self._fl_stack.mark_keyframe(layer_idx, start) self._fl_stack.set_keyframe_data(layer_idx, start, scene_node) self._fl_stack.tween(layer_idx, start, tween_len, tween_type) pass ## \brief Manage a layer group that is unknown by domview_ui before. # def manage_layer_group(self, layer_group): try: layer_group_id = layer_group.getAttribute('id') except: return layer_idx = self._dom.manage_layer_group(layer_group_id) if layer_idx == -1: return self._fl_stack.add_frameline(layer_idx) self._fl_stack.show_framelines() try: label = layer_group.getAttribute('inkscape:label') except: label = layer_group.getAttribute('id') pass self._fl_stack.set_layer_label(layer_idx, label) pass ## \brief Get layer group. # def get_layer_group(self, layer_idx): layer_group = self._dom.get_layer_group(layer_idx) return layer_group pass ## \brief Oven domview_ui and all mix-ins # class domview_ui_oven(domview_ui, domview_ui_comp, domview_ui_FSM): def __init__(self): super(domview_ui_oven, self).__init__() pass pass ## \brief A mix-in to enable workers for a domview_ui. # class domview_ui_with_workers(domview_ui_oven, domview_internal): def __init__(self): super(domview_ui_with_workers, self).__init__() self._consistency_checker = consistency.consistency_checker(self) self._unlink_clone_checker = unlink_clone.unlink_clone_checker(self) pass def handle_doc_root(self, doc, root): super(domview_ui_with_workers, self).handle_doc_root(doc, root) self._consistency_checker.handle_doc_root(doc, root) self._unlink_clone_checker.handle_doc_root(doc, root) pass pass ## \brief Factory function of domview_ui. # def create_domview_ui(): domview = domview_ui_with_workers() return domview