################################################################################
#
# This file is part of Gato (Graph Animation Toolbox)
#
# file: AnimationHistory.py
# author: Alexander Schliep (schliep@molgen.mpg.de)
#
# Copyright (C) 1998-2005, Alexander Schliep, Winfried Hochstaettler and
# Copyright 1998-2001 ZAIK/ZPR, Universitaet zu Koeln
#
# Contact: schliep@molgen.mpg.de, wh@zpr.uni-koeln.de
#
# Information: http://gato.sf.net
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the Free
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
#
# This file is version $Revision: 1.1 $
# from $Date: 2007/10/04 14:36:39 $
# last change by $Author: edream $.
#
################################################################################
import time
from GatoGlobals import gBlinkRate
class AnimationCommand:
def __init__(self, method, target, args, undo_method=None, undo_args=None):
self.target = target
self.method = method
self.args = args
self.undo_method = undo_method
self.undo_args = undo_args
def Do(self):
apply(self.method, self.target + self.args)
def Undo(self):
if self.undo_method == None:
apply(self.method, self.target + self.undo_args)
else:
apply(self.undo_method, self.target + self.undo_args)
class AnimationHistory:
"""AnimationHistory provides a history of animation commands, and a undo and
redo facility. It is to be used as a wrapper around a GraphDisplay and it
will happily dispatch all calls to GraphDisplay.
Animation commands for which undo/redo is provided, have to be methods of
AnimationHistory
"""
def __init__(self, animator):
self.animator = animator
self.history = []
self.history_index = None
#========== Provide Undo/Redo for animation commands from GraphDisplay ======
def SetVertexColor(self, v, color):
# print 'SetVertexColor', v, color
animation = AnimationCommand(self.animator.SetVertexColor, (v,), (color,),
undo_args=(self.animator.GetVertexColor(v),))
animation.Do()
self.append(animation)
#SetAllVerticesColor
#SetAllEdgesColor
def SetEdgeColor(self,tail, head, color):
# print 'SetEdgeColor', tail, head, color
animation = AnimationCommand(self.animator.SetEdgeColor, (tail,head), (color,),
undo_args=(self.animator.GetEdgeColor(tail,head),))
animation.Do()
self.append(animation)
def BlinkVertex(self, v, color=None):
# print 'BlinkVertex', v, color
animation = AnimationCommand(self.animator.BlinkVertex, (v,), (color,))
animation.Do()
self.append(animation)
def BlinkEdge(self, tail, head, color=None):
# print 'BlinkEdge', tail, head, color
animation = AnimationCommand(self.animator.BlinkEdge, (tail,head), (color,))
animation.Do()
self.append(animation)
def SetVertexFrameWidth(self,v,val):
# print 'SetVertexFrameWidth', v, val
animation = AnimationCommand(self.animator.SetVertexFrameWidth, (v,), (val,),
undo_args=(self.animator.GetVertexFrameWidth(v),))
animation.Do()
self.append(animation)
def SetVertexAnnotation(self,v,annotation,color="black"):
# print 'SetVertexAnnotation',v,annotation,color
animation = AnimationCommand(self.animator.SetVertexAnnotation, (v,), (annotation,),
undo_args=(self.animator.GetVertexAnnotation(v),))
animation.Do()
self.append(animation)
#========== Handle all other methods from GraphDisplay =====================
def __getattr__(self,arg):
# This is broken. Calls to self.animator methods as args in self.animator method
# calls should fail.
tmp = getattr(self.animator,arg)
if callable(tmp):
self.methodName = arg
self.method = tmp
return getattr(self,'caller')
else:
return self.animator.__dict__[arg]
def caller(self,*args):
# print self.methodName,"(",args,")"
return apply(self.method,args)
#========== AnimationHistory methods =======================================
def Undo(self):
if self.history_index == None: # Have never undone anything
self.history_index = len(self.history) - 1
if self.history_index >= 0:
self.history[self.history_index][1].Undo()
self.history_index -= 1
def Do(self):
if self.history_index is None:
return
if self.history_index >= len(self.history):
self.history_index = None
else:
self.history[self.history_index][1].Do()
self.history_index += 1
def DoAll(self):
# Catchup
if self.history_index is not None:
for time, cmd in self.history[self.history_index:]:
cmd.Do()
self.history_index = None
def Replay(self):
if len(self.history) > 1:
self.history[-1][1].Undo()
self.animator.update()
self.animator.canvas.after(10*gBlinkRate)
self.history[-1][1].Do()
self.animator.update()
self.animator.canvas.after(10*gBlinkRate)
self.history[-1][1].Undo()
self.animator.update()
self.animator.canvas.after(10*gBlinkRate)
self.history[-1][1].Do()
self.animator.update()
def append(self, animation):
#print "AnimationHistory: appending animation", animation.method
self.history.append((time.time(), animation))
|