anim.py 5.4 KB

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