mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Use native code to draw wait spinner
This commit is contained in:
parent
e228e601d5
commit
60b9cd1d8d
@ -4,97 +4,20 @@
|
|||||||
|
|
||||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
import numbers
|
|
||||||
from PyQt5.Qt import (
|
from PyQt5.Qt import (
|
||||||
Qt, QWidget, QSizePolicy, QSize, QRect, QConicalGradient, QPen, QBrush,
|
QDialog, QLabel, QSizePolicy, QStackedLayout, QStackedWidget, Qt, QVBoxLayout,
|
||||||
QPainter, QTimer, QVBoxLayout, QLabel, QStackedWidget, QDialog, QStackedLayout
|
QWidget
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from calibre.constants import plugins
|
||||||
|
|
||||||
def draw_snake_spinner(painter, rect, angle, light, dark):
|
pi, err = plugins['progress_indicator']
|
||||||
painter.setRenderHint(QPainter.Antialiasing)
|
if err:
|
||||||
|
raise RuntimeError('Failed to import the progress_indicator plugin with error: {}'.format(err))
|
||||||
if rect.width() > rect.height():
|
|
||||||
delta = (rect.width() - rect.height()) // 2
|
|
||||||
rect = rect.adjusted(delta, 0, -delta, 0)
|
|
||||||
elif rect.height() > rect.width():
|
|
||||||
delta = (rect.height() - rect.width()) // 2
|
|
||||||
rect = rect.adjusted(0, delta, 0, -delta)
|
|
||||||
disc_width = max(3, min(rect.width() // 10, 8))
|
|
||||||
|
|
||||||
drawing_rect = QRect(rect.x() + disc_width, rect.y() + disc_width, rect.width() - 2 * disc_width, rect.height() - 2 *disc_width)
|
|
||||||
|
|
||||||
gap = 60 # degrees
|
|
||||||
gradient = QConicalGradient(drawing_rect.center(), angle - gap // 2)
|
|
||||||
gradient.setColorAt((360 - gap//2)/360.0, light)
|
|
||||||
gradient.setColorAt(0, dark)
|
|
||||||
|
|
||||||
pen = QPen(QBrush(gradient), disc_width)
|
|
||||||
pen.setCapStyle(Qt.RoundCap)
|
|
||||||
painter.setPen(pen)
|
|
||||||
painter.drawArc(drawing_rect, angle * 16, (360 - gap) * 16)
|
|
||||||
|
|
||||||
|
|
||||||
class ProgressSpinner(QWidget):
|
ProgressIndicator = pi.QProgressIndicator
|
||||||
|
draw_snake_spinner = pi.draw_snake_spinner
|
||||||
def __init__(self, parent=None, size=64, interval=10):
|
|
||||||
QWidget.__init__(self, parent)
|
|
||||||
self.setSizePolicy(QSizePolicy(
|
|
||||||
QSizePolicy.GrowFlag | QSizePolicy.ShrinkFlag, QSizePolicy.GrowFlag | QSizePolicy.ShrinkFlag))
|
|
||||||
self._size_hint = QSize(size, size)
|
|
||||||
self.timer = t = QTimer(self)
|
|
||||||
t.setInterval(interval)
|
|
||||||
self.timer.timeout.connect(self.tick)
|
|
||||||
self.loading_angle = 0
|
|
||||||
pal = self.palette()
|
|
||||||
self.dark = pal.color(pal.Text)
|
|
||||||
self.light = pal.color(pal.Window)
|
|
||||||
self.errored_out = False
|
|
||||||
|
|
||||||
def heightForWidth(self, w):
|
|
||||||
return w
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
self.loading_angle = 0
|
|
||||||
self.timer.start()
|
|
||||||
self.update()
|
|
||||||
startAnimation = start
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
self.timer.stop()
|
|
||||||
self.loading_angle = 0
|
|
||||||
self.update()
|
|
||||||
stopAnimation = stop
|
|
||||||
|
|
||||||
def isAnimated(self):
|
|
||||||
return self.timer.isActive()
|
|
||||||
|
|
||||||
def sizeHint(self):
|
|
||||||
return self._size_hint
|
|
||||||
|
|
||||||
def setSizeHint(self, val):
|
|
||||||
if isinstance(val, numbers.Integral):
|
|
||||||
val = QSize(val, val)
|
|
||||||
self._size_hint = val
|
|
||||||
self.update()
|
|
||||||
setDisplaySize = setSizeHint
|
|
||||||
|
|
||||||
def tick(self):
|
|
||||||
self.loading_angle -= 2
|
|
||||||
self.loading_angle %= 360
|
|
||||||
self.update()
|
|
||||||
|
|
||||||
def paintEvent(self, ev):
|
|
||||||
if not self.errored_out:
|
|
||||||
try:
|
|
||||||
draw_snake_spinner(QPainter(self), self.rect(), self.loading_angle, self.light, self.dark)
|
|
||||||
except Exception:
|
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
self.errored_out = True
|
|
||||||
|
|
||||||
|
|
||||||
ProgressIndicator = ProgressSpinner
|
|
||||||
|
|
||||||
|
|
||||||
class WaitPanel(QWidget):
|
class WaitPanel(QWidget):
|
||||||
@ -103,7 +26,7 @@ class WaitPanel(QWidget):
|
|||||||
QWidget.__init__(self, parent)
|
QWidget.__init__(self, parent)
|
||||||
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||||
self.l = l = QVBoxLayout(self)
|
self.l = l = QVBoxLayout(self)
|
||||||
self.spinner = ProgressIndicator(parent=self, size=size, interval=interval)
|
self.spinner = ProgressIndicator(self, size, interval)
|
||||||
self.start, self.stop = self.spinner.start, self.spinner.stop
|
self.start, self.stop = self.spinner.start, self.spinner.stop
|
||||||
l.addStretch(), l.addWidget(self.spinner, 0, Qt.AlignCenter)
|
l.addStretch(), l.addWidget(self.spinner, 0, Qt.AlignCenter)
|
||||||
self.la = QLabel(msg)
|
self.la = QLabel(msg)
|
||||||
@ -182,7 +105,7 @@ if __name__ == '__main__':
|
|||||||
app = Application([])
|
app = Application([])
|
||||||
d = QDialog()
|
d = QDialog()
|
||||||
d.resize(64, 64)
|
d.resize(64, 64)
|
||||||
w = ProgressSpinner(d)
|
w = ProgressIndicator(d)
|
||||||
l = QVBoxLayout(d)
|
l = QVBoxLayout(d)
|
||||||
l.addWidget(w)
|
l.addWidget(w)
|
||||||
w.start()
|
w.start()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user