diff --git a/novelwriter/extensions/modified.py b/novelwriter/extensions/modified.py index ee1be5e7..abc12da1 100644 --- a/novelwriter/extensions/modified.py +++ b/novelwriter/extensions/modified.py @@ -214,10 +214,10 @@ class NPushButton(QPushButton): self._color = color self.setText(text) self.setIconSize(iconSize) - self.refreshIcon() + self.updateIcon() - def refreshIcon(self) -> None: - """Reload the theme icon.""" + def updateIcon(self) -> None: + """Update the theme icon.""" if self._icon: self.setIcon(SHARED.theme.getIcon(self._icon, self._color)) @@ -262,8 +262,8 @@ class NIconToggleButton(QToolButton): def setThemeIcon(self, iconKey: str) -> None: """Set an icon from the current theme.""" - iconSize = self.iconSize() - self.setIcon(SHARED.theme.getToggleIcon(iconKey, (iconSize.width(), iconSize.height()))) + size = self.iconSize() + self.setIcon(SHARED.theme.getToggleIcon(iconKey, (size.width(), size.height()))) class NClickableLabel(QLabel): diff --git a/novelwriter/extensions/switch.py b/novelwriter/extensions/switch.py index cc0d43a9..983d6294 100644 --- a/novelwriter/extensions/switch.py +++ b/novelwriter/extensions/switch.py @@ -34,7 +34,7 @@ from novelwriter.types import QtNoPen, QtPaintAntiAlias, QtSizeFixed class NSwitch(QAbstractButton): """Custom: Toggle Switch.""" - __slots__ = ("_cOff", "_cOn", "_offset", "_rH", "_rR", "_xH", "_xR", "_xW") + __slots__ = ("_offset", "_rH", "_rR", "_xH", "_xR", "_xW") def __init__(self, parent: QWidget, height: int = 0) -> None: super().__init__(parent=parent) @@ -45,13 +45,11 @@ class NSwitch(QAbstractButton): self._rH = self._xH - 4 self._rR = self._xR - 2 - self._cOn = SHARED.theme.accentCol - self._cOff = self.palette().alternateBase() - self.setCheckable(True) self.setSizePolicy(QtSizeFixed, QtSizeFixed) self.setFixedWidth(self._xW) self.setFixedHeight(self._xH) + self.setUpdatesEnabled(True) self._offset = self._xR self.clicked.connect(self._onClick) @@ -96,7 +94,7 @@ class NSwitch(QAbstractButton): painter.setOpacity(1.0 if self.isEnabled() else 0.5) painter.setPen(palette.highlight().color() if self.hasFocus() else palette.mid().color()) - painter.setBrush(self._cOn if self.isChecked() else self._cOff) + painter.setBrush(SHARED.theme.accentCol if self.isChecked() else palette.alternateBase()) painter.drawRoundedRect(0, 0, self._xW, self._xH, self._xR, self._xR) painter.setPen(QtNoPen) @@ -110,6 +108,10 @@ class NSwitch(QAbstractButton): self.setCursor(Qt.CursorShape.PointingHandCursor) super().enterEvent(event) + ## + # Internal Functions + ## + @pyqtSlot(bool) def _onClick(self, checked: bool) -> None: """Animate the toggle action.""" diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index 1496743f..72e7577f 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -2590,7 +2590,7 @@ class GuiDocEditSearch(QFrame): # Buttons # ======= - self.showReplace = NIconToggleButton(self, iSz, "unfold") + self.showReplace = NIconToggleButton(self, iSz) self.showReplace.toggled.connect(self._doToggleReplace) self.searchButton = NIconToolButton(self, iSz) @@ -2732,6 +2732,7 @@ class GuiDocEditSearch(QFrame): self.cancelSearch.setIcon(SHARED.theme.getIcon("search_cancel")) self.searchButton.setThemeIcon("search", "green") self.replaceButton.setThemeIcon("search_replace", "green") + self.showReplace.setThemeIcon("unfold") # Set stylesheets self.searchOpt.setStyleSheet("QToolBar {padding: 0;}") diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py index acf6114b..20e86ad8 100644 --- a/novelwriter/guimain.py +++ b/novelwriter/guimain.py @@ -910,6 +910,9 @@ class GuiMain(QMainWindow): self.mainStatus.updateTheme() SHARED.project.tree.refreshAllItems() + if dialog := SHARED.findTopLevelWidget(GuiManuscript): + dialog.updateTheme() + if syntax: self.docEditor.updateSyntaxColors() diff --git a/novelwriter/tools/manuscript.py b/novelwriter/tools/manuscript.py index 79a93787..9ad1557e 100644 --- a/novelwriter/tools/manuscript.py +++ b/novelwriter/tools/manuscript.py @@ -101,30 +101,20 @@ class GuiManuscript(NToolDialog): # Build Controls # ============== - qPalette = self.palette() - qPalette.setBrush(QPalette.ColorRole.Window, qPalette.base()) - self.setPalette(qPalette) - - buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON) - - self.tbAdd = NIconToolButton(self, iSz, "add", "green") + self.tbAdd = NIconToolButton(self, iSz) self.tbAdd.setToolTip(self.tr("Add New Build")) - self.tbAdd.setStyleSheet(buttonStyle) self.tbAdd.clicked.connect(self._createNewBuild) - self.tbDel = NIconToolButton(self, iSz, "remove", "red") + self.tbDel = NIconToolButton(self, iSz) self.tbDel.setToolTip(self.tr("Delete Selected Build")) - self.tbDel.setStyleSheet(buttonStyle) self.tbDel.clicked.connect(self._deleteSelectedBuild) - self.tbCopy = NIconToolButton(self, iSz, "copy", "blue") + self.tbCopy = NIconToolButton(self, iSz) self.tbCopy.setToolTip(self.tr("Duplicate Selected Build")) - self.tbCopy.setStyleSheet(buttonStyle) self.tbCopy.clicked.connect(self._copySelectedBuild) - self.tbEdit = NIconToolButton(self, iSz, "edit", "green") + self.tbEdit = NIconToolButton(self, iSz) self.tbEdit.setToolTip(self.tr("Edit Selected Build")) - self.tbEdit.setStyleSheet(buttonStyle) self.tbEdit.clicked.connect(self._editSelectedBuild) self.lblBuilds = QLabel("{0}".format(self.tr("Builds")), self) @@ -159,7 +149,6 @@ class GuiManuscript(NToolDialog): self.detailsTabs = QTabWidget(self) self.detailsTabs.addTab(self.buildDetails, self.tr("Details")) self.detailsTabs.addTab(self.buildOutline, self.tr("Outline")) - self.detailsTabs.setStyleSheet(SHARED.theme.getStyleSheet(STYLES_FLAT_TABS)) self.buildSplit = QSplitter(Qt.Orientation.Vertical, self) self.buildSplit.addWidget(self.buildList) @@ -247,6 +236,8 @@ class GuiManuscript(NToolDialog): self.setLayout(self.outerBox) self.setSizeGripEnabled(True) + self.updateTheme(init=True) + # Signals self.buildOutline.outlineEntryClicked.connect(self.docPreview.navigateTo) @@ -270,6 +261,31 @@ class GuiManuscript(NToolDialog): self.buildList.setCurrentItem(self._buildMap[selected]) QTimer.singleShot(200, self._generatePreview) + def updateTheme(self, *, init: bool = False) -> None: + """Update theme elements.""" + self.tbAdd.setThemeIcon("add", "green") + self.tbDel.setThemeIcon("remove", "red") + self.tbCopy.setThemeIcon("copy", "blue") + self.tbEdit.setThemeIcon("edit", "green") + + if not init: + self.btnPreview.updateIcon() + self.btnPrint.updateIcon() + self.btnBuild.updateIcon() + self.btnClose.updateIcon() + + buttonStyle = SHARED.theme.getStyleSheet(STYLES_MIN_TOOLBUTTON) + self.tbAdd.setStyleSheet(buttonStyle) + self.tbDel.setStyleSheet(buttonStyle) + self.tbCopy.setStyleSheet(buttonStyle) + self.tbEdit.setStyleSheet(buttonStyle) + + self.detailsTabs.setStyleSheet(SHARED.theme.getStyleSheet(STYLES_FLAT_TABS)) + + self.buildDetails.updateTheme() + self.buildOutline.updateTheme() + self.docPreview.updateTheme() + ## # Events ## @@ -490,6 +506,7 @@ class _DetailsWidget(QWidget): super().__init__(parent=parent) self._initExpanded = True + self._build = None # Tree Widget self.listView = QTreeWidget(self) @@ -612,9 +629,16 @@ class _DetailsWidget(QWidget): sub.setIcon(1, on if build.getBool(key) else off) item.addChild(sub) + self._build = build + # Restore expanded state self.setExpandedState(expanded) + def updateTheme(self) -> None: + """Update theme elements.""" + if self._build: + self.updateInfo(self._build) + class _OutlineWidget(QWidget): @@ -639,9 +663,9 @@ class _OutlineWidget(QWidget): self.outerBox.setContentsMargins(0, 0, 0, 0) self.setLayout(self.outerBox) - def updateOutline(self, data: dict[str, str]) -> None: + def updateOutline(self, data: dict[str, str], *, force: bool = False) -> None: """Update the outline.""" - if isinstance(data, dict) and data != self._outline: + if isinstance(data, dict) and (data != self._outline or force): self.listView.clear() tFont = self.font() @@ -679,6 +703,10 @@ class _OutlineWidget(QWidget): self.listView.setIndentation(SHARED.theme.baseIconHeight if indent else 4) self._outline = data + def updateTheme(self) -> None: + """Update theme elements.""" + self.updateOutline(self._outline, force=True) + ## # Private Slots ## @@ -721,17 +749,12 @@ class _PreviewWidget(QTextBrowser): self.anchorClicked.connect(self._linkClicked) # Document Age - aPalette = self.palette() - aPalette.setColor(QPalette.ColorRole.Window, aPalette.toolTipBase().color()) - aPalette.setColor(QPalette.ColorRole.WindowText, aPalette.toolTipText().color()) - aFont = self.font() aFont.setPointSizeF(0.9*SHARED.theme.fontPointSize) self.ageLabel = QLabel("", self) self.ageLabel.setIndent(0) self.ageLabel.setFont(aFont) - self.ageLabel.setPalette(aPalette) self.ageLabel.setAutoFillBackground(True) self.ageLabel.setAlignment(QtAlignCenter) self.ageLabel.setFixedHeight(int(2.1*SHARED.theme.fontPixelSize)) @@ -750,6 +773,7 @@ class _PreviewWidget(QTextBrowser): self._updateDocMargins() self._updateBuildAge() + self.updateTheme() self.setTextFont(CONFIG.textFont) # Age Timer @@ -815,6 +839,13 @@ class _PreviewWidget(QTextBrowser): QApplication.processEvents() QTimer.singleShot(300, self._postUpdate) + def updateTheme(self) -> None: + """Update theme elements.""" + palette = QApplication.palette() + palette.setColor(QPalette.ColorRole.Window, palette.toolTipBase().color()) + palette.setColor(QPalette.ColorRole.WindowText, palette.toolTipText().color()) + self.ageLabel.setPalette(palette) + ## # Events ## @@ -907,7 +938,7 @@ class _StatsWidget(QWidget): self.minWidget = QWidget(self) self.maxWidget = QWidget(self) - self.toggleButton = NIconToggleButton(self, SHARED.theme.baseIconSize, "unfold") + self.toggleButton = NIconToggleButton(self, SHARED.theme.baseIconSize) self.toggleButton.toggled.connect(self._toggleView) self._buildBottomPanel() @@ -922,6 +953,7 @@ class _StatsWidget(QWidget): self.outerBox.setContentsMargins(0, 0, 0, 0) self.setLayout(self.outerBox) + self.updateTheme() self._toggleView(False) @@ -946,6 +978,10 @@ class _StatsWidget(QWidget): self.maxHeadWordChars.setText(f"{data.get(nwStats.WCHARS_TITLE, 0):n}") self.maxTextWordChars.setText(f"{data.get(nwStats.WCHARS_TEXT, 0):n}") + def updateTheme(self) -> None: + """Update theme elements.""" + self.toggleButton.setThemeIcon("unfold") + ## # Private Slots ##