anim.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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(self.currentIndex, self.GetFrame(self.currentIndex))
  76. def _arrivedToEnd(self):
  77. """Decides which action to do after animation end (stop, repeat)."""
  78. if not self.IsActive():
  79. return
  80. if self.replayMode == ReplayMode.ONESHOT:
  81. self.Stop()
  82. if self.orientation == Orientation.FORWARD:
  83. if self.replayMode == ReplayMode.REPEAT:
  84. self.currentIndex = 0
  85. elif self.replayMode == ReplayMode.REVERSE:
  86. self.orientation = Orientation.BACKWARD
  87. self.currentIndex = self.count - 2 # -1
  88. self.callbackOrientationChanged(Orientation.BACKWARD)
  89. else:
  90. if self.replayMode == ReplayMode.REPEAT:
  91. self.currentIndex = self.count - 1
  92. elif self.replayMode == ReplayMode.REVERSE:
  93. self.orientation = Orientation.FORWARD
  94. self.currentIndex = 1 # 0
  95. self.callbackOrientationChanged(Orientation.FORWARD)
  96. def Update(self):
  97. """Updates frame."""
  98. if not self.IsActive():
  99. return
  100. self.callbackUpdateFrame(self.currentIndex, self.GetFrame(self.currentIndex))
  101. if self.orientation == Orientation.FORWARD:
  102. self.currentIndex += 1
  103. if self.currentIndex == self.count:
  104. self._arrivedToEnd()
  105. else:
  106. self.currentIndex -= 1
  107. if self.currentIndex == -1:
  108. self._arrivedToEnd()
  109. def FrameChangedFromOutside(self, index):
  110. """Let the animation know that frame was changed from outside."""
  111. if not self.IsActive():
  112. return
  113. self.currentIndex = index
  114. self.callbackUpdateFrame(self.currentIndex, self.GetFrame(self.currentIndex))
  115. def PreviousFrameIndex(self):
  116. if not self.IsActive():
  117. return
  118. if self.orientation == Orientation.FORWARD:
  119. self.currentIndex -= 1
  120. if self.currentIndex == -1:
  121. self.currentIndex = 0
  122. else:
  123. self.currentIndex += 1
  124. if self.currentIndex == self.count:
  125. self.currentIndex = self.count - 1
  126. def NextFrameIndex(self):
  127. if not self.IsActive():
  128. return
  129. if self.orientation == Orientation.FORWARD:
  130. self.currentIndex += 1
  131. if self.currentIndex == self.count:
  132. self.currentIndex = self.count - 1
  133. else:
  134. self.currentIndex -= 1
  135. if self.currentIndex == -1:
  136. self.currentIndex = 0
  137. # def test():
  138. # import wx
  139. # app = wx.PySimpleApp()
  140. # a = Animation()
  141. #
  142. #
  143. # frame = wx.Frame(None)
  144. # frame.Show()
  145. #
  146. # a.SetReplayMode(ReplayMode.REVERSE)
  147. # a.Start()
  148. # app.MainLoop()
  149. #
  150. #
  151. # if __name__ == '__main__':
  152. # test()