# HG changeset patch # User Thinker K.F. Li # Date 1293362232 -28800 # Node ID 6586cd10c92f1639a50b958b69dbd1d697ad8cf5 # Parent 0ffef2df6201c75118e001168089ea3a1109bb90 Refactory frameline.py diff -r 0ffef2df6201 -r 6586cd10c92f pyink/MBScene.py --- a/pyink/MBScene.py Fri Dec 24 15:40:16 2010 +0800 +++ b/pyink/MBScene.py Sun Dec 26 19:17:12 2010 +0800 @@ -1,6 +1,6 @@ #!/usr/bin/python -# -*- indent-tabs-mode: t; tab-width: 8; python-indent: 4; -*- -# vim: sw=4:ts=8:sts=4 +# -*- indent-tabs-mode: t; tab-width: 8; python-indent: 4; fill-column: 79 -*- +# vim: sw=4:ts=8:sts=4:textwidth=79 import pygtk import gtk import glib @@ -12,6 +12,7 @@ import pybInkscape import math from tween import TweenObject +from frameline import frameline, frameruler # Please refer to # http://www.assembla.com/wiki/show/MadButterfly/Inkscape_extention @@ -141,6 +142,11 @@ pass class MBScene(): + _tween_types = (frameline.TWEEN_TYPE_NONE, + frameline.TWEEN_TYPE_MOVE, + frameline.TWEEN_TYPE_SHAPE) + _tween_type_names = ('normal', 'relocate', 'scale') + def __init__(self, desktop, win, root=None): self.desktop = desktop self.window = win @@ -157,6 +163,7 @@ self.root = root self.framerate=12 self.maxframe=0 + self._disable_tween_type_selector = False pass def show_selection(self,w,obj): @@ -267,7 +274,7 @@ node.appendChild(ns) for layer in range(0,len(self._framelines)): lobj = self._framelines[layer] - lobj.addScenes(rdoc,ns) + self.addScenes(lobj, ns) pass pass pass @@ -285,9 +292,6 @@ self.scenemap = None doc = self.root - #obs = pybInkscape.PYNodeObserver() - #obs = LayerAddRemoveWatcher(self) - #doc.addObserver(obs) addEventListener(doc,'DOMNodeInserted',self.updateUI,None) addEventListener(doc,'DOMNodeRemoved',self.updateUI,None) doc.childList() @@ -413,8 +417,7 @@ print 'Add key ', x self.last_line.add_keyframe(x,ns) self.update() - self.last_line.update() - + pass def removeKeyScene(self): nth = self.last_frame @@ -552,8 +555,7 @@ # Check the duplicated scene group and create it if it is not available try: - if layer.duplicateGroup: - layer.duplicateGroup.setAttribute("style","display:none") + layer.duplicateGroup.setAttribute("style","display:none") except: print "*"*40 layer.duplicateGroup = self.document.createElement("svg:g") @@ -574,23 +576,22 @@ s.ref.setAttribute("style","display:none") i = i + 1 continue + if nth == s.idx + 1: s.ref.setAttribute("style","") else: if nth > (s.idx+1) and nth <= (layer._keys[i+1].idx+1): if i+2 < len(layer._keys): - #s.ref.parent().appendChild(layer.duplicateGroup) s.ref.setAttribute("style","display:none") layer.duplicateGroup.setAttribute("style","") - self.tween.updateTweenContent(layer.duplicateGroup, layer.get_tween_type(s.idx),s, layer._keys[i+2], nth) + d = layer._keys[i + 2] + self.tween.\ + updateTweenContent(layer.duplicateGroup, + layer.get_tween_type(s.idx), + s, d, nth) else: layer.duplicateGroup.setAttribute("style","") - #layer.duplicateGroup = s.ref.duplicate(self.document) - #layer.duplicateGroup.setAttribute("style","") - #layer.duplicateGroup.setAttribute("inkscape:label","dup") - #layer.duplicateGroup.setAttribute("sodipodi:insensitive","1") s.ref.setAttribute("style","display:none") - #s.ref.parent().appendChild(layer.duplicateGroup) pass else: s.ref.setAttribute("style","display:none") @@ -599,21 +600,6 @@ pass pass - def DOMtoItem(self,obj): - """ - Find the corresponding PYSPObject object for a DOM object. - """ - return self.DOMtoItem_recursive(self.desktop.doc().root(),obj) - - def DOMtoItem_recursive(self,tree,obj): - nodes = tree.childList() - for s in nodes: - if s.getId() == obj.getAttribute('id'): - return s - d = self.DOMtoItem_recursive(s,obj) - if d != None: return d - - def enterGroup(self,obj): for l in self.layers: for s in l.node.childList(): @@ -648,14 +634,11 @@ pass pass - def setTweenType(self,typ): - if typ == 'normal': - self.tweenTypeSelector.set_active(0) - elif typ == 'relocate': - self.tweenTypeSelector.set_active(1) - elif typ == 'scale': - self.tweenTypeSelector.set_active(2) - pass + def setTweenType(self, tween_type): + sel_type = MBScene._tween_types.index(tween_type) + self._disable_tween_type_selector = True + self.tweenTypeSelector.set_active(sel_type) + self._disable_tween_type_selector = False pass def newCell(self,file): @@ -689,7 +672,6 @@ pass def _create_framelines(self): - import frameline self.scrollwin = gtk.ScrolledWindow() self.scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.scrollwin.set_size_request(-1,150) @@ -700,7 +682,7 @@ vbox.show() self.scrollwin.add_with_viewport(vbox) - ruler = frameline.frameruler(nframes) + ruler = frameruler(nframes) ruler.set_size_request(nframes * 10, 20) ruler.show() hbox = gtk.HBox() @@ -715,7 +697,7 @@ # self._framelines = [] for i in range(len(self.layers)-1,-1,-1): - line = frameline.frameline(nframes) + line = frameline(nframes) hbox = gtk.HBox() label = gtk.Label(self.layers[i].node.getAttribute("inkscape:label")) label.set_size_request(100,0) @@ -746,7 +728,9 @@ frameline.add_keyframe(scene.start-1,scene.node) if scene.start != scene.end: frameline.add_keyframe(scene.end-1,scene.node) - frameline.tween(scene.start-1,scene.type) + tween_type_idx = self._tween_type_names.index(scene.type) + tween_type = self._tween_types[tween_type_idx] + frameline.tween(scene.start-1, tween_type) pass pass pass @@ -895,39 +879,25 @@ hbox.pack_start(btn,expand=False,fill=False) self.addNameEditor(hbox) self.addTweenTypeSelector(hbox) - pass - def onTweenTypeChange(self,w): - n = self.tweenTypeSelector.get_active() + def onTweenTypeChange(self, w): + if self._disable_tween_type_selector: + return + if self.last_line == None: return frameline = self.last_line i = 0 found = -1 - while i < len(frameline._keys): - s = frameline._keys[i] - if s.right_tween is False: - if self.last_frame == s.idx: - found = s.idx - break - else: - pass - i = i + 1 - continue - - if self.last_frame >= s.idx and self.last_frame <= frameline._keys[i+1].idx: - found = s.idx + for start_idx, stop_idx, tween_type in frameline.get_frame_blocks(): + if start_idx < stop_idx: + n = self.tweenTypeSelector.get_active() + new_tween_type = MBScene._tween_types[n] + self.last_line.set_tween_type(start_idx, new_tween_type) + self.update() break - else: - pass - i = i + 2 pass - pass - if found == -1: return - self.last_line.set_tween_type(found,self.tweenTypeSelector.get_active_text()) - self.last_line.update() - self.update() pass def addTweenTypeSelector(self,hbox): @@ -955,6 +925,24 @@ gtk.main_quit() pass + def addScenes(self, frameline, scenes_node): + doc = self.document + for start_idx, stop_idx, tween_type in frameline.get_frame_blocks(): + ref = frameline.get_frame_data(start_idx) + tween_type_idx = self._tween_types.index(tween_type) + tween_type_name = self._tween_type_names[tween_type_idx] + + scene_node = doc.createElement("ns0:scene") + scenes_node.appendChild(scene_node) + scene_node.setAttribute("start", str(start_idx + 1)) + if start_idx != stop_idx: + scene_node.setAttribute("end", str(stop_idx + 1)) + pass + scene_node.setAttribute("ref", ref.attribute("id")) + scene_node.setAttribute("type", tween_type_name) + pass + pass + def updateUI(self,node=None,arg=None): if self.lockui: return self.lockui = True @@ -984,6 +972,8 @@ self.desktop.getToplevel().child.child.pack_end(self.top,expand=False) else: self.top.remove(self.startWindow) + pass + vbox = gtk.VBox(False,0) self.startWindow = vbox self.top.pack_start(vbox,expand=False) @@ -992,10 +982,6 @@ self.addButtons(hbox) vbox.pack_start(hbox,expand=False) - # self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) - # self.window.connect("destroy", gtk.main_quit) - # self.window.set_position(gtk.WIN_POS_MOUSE) - self.top.show_all() self.last_update = None return False diff -r 0ffef2df6201 -r 6586cd10c92f pyink/frameline.py --- a/pyink/frameline.py Fri Dec 24 15:40:16 2010 +0800 +++ b/pyink/frameline.py Sun Dec 26 19:17:12 2010 +0800 @@ -1,3 +1,5 @@ +# -*- indent-tabs-mode: t; tab-width: 8; python-indent: 4; fill-column: 79 -*- +# vim: sw=4:ts=8:sts=4:textwidth=79 import pygtk pygtk.require("2.0") import gtk @@ -16,7 +18,7 @@ self.left_tween = False self.right_tween = False self.right_tween_type = 0 - self.ref='' + self.ref = '' pass pass @@ -109,6 +111,9 @@ # - 'frame-button-pree' for user press on a frame. # - callback(widget, frame_idx, button) # +# All methos that change state of the frameline, must call methods to update +# the screen. +# class frameline(gtk.DrawingArea): _type = 0 _frame_width = 10 # Width for each frame is 10 pixels @@ -116,17 +121,18 @@ _key_mark_color = 0x000000 # color of marks for key frames. _key_mark_sz = 4 # width and height of a key frame mark _tween_color = 0x808080 # color of tween line - _tween_bgcolors = [0x80ff80, 0xff8080,0xffff80] # bg colors of tween frames + # bg colors of tween frames + _tween_bgcolors = [0x80ff80, 0xff8080, 0xffff80] # Colors for normal frames _normal_bgcolors = [0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xcccccc] _normal_border = 0xaaaaaa # border color of normal frames. _active_border = 0xff3030 # border color of an active frame _hover_border_color = 0xa0a0a0 # border when the pointer over a frame + # tween types - _tween_type_none=0 - _tween_type_move=1 - _tween_type_shape=2 - + TWEEN_TYPE_NONE = 0 + TWEEN_TYPE_MOVE = 1 + TWEEN_TYPE_SHAPE = 2 FRAME_BUT_PRESS = 'frame-button-press' @@ -155,20 +161,100 @@ self._drawing = False pass + def __len__(self): + return self._num_frames + + def _find_keyframe(self, idx): + key_indic = [key.idx for key in self._keys] + key_pos = key_indic.index(idx) + return key_pos + + def _find_keyframe_floor(self, frame_idx): + pos = 0 + keys = [key.idx for key in self._keys] + keys.append(frame_idx) + keys.sort() + keys.reverse() + pos = (len(keys) - 1) - keys.index(frame_idx) - 1 + return pos + + ## \brief Find the range a continous tween. + # + def _find_tween_range(self, key_pos): + key = self._keys[key_pos] + if not (key.left_tween or key.right_tween): + raise ValueError, 'the keyframe is not in a tween' + + # + # Initialize tween type and first_pos + # + if key.right_tween: + tween_type = key.right_tween_type + first_pos = key_pos + else: + # key.left_tween is True since the key is in a tween. + first_pos = key_pos -1 + key = self._keys[first_pos] + tween_type = key.right_tween_type + pass + + # + # Find first_pos + # + while first_pos and key.left_tween: + right_pos = first_pos - 1 + right_key = self._keys[right_pos] + if right_key.right_tween_type != tween_type: + break + first_pos = right_pos + key = right_key + pass + + # + # Find last_pos + # + max_pos = len(self._keys) - 1 + last_pos = key_pos + key = self._keys[last_pos] + while last_pos < max_pos and self._keys[last_pos].right_tween: + if key.right_tween_type != tween_type: + break + last_pos = last_pos + 1 + key = self._keys[last_pos] + pass + + return first_pos, last_pos + def _press_hdl(self, widget, event): frame = event.x / self._frame_width but = event.button self.emit(frameline.FRAME_BUT_PRESS, frame, but) pass + def hide_hover(self): if self._active_frame != self._last_hover: self._draw_normal_frame(self._last_hover) + pass + pass def _motion_hdl(self, widget, event): - frame = int(event.x / self._frame_width) - - if frame < self._num_frames and frame >= 0: - self._draw_hover(frame) + frame_idx = int(event.x / self._frame_width) + if self._last_hover != -1: + self._draw_frame(self._last_hover) + if self._last_hover == self._active_frame: + self._draw_active_frame() + pass + pass + + if frame_idx < self._num_frames and frame_idx >= 0: + self._draw_hover_frame(frame_idx) + if self._last_hover == self._active_frame: + self._draw_active_frame() + pass + self._last_hover = frame_idx + else: + self._last_hover = -1 + pass pass def _fl_expose(self, widget, event): @@ -188,12 +274,11 @@ self.update() pass - def _draw_tween(self, first_key, last_key): - if not self._drawing: - return - + def _draw_tween(self, first_pos, last_pos): win = self.window w_x, w_y, w_w, w_h, depth = win.get_geometry() + first_key = self._keys[first_pos] + last_key = self._keys[last_pos] # # Get background color of a tween @@ -229,9 +314,6 @@ pass def _draw_normal_frame(self, idx): - if not self._drawing: - return - win = self.window w_x, w_y, w_w, w_h, depth = win.get_geometry() @@ -255,10 +337,7 @@ ## \brief Draw a bottom line from start to the point before stop frame. # - def _draw_bottom_line(self, start, stop): - if not self._drawing: - return - + def _draw_bottom_line(self, start_idx, stop_idx): win = self.window w_x, w_y, w_w, w_h, depth = win.get_geometry() gc = self._gc @@ -266,66 +345,41 @@ border_rgb = color_to_rgb(self._normal_border) border_color = gtk.gdk.Color(*border_rgb) gc.set_rgb_fg_color(border_color) - start_x = start * self._frame_width - stop_x = stop * self._frame_width + start_x = start_idx * self._frame_width + stop_x = stop_idx * self._frame_width win.draw_line(gc, start_x, w_h - 1, stop_x, w_h - 1) pass - def _draw_all_frames(self): - if not self._drawing: - return - + def _draw_active(self, idx): win = self.window w_x, w_y, w_w, w_h, depth = win.get_geometry() + + color_v = self._active_border + color_rgb = color_to_rgb(color_v) + color = gtk.gdk.Color(*color_rgb) + gc = self._gc + gc.set_rgb_fg_color(color) - i = 0 - key_i = 0 - try: - key = self._keys[key_i] - except IndexError: - key = keyframe(self._num_frames) - pass - num_frames = self._num_frames - while i < num_frames: - if key.idx == i and key.right_tween: - # - # Skip tween keys - # - first_tween_key = key - while key.idx == i or key.left_tween: - last_tween_key = key - key_i = key_i + 1 - try: - key = self._keys[key_i] - except IndexError: - key = keyframe(self._num_frames) - pass - pass + line_x1 = idx * self._frame_width + line_x2 = line_x1 + self._frame_width - if first_tween_key != last_tween_key: - self._draw_tween(first_tween_key, last_tween_key) - - i = last_tween_key.idx + 1 - pass - else: - if key.idx == i: - key_i=key_i+1 - try: - key = self._keys[key_i] - except: - key = keyframe(self._num_frames) - self._draw_normal_frame(i) - i = i + 1 - pass - pass - - self._draw_bottom_line(0, num_frames) - pass + win.draw_line(gc, line_x1, 0, line_x1, w_h) + win.draw_line(gc, line_x2, 0, line_x2, w_h) + win.draw_line(gc, line_x1, w_h - 1, line_x2, w_h - 1) + win.draw_line(gc, line_x1, 0, line_x2, 0) + pass def _draw_keyframe(self, frame_idx): - if not self._drawing: - return + # Only keyframes that is not right-side of NONE type tween should be + # draw. + pos = self._find_keyframe(frame_idx) + key = self._keys[pos] + if key.left_tween and not key.right_tween: + left_key = self._keys[pos - 1] + if left_key.right_tween_type == 0: + return + pass win = self.window w_x, w_y, w_w, w_h, depth = win.get_geometry() @@ -345,157 +399,14 @@ pass def _draw_keyframes(self): - if not self._drawing: - return - - win = self.window - w_x, w_y, w_w, w_h, depth = win.get_geometry() - - color_v = self._key_mark_color - color_rgb = color_to_rgb(color_v) - color = gtk.gdk.Color(*color_rgb) - - gc = self._gc - gc.set_rgb_fg_color(color) - for key in self._keys: - if key.left_tween is True and lastkey.right_tween_type == frameline._tween_type_none: - continue - - mark_sz = self._key_mark_sz - mark_x = int((key.idx + 0.5) * self._frame_width - mark_sz / 2) - mark_y = w_h * 2 / 3 - mark_sz / 2 - - win.draw_rectangle(gc, True, mark_x, mark_y, mark_sz, mark_sz) - lastkey = key + self._draw_keyframe(key.idx) pass pass - def _draw_active(self): - if not self._drawing: - return - - if self._active_frame == -1: - return - - win = self.window - w_x, w_y, w_w, w_h, depth = win.get_geometry() - - color_v = self._active_border - color_rgb = color_to_rgb(color_v) - color = gtk.gdk.Color(*color_rgb) - - gc = self._gc - gc.set_rgb_fg_color(color) - - idx = self._active_frame - line_x1 = idx * self._frame_width - line_x2 = line_x1 + self._frame_width - - win.draw_line(gc, line_x1, 0, line_x1, w_h) - win.draw_line(gc, line_x2, 0, line_x2, w_h) - win.draw_line(gc, line_x1, w_h - 1, line_x2, w_h - 1) - win.draw_line(gc, line_x1, 0, line_x2, 0) - pass - - ## \brief Find the range a continous tween. - # - def _find_tween_range(self, key_pos): - first_pos = key_pos - while first_pos and self._keys[first_pos].left_tween: - first_pos = first_pos - 1 - pass - - max_pos = len(self._keys) - 1 - - last_pos = key_pos - while last_pos < max_pos and self._keys[last_pos].right_tween: - last_pos = last_pos + 1 - pass - - return first_pos, last_pos - - ## \brief Redraw a frame specified by an index. - # - def _redraw_frame(self, frame_idx): - if not self._drawing: - return - - keys = [key.idx for key in self._keys] - if len(keys): - try: - pos = keys.index(frame_idx) - except ValueError: - keys.append(frame_idx) - keys.sort() - pos = keys.index(frame_idx) - 1 - pass - if pos < 0: - pos = 0 - pass - key = self._keys[pos] - else: - key = None - pass - - if key and (key.right_tween or \ - (key.left_tween and key.idx == frame_idx)): - # - # in tween - # - first_pos, last_pos = self._find_tween_range(pos) - first_key = self._keys[first_pos] - last_key = self._keys[last_pos] - - self._draw_tween(first_key, last_key) - self._draw_bottom_line(first_key.idx, last_key.idx + 1) - - for i in range(first_pos, last_pos + 1): - key = self._keys[i] - if key.left_tween is False or lastkey.right_tween_type != frameline._tween_type_none: - self._draw_keyframe(key.idx) - lastkey = key - pass - pass - else: # not in tween - self._draw_normal_frame(frame_idx) - self._draw_bottom_line(frame_idx, frame_idx + 1) - if key and (key.idx == frame_idx): - self._draw_keyframe(frame_idx) - pass - pass - pass - def set_tween_type(self,frame_idx,typ): - found=False - for i in range(0,len(self._keys)): - if self._keys[i].idx == frame_idx: - idx = i - found = True - break - if not found: return - key = self._keys[idx] - if typ == 'normal': - type = self._tween_type_none - elif typ == 'relocate': - type = self._tween_type_move - elif typ == 'scale': - type = self._tween_type_shape - if key.left_tween is False and key.right_tween is True: - key.right_tween_type = type - - ## \brief Show a mark for the pointer for a frame. # def _draw_hover(self, frame_idx): - if not self._drawing: - return - - if self._last_hover != -1: - self._redraw_frame(self._last_hover) - pass - - self._draw_active() - win = self.window w_x, w_y, w_w, w_h, depth = win.get_geometry() gc = self._gc @@ -511,10 +422,125 @@ win.draw_line(gc, line_x2, 1, line_x2, w_h - 2) win.draw_line(gc, line_x1, 1, line_x2, 1) win.draw_line(gc, line_x1, w_h - 2, line_x2, w_h - 2) + pass + + ## \brief Redraw a frame specified by an index. + # + def _draw_frame(self, frame_idx): + if not self._drawing: + return - self._last_hover = frame_idx + pos = self._find_keyframe_floor(frame_idx) + try: + key = self._keys[pos] + except IndexError: + key = None + pass + + if key and (key.right_tween or + (key.left_tween and key.idx == frame_idx)): + # + # in tween + # + first_pos, last_pos = self._find_tween_range(pos) + first_key = self._keys[first_pos] + last_key = self._keys[last_pos] + + self._draw_tween_of_key(first_pos) + else: # not in tween + self._draw_normal_frame(frame_idx) + self._draw_bottom_line(frame_idx, frame_idx + 1) + if key and (key.idx == frame_idx): + self._draw_keyframe(frame_idx) + pass + pass pass + def _draw_all_frames(self): + if not self._drawing: + return + + i = 0 + key_pos = 0 + try: + key = self._keys[key_pos] + except IndexError: + key = keyframe(self._num_frames) + pass + num_frames = self._num_frames + while i < num_frames: + if key.idx == i and key.right_tween: + # + # Skip tween keys + # + first_tween_pos, last_tween_pos = \ + self._find_tween_range(key_pos) + self._draw_tween(first_tween_pos, last_tween_pos) + last_tween_key = self._keys[last_tween_pos] + i = last_tween_key.idx + 1 + else: + self._draw_normal_frame(i) + if key.idx == i: + key_pos = key_pos+1 + try: + key = self._keys[key_pos] + except: + key = keyframe(self._num_frames) + pass + pass + i = i + 1 + pass + pass + + self._draw_bottom_line(0, num_frames) + + self._draw_keyframes() + pass + + def _draw_tween_of_key(self, key_pos): + if not self._drawing: + return + + first_pos, last_pos = self._find_tween_range(key_pos) + first_key = self._keys[first_pos] + last_key = self._keys[last_pos] + + self._draw_tween(first_pos, last_pos) + self._draw_bottom_line(first_key.idx, last_key.idx + 1) + + for i in range(first_pos, last_pos + 1): + key = self._keys[i] + self._draw_keyframe(key.idx) + pass + pass + + def _draw_active_frame(self): + if not self._drawing: + return + + if self._active_frame == -1: + return + + self._draw_active(self._active_frame) + pass + + def _draw_hover_frame(self, frame_idx): + if not self._drawing: + return + self._draw_hover(frame_idx) + pass + + def set_tween_type(self, frame_idx, tween_type): + pos = self._find_keyframe(frame_idx) + key = self._keys[pos] + assert key.right_tween + + key.right_tween_type = tween_type + self._draw_tween_of_key(pos) + + self._draw_active_frame() + pass + def update(self): if not self._drawing: return @@ -522,21 +548,22 @@ win = self.window x, y, w, h, depth = win.get_geometry() self._draw_all_frames() - self._draw_keyframes() - if self._active_frame != -1: - self._draw_active() - pass + self._draw_active_frame() pass ## Add a key frame # # A key frame is the frame that user specify actions. For # example, move a object or add new objects at the frame. - def add_keyframe(self, idx,ref=None): - key_indic = [key.idx for key in self._keys] - if idx in key_indic: - return - + def add_keyframe(self, idx, ref=None): + try: + pos = self._find_keyframe(idx) # it is not already a keyframe. + except ValueError: + pass + else: + raise ValueError, 'the frame is already a key frame' + + key_indic = [key.idx for key in self._keys] key_indic.append(idx) key_indic.sort() insert_pos = key_indic.index(idx) @@ -552,78 +579,99 @@ key.right_tween = True pass - self._draw_keyframe(idx) + if self._drawing: + self._draw_keyframe(idx) + pass pass def rm_keyframe(self, idx): - found=False - for i in range(0,len(self._keys)): - if self._keys[i].idx == idx: - idx = i - found = True - break - if not found: return - key = self._keys[idx] + key_pos = self._find_keyframe(idx) + key = self._keys[key_pos] + del self._keys[key_pos] if key.right_tween ^ key.left_tween: # # tween in one side # if key.right_tween: - right_key = self._keys[idx] + right_key = self._keys[key_pos] right_key.left_tween = False redraw_range = (right_key.idx, idx + 1) else: - left_key = self._keys[idx - 1] + left_key = self._keys[key_pos - 1] left_key.right_key = False redraw_range = (idx, left_key.idx + 1) pass for i in range(*redraw_range): - self._redraw_frame(i) + self._draw_frame(i) pass else: - self._redraw_frame(idx) + self._draw_frame(idx) pass - del self._keys[idx] - self._draw_active() + self._draw_active_frame() pass ## Tween the key frame specified by an index and the key frame at right. # # \see http://www.entheosweb.com/Flash/shape_tween.asp - def tween(self, idx, _type='normal'): - key_indic = [key.idx for key in self._keys] - pos = key_indic.index(idx) + def tween(self, idx, tween_type=TWEEN_TYPE_NONE): + pos = self._find_keyframe(idx) key = self._keys[pos] try: right_key = self._keys[pos + 1] except IndexError: - raise ValueError, 'No right key frame' + raise ValueError, 'no right key frame' key.right_tween = True right_key.left_tween = True - if _type == 'normal': - key.right_tween_type = self._tween_type_none - elif _type == 'relocate': - key.right_tween_type = self._tween_type_move - elif _type == 'scale': - key.right_tween_type = self._tween_type_shape + key.right_tween_type = tween_type + + self._draw_tween_of_key(pos) + self._draw_active_frame() pass - def get_tween_type(self,idx): + + def get_tween_type(self, idx): for i in range(0,len(self._keys)): key = self._keys[i] if key.left_tween is True: continue if key.idx == idx: - if key.right_tween_type == self._tween_type_none: - return 'normal' - elif key.right_tween_type == self._tween_type_move: - return 'relocate' - elif key.right_tween_type == self._tween_type_shape: - return 'scale' - + return key.right_tween_type + pass + pass + + def get_frame_blocks(self): + blocks = [] + for pos, key in enumerate(self._keys): + if key.right_tween: + next_key = self._keys[pos + 1] + block = (key.idx, next_key.idx, key.right_tween_type) + elif not key.left_tween: + block = (key.idx, key.idx, 0) + pass + blocks.append(block) + pass + return blocks + def get_frame_block(self, idx): + pos = self._find_keyframe_floor(idx) + if pos != -1: + key = self._keys[pos] + if key.idx == idx: + return key.idx, key.idx, 0 + elif key.right_tween: + next_key = self._keys[pos + 1] + return key.idx, next_key.idx, key.right_tween_type + pass + raise ValueError, \ + 'the frame specified by idx is not in any tween or a key frame' + + def get_frame_data(self, idx): + pos = self._find_keyframe(idx) + key = self._keys[pos] + return key.ref + ## Set active frame # # The active frame is the frame that is working on. @@ -633,49 +681,28 @@ raise IndexError, 'value of index (%d) is out of range' % (idx) if self._active_frame != -1: - self._redraw_frame(self._active_frame) + self._draw_frame(self._active_frame) pass self._active_frame = idx - self._draw_active() + self._draw_active_frame() pass def deactive(self): - self._redraw_frame(self._active_frame) + self._draw_frame(self._active_frame) self._active_frame = -1 pass def set_num_frames(self, num): self._num_frames = num + self._ pass def reset(self): self._keys = [] + self._active_frame = -1 + self._draw_all_frames() pass - def addScenes(self,rdoc,node): - for i in range(0,len(self._keys)): - key = self._keys[i] - if key.left_tween is True: continue - if key.right_tween is True: - ss = rdoc.createElement("ns0:scene") - node.appendChild(ss) - ss.setAttribute("start", str(key.idx+1)) - ss.setAttribute("ref",key.ref.attribute("id")) - ss.setAttribute("end", str(self._keys[i+1].idx+1)) - if self._keys[i].right_tween_type == self._tween_type_none: - ss.setAttribute("type", "normal") - elif self._keys[i].right_tween_type == self._tween_type_move: - ss.setAttribute("type", "relocate") - elif self._keys[i].right_tween_type == self._tween_type_shape: - ss.setAttribute("type", "scale") - else: - ss = rdoc.createElement("ns0:scene") - node.appendChild(ss) - ss.setAttribute("start", str(key.idx+1)) - ss.setAttribute("ref",key.ref.attribute("id")) - ss.setAttribute("type", "normal") - - ## \brief Start future drawing actions # def start_drawing(self): @@ -691,9 +718,6 @@ def stop_drawing(self): self._drawing = False pass - - def __len__(self): - return self._num_frames pass if __name__ == '__main__': diff -r 0ffef2df6201 -r 6586cd10c92f pyink/pyink.py --- a/pyink/pyink.py Fri Dec 24 15:40:16 2010 +0800 +++ b/pyink/pyink.py Sun Dec 26 19:17:12 2010 +0800 @@ -1,3 +1,14 @@ +import os + +try: + if os.environ['PYINK_DBG_ENABLE'] == 'yes': + import pdb + pdb.set_trace() + pass + pass +except: + pass + import pybInkscape import pygtk import gtk diff -r 0ffef2df6201 -r 6586cd10c92f pyink/tween.py --- a/pyink/tween.py Fri Dec 24 15:40:16 2010 +0800 +++ b/pyink/tween.py Sun Dec 26 19:17:12 2010 +0800 @@ -26,8 +26,10 @@ pass def updateTweenContent(self,obj, typ, source,dest,cur): """ - Update the content of the duplicate scene group. We will use the (start,end) and cur to calculate the percentage of - the tween motion effect and then use it to update the transform matrix of the duplicated scene group. + Update the content of the duplicate scene group. We will + use the (start,end) and cur to calculate the percentage of + the tween motion effect and then use it to update the + transform matrix of the duplicated scene group. """ start = source.idx @@ -76,8 +78,9 @@ label = s.getAttribute("inkscape:label") # Use i8nkscape:label to identidy the equipvalent objects if label: - if dests.hasattr(label.value()): - self.updateTweenObject(obj,typ,s,dests[label.value()],percent,o) + if dests.has_key(label): + self.updateTweenObject(obj, typ, s, + dests[label], percent, o) s = s.next() continue except: @@ -168,18 +171,29 @@ Generate tweened object in the @obj by using s and d in the @p percent http://lists.w3.org/Archives/Public/www-style/2010Jun/0602.html """ - if typ == 'relocate': - newobj = s.duplicate(self.document) - top = self.document.createElement("svg:g") - top.setAttribute("ref", s.getAttribute("id")) - top.appendChild(newobj) - obj.appendChild(top) + if typ == 1: if s.name() == 'svg:g': + if not newobj: + newobj = s.duplicate(self.document) + top = self.document.createElement("svg:g") + top.setAttribute("ref", s.getAttribute("id")) + top.appendChild(newobj) + obj.appendChild(top) + else: + top = newobj + pass # Parse the translate or matrix sm = self.parseTransform(s) dm = self.parseTransform(d) top.setAttribute("transform","translate(%g,%g)" % ((dm[2]-sm[2])*p,(dm[5]-sm[5])*p)) else: + if not newobj: + top = s.duplicate(self.document) + top.setAttribute('ref', s.getAttribute('id')) + obj.appendChild(top) + else: + top = newobj + pass try: sx = float(s.getAttribute("x")) sy = float(s.getAttribute("y")) @@ -193,10 +207,10 @@ traceback.print_exc() pass pass - elif typ == 'scale': + elif typ == 2: self.updateTweenObjectScale(obj,s,d,p,newobj) pass - elif typ == 'normal': + elif typ == 0: newobj = s.duplicate(self.document) newobj.setAttribute("ref", s.getAttribute("id")) top = self.document.createElement("svg:g")