From d37da7ee882ac037d55550f995383ff62e078023 Mon Sep 17 00:00:00 2001 From: Sam Parkinson Date: Tue, 26 Jul 2016 21:06:44 +1000 Subject: [PATCH 1/2] 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. --- src/sugar3/graphics/animator.py | 43 +++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/sugar3/graphics/animator.py b/src/sugar3/graphics/animator.py index 37224890..d7368456 100644 --- a/src/sugar3/graphics/animator.py +++ b/src/sugar3/graphics/animator.py @@ -146,6 +146,9 @@ class Animator(GObject.GObject): ''' Stop the animation and emit the `completed` signal ''' + for animation in self._animations: + animation.do_stop() + if self._timeout_sid and \ not hasattr(self._widget, 'add_tick_callback'): GObject.source_remove(self._timeout_sid) @@ -235,3 +238,43 @@ class Animation(object): the current progress in the animation ''' 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 From 92ea35d724b37dd9c1957aa5d1b45bdb865f51e8 Mon Sep 17 00:00:00 2001 From: Sam Parkinson Date: Tue, 26 Jul 2016 21:14:10 +1000 Subject: [PATCH 2/2] Fix typos in sugar3.graphics.animator docs --- src/sugar3/graphics/animator.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sugar3/graphics/animator.py b/src/sugar3/graphics/animator.py index d7368456..7d4ca90c 100644 --- a/src/sugar3/graphics/animator.py +++ b/src/sugar3/graphics/animator.py @@ -16,7 +16,7 @@ # Boston, MA 02111-1307, USA. """ -The animator module provides a simple framwork to create animations. +The animator module provides a simple framework to create animations. Example: Animate the size of a window:: @@ -65,7 +65,7 @@ EASE_IN_EXPO = 1 class Animator(GObject.GObject): ''' - The animator class manages the the timing for calling the + The animator class manages the timing for calling the animations. The animations can be added using the `add` function and then started with the `start` function. If multiple animations are added, then they will be played back at the same time and rate @@ -90,7 +90,7 @@ class Animator(GObject.GObject): When creating an animation, take into account the limited cpu power on some devices, such as the XO. Setting the fps too high on can - use signifigant cpu usage on the XO. + use significant cpu usage on the XO. ''' __gsignals__ = { @@ -206,7 +206,7 @@ class Animation(object): def do_frame(self, t, duration, easing): ''' - This method is called by the animtor class every frame. This + This method is called by the animator class every frame. This method calculated the `frame` value to then call `next_frame`. Args: @@ -230,7 +230,7 @@ class Animation(object): def next_frame(self, frame): ''' - This method is called every frame and should be overriden by + This method is called every frame and should be overridden by subclasses. Args: