anim.py 5.4 KB

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