anim.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. """
  2. @package animation.anim
  3. @brief Animation class controls frame order
  4. Classes:
  5. - anim::Animation
  6. (C) 2013 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 Petrasova <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. if len(self.frames) <= 1: # special case handling (only 1 map)
  39. return self.frames[0]
  40. return self.frames[index]
  41. def GetCount(self):
  42. """Get frame count."""
  43. return len(self.frames)
  44. count = property(fget=GetCount)
  45. def GetReplayMode(self):
  46. """Returns replay mode (loop)."""
  47. return self._replayMode
  48. def SetReplayMode(self, mode):
  49. self._replayMode = mode
  50. replayMode = property(fset=SetReplayMode, fget=GetReplayMode)
  51. def GetOrientation(self):
  52. return self._orientation
  53. def SetOrientation(self, mode):
  54. self._orientation = mode
  55. orientation = property(fset=SetOrientation, fget=GetOrientation)
  56. def SetCallbackUpdateFrame(self, callback):
  57. """Sets function to be called when updating frame."""
  58. self.callbackUpdateFrame = callback
  59. def SetCallbackEndAnimation(self, callback):
  60. """Sets function to be called when animation ends."""
  61. self.callbackEndAnimation = callback
  62. def SetCallbackOrientationChanged(self, callback):
  63. """Sets function to be called when orientation changes."""
  64. self.callbackOrientationChanged = callback
  65. def Start(self):
  66. if not self.IsActive():
  67. return
  68. def Pause(self, paused):
  69. if not self.IsActive():
  70. return
  71. def Stop(self):
  72. if not self.IsActive():
  73. return
  74. self.currentIndex = 0
  75. self.callbackEndAnimation(
  76. self.currentIndex, self.GetFrame(
  77. self.currentIndex))
  78. def _arrivedToEnd(self):
  79. """Decides which action to do after animation end (stop, repeat)."""
  80. if not self.IsActive():
  81. return
  82. if self.replayMode == ReplayMode.ONESHOT:
  83. self.Stop()
  84. if self.orientation == Orientation.FORWARD:
  85. if self.replayMode == ReplayMode.REPEAT:
  86. self.currentIndex = 0
  87. elif self.replayMode == ReplayMode.REVERSE:
  88. self.orientation = Orientation.BACKWARD
  89. self.currentIndex = self.count - 2 # -1
  90. self.callbackOrientationChanged(Orientation.BACKWARD)
  91. else:
  92. if self.replayMode == ReplayMode.REPEAT:
  93. self.currentIndex = self.count - 1
  94. elif self.replayMode == ReplayMode.REVERSE:
  95. self.orientation = Orientation.FORWARD
  96. self.currentIndex = 1 # 0
  97. self.callbackOrientationChanged(Orientation.FORWARD)
  98. def Update(self):
  99. """Updates frame."""
  100. if not self.IsActive():
  101. return
  102. self.callbackUpdateFrame(
  103. self.currentIndex, self.GetFrame(
  104. self.currentIndex))
  105. if self.orientation == Orientation.FORWARD:
  106. self.currentIndex += 1
  107. if self.currentIndex == self.count:
  108. self._arrivedToEnd()
  109. else:
  110. self.currentIndex -= 1
  111. if self.currentIndex == -1:
  112. self._arrivedToEnd()
  113. def FrameChangedFromOutside(self, index):
  114. """Let the animation know that frame was changed from outside."""
  115. if not self.IsActive():
  116. return
  117. self.currentIndex = index
  118. self.callbackUpdateFrame(
  119. self.currentIndex, self.GetFrame(
  120. self.currentIndex))
  121. def PreviousFrameIndex(self):
  122. if not self.IsActive():
  123. return
  124. if self.orientation == Orientation.FORWARD:
  125. self.currentIndex -= 1
  126. if self.currentIndex == -1:
  127. self.currentIndex = 0
  128. else:
  129. self.currentIndex += 1
  130. if self.currentIndex == self.count:
  131. self.currentIndex = self.count - 1
  132. def NextFrameIndex(self):
  133. if not self.IsActive():
  134. return
  135. if self.orientation == Orientation.FORWARD:
  136. self.currentIndex += 1
  137. if self.currentIndex == self.count:
  138. self.currentIndex = self.count - 1
  139. else:
  140. self.currentIndex -= 1
  141. if self.currentIndex == -1:
  142. self.currentIndex = 0
  143. # def test():
  144. # import wx
  145. # app = wx.PySimpleApp()
  146. # a = Animation()
  147. #
  148. #
  149. # frame = wx.Frame(None)
  150. # frame.Show()
  151. #
  152. # a.SetReplayMode(ReplayMode.REVERSE)
  153. # a.Start()
  154. # app.MainLoop()
  155. #
  156. #
  157. # if __name__ == '__main__':
  158. # test()