diff --git a/CHANGELOG.md b/CHANGELOG.md index 3713260..365867b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - chore: migrate from poetry to uv for the sake of improving performance and dealing with conflicting sub-dependencies - feat: add spinner widget which doesn't trigger whole screen renders and uses new local renders of headless-kivy +- chore: update to the latest version of headless-kivy which drops fps control ## Version 0.13.3 diff --git a/ubo_gui/menu/_transitions.py b/ubo_gui/menu/_transitions.py index 9287526..374b133 100644 --- a/ubo_gui/menu/_transitions.py +++ b/ubo_gui/menu/_transitions.py @@ -6,7 +6,6 @@ from functools import cached_property from typing import Any, NotRequired, TypedDict -from headless_kivy import HeadlessWidget from kivy.clock import mainthread from kivy.uix.screenmanager import ( NoTransition, @@ -17,7 +16,6 @@ SwapTransition, TransitionBase, ) -from kivy.uix.widget import Widget class SwitchParameters(TypedDict): @@ -80,10 +78,6 @@ def _handle_transition_complete( **switch_parameters, ) else: - if isinstance(self, Widget): - headless_widget = HeadlessWidget.get_instance(self) - if headless_widget: - headless_widget.activate_low_fps_mode() self._is_transition_in_progress = False def _setup_transition(self: TransitionsMixin, transition: TransitionBase) -> None: @@ -155,10 +149,6 @@ def _switch_to( (screen, transition, direction, duration), ] else: - if isinstance(self, Widget): - headless_widget = HeadlessWidget.get_instance(self) - if headless_widget: - headless_widget.activate_high_fps_mode() self._is_transition_in_progress = transition is not self._no_transition self._is_preparation_in_progress = True self._perform_switch( diff --git a/ubo_gui/menu/menu_widget.py b/ubo_gui/menu/menu_widget.py index 20c039f..c839ed8 100644 --- a/ubo_gui/menu/menu_widget.py +++ b/ubo_gui/menu/menu_widget.py @@ -15,7 +15,6 @@ import warnings from typing import TYPE_CHECKING, cast, overload -from headless_kivy import HeadlessWidget from kivy.clock import mainthread from kivy.lang.builder import Builder from kivy.properties import ( @@ -544,9 +543,6 @@ def set_current_screen(self: MenuWidget, screen: Screen) -> bool: def open_application(self: MenuWidget, application: PageWidget) -> None: """Open an application.""" with self.stack_lock: - headless_widget = HeadlessWidget.get_instance(self) - if headless_widget: - headless_widget.activate_high_fps_mode() application.name = uuid.uuid4().hex application.padding_bottom = self.padding_bottom application.padding_top = self.padding_top diff --git a/ubo_gui/spinner/__init__.py b/ubo_gui/spinner/__init__.py index f8fbdb2..3280993 100644 --- a/ubo_gui/spinner/__init__.py +++ b/ubo_gui/spinner/__init__.py @@ -2,17 +2,17 @@ from __future__ import annotations -import math +import pathlib from typing import Any, cast from headless_kivy import HeadlessWidget from kivy.clock import Clock -from kivy.graphics.context_instructions import Rotate +from kivy.lang.builder import Builder from kivy.properties import NumericProperty from kivy.uix.label import Label -class SpinnerWidget(HeadlessWidget): +class SpinnerWidget(HeadlessWidget, Label): """Spinner widget for loading indication.""" angle = NumericProperty(0) @@ -20,29 +20,18 @@ class SpinnerWidget(HeadlessWidget): def __init__(self: SpinnerWidget, **kwargs: object) -> None: """Initialize the SpinnerWidget class.""" super().__init__(**cast(Any, kwargs)) - self.interval = Clock.schedule_interval(self.rotate_spinner, 1 / 40) - self.label = Label( - text='', - color=(1, 1, 1), - ) - self.label.bind(texture_size=self.label.setter('size')) - self.bind( - size=lambda *_: self.label.setter('center')( - self.label, - (self.width / 2, self.height / 2), - ), - ) - self.add_widget(self.label) + self.interval = Clock.schedule_interval(self.rotate_spinner, 1 / 60) def __del__(self: SpinnerWidget) -> None: - """Remove the spinner widget.""" + """Cancel the interval when the widget is deleted.""" self.interval.cancel() def rotate_spinner(self: SpinnerWidget, dt: float) -> None: """Rotate the spinner.""" - self.angle = (self.angle + dt) % math.tau - with self.label.canvas.before: - Rotate( - angle=-dt * 400, - origin=self.label.center, - ) + self.angle -= dt * 500 + self.angle %= 360 + + +Builder.load_file( + pathlib.Path(__file__).parent.joinpath('spinner_widget.kv').resolve().as_posix(), +) diff --git a/ubo_gui/spinner/spinner_widget.kv b/ubo_gui/spinner/spinner_widget.kv new file mode 100644 index 0000000..cacbfc9 --- /dev/null +++ b/ubo_gui/spinner/spinner_widget.kv @@ -0,0 +1,16 @@ +#:kivy 2.3.0 + +: + Label: + text: '' + size: print(root.size) or root.size + + canvas.before: + PushMatrix + + Rotate: + angle: root.angle + origin: self.center + + canvas.after: + PopMatrix