Version 3.2.0: fast lists with loading spinners, names from the game files, INT docs and screenshots, cleanup
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"""Small activity spinner: a rotating accent-coloured arc. Runs only while visible."""
|
||||
from PySide6.QtCore import QRectF, QTimer, Qt
|
||||
from PySide6.QtGui import QColor, QPainter, QPen
|
||||
from PySide6.QtCore import QEvent, QRectF, QTimer, Qt
|
||||
from PySide6.QtGui import QColor, QPainter, QPalette, QPen
|
||||
from PySide6.QtWidgets import QWidget
|
||||
|
||||
from . import icons
|
||||
@@ -51,3 +51,68 @@ class Spinner(QWidget):
|
||||
def paintEvent(self, _):
|
||||
p = QPainter(self)
|
||||
paint_arc(p, QRectF(self.rect()), self.angle)
|
||||
|
||||
|
||||
class BusyOverlay(QWidget):
|
||||
"""A list being (re)loaded: a light veil over the widget with the spinner and a message in its centre, the
|
||||
same arc as the waveform's loading state. Covers the target and follows its size; blocks clicks while on."""
|
||||
|
||||
def __init__(self, target):
|
||||
super().__init__(target)
|
||||
self.target = target
|
||||
self.message = ""
|
||||
self.angle = 0
|
||||
self.timer = QTimer(self)
|
||||
self.timer.setInterval(STEP_MS)
|
||||
self.timer.timeout.connect(self._step)
|
||||
target.installEventFilter(self)
|
||||
self.hide()
|
||||
|
||||
def start(self, message):
|
||||
self.message = message
|
||||
self.setGeometry(self.target.rect())
|
||||
self.raise_()
|
||||
self.show()
|
||||
self.timer.start()
|
||||
self.update()
|
||||
|
||||
def stop(self):
|
||||
self.timer.stop()
|
||||
self.hide()
|
||||
|
||||
@property
|
||||
def busy(self):
|
||||
return not self.isHidden() # on, whether or not the window is on screen yet
|
||||
|
||||
def _step(self):
|
||||
self.angle = (self.angle + STEP_DEG) % 360
|
||||
if self.isVisible():
|
||||
self.update()
|
||||
|
||||
def eventFilter(self, obj, e):
|
||||
if obj is self.target and e.type() == QEvent.Type.Resize:
|
||||
self.setGeometry(self.target.rect())
|
||||
return False
|
||||
|
||||
def paintEvent(self, _):
|
||||
p = QPainter(self)
|
||||
p.setRenderHint(QPainter.RenderHint.Antialiasing)
|
||||
pal = self.palette()
|
||||
veil = QColor(pal.color(QPalette.ColorRole.Base))
|
||||
veil.setAlpha(210)
|
||||
p.fillRect(self.rect(), veil)
|
||||
fm = p.fontMetrics()
|
||||
d, gap, pad = 20, 12, 16
|
||||
tw = fm.horizontalAdvance(self.message)
|
||||
w, h = pad + d + gap + tw + pad, max(d, fm.height()) + 2 * pad - 8
|
||||
box = QRectF((self.width() - w) / 2, (self.height() - h) / 2, w, h)
|
||||
border = QColor(pal.color(QPalette.ColorRole.Text))
|
||||
border.setAlpha(40)
|
||||
p.setPen(QPen(border, 1))
|
||||
p.setBrush(pal.color(QPalette.ColorRole.Window))
|
||||
p.drawRoundedRect(box, 8, 8)
|
||||
y = box.center().y()
|
||||
paint_arc(p, QRectF(box.left() + pad, y - d / 2, d, d), self.angle)
|
||||
p.setPen(pal.color(QPalette.ColorRole.Text))
|
||||
p.drawText(QRectF(box.left() + pad + d + gap, y - fm.height() / 2, tw + 2, fm.height()),
|
||||
Qt.AlignmentFlag.AlignVCenter | Qt.AlignmentFlag.AlignLeft, self.message)
|
||||
|
||||
Reference in New Issue
Block a user