Instead of animating a certain amount on each call to animate(), we'll measure the time since the animation started - that should be stabler.

This also means I do not need to use nonlocal, since we don't keep mutable state in captured variables. Hope that makes this code clearer.
This commit is contained in:
Daniel Johnson 2023-12-13 18:57:12 -05:00 committed by Mathieu Comandon
parent 58b1401774
commit 87f6706a44
2 changed files with 29 additions and 13 deletions

View file

@ -1,3 +1,4 @@
import time
from typing import List
from gi.repository import Gdk, Gio, GLib, GObject
@ -119,24 +120,31 @@ class GameView:
raise NotImplementedError
def on_game_start(self, game):
fraction = 0
delta = 0.05
limit = 0.1
"""On game start, we trigger an animation to show the game is starting; it runs at least
one cycle, but continues until the game exits the STATE_LAUNCHING state."""
# We animate by looking at how long the animation has been running;
# This keeps things on track even if drawing is low or the timeout we use
# is not quite regular.
start_time = time.monotonic()
cycle_time = 0.375
max_indent = 0.1
def animate():
nonlocal fraction, delta, limit
elapsed = time.monotonic() - start_time
cycle = elapsed % cycle_time
# After 1/2 the cycle, start counting down instead of up
if cycle > cycle_time / 2:
cycle = cycle_time - cycle
# scale to achieve the max_indent at cycle_time/2.
fraction = max_indent * (cycle * 2 / cycle_time)
self.queue_draw()
fraction += delta
if fraction > limit:
fraction = limit
delta = -0.0125
elif fraction <= 0.0:
if game.state == game.STATE_LAUNCHING:
fraction = 0.0
delta = 0.0125
else:
if elapsed >= cycle_time:
if game.state != game.STATE_LAUNCHING:
self.image_renderer.inset_game(game.id, 0.0)
return False

View file

@ -115,6 +115,14 @@ class GridViewCellRendererImage(Gtk.CellRenderer):
self._inset_fractions = {}
def inset_game(self, game_id, fraction):
"""This function indicates that a particular game should be displayed inset by a certain fraction of
its total size; 0 is full size, 0.1 would show it at 90% size, but centered.
This is not bound as an attribute; it's used for an ephemeral animation, and we wouldn't want
to mess with the GameStore to do it. Instead, the cell renderer tracks these per game ID, and
the caller uses queue_draw() to trigger a redraw.
Set the fraction to 0 for a game to remove the effect when done."""
if fraction > 0.0:
self._inset_fractions[game_id] = fraction
else: