anim.py 5.5 KB

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