Add do_stop method for animations

This adds a explicit method for cleaning up the animation.  Previously,
animations expected the next_frame to be called where frame=end.

That guarantee was never provided by the api.  This resulted in
animations sometimes being in odd states.  For example, Browse activity
had an animation that overrode the Gtk "draw" signal.  If the signal
was not unbound, the animated object was mistakenly rendered after
the completion of the animation, obstructing the user's view.

This api is explicit and allows cleaner code in the animation
implementation.  The clean up code goes in do_stop rather than in a
conditional of next_frame.
This commit is contained in:
Sam Parkinson 2016-07-26 21:06:44 +10:00
parent 61bc42f2c2
commit d37da7ee88
No known key found for this signature in database
GPG Key ID: 34E268B2FA2F8B13

View File

@ -146,6 +146,9 @@ class Animator(GObject.GObject):
''' '''
Stop the animation and emit the `completed` signal Stop the animation and emit the `completed` signal
''' '''
for animation in self._animations:
animation.do_stop()
if self._timeout_sid and \ if self._timeout_sid and \
not hasattr(self._widget, 'add_tick_callback'): not hasattr(self._widget, 'add_tick_callback'):
GObject.source_remove(self._timeout_sid) GObject.source_remove(self._timeout_sid)
@ -235,3 +238,43 @@ class Animation(object):
the current progress in the animation the current progress in the animation
''' '''
pass pass
def do_stop(self):
'''
This method is called whenever the animation is stopped, either
due to the animation ending or being stopped by the animation.
`next_frame` will not be called after do_stop, unless the animation
is restarted.
.. versionadded:: 0.109.0.3
This should be used in subclasses if they bind any signals. Eg.
if they bind the draw signal for a widget:
.. code-block:: python
class SignalAnimation(Animation):
def __init__(self, widget):
Animation.__init__(self, 0, 1)
self._draw_hid = None
self._widget = widget
def next_frame(self, frame):
self._frame = frame
if self._draw_hid is None:
self._draw_hid = self._widget.connect_after(
'draw', self.__draw_cb)
self._widget.queue_draw()
def __draw_cb(self, widget, cr):
cr.save()
# Do the draw
cr.restore()
def do_stop(self):
self._widget.disconnect(self._draw_hid)
self._widget.queue_draw()
'''
pass