Skip to content

Commit

Permalink
Merge pull request #27 from ubopod/transactions-queue
Browse files Browse the repository at this point in the history
fix: queue transitions instead of letting the last transition interrupt the active
  • Loading branch information
sassanh authored Feb 9, 2024
2 parents 8239390 + 36c17a4 commit bc4d55e
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 14 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## Version 0.9.2

- fix: queue transitions instead of letting the last transition interrupt the active
one

## Version 0.9.1

- hotfix: remove debug background rectangle
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "ubo-gui"
version = "0.9.1"
version = "0.9.2"
description = "GUI sdk for Ubo Pod"
authors = ["Sassan Haradji <[email protected]>"]
license = "Apache-2.0"
Expand Down
21 changes: 11 additions & 10 deletions ubo_gui/menu/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def go_down(self: MenuWidget) -> None:
return
self.page_index = (self.page_index + 1) % self.pages
self.render_items()
self.screen_manager.switch_to(
self._switch_to(
self.current_screen,
transition=self._slide_transition,
direction='up',
Expand All @@ -181,7 +181,7 @@ def go_up(self: MenuWidget) -> None:
return
self.page_index = (self.page_index - 1) % self.pages
self.render_items()
self.screen_manager.switch_to(
self._switch_to(
self.current_screen,
transition=self._slide_transition,
direction='down',
Expand Down Expand Up @@ -371,7 +371,7 @@ def handle_items_change(items: Sequence[Item]) -> None:
self.current_menu_items = items
self.render_items()
if last_items:
self.screen_manager.switch_to(
self._switch_to(
self.current_screen,
transition=self._no_transition,
)
Expand Down Expand Up @@ -459,7 +459,7 @@ def replace(
parent=self.top.parent,
)
self.top.subscriptions = subscriptions
self.screen_manager.switch_to(
self._switch_to(
self.current_screen,
transition=self._no_transition,
)
Expand All @@ -485,11 +485,12 @@ def push( # noqa: PLR0913
*self.stack,
StackApplicationItem(application=item, parent=parent),
]
self.screen_manager.switch_to(

self._switch_to(
self.current_screen,
transition=transition,
**({'duration': duration} if duration else {}),
**({'direction': direction} if direction else {}),
duration=duration,
direction=direction,
)

def pop(
Expand All @@ -516,11 +517,11 @@ def pop(
elif self.current_application:
self.clean_application(self.current_application)
transition_ = self._swap_transition
self.screen_manager.switch_to(
self._switch_to(
self.current_screen,
transition=transition or transition_,
**({'duration': duration} if duration else {}),
**({'direction': direction} if direction else {}),
duration=duration,
direction=direction,
)

def get_is_scrollbar_visible(self: MenuWidget) -> bool:
Expand Down
71 changes: 68 additions & 3 deletions ubo_gui/menu/transitions.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
"""Provides easy access to different transitions."""
from __future__ import annotations

import threading
from functools import cached_property
from typing import Any

from headless_kivy_pi import HeadlessWidget
from kivy.clock import Clock
from kivy.uix.screenmanager import (
NoTransition,
Screen,
ScreenManager,
SlideTransition,
SwapTransition,
TransitionBase,
Expand All @@ -15,13 +20,24 @@
class TransitionsMixin:
"""Provides easy access to different transitions."""

transition_queue: list[
tuple[Screen | None, TransitionBase, str | None, float | None]
]
screen_manager: ScreenManager
_is_transition_in_progress: bool = False
_transition_progress_lock: threading.Lock

def __init__(self: TransitionsMixin, **kwargs: dict[str, Any]) -> None:
"""Initialize the transitions mixin."""
_ = kwargs
self._transition_progress_lock = threading.Lock()
self.transition_queue = []

def _handle_transition_progress(
self: TransitionsMixin,
transition: TransitionBase,
progression: float,
) -> None:
if progression is 0: # noqa: F632 - float 0.0 is not accepted, we are looking for int 0
HeadlessWidget.activate_high_fps_mode()
transition.screen_out.opacity = 1 - progression
transition.screen_in.opacity = progression

Expand All @@ -31,7 +47,28 @@ def _handle_transition_complete(
) -> None:
transition.screen_out.opacity = 0
transition.screen_in.opacity = 1
HeadlessWidget.activate_low_fps_mode()
with self._transition_progress_lock:
if self.transition_queue:
(
(screen, transition, direction, duration),
*self.transition_queue,
) = self.transition_queue
if (
len(self.transition_queue) > 1
and transition is not self._no_transition
):
duration = 0.1
Clock.schedule_once(
lambda *_: self.screen_manager.switch_to(
screen,
transition=transition,
**({'duration': duration} if duration else {}),
**({'direction': direction} if direction else {}),
),
)
else:
HeadlessWidget.activate_low_fps_mode()
self._is_transition_in_progress = False

def _setup_transition(self: TransitionsMixin, transition: TransitionBase) -> None:
transition.bind(on_progress=self._handle_transition_progress)
Expand All @@ -54,3 +91,31 @@ def _swap_transition(self: TransitionsMixin) -> SwapTransition:
transition = SwapTransition()
self._setup_transition(transition)
return transition

def _switch_to(
self: TransitionsMixin,
screen: Screen | None,
/,
*,
transition: TransitionBase,
duration: float | None = None,
direction: str | None = None,
) -> None:
"""Switch to a new screen."""
with self._transition_progress_lock:
if not self._is_transition_in_progress:
HeadlessWidget.activate_high_fps_mode()
self._is_transition_in_progress = transition is not self._no_transition
Clock.schedule_once(
lambda *_: self.screen_manager.switch_to(
screen,
transition=transition,
**({'duration': duration} if duration else {}),
**({'direction': direction} if direction else {}),
),
)
else:
self.transition_queue = [
*self.transition_queue,
(screen, transition, direction, duration),
]

0 comments on commit bc4d55e

Please sign in to comment.