1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
"""
@package animation.anim
@brief Animation class controls frame order
Classes:
- anim::Animation
(C) 2013 by the GRASS Development Team
This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.
@author Anna Petrasova <kratochanna gmail.com>
"""
import wx
from .utils import Orientation, ReplayMode
class Animation(wx.EvtHandler):
"""Animation class specifies which frame to show at which instance."""
def __init__(self):
wx.EvtHandler.__init__(self)
self.currentIndex = 0
self.frames = []
# states
self.orientation = Orientation.FORWARD
self.replayMode = ReplayMode.ONESHOT
self.callbackUpdateFrame = None
self.callbackEndAnimation = None
self.callbackOrientationChanged = None
self.isActive = False
def IsActive(self):
"""Returns if the animation is active or not"""
return self.isActive
def SetActive(self, active):
self.isActive = active
def SetFrames(self, frames):
"""Sets animation frames.
:param frames: list of strings
"""
self.frames = frames
def GetFrame(self, index):
"""Returns animation frame"""
if len(self.frames) <= 1: # special case handling (only 1 map)
return self.frames[0]
return self.frames[index]
def GetCount(self):
"""Get frame count."""
return len(self.frames)
count = property(fget=GetCount)
def GetReplayMode(self):
"""Returns replay mode (loop)."""
return self._replayMode
def SetReplayMode(self, mode):
self._replayMode = mode
replayMode = property(fset=SetReplayMode, fget=GetReplayMode)
def GetOrientation(self):
return self._orientation
def SetOrientation(self, mode):
self._orientation = mode
orientation = property(fset=SetOrientation, fget=GetOrientation)
def SetCallbackUpdateFrame(self, callback):
"""Sets function to be called when updating frame."""
self.callbackUpdateFrame = callback
def SetCallbackEndAnimation(self, callback):
"""Sets function to be called when animation ends."""
self.callbackEndAnimation = callback
def SetCallbackOrientationChanged(self, callback):
"""Sets function to be called when orientation changes."""
self.callbackOrientationChanged = callback
def Start(self):
if not self.IsActive():
return
def Pause(self, paused):
if not self.IsActive():
return
def Stop(self):
if not self.IsActive():
return
self.currentIndex = 0
self.callbackEndAnimation(self.currentIndex, self.GetFrame(self.currentIndex))
def _arrivedToEnd(self):
"""Decides which action to do after animation end (stop, repeat)."""
if not self.IsActive():
return
if self.replayMode == ReplayMode.ONESHOT:
self.Stop()
if self.orientation == Orientation.FORWARD:
if self.replayMode == ReplayMode.REPEAT:
self.currentIndex = 0
elif self.replayMode == ReplayMode.REVERSE:
self.orientation = Orientation.BACKWARD
self.currentIndex = self.count - 2 # -1
self.callbackOrientationChanged(Orientation.BACKWARD)
else:
if self.replayMode == ReplayMode.REPEAT:
self.currentIndex = self.count - 1
elif self.replayMode == ReplayMode.REVERSE:
self.orientation = Orientation.FORWARD
self.currentIndex = 1 # 0
self.callbackOrientationChanged(Orientation.FORWARD)
def Update(self):
"""Updates frame."""
if not self.IsActive():
return
self.callbackUpdateFrame(self.currentIndex, self.GetFrame(self.currentIndex))
if self.orientation == Orientation.FORWARD:
self.currentIndex += 1
if self.currentIndex == self.count:
self._arrivedToEnd()
else:
self.currentIndex -= 1
if self.currentIndex == -1:
self._arrivedToEnd()
def FrameChangedFromOutside(self, index):
"""Let the animation know that frame was changed from outside."""
if not self.IsActive():
return
self.currentIndex = index
self.callbackUpdateFrame(self.currentIndex, self.GetFrame(self.currentIndex))
def PreviousFrameIndex(self):
if not self.IsActive():
return
if self.orientation == Orientation.FORWARD:
self.currentIndex -= 1
if self.currentIndex == -1:
self.currentIndex = 0
else:
self.currentIndex += 1
if self.currentIndex == self.count:
self.currentIndex = self.count - 1
def NextFrameIndex(self):
if not self.IsActive():
return
if self.orientation == Orientation.FORWARD:
self.currentIndex += 1
if self.currentIndex == self.count:
self.currentIndex = self.count - 1
else:
self.currentIndex -= 1
if self.currentIndex == -1:
self.currentIndex = 0
# def test():
# import wx
# app = wx.PySimpleApp()
# a = Animation()
#
#
# frame = wx.Frame(None)
# frame.Show()
#
# a.SetReplayMode(ReplayMode.REVERSE)
# a.Start()
# app.MainLoop()
#
#
# if __name__ == '__main__':
# test()
|