Eliminate hardcoded colors from qml to make theming more flexible

This commit is contained in:
luisangelsm
2026-03-07 19:58:24 +01:00
parent d65ce375df
commit 7103d0de3c
13 changed files with 187 additions and 38 deletions

View File

@ -294,6 +294,17 @@ void FolderContentView::applyTheme(const Theme &theme)
ctxt->setContextProperty("readTickUncheckedColor", giv.readTickUncheckedColor);
ctxt->setContextProperty("readTickCheckedColor", giv.readTickCheckedColor);
// New item indicator, cover borders, placeholder pages, scrollbar
ctxt->setContextProperty("newItemColor", giv.newItemColor);
ctxt->setContextProperty("scrollbarColor", giv.scrollbarColor);
ctxt->setContextProperty("scrollbarBorderColor", giv.scrollbarBorderColor);
ctxt->setContextProperty("comicCoverBorderColor", giv.comicCoverBorderColor);
ctxt->setContextProperty("folderCoverBorderColor", giv.folderCoverBorderColor);
ctxt->setContextProperty("placeholderFolder1Color", giv.placeholderFolder1Color);
ctxt->setContextProperty("placeholderFolder1BorderColor", giv.placeholderFolder1BorderColor);
ctxt->setContextProperty("placeholderFolder2Color", giv.placeholderFolder2Color);
ctxt->setContextProperty("placeholderFolder2BorderColor", giv.placeholderFolder2BorderColor);
// Update zoom slider icons
if (smallZoomLabel) {
smallZoomLabel->setPixmap(theme.comicsViewToolbar.smallGridZoomIcon.pixmap(18, 18));

View File

@ -517,6 +517,19 @@ void GridComicsView::applyTheme(const Theme &theme)
// Current comic banner
ctxt->setContextProperty("currentComicBackgroundColor", giv.currentComicBackgroundColor);
// New item indicator, button colors, links, scrollbars, cover borders, shadows
ctxt->setContextProperty("newItemColor", giv.newItemColor);
ctxt->setContextProperty("buttonColor", giv.buttonColor);
ctxt->setContextProperty("buttonTextColor", giv.buttonTextColor);
ctxt->setContextProperty("themeLinkColor", giv.linkColor);
ctxt->setContextProperty("themeLinkColorStr", giv.linkColor.name());
ctxt->setContextProperty("scrollbarColor", giv.scrollbarColor);
ctxt->setContextProperty("scrollbarBorderColor", giv.scrollbarBorderColor);
ctxt->setContextProperty("infoScrollbarColor", giv.infoScrollbarColor);
ctxt->setContextProperty("comicCoverBorderColor", giv.comicCoverBorderColor);
ctxt->setContextProperty("currentComicCoverShadowColor", giv.currentComicCoverShadowColor);
ctxt->setContextProperty("buttonShadowColor", giv.buttonShadowColor);
// Update background config to apply theme cell colors
updateBackgroundConfig();

View File

@ -252,4 +252,10 @@ void InfoComicsView::applyTheme(const Theme &theme)
ctxt->setContextProperty("showDropShadow", QVariant(giv.showDropShadow));
ctxt->setContextProperty("backgroundBlurOverlayColor", giv.backgroundBlurOverlayColor);
// Info panel scrollbar, comic cover border, links
ctxt->setContextProperty("infoScrollbarColor", giv.infoScrollbarColor);
ctxt->setContextProperty("comicCoverBorderColor", giv.comicCoverBorderColor);
ctxt->setContextProperty("themeLinkColor", giv.linkColor);
ctxt->setContextProperty("themeLinkColorStr", giv.linkColor.name());
}

View File

@ -260,7 +260,7 @@ Rectangle {
Text {
id: showInComicVine
font: mainContainer.infoFont
color: "#ffcc00"
color: themeLinkColor
text: "Show in Comic Vine"
visible: comicInfo ? comicInfo.comicVineID ?? false : false
MouseArea {
@ -284,12 +284,7 @@ Rectangle {
font.pixelSize: 15
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignJustify
text: '<html><head><style>
a {
color: #FFCB00;
text-decoration:none;
}
</style></head><body>' + (comicInfo ? comicInfo.synopsis ?? "" : "") + '</body></html>'
text: '<html><head><style>a { color: ' + themeLinkColorStr + '; text-decoration: none; }</style></head><body>' + (comicInfo ? comicInfo.synopsis ?? "" : "") + '</body></html>'
visible: comicInfo ? comicInfo.synopsis ?? false : false
textFormat: Text.RichText
}

View File

@ -171,7 +171,7 @@ Rectangle {
anchors.centerIn: coverElement
color: "transparent"
border {
color: "#30FFFFFF"
color: comicCoverBorderColor
width: 1
}
}

View File

@ -84,9 +84,9 @@ Rectangle {
height: coverElement.height
radius: 10
anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0}
color: "#20000000"
color: placeholderFolder1Color
border {
color: "#20FFFFFF"
color: placeholderFolder1BorderColor
width: 1
}
}
@ -97,9 +97,9 @@ Rectangle {
height: coverElement.height
radius: 10
anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0}
color: "#88000000"
color: placeholderFolder2Color
border {
color: "#20FFFFFF"
color: placeholderFolder2BorderColor
width: 1
}
}
@ -152,7 +152,7 @@ Rectangle {
height: 10
radius: 5
anchors { left: coverElement.left; top: coverElement.top; topMargin: 10; leftMargin: 10; }
color: "#FFFFCC00"
color: newItemColor
visible: (((new Date() / 1000) - added) < recent_range || ((new Date() / 1000) - updated) < recent_range) && show_recent
}
@ -164,7 +164,7 @@ Rectangle {
anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0}
color: "transparent"
border {
color: "#20FFFFFF"
color: folderCoverBorderColor
width: 1
}
}
@ -310,7 +310,7 @@ Rectangle {
anchors.centerIn: coverElement
color: "transparent"
border {
color: "#30FFFFFF"
color: comicCoverBorderColor
width: 1
}
}
@ -433,13 +433,13 @@ Rectangle {
implicitWidth: 12
implicitHeight: 26
Rectangle {
color: "#88424242"
color: scrollbarColor
anchors.fill: parent
anchors.topMargin: 6
anchors.leftMargin: 3
anchors.rightMargin: 2
anchors.bottomMargin: 6
border.color: "#AA313131"
border.color: scrollbarBorderColor
border.width: 1
radius: 3.5
}

View File

@ -295,7 +295,7 @@ SplitView {
height: 10
radius: 5
anchors { left: coverElement.left; top: coverElement.top; topMargin: 5; leftMargin: 5; }
color: "#FFFFCC00"
color: newItemColor
visible: (((new Date() / 1000) - added_date) < recent_range) && show_recent
}
@ -306,7 +306,7 @@ SplitView {
anchors {horizontalCenter: parent.horizontalCenter; top: realCell.top; topMargin: 0}
color: "transparent"
border {
color: "#20FFFFFF"
color: comicCoverBorderColor
width: 1
}
}
@ -481,7 +481,7 @@ SplitView {
layer.enabled: showDropShadow
layer.effect: MultiEffect {
shadowEnabled: true
shadowColor: "#FF000000"
shadowColor: currentComicCoverShadowColor
shadowBlur: 1.0
blurMax: 8
shadowHorizontalOffset: 0
@ -608,7 +608,7 @@ SplitView {
Text {
id: currentComicInfoShowInComicVine
font: currentComicDetailsFlowView.infoFont
color: "#ffcc00"
color: themeLinkColor
text: "Show in Comic Vine"
visible: currentComicInfo.comicVineID ? true : false
MouseArea {
@ -648,12 +648,7 @@ SplitView {
font.pixelSize: 14
wrapMode: Text.WordWrap
text: '<html><head><style>
a {
color: #FFCB00;
text-decoration:none;
}
</style></head><body>' + currentComicInfo.synopsis ?? "" + '</body></html>'
text: '<html><head><style>a { color: ' + themeLinkColorStr + '; text-decoration: none; }</style></head><body>' + (currentComicInfo.synopsis ?? "") + '</body></html>'
visible: currentComicInfo.synopsis ?? false
textFormat: Text.RichText
}
@ -673,9 +668,9 @@ SplitView {
implicitWidth: 100
implicitHeight: 30
border.width: readButton.activeFocus ? 2 : 1
border.color: "#FFCC00"
border.color: buttonColor
radius: height / 2
color: "#FFCC00"
color: buttonColor
}
contentItem: Text {
@ -685,14 +680,14 @@ SplitView {
font.family: "Arial"
font.pointSize: 12
font.bold: true
color: "white"
color: buttonTextColor
text: readButton.text
}
layer.enabled: showDropShadow && !readButton.pressed
layer.effect: MultiEffect {
shadowEnabled: true
shadowColor: "#AA000000"
shadowColor: buttonShadowColor
shadowBlur: 1.0
blurMax: 8
shadowHorizontalOffset: 0
@ -782,13 +777,13 @@ SplitView {
implicitWidth: 12
implicitHeight: 26
Rectangle {
color: "#88424242"
color: scrollbarColor
anchors.fill: parent
anchors.topMargin: 6
anchors.leftMargin: 3
anchors.rightMargin: 2
anchors.bottomMargin: 6
border.color: "#AA313131"
border.color: scrollbarBorderColor
border.width: 1
radius: 3.5
}
@ -911,7 +906,7 @@ SplitView {
implicitWidth: 12
implicitHeight: 26
Rectangle {
color: "#424246"
color: infoScrollbarColor
anchors.fill: parent
anchors.topMargin: 6
anchors.leftMargin: 5

View File

@ -94,7 +94,7 @@ Rectangle {
implicitWidth: 12
implicitHeight: 26
Rectangle {
color: "#424246"
color: infoScrollbarColor
anchors.fill: parent
anchors.topMargin: 6
anchors.leftMargin: 5

View File

@ -65,7 +65,22 @@
"selectedColor": "#121212",
"showDropShadow": true,
"textColor": "#a8a8a8",
"titleColor": "#ffffff"
"titleColor": "#ffffff",
"newItemColor": "#ffffcc00",
"buttonColor": "#ffcc00",
"buttonTextColor": "#ffffff",
"linkColor": "#ffcc00",
"scrollbarColor": "#88424242",
"scrollbarBorderColor": "#aa313131",
"infoScrollbarColor": "#ff424246",
"comicCoverBorderColor": "#30ffffff",
"folderCoverBorderColor": "#20ffffff",
"placeholderFolder1Color": "#20000000",
"placeholderFolder1BorderColor": "#20ffffff",
"placeholderFolder2Color": "#88000000",
"placeholderFolder2BorderColor": "#20ffffff",
"currentComicCoverShadowColor": "#ff000000",
"buttonShadowColor": "#aa000000"
},
"helpAboutDialog": {
"headingColor": "#302f2d",

View File

@ -65,7 +65,22 @@
"selectedColor": "#121212",
"showDropShadow": true,
"textColor": "#a8a8a8",
"titleColor": "#ffffff"
"titleColor": "#ffffff",
"newItemColor": "#ffffcc00",
"buttonColor": "#ffcc00",
"buttonTextColor": "#ffffff",
"linkColor": "#ffcc00",
"scrollbarColor": "#88424242",
"scrollbarBorderColor": "#aa313131",
"infoScrollbarColor": "#ff424246",
"comicCoverBorderColor": "#30ffffff",
"folderCoverBorderColor": "#20ffffff",
"placeholderFolder1Color": "#20000000",
"placeholderFolder1BorderColor": "#20ffffff",
"placeholderFolder2Color": "#88000000",
"placeholderFolder2BorderColor": "#20ffffff",
"currentComicCoverShadowColor": "#ff000000",
"buttonShadowColor": "#aa000000"
},
"helpAboutDialog": {
"headingColor": "#e0e0e0",

View File

@ -65,7 +65,22 @@
"selectedColor": "#ffffff",
"showDropShadow": true,
"textColor": "#636363",
"titleColor": "#121212"
"titleColor": "#121212",
"newItemColor": "#ffffcc00",
"buttonColor": "#ffcc00",
"buttonTextColor": "#ffffff",
"linkColor": "#ffcc00",
"scrollbarColor": "#88424242",
"scrollbarBorderColor": "#aa313131",
"infoScrollbarColor": "#ff424246",
"comicCoverBorderColor": "#30ffffff",
"folderCoverBorderColor": "#20ffffff",
"placeholderFolder1Color": "#20000000",
"placeholderFolder1BorderColor": "#20ffffff",
"placeholderFolder2Color": "#88000000",
"placeholderFolder2BorderColor": "#20ffffff",
"currentComicCoverShadowColor": "#ff000000",
"buttonShadowColor": "#aa000000"
},
"helpAboutDialog": {
"headingColor": "#302f2d",

View File

@ -247,6 +247,33 @@ struct GridAndInfoViewTheme {
// Blur overlay background (FlowView always, GridView when background image enabled)
QColor backgroundBlurOverlayColor;
// New item indicator dot (cover grid and folder grid)
QColor newItemColor;
// Button colors
QColor buttonColor;
QColor buttonTextColor;
QColor linkColor;
// Scrollbar colors — content grid (on backgroundColor)
QColor scrollbarColor;
QColor scrollbarBorderColor;
// Scrollbar color — info panel (on infoBackgroundColor)
QColor infoScrollbarColor;
// Cover overlay / border effects
QColor comicCoverBorderColor;
QColor folderCoverBorderColor;
QColor placeholderFolder1Color;
QColor placeholderFolder1BorderColor;
QColor placeholderFolder2Color;
QColor placeholderFolder2BorderColor;
// Drop shadow effects
QColor currentComicCoverShadowColor;
QColor buttonShadowColor;
};
struct MainToolbarThemeTemplates {

View File

@ -174,6 +174,33 @@ struct GridAndInfoViewParams {
// Blur overlay background (FlowView always, GridView when background image enabled)
QColor backgroundBlurOverlayColor;
// New item indicator dot
QColor newItemColor;
// Button colors
QColor buttonColor;
QColor buttonTextColor;
QColor linkColor;
// Scrollbar colors — content grid
QColor scrollbarColor;
QColor scrollbarBorderColor;
// Scrollbar color — info panel
QColor infoScrollbarColor;
// Cover overlay / border effects
QColor comicCoverBorderColor;
QColor folderCoverBorderColor;
QColor placeholderFolder1Color;
QColor placeholderFolder1BorderColor;
QColor placeholderFolder2Color;
QColor placeholderFolder2BorderColor;
// Drop shadow effects
QColor currentComicCoverShadowColor;
QColor buttonShadowColor;
};
struct MainToolbarParams {
@ -515,6 +542,21 @@ Theme makeTheme(const ThemeParams &params)
theme.gridAndInfoView.continueReadingBackgroundColor = giv.continueReadingBackgroundColor;
theme.gridAndInfoView.continueReadingColor = giv.continueReadingColor;
theme.gridAndInfoView.backgroundBlurOverlayColor = giv.backgroundBlurOverlayColor;
theme.gridAndInfoView.newItemColor = giv.newItemColor;
theme.gridAndInfoView.buttonColor = giv.buttonColor;
theme.gridAndInfoView.buttonTextColor = giv.buttonTextColor;
theme.gridAndInfoView.linkColor = giv.linkColor;
theme.gridAndInfoView.scrollbarColor = giv.scrollbarColor;
theme.gridAndInfoView.scrollbarBorderColor = giv.scrollbarBorderColor;
theme.gridAndInfoView.infoScrollbarColor = giv.infoScrollbarColor;
theme.gridAndInfoView.comicCoverBorderColor = giv.comicCoverBorderColor;
theme.gridAndInfoView.folderCoverBorderColor = giv.folderCoverBorderColor;
theme.gridAndInfoView.placeholderFolder1Color = giv.placeholderFolder1Color;
theme.gridAndInfoView.placeholderFolder1BorderColor = giv.placeholderFolder1BorderColor;
theme.gridAndInfoView.placeholderFolder2Color = giv.placeholderFolder2Color;
theme.gridAndInfoView.placeholderFolder2BorderColor = giv.placeholderFolder2BorderColor;
theme.gridAndInfoView.currentComicCoverShadowColor = giv.currentComicCoverShadowColor;
theme.gridAndInfoView.buttonShadowColor = giv.buttonShadowColor;
// end GridAndInfoView
// MainToolbar
@ -1094,6 +1136,21 @@ Theme makeTheme(const QJsonObject &json)
giv.continueReadingBackgroundColor = colorFromJson(o, "continueReadingBackgroundColor", giv.continueReadingBackgroundColor);
giv.continueReadingColor = colorFromJson(o, "continueReadingColor", giv.continueReadingColor);
giv.backgroundBlurOverlayColor = colorFromJson(o, "backgroundBlurOverlayColor", giv.backgroundBlurOverlayColor);
giv.newItemColor = colorFromJson(o, "newItemColor", giv.newItemColor);
giv.buttonColor = colorFromJson(o, "buttonColor", giv.buttonColor);
giv.buttonTextColor = colorFromJson(o, "buttonTextColor", giv.buttonTextColor);
giv.linkColor = colorFromJson(o, "linkColor", giv.linkColor);
giv.scrollbarColor = colorFromJson(o, "scrollbarColor", giv.scrollbarColor);
giv.scrollbarBorderColor = colorFromJson(o, "scrollbarBorderColor", giv.scrollbarBorderColor);
giv.infoScrollbarColor = colorFromJson(o, "infoScrollbarColor", giv.infoScrollbarColor);
giv.comicCoverBorderColor = colorFromJson(o, "comicCoverBorderColor", giv.comicCoverBorderColor);
giv.folderCoverBorderColor = colorFromJson(o, "folderCoverBorderColor", giv.folderCoverBorderColor);
giv.placeholderFolder1Color = colorFromJson(o, "placeholderFolder1Color", giv.placeholderFolder1Color);
giv.placeholderFolder1BorderColor = colorFromJson(o, "placeholderFolder1BorderColor", giv.placeholderFolder1BorderColor);
giv.placeholderFolder2Color = colorFromJson(o, "placeholderFolder2Color", giv.placeholderFolder2Color);
giv.placeholderFolder2BorderColor = colorFromJson(o, "placeholderFolder2BorderColor", giv.placeholderFolder2BorderColor);
giv.currentComicCoverShadowColor = colorFromJson(o, "currentComicCoverShadowColor", giv.currentComicCoverShadowColor);
giv.buttonShadowColor = colorFromJson(o, "buttonShadowColor", giv.buttonShadowColor);
}
if (json.contains("comicsViewToolbar")) {