Add theme settings for active icons, a base colour, and accent palette colour (#2382)
This commit is contained in:
@@ -445,6 +445,7 @@ class nwLabels:
|
|||||||
THEME_COLORS: Final[dict[str, str]] = {
|
THEME_COLORS: Final[dict[str, str]] = {
|
||||||
"theme": QT_TRANSLATE_NOOP("Constant", "Theme Colours"),
|
"theme": QT_TRANSLATE_NOOP("Constant", "Theme Colours"),
|
||||||
"default": QT_TRANSLATE_NOOP("Constant", "Foreground Colour"),
|
"default": QT_TRANSLATE_NOOP("Constant", "Foreground Colour"),
|
||||||
|
"base": QT_TRANSLATE_NOOP("Constant", "Background Colour"),
|
||||||
"faded": QT_TRANSLATE_NOOP("Constant", "Faded Colour"),
|
"faded": QT_TRANSLATE_NOOP("Constant", "Faded Colour"),
|
||||||
"red": QT_TRANSLATE_NOOP("Constant", "Red"),
|
"red": QT_TRANSLATE_NOOP("Constant", "Red"),
|
||||||
"orange": QT_TRANSLATE_NOOP("Constant", "Orange"),
|
"orange": QT_TRANSLATE_NOOP("Constant", "Orange"),
|
||||||
|
|||||||
@@ -363,13 +363,13 @@ class NWItem:
|
|||||||
"""
|
"""
|
||||||
if self.isFileType():
|
if self.isFileType():
|
||||||
key = "checked" if self._active else "unchecked"
|
key = "checked" if self._active else "unchecked"
|
||||||
color = "green" if self._active else "red"
|
color = "active" if self._active else "inactive"
|
||||||
text = trConst(nwLabels.ACTIVE_NAME[key])
|
text = trConst(nwLabels.ACTIVE_NAME[key])
|
||||||
icon = SHARED.theme.getIcon(key, color)
|
|
||||||
else:
|
else:
|
||||||
|
key = "noncheckable"
|
||||||
|
color = "disabled"
|
||||||
text = ""
|
text = ""
|
||||||
icon = SHARED.theme.getIcon("noncheckable", "faded")
|
return text, SHARED.theme.getIcon(key, color)
|
||||||
return text, icon
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Checker Methods
|
# Checker Methods
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ from novelwriter.types import QtNoPen, QtPaintAntiAlias, QtSizeFixed
|
|||||||
|
|
||||||
class NSwitch(QAbstractButton):
|
class NSwitch(QAbstractButton):
|
||||||
|
|
||||||
__slots__ = ("_offset", "_rH", "_rR", "_xH", "_xR", "_xW")
|
__slots__ = ("_cOff", "_cOn", "_offset", "_rH", "_rR", "_xH", "_xR", "_xW")
|
||||||
|
|
||||||
def __init__(self, parent: QWidget, height: int = 0) -> None:
|
def __init__(self, parent: QWidget, height: int = 0) -> None:
|
||||||
super().__init__(parent=parent)
|
super().__init__(parent=parent)
|
||||||
@@ -44,6 +44,9 @@ class NSwitch(QAbstractButton):
|
|||||||
self._rH = self._xH - 4
|
self._rH = self._xH - 4
|
||||||
self._rR = self._xR - 2
|
self._rR = self._xR - 2
|
||||||
|
|
||||||
|
self._cOn = SHARED.theme.accentCol
|
||||||
|
self._cOff = self.palette().alternateBase()
|
||||||
|
|
||||||
self.setCheckable(True)
|
self.setCheckable(True)
|
||||||
self.setSizePolicy(QtSizeFixed, QtSizeFixed)
|
self.setSizePolicy(QtSizeFixed, QtSizeFixed)
|
||||||
self.setFixedWidth(self._xW)
|
self.setFixedWidth(self._xW)
|
||||||
@@ -97,7 +100,7 @@ class NSwitch(QAbstractButton):
|
|||||||
painter.setOpacity(1.0 if self.isEnabled() else 0.5)
|
painter.setOpacity(1.0 if self.isEnabled() else 0.5)
|
||||||
|
|
||||||
painter.setPen(palette.highlight().color() if self.hasFocus() else palette.mid().color())
|
painter.setPen(palette.highlight().color() if self.hasFocus() else palette.mid().color())
|
||||||
painter.setBrush(palette.highlight() if self.isChecked() else palette.alternateBase())
|
painter.setBrush(self._cOn if self.isChecked() else self._cOff)
|
||||||
painter.drawRoundedRect(0, 0, self._xW, self._xH, self._xR, self._xR)
|
painter.drawRoundedRect(0, 0, self._xW, self._xH, self._xR, self._xR)
|
||||||
|
|
||||||
painter.setPen(QtNoPen)
|
painter.setPen(QtNoPen)
|
||||||
|
|||||||
@@ -233,14 +233,8 @@ class GuiItemDetails(QWidget):
|
|||||||
# Label
|
# Label
|
||||||
# =====
|
# =====
|
||||||
|
|
||||||
if nwItem.isFileType():
|
_, icon = nwItem.getActiveStatus()
|
||||||
if nwItem.isActive:
|
self.labelIcon.setPixmap(icon.pixmap(iPx, iPx))
|
||||||
self.labelIcon.setPixmap(SHARED.theme.getPixmap("checked", (iPx, iPx), "green"))
|
|
||||||
else:
|
|
||||||
self.labelIcon.setPixmap(SHARED.theme.getPixmap("unchecked", (iPx, iPx), "red"))
|
|
||||||
else:
|
|
||||||
self.labelIcon.setPixmap(SHARED.theme.getPixmap("noncheckable", (iPx, iPx), "faded"))
|
|
||||||
|
|
||||||
self.labelData.setText(elide(nwItem.itemName, 100))
|
self.labelData.setText(elide(nwItem.itemName, 100))
|
||||||
|
|
||||||
# Status
|
# Status
|
||||||
|
|||||||
+38
-27
@@ -108,7 +108,7 @@ class GuiTheme:
|
|||||||
|
|
||||||
__slots__ = (
|
__slots__ = (
|
||||||
"_allThemes", "_currentTheme", "_darkThemes", "_guiPalette", "_lightThemes", "_meta",
|
"_allThemes", "_currentTheme", "_darkThemes", "_guiPalette", "_lightThemes", "_meta",
|
||||||
"_qColors", "_styleSheets", "_svgColors", "_syntaxList", "baseButtonHeight",
|
"_qColors", "_styleSheets", "_svgColors", "_syntaxList", "accentCol", "baseButtonHeight",
|
||||||
"baseIconHeight", "baseIconSize", "buttonIconSize", "errorText", "fadedText",
|
"baseIconHeight", "baseIconSize", "buttonIconSize", "errorText", "fadedText",
|
||||||
"fontPixelSize", "fontPointSize", "getDecoration", "getHeaderDecoration",
|
"fontPixelSize", "fontPointSize", "getDecoration", "getHeaderDecoration",
|
||||||
"getHeaderDecorationNarrow", "getIcon", "getItemIcon", "getPixmap", "getToggleIcon",
|
"getHeaderDecorationNarrow", "getIcon", "getItemIcon", "getPixmap", "getToggleIcon",
|
||||||
@@ -123,10 +123,11 @@ class GuiTheme:
|
|||||||
self.syntaxTheme = SyntaxColors()
|
self.syntaxTheme = SyntaxColors()
|
||||||
self.isDarkTheme = False
|
self.isDarkTheme = False
|
||||||
|
|
||||||
# Special Text Colours
|
# Special Colours
|
||||||
self.helpText = QColor(0, 0, 0)
|
self.helpText = QColor(0, 0, 0)
|
||||||
self.fadedText = QColor(0, 0, 0)
|
self.fadedText = QColor(0, 0, 0)
|
||||||
self.errorText = QColor(255, 0, 0)
|
self.errorText = QColor(255, 0, 0)
|
||||||
|
self.accentCol = QColor(255, 0, 255) # Needed until we move to Qt 6.6
|
||||||
|
|
||||||
# Theme Data
|
# Theme Data
|
||||||
self._meta = ThemeMeta()
|
self._meta = ThemeMeta()
|
||||||
@@ -306,6 +307,7 @@ class GuiTheme:
|
|||||||
# Base
|
# Base
|
||||||
sec = "Base"
|
sec = "Base"
|
||||||
if parser.has_section(sec):
|
if parser.has_section(sec):
|
||||||
|
self._setBaseColor("base", self._readColor(parser, sec, "base"))
|
||||||
self._setBaseColor("default", self._readColor(parser, sec, "default"))
|
self._setBaseColor("default", self._readColor(parser, sec, "default"))
|
||||||
self._setBaseColor("faded", self._readColor(parser, sec, "faded"))
|
self._setBaseColor("faded", self._readColor(parser, sec, "faded"))
|
||||||
self._setBaseColor("red", self._readColor(parser, sec, "red"))
|
self._setBaseColor("red", self._readColor(parser, sec, "red"))
|
||||||
@@ -319,13 +321,16 @@ class GuiTheme:
|
|||||||
# Project
|
# Project
|
||||||
sec = "Project"
|
sec = "Project"
|
||||||
if parser.has_section(sec):
|
if parser.has_section(sec):
|
||||||
self._setBaseColor("root", self._readColor(parser, sec, "root"))
|
self._setBaseColor("root", self._readColor(parser, sec, "root"))
|
||||||
self._setBaseColor("folder", self._readColor(parser, sec, "folder"))
|
self._setBaseColor("folder", self._readColor(parser, sec, "folder"))
|
||||||
self._setBaseColor("file", self._readColor(parser, sec, "file"))
|
self._setBaseColor("file", self._readColor(parser, sec, "file"))
|
||||||
self._setBaseColor("title", self._readColor(parser, sec, "title"))
|
self._setBaseColor("title", self._readColor(parser, sec, "title"))
|
||||||
self._setBaseColor("chapter", self._readColor(parser, sec, "chapter"))
|
self._setBaseColor("chapter", self._readColor(parser, sec, "chapter"))
|
||||||
self._setBaseColor("scene", self._readColor(parser, sec, "scene"))
|
self._setBaseColor("scene", self._readColor(parser, sec, "scene"))
|
||||||
self._setBaseColor("note", self._readColor(parser, sec, "note"))
|
self._setBaseColor("note", self._readColor(parser, sec, "note"))
|
||||||
|
self._setBaseColor("active", self._readColor(parser, sec, "active"))
|
||||||
|
self._setBaseColor("inactive", self._readColor(parser, sec, "inactive"))
|
||||||
|
self._setBaseColor("disabled", self._readColor(parser, sec, "disabled"))
|
||||||
|
|
||||||
# Palette
|
# Palette
|
||||||
sec = "Palette"
|
sec = "Palette"
|
||||||
@@ -344,6 +349,7 @@ class GuiTheme:
|
|||||||
self._setPalette(parser, sec, "highlightedtext", QPalette.ColorRole.HighlightedText)
|
self._setPalette(parser, sec, "highlightedtext", QPalette.ColorRole.HighlightedText)
|
||||||
self._setPalette(parser, sec, "link", QPalette.ColorRole.Link)
|
self._setPalette(parser, sec, "link", QPalette.ColorRole.Link)
|
||||||
self._setPalette(parser, sec, "linkvisited", QPalette.ColorRole.LinkVisited)
|
self._setPalette(parser, sec, "linkvisited", QPalette.ColorRole.LinkVisited)
|
||||||
|
self.accentCol = self._readColor(parser, sec, "accent") # Special handling 'til Qt 6.6
|
||||||
|
|
||||||
# GUI
|
# GUI
|
||||||
sec = "GUI"
|
sec = "GUI"
|
||||||
@@ -427,8 +433,8 @@ class GuiTheme:
|
|||||||
self._guiPalette.setBrush(QtColDisabled, QPalette.ColorRole.Highlight, grey)
|
self._guiPalette.setBrush(QtColDisabled, QPalette.ColorRole.Highlight, grey)
|
||||||
|
|
||||||
if CONFIG.verQtValue >= 0x060600:
|
if CONFIG.verQtValue >= 0x060600:
|
||||||
self._guiPalette.setBrush(QtColActive, QPalette.ColorRole.Accent, highlight)
|
self._guiPalette.setBrush(QtColActive, QPalette.ColorRole.Accent, self.accentCol)
|
||||||
self._guiPalette.setBrush(QtColInactive, QPalette.ColorRole.Accent, highlight)
|
self._guiPalette.setBrush(QtColInactive, QPalette.ColorRole.Accent, self.accentCol)
|
||||||
self._guiPalette.setBrush(QtColDisabled, QPalette.ColorRole.Accent, grey)
|
self._guiPalette.setBrush(QtColDisabled, QPalette.ColorRole.Accent, grey)
|
||||||
|
|
||||||
# Set project override colours
|
# Set project override colours
|
||||||
@@ -506,6 +512,7 @@ class GuiTheme:
|
|||||||
isDark = self.isDesktopDarkMode()
|
isDark = self.isDesktopDarkMode()
|
||||||
|
|
||||||
# Reset GUI Palette
|
# Reset GUI Palette
|
||||||
|
base = palette.color(QPalette.ColorRole.Base)
|
||||||
default = palette.color(QPalette.ColorRole.Text)
|
default = palette.color(QPalette.ColorRole.Text)
|
||||||
faded = QColor(128, 128, 128)
|
faded = QColor(128, 128, 128)
|
||||||
dimmed = QColor(130, 130, 130) if isDark else QColor(190, 190, 190)
|
dimmed = QColor(130, 130, 130) if isDark else QColor(190, 190, 190)
|
||||||
@@ -528,22 +535,26 @@ class GuiTheme:
|
|||||||
self.iconCache.clear()
|
self.iconCache.clear()
|
||||||
self._svgColors = {}
|
self._svgColors = {}
|
||||||
self._qColors = {}
|
self._qColors = {}
|
||||||
self._setBaseColor("default", default)
|
self._setBaseColor("base", base)
|
||||||
self._setBaseColor("faded", faded)
|
self._setBaseColor("default", default)
|
||||||
self._setBaseColor("red", red)
|
self._setBaseColor("faded", faded)
|
||||||
self._setBaseColor("orange", orange)
|
self._setBaseColor("red", red)
|
||||||
self._setBaseColor("yellow", yellow)
|
self._setBaseColor("orange", orange)
|
||||||
self._setBaseColor("green", green)
|
self._setBaseColor("yellow", yellow)
|
||||||
self._setBaseColor("cyan", cyan)
|
self._setBaseColor("green", green)
|
||||||
self._setBaseColor("blue", blue)
|
self._setBaseColor("cyan", cyan)
|
||||||
self._setBaseColor("purple", purple)
|
self._setBaseColor("blue", blue)
|
||||||
self._setBaseColor("root", blue)
|
self._setBaseColor("purple", purple)
|
||||||
self._setBaseColor("folder", yellow)
|
self._setBaseColor("root", blue)
|
||||||
self._setBaseColor("file", default)
|
self._setBaseColor("folder", yellow)
|
||||||
self._setBaseColor("title", green)
|
self._setBaseColor("file", default)
|
||||||
self._setBaseColor("chapter", red)
|
self._setBaseColor("title", green)
|
||||||
self._setBaseColor("scene", blue)
|
self._setBaseColor("chapter", red)
|
||||||
self._setBaseColor("note", yellow)
|
self._setBaseColor("scene", blue)
|
||||||
|
self._setBaseColor("note", yellow)
|
||||||
|
self._setBaseColor("active", green)
|
||||||
|
self._setBaseColor("inactive", red)
|
||||||
|
self._setBaseColor("disabled", faded)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -616,16 +616,17 @@ def testGuiTheme_CheckTheme(theme):
|
|||||||
"name", "mode", # The rest are not required
|
"name", "mode", # The rest are not required
|
||||||
],
|
],
|
||||||
"Base": [
|
"Base": [
|
||||||
"default", "faded", "red", "orange", "yellow", "green", "cyan",
|
"base", "default", "faded", "red", "orange", "yellow", "green",
|
||||||
"blue", "purple",
|
"cyan", "blue", "purple",
|
||||||
],
|
],
|
||||||
"Project": [
|
"Project": [
|
||||||
"root", "folder", "file", "title", "chapter", "scene", "note",
|
"root", "folder", "file", "title", "chapter", "scene", "note",
|
||||||
|
"active", "inactive", "disabled",
|
||||||
],
|
],
|
||||||
"Palette": [
|
"Palette": [
|
||||||
"window", "windowtext", "base", "alternatebase", "text",
|
"window", "windowtext", "base", "alternatebase", "text",
|
||||||
"tooltipbase", "tooltiptext", "button", "buttontext", "brighttext",
|
"tooltipbase", "tooltiptext", "button", "buttontext", "brighttext",
|
||||||
"highlight", "highlightedtext", "link", "linkvisited",
|
"highlight", "highlightedtext", "link", "linkvisited", "accent",
|
||||||
],
|
],
|
||||||
"GUI": [
|
"GUI": [
|
||||||
"helptext", "fadedtext", "errortext",
|
"helptext", "fadedtext", "errortext",
|
||||||
|
|||||||
Reference in New Issue
Block a user