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
from typing import Literal
from PyQt5.QtGui import QColor, QPainter, QPaintEvent
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__)
class StatusLED(QAbstractButton):
S_NONE = 0
S_BAD = 1
S_GOOD = 2
def __init__(self, colNone: QColor, colGood: QColor, colBad: QColor,
sW: int, sH: int, parent: QWidget | None = None) -> None:
def __init__(self, sW: int, sH: int, parent: QWidget | None = None) -> None:
super().__init__(parent=parent)
self._colNone = colNone
self._colGood = colGood
self._colBad = colBad
self._theCol = colNone
self._neutral = QtBlack
self._postitve = QtBlack
self._negative = QtBlack
self._color = QtBlack
self._state = nwTrinary.NEUTRAL
self.setFixedWidth(sW)
self.setFixedHeight(sH)
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."""
if state == self.S_GOOD:
self._theCol = self._colGood
elif state == self.S_BAD:
self._theCol = self._colBad
if state == nwTrinary.POSITIVE:
self._color = self._postitve
elif state == nwTrinary.NEGATIVE:
self._color = self._negative
else:
self._theCol = self._colNone
self._color = self._neutral
self._state = state
self.update()
return
@@ -71,7 +77,7 @@ class StatusLED(QAbstractButton):
painter = QPainter(self)
painter.setRenderHint(QtPaintAnitAlias, True)
painter.setPen(self.palette().dark().color())
painter.setBrush(self._theCol)
painter.setBrush(self._color)
painter.setOpacity(1.0)
painter.drawEllipse(1, 1, self.width() - 2, self.height() - 2)
return
+16 -13
View File
@@ -27,7 +27,6 @@ import logging
from datetime import datetime
from time import time
from typing import Literal
from PyQt5.QtCore import QLocale, pyqtSlot
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.common import formatTime
from novelwriter.constants import nwConst
from novelwriter.enum import nwTrinary
from novelwriter.extensions.statusled import StatusLED
logger = logging.getLogger(__name__)
@@ -51,10 +51,6 @@ class GuiMainStatus(QStatusBar):
self._userIdle = False
self._debugInfo = False
colNone = SHARED.theme.statNone
colSaved = SHARED.theme.statSaved
colUnsaved = SHARED.theme.statUnsaved
iPx = SHARED.theme.baseIconHeight
# Permanent Widgets
@@ -71,7 +67,7 @@ class GuiMainStatus(QStatusBar):
self.addPermanentWidget(self.langText)
# 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.docIcon.setContentsMargins(0, 0, 0, 0)
self.docText.setContentsMargins(0, 0, xM, 0)
@@ -79,7 +75,7 @@ class GuiMainStatus(QStatusBar):
self.addPermanentWidget(self.docText)
# 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.projIcon.setContentsMargins(0, 0, 0, 0)
self.projText.setContentsMargins(0, 0, xM, 0)
@@ -120,8 +116,8 @@ class GuiMainStatus(QStatusBar):
self.setRefTime(-1.0)
self.setLanguage(*SHARED.spelling.describeDict())
self.setProjectStats(0, 0)
self.setProjectStatus(StatusLED.S_NONE)
self.setDocumentStatus(StatusLED.S_NONE)
self.setProjectStatus(nwTrinary.NEUTRAL)
self.setDocumentStatus(nwTrinary.NEUTRAL)
self.updateTime()
return
@@ -133,6 +129,13 @@ class GuiMainStatus(QStatusBar):
self.timePixmap = SHARED.theme.getPixmap("status_time", (iPx, iPx))
self.idlePixmap = SHARED.theme.getPixmap("status_idle", (iPx, iPx))
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
##
@@ -144,12 +147,12 @@ class GuiMainStatus(QStatusBar):
self._refTime = refTime
return
def setProjectStatus(self, state: Literal[0, 1, 2]) -> None:
def setProjectStatus(self, state: nwTrinary) -> None:
"""Set the project status colour icon."""
self.projIcon.setState(state)
return
def setDocumentStatus(self, state: Literal[0, 1, 2]) -> None:
def setDocumentStatus(self, state: nwTrinary) -> None:
"""Set the document status colour icon."""
self.docIcon.setState(state)
return
@@ -212,13 +215,13 @@ class GuiMainStatus(QStatusBar):
@pyqtSlot(bool)
def updateProjectStatus(self, status: bool) -> None:
"""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
@pyqtSlot(bool)
def updateDocumentStatus(self, status: bool) -> None:
"""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
##
+13 -13
View File
@@ -25,7 +25,7 @@ import time
import pytest
from novelwriter import CONFIG, SHARED
from novelwriter.extensions.statusled import StatusLED
from novelwriter.enum import nwTrinary
from tests.tools import C, buildTestProject
@@ -46,20 +46,20 @@ def testGuiStatusBar_Main(qtbot, nwGUI, projPath, mockRnd):
assert nwGUI.mainStatus._refTime == refTime
# Project Status
nwGUI.mainStatus.setProjectStatus(StatusLED.S_NONE)
assert nwGUI.mainStatus.projIcon._theCol == nwGUI.mainStatus.projIcon._colNone
nwGUI.mainStatus.setProjectStatus(StatusLED.S_BAD)
assert nwGUI.mainStatus.projIcon._theCol == nwGUI.mainStatus.projIcon._colBad
nwGUI.mainStatus.setProjectStatus(StatusLED.S_GOOD)
assert nwGUI.mainStatus.projIcon._theCol == nwGUI.mainStatus.projIcon._colGood
nwGUI.mainStatus.setProjectStatus(nwTrinary.NEUTRAL)
assert nwGUI.mainStatus.projIcon.state == nwTrinary.NEUTRAL
nwGUI.mainStatus.setProjectStatus(nwTrinary.NEGATIVE)
assert nwGUI.mainStatus.projIcon.state == nwTrinary.NEGATIVE
nwGUI.mainStatus.setProjectStatus(nwTrinary.POSITIVE)
assert nwGUI.mainStatus.projIcon.state == nwTrinary.POSITIVE
# Document Status
nwGUI.mainStatus.setDocumentStatus(StatusLED.S_NONE)
assert nwGUI.mainStatus.docIcon._theCol == nwGUI.mainStatus.docIcon._colNone
nwGUI.mainStatus.setDocumentStatus(StatusLED.S_BAD)
assert nwGUI.mainStatus.docIcon._theCol == nwGUI.mainStatus.docIcon._colBad
nwGUI.mainStatus.setDocumentStatus(StatusLED.S_GOOD)
assert nwGUI.mainStatus.docIcon._theCol == nwGUI.mainStatus.docIcon._colGood
nwGUI.mainStatus.setDocumentStatus(nwTrinary.NEUTRAL)
assert nwGUI.mainStatus.docIcon.state == nwTrinary.NEUTRAL
nwGUI.mainStatus.setDocumentStatus(nwTrinary.NEGATIVE)
assert nwGUI.mainStatus.docIcon.state == nwTrinary.NEGATIVE
nwGUI.mainStatus.setDocumentStatus(nwTrinary.POSITIVE)
assert nwGUI.mainStatus.docIcon.state == nwTrinary.POSITIVE
# Idle Status
CONFIG.stopWhenIdle = False