Simplify the custom switch widget

This commit is contained in:
Veronica Berglyd Olsen
2024-01-08 19:14:36 +01:00
parent 978a8145a8
commit 1ed3cea414
+28 -60
View File
@@ -24,31 +24,22 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
from __future__ import annotations from __future__ import annotations
from PyQt5.QtGui import QMouseEvent, QPainter, QPaintEvent, QResizeEvent from PyQt5.QtGui import QMouseEvent, QPainter, QPaintEvent, QResizeEvent
from PyQt5.QtCore import QEvent, QPropertyAnimation, QRectF, Qt, pyqtProperty from PyQt5.QtCore import QEvent, QPropertyAnimation, Qt, pyqtProperty
from PyQt5.QtWidgets import QAbstractButton, QSizePolicy, QWidget from PyQt5.QtWidgets import QAbstractButton, QSizePolicy, QWidget
from novelwriter import CONFIG from novelwriter import CONFIG
from novelwriter.constants import nwUnicode
class NSwitch(QAbstractButton): class NSwitch(QAbstractButton):
def __init__(self, parent: QWidget | None = None, __slots__ = ("_xW", "_xH", "_xR", "_rB", "_rH", "_rR", "_offset")
width: int | None = None, height: int | None = None) -> None:
def __init__(self, parent: QWidget | None = None, width: int = 0, height: int = 0) -> None:
super().__init__(parent=parent) super().__init__(parent=parent)
if width is None: self._xW = width or CONFIG.pxInt(40)
self._xW = CONFIG.pxInt(40) self._xH = height or CONFIG.pxInt(20)
else:
self._xW = width
if height is None:
self._xH = CONFIG.pxInt(20)
else:
self._xH = height
self._xR = int(self._xH*0.5) self._xR = int(self._xH*0.5)
self._xT = int(self._xH*0.6)
self._rB = int(CONFIG.guiScale*2) self._rB = int(CONFIG.guiScale*2)
self._rH = self._xH - 2*self._rB self._rH = self._xH - 2*self._rB
self._rR = self._xR - self._rB self._rR = self._xR - self._rB
@@ -82,10 +73,7 @@ class NSwitch(QAbstractButton):
def setChecked(self, checked: bool) -> None: def setChecked(self, checked: bool) -> None:
"""Overload setChecked to also alter the offset.""" """Overload setChecked to also alter the offset."""
super().setChecked(checked) super().setChecked(checked)
if checked: self._offset = (self._xW - self._xR) if checked else self._xR
self._offset = self._xW - self._xR
else:
self._offset = self._xR
return return
## ##
@@ -95,53 +83,36 @@ class NSwitch(QAbstractButton):
def resizeEvent(self, event: QResizeEvent) -> None: def resizeEvent(self, event: QResizeEvent) -> None:
"""Overload resize to ensure correct offset.""" """Overload resize to ensure correct offset."""
super().resizeEvent(event) super().resizeEvent(event)
if self.isChecked(): self._offset = (self._xW - self._xR) if self.isChecked() else self._xR
self._offset = self._xW - self._xR
else:
self._offset = self._xR
return return
def paintEvent(self, event: QPaintEvent) -> None: def paintEvent(self, event: QPaintEvent) -> None:
"""Drawing the switch itself.""" """Drawing the switch itself."""
qPaint = QPainter(self) painter = QPainter(self)
qPaint.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHint(QPainter.Antialiasing, True)
qPaint.setPen(Qt.NoPen) painter.setPen(Qt.NoPen)
qPalette = self.palette() palette = self.palette()
if self.isChecked(): if self.isChecked():
trackBrush = qPalette.highlight() trackBrush = palette.highlight()
thumbBrush = qPalette.highlightedText() thumbBrush = palette.highlightedText()
textColor = qPalette.highlight().color()
thumbText = nwUnicode.U_CHECK
else: else:
trackBrush = qPalette.dark() trackBrush = palette.dark()
thumbBrush = qPalette.light() thumbBrush = palette.light()
textColor = qPalette.dark().color()
thumbText = nwUnicode.U_CROSS
if self.isEnabled(): if self.isEnabled():
trackOpacity = 1.0 trackOpacity = 1.0
else: else:
trackOpacity = 0.6 trackOpacity = 0.6
trackBrush = qPalette.shadow() trackBrush = palette.shadow()
thumbBrush = qPalette.mid() thumbBrush = palette.mid()
textColor = qPalette.shadow().color()
qPaint.setBrush(trackBrush) painter.setBrush(trackBrush)
qPaint.setOpacity(trackOpacity) painter.setOpacity(trackOpacity)
qPaint.drawRoundedRect(0, 0, self._xW, self._xH, self._xR, self._xR) painter.drawRoundedRect(0, 0, self._xW, self._xH, self._xR, self._xR)
qPaint.setBrush(thumbBrush) painter.setBrush(thumbBrush)
qPaint.drawEllipse(self._offset - self._rR, self._rB, self._rH, self._rH) painter.drawEllipse(self._offset - self._rR, self._rB, self._rH, self._rH)
font = qPaint.font()
font.setPixelSize(self._xT)
qPaint.setPen(textColor)
qPaint.setFont(font)
qPaint.drawText(
QRectF(self._offset - self._rR, self._rB, self._rH, self._rH),
Qt.AlignCenter, thumbText
)
return return
@@ -149,14 +120,11 @@ class NSwitch(QAbstractButton):
"""Animate the switch on mouse release.""" """Animate the switch on mouse release."""
super().mouseReleaseEvent(event) super().mouseReleaseEvent(event)
if event.button() == Qt.LeftButton: if event.button() == Qt.LeftButton:
doAnim = QPropertyAnimation(self, b"offset", self) anim = QPropertyAnimation(self, b"offset", self)
doAnim.setDuration(120) anim.setDuration(120)
doAnim.setStartValue(self._offset) anim.setStartValue(self._offset)
if self.isChecked(): anim.setEndValue((self._xW - self._xR) if self.isChecked() else self._xR)
doAnim.setEndValue(self._xW - self._xR) anim.start()
else:
doAnim.setEndValue(self._xR)
doAnim.start()
return return
def enterEvent(self, event: QEvent) -> None: def enterEvent(self, event: QEvent) -> None: