From d05f2fccd64b72cb1ac300c72d8639733e1315fb Mon Sep 17 00:00:00 2001 From: igor Date: Wed, 1 Oct 2025 23:44:59 +0300 Subject: [PATCH] Preloader for load games --- portprotonqt/main_window.py | 14 +++++++++++ portprotonqt/preloader.py | 50 +++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 portprotonqt/preloader.py diff --git a/portprotonqt/main_window.py b/portprotonqt/main_window.py index 3473088..47d3f2b 100644 --- a/portprotonqt/main_window.py +++ b/portprotonqt/main_window.py @@ -14,6 +14,7 @@ from portprotonqt.custom_widgets import ClickableLabel, AutoSizeButton, NavLabel from portprotonqt.portproton_api import PortProtonAPI from portprotonqt.input_manager import InputManager from portprotonqt.context_menu_manager import ContextMenuManager, CustomLineEdit +from portprotonqt.preloader import Preloader from portprotonqt.system_overlay import SystemOverlay from portprotonqt.input_manager import GamepadType @@ -219,6 +220,17 @@ class MainWindow(QMainWindow): self.resize(width, height) else: self.showNormal() + self._preloader = Preloader(parent=self) + self._update_preloader_position() + + def _update_preloader_position(self): + if self._preloader: + self._preloader.move(self.rect().center() - self._preloader.rect().center()) + + def _close_preloader(self): + if self._preloader: + self._preloader.close() + self._preloader = None def on_slider_released(self) -> None: """Delegate to game library manager.""" @@ -434,6 +446,7 @@ class MainWindow(QMainWindow): def on_games_loaded(self, games: list[tuple]): self.game_library_manager.set_games(games) self.progress_bar.setVisible(False) + self._close_preloader() def open_portproton_forum_topic(self, topic_name: str): """Open the PortProton forum topic or search page for this game.""" @@ -775,6 +788,7 @@ class MainWindow(QMainWindow): self._last_width = self.width() if abs(self.width() - self._last_width) > 10: self._last_width = self.width() + self._update_preloader_position() def dragEnterEvent(self, event): diff --git a/portprotonqt/preloader.py b/portprotonqt/preloader.py new file mode 100644 index 0000000..91e2cad --- /dev/null +++ b/portprotonqt/preloader.py @@ -0,0 +1,50 @@ +import time + +from PySide6.QtCore import QRect +from PySide6.QtGui import QPainter, QPen, QBrush, Qt, QColor, QConicalGradient +from PySide6.QtWidgets import QWidget + + +class Preloader(QWidget): + def __init__(self, speed=180.0, line_line_width=20, color=QColor(0, 120, 215), parent=None): + super().__init__(parent) + self.setFixedSize(150, 150) + self._speed = speed + self._line_width = line_line_width + self._color1 = color + self._color2 = QColor(color.red(), color.green(), color.blue(), 0) + self._start_time = time.time() + + def showEvent(self, event): + self._start_time = time.time() + + def paintEvent(self, event): + rect = self._get_preloader_rect() + center = rect.center() + painter = QPainter(self) + painter.setRenderHint(QPainter.RenderHint.Antialiasing) + painter.setPen(self._get_pen()) + painter.translate(center) + painter.rotate(self._get_angle()) + painter.translate(-center) + painter.drawArc(rect, 0, 270 * 16) + self.update() + + def _get_pen(self) -> QPen: + gradient = QConicalGradient() + gradient.setCenter(self.rect().center()) + gradient.setColorAt(0, self._color1) + gradient.setColorAt(1, self._color2) + pen = QPen(QBrush(gradient), self._line_width) + pen.setCapStyle(Qt.PenCapStyle.RoundCap) + return pen + + def _get_angle(self) -> float: + duration = time.time() - self._start_time + return (self._speed * duration) % 360.0 + + def _get_preloader_rect(self) -> QRect: + size = self._line_width // 2 + rect = self.rect() + rect.adjust(size, size, -size, -size) + return rect -- 2.49.1