Refresh StatusLEDs when theme changes (#1906)

This commit is contained in:
Veronica Berglyd Olsen
2024-05-30 20:54:01 +02:00
committed by GitHub
3 changed files with 58 additions and 49 deletions
+29 -23
View File
@@ -25,44 +25,50 @@ from __future__ import annotations
import logging import logging
from typing import Literal
from PyQt5.QtGui import QColor, QPainter, QPaintEvent from PyQt5.QtGui import QColor, QPainter, QPaintEvent
from PyQt5.QtWidgets import QAbstractButton, QWidget from PyQt5.QtWidgets import QAbstractButton, QWidget
from novelwriter.types import QtPaintAnitAlias from novelwriter.enum import nwTrinary
from novelwriter.types import QtBlack, QtPaintAnitAlias
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class StatusLED(QAbstractButton): class StatusLED(QAbstractButton):
S_NONE = 0 def __init__(self, sW: int, sH: int, parent: QWidget | None = None) -> None:
S_BAD = 1
S_GOOD = 2
def __init__(self, colNone: QColor, colGood: QColor, colBad: QColor,
sW: int, sH: int, parent: QWidget | None = None) -> None:
super().__init__(parent=parent) super().__init__(parent=parent)
self._neutral = QtBlack
self._colNone = colNone self._postitve = QtBlack
self._colGood = colGood self._negative = QtBlack
self._colBad = colBad self._color = QtBlack
self._theCol = colNone self._state = nwTrinary.NEUTRAL
self.setFixedWidth(sW) self.setFixedWidth(sW)
self.setFixedHeight(sH) self.setFixedHeight(sH)
return return
def setState(self, state: Literal[0, 1, 2]) -> None: @property
def state(self) -> nwTrinary:
"""The current state of the LED."""
return self._state
def setColors(self, neutral: QColor, positive: QColor, negative: QColor) -> None:
"""Set the three colours for the status values."""
self._neutral = neutral
self._postitve = positive
self._negative = negative
self.setState(self._state)
return
def setState(self, state: nwTrinary) -> None:
"""Set the colour state.""" """Set the colour state."""
if state == self.S_GOOD: if state == nwTrinary.POSITIVE:
self._theCol = self._colGood self._color = self._postitve
elif state == self.S_BAD: elif state == nwTrinary.NEGATIVE:
self._theCol = self._colBad self._color = self._negative
else: else:
self._theCol = self._colNone self._color = self._neutral
self._state = state
self.update() self.update()
return return
@@ -71,7 +77,7 @@ class StatusLED(QAbstractButton):
painter = QPainter(self) painter = QPainter(self)
painter.setRenderHint(QtPaintAnitAlias, True) painter.setRenderHint(QtPaintAnitAlias, True)
painter.setPen(self.palette().dark().color()) painter.setPen(self.palette().dark().color())
painter.setBrush(self._theCol) painter.setBrush(self._color)
painter.setOpacity(1.0) painter.setOpacity(1.0)
painter.drawEllipse(1, 1, self.width() - 2, self.height() - 2) painter.drawEllipse(1, 1, self.width() - 2, self.height() - 2)
return return
+16 -13
View File
@@ -27,7 +27,6 @@ import logging
from datetime import datetime from datetime import datetime
from time import time from time import time
from typing import Literal
from PyQt5.QtCore import QLocale, pyqtSlot from PyQt5.QtCore import QLocale, pyqtSlot
from PyQt5.QtWidgets import QApplication, QLabel, QStatusBar, QWidget from PyQt5.QtWidgets import QApplication, QLabel, QStatusBar, QWidget
@@ -35,6 +34,7 @@ from PyQt5.QtWidgets import QApplication, QLabel, QStatusBar, QWidget
from novelwriter import CONFIG, SHARED from novelwriter import CONFIG, SHARED
from novelwriter.common import formatTime from novelwriter.common import formatTime
from novelwriter.constants import nwConst from novelwriter.constants import nwConst
from novelwriter.enum import nwTrinary
from novelwriter.extensions.statusled import StatusLED from novelwriter.extensions.statusled import StatusLED
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -51,10 +51,6 @@ class GuiMainStatus(QStatusBar):
self._userIdle = False self._userIdle = False
self._debugInfo = False self._debugInfo = False
colNone = SHARED.theme.statNone
colSaved = SHARED.theme.statSaved
colUnsaved = SHARED.theme.statUnsaved
iPx = SHARED.theme.baseIconHeight iPx = SHARED.theme.baseIconHeight
# Permanent Widgets # Permanent Widgets
@@ -71,7 +67,7 @@ class GuiMainStatus(QStatusBar):
self.addPermanentWidget(self.langText) self.addPermanentWidget(self.langText)
# The Editor Status # The Editor Status
self.docIcon = StatusLED(colNone, colSaved, colUnsaved, iPx, iPx, self) self.docIcon = StatusLED(iPx, iPx, self)
self.docText = QLabel(self.tr("Editor"), self) self.docText = QLabel(self.tr("Editor"), self)
self.docIcon.setContentsMargins(0, 0, 0, 0) self.docIcon.setContentsMargins(0, 0, 0, 0)
self.docText.setContentsMargins(0, 0, xM, 0) self.docText.setContentsMargins(0, 0, xM, 0)
@@ -79,7 +75,7 @@ class GuiMainStatus(QStatusBar):
self.addPermanentWidget(self.docText) self.addPermanentWidget(self.docText)
# The Project Status # The Project Status
self.projIcon = StatusLED(colNone, colSaved, colUnsaved, iPx, iPx, self) self.projIcon = StatusLED(iPx, iPx, self)
self.projText = QLabel(self.tr("Project"), self) self.projText = QLabel(self.tr("Project"), self)
self.projIcon.setContentsMargins(0, 0, 0, 0) self.projIcon.setContentsMargins(0, 0, 0, 0)
self.projText.setContentsMargins(0, 0, xM, 0) self.projText.setContentsMargins(0, 0, xM, 0)
@@ -120,8 +116,8 @@ class GuiMainStatus(QStatusBar):
self.setRefTime(-1.0) self.setRefTime(-1.0)
self.setLanguage(*SHARED.spelling.describeDict()) self.setLanguage(*SHARED.spelling.describeDict())
self.setProjectStats(0, 0) self.setProjectStats(0, 0)
self.setProjectStatus(StatusLED.S_NONE) self.setProjectStatus(nwTrinary.NEUTRAL)
self.setDocumentStatus(StatusLED.S_NONE) self.setDocumentStatus(nwTrinary.NEUTRAL)
self.updateTime() self.updateTime()
return return
@@ -133,6 +129,13 @@ class GuiMainStatus(QStatusBar):
self.timePixmap = SHARED.theme.getPixmap("status_time", (iPx, iPx)) self.timePixmap = SHARED.theme.getPixmap("status_time", (iPx, iPx))
self.idlePixmap = SHARED.theme.getPixmap("status_idle", (iPx, iPx)) self.idlePixmap = SHARED.theme.getPixmap("status_idle", (iPx, iPx))
self.timeIcon.setPixmap(self.timePixmap) self.timeIcon.setPixmap(self.timePixmap)
colNone = SHARED.theme.statNone
colSaved = SHARED.theme.statSaved
colUnsaved = SHARED.theme.statUnsaved
self.docIcon.setColors(colNone, colSaved, colUnsaved)
self.projIcon.setColors(colNone, colSaved, colUnsaved)
return return
## ##
@@ -144,12 +147,12 @@ class GuiMainStatus(QStatusBar):
self._refTime = refTime self._refTime = refTime
return return
def setProjectStatus(self, state: Literal[0, 1, 2]) -> None: def setProjectStatus(self, state: nwTrinary) -> None:
"""Set the project status colour icon.""" """Set the project status colour icon."""
self.projIcon.setState(state) self.projIcon.setState(state)
return return
def setDocumentStatus(self, state: Literal[0, 1, 2]) -> None: def setDocumentStatus(self, state: nwTrinary) -> None:
"""Set the document status colour icon.""" """Set the document status colour icon."""
self.docIcon.setState(state) self.docIcon.setState(state)
return return
@@ -212,13 +215,13 @@ class GuiMainStatus(QStatusBar):
@pyqtSlot(bool) @pyqtSlot(bool)
def updateProjectStatus(self, status: bool) -> None: def updateProjectStatus(self, status: bool) -> None:
"""Update the project status.""" """Update the project status."""
self.setProjectStatus(StatusLED.S_BAD if status else StatusLED.S_GOOD) self.setProjectStatus(nwTrinary.NEGATIVE if status else nwTrinary.POSITIVE)
return return
@pyqtSlot(bool) @pyqtSlot(bool)
def updateDocumentStatus(self, status: bool) -> None: def updateDocumentStatus(self, status: bool) -> None:
"""Update the document status.""" """Update the document status."""
self.setDocumentStatus(StatusLED.S_BAD if status else StatusLED.S_GOOD) self.setDocumentStatus(nwTrinary.NEGATIVE if status else nwTrinary.POSITIVE)
return return
## ##
+13 -13
View File
@@ -25,7 +25,7 @@ import time
import pytest import pytest
from novelwriter import CONFIG, SHARED from novelwriter import CONFIG, SHARED
from novelwriter.extensions.statusled import StatusLED from novelwriter.enum import nwTrinary
from tests.tools import C, buildTestProject from tests.tools import C, buildTestProject
@@ -46,20 +46,20 @@ def testGuiStatusBar_Main(qtbot, nwGUI, projPath, mockRnd):
assert nwGUI.mainStatus._refTime == refTime assert nwGUI.mainStatus._refTime == refTime
# Project Status # Project Status
nwGUI.mainStatus.setProjectStatus(StatusLED.S_NONE) nwGUI.mainStatus.setProjectStatus(nwTrinary.NEUTRAL)
assert nwGUI.mainStatus.projIcon._theCol == nwGUI.mainStatus.projIcon._colNone assert nwGUI.mainStatus.projIcon.state == nwTrinary.NEUTRAL
nwGUI.mainStatus.setProjectStatus(StatusLED.S_BAD) nwGUI.mainStatus.setProjectStatus(nwTrinary.NEGATIVE)
assert nwGUI.mainStatus.projIcon._theCol == nwGUI.mainStatus.projIcon._colBad assert nwGUI.mainStatus.projIcon.state == nwTrinary.NEGATIVE
nwGUI.mainStatus.setProjectStatus(StatusLED.S_GOOD) nwGUI.mainStatus.setProjectStatus(nwTrinary.POSITIVE)
assert nwGUI.mainStatus.projIcon._theCol == nwGUI.mainStatus.projIcon._colGood assert nwGUI.mainStatus.projIcon.state == nwTrinary.POSITIVE
# Document Status # Document Status
nwGUI.mainStatus.setDocumentStatus(StatusLED.S_NONE) nwGUI.mainStatus.setDocumentStatus(nwTrinary.NEUTRAL)
assert nwGUI.mainStatus.docIcon._theCol == nwGUI.mainStatus.docIcon._colNone assert nwGUI.mainStatus.docIcon.state == nwTrinary.NEUTRAL
nwGUI.mainStatus.setDocumentStatus(StatusLED.S_BAD) nwGUI.mainStatus.setDocumentStatus(nwTrinary.NEGATIVE)
assert nwGUI.mainStatus.docIcon._theCol == nwGUI.mainStatus.docIcon._colBad assert nwGUI.mainStatus.docIcon.state == nwTrinary.NEGATIVE
nwGUI.mainStatus.setDocumentStatus(StatusLED.S_GOOD) nwGUI.mainStatus.setDocumentStatus(nwTrinary.POSITIVE)
assert nwGUI.mainStatus.docIcon._theCol == nwGUI.mainStatus.docIcon._colGood assert nwGUI.mainStatus.docIcon.state == nwTrinary.POSITIVE
# Idle Status # Idle Status
CONFIG.stopWhenIdle = False CONFIG.stopWhenIdle = False