1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-06 05:25:41 -05:00

Clean up entire theme system

This commit is contained in:
bbedward
2025-08-20 19:30:45 -04:00
parent daaf1ae74c
commit 0a846fd1ee
7 changed files with 927 additions and 1018 deletions

View File

@@ -1,456 +0,0 @@
pragma Singleton
pragma ComponentBehavior
import Qt.labs.platform
import QtQuick
import Quickshell
import Quickshell.Io
import qs.Services
Singleton {
id: root
readonly property string _homeUrl: StandardPaths.writableLocation(
StandardPaths.HomeLocation)
readonly property string homeDir: _homeUrl.startsWith(
"file://") ? _homeUrl.substring(
7) : _homeUrl
readonly property string _configUrl: StandardPaths.writableLocation(
StandardPaths.ConfigLocation)
readonly property string configDir: _configUrl.startsWith(
"file://") ? _configUrl.substring(
7) : _configUrl
readonly property string shellDir: Qt.resolvedUrl(".").toString().replace(
"file://",
"").replace("/Common/", "")
readonly property string wallpaperPath: SessionData.wallpaperPath
property bool matugenAvailable: false
property bool gtkThemingEnabled: false
property bool qtThemingEnabled: false
property bool systemThemeGenerationInProgress: false
property var matugenColors: ({})
property bool extractionRequested: false
property int colorUpdateTrigger: 0
property string lastWallpaperTimestamp: ""
property color primary: getMatugenColor("primary", "#42a5f5")
property color secondary: getMatugenColor("secondary", "#8ab4f8")
property color tertiary: getMatugenColor("tertiary", "#bb86fc")
property color tertiaryContainer: getMatugenColor("tertiary_container",
"#3700b3")
property color error: getMatugenColor("error", "#cf6679")
property color inversePrimary: getMatugenColor("inverse_primary", "#6200ea")
property color bg: getMatugenColor("background", "#1a1c1e")
property color surface: getMatugenColor("surface", "#1a1c1e")
property color surfaceContainer: getMatugenColor("surface_container",
"#1e2023")
property color surfaceContainerHigh: getMatugenColor(
"surface_container_high",
"#292b2f")
property color surfaceVariant: getMatugenColor("surface_variant", "#44464f")
property color surfaceText: getMatugenColor("on_background", "#e3e8ef")
property color primaryText: getMatugenColor("on_primary", "#ffffff")
property color surfaceVariantText: getMatugenColor("on_surface_variant",
"#c4c7c5")
property color primaryContainer: getMatugenColor("primary_container",
"#1976d2")
property color surfaceTint: getMatugenColor("surface_tint", "#8ab4f8")
property color outline: getMatugenColor("outline", "#8e918f")
property color accentHi: primary
property color accentLo: secondary
signal colorsUpdated
function onLightModeChanged() {
if (matugenColors && Object.keys(matugenColors).length > 0) {
colorUpdateTrigger++
colorsUpdated()
if (typeof Theme !== "undefined" && Theme.isDynamicTheme) {
generateSystemThemes()
}
}
}
function extractColors() {
extractionRequested = true
if (matugenAvailable)
fileChecker.running = true
else
matugenCheck.running = true
}
function getMatugenColor(path, fallback) {
colorUpdateTrigger
const colorMode = (typeof SessionData !== "undefined"
&& SessionData.isLightMode) ? "light" : "dark"
let cur = matugenColors && matugenColors.colors
&& matugenColors.colors[colorMode]
for (const part of path.split(".")) {
if (!cur || typeof cur !== "object" || !(part in cur))
return fallback
cur = cur[part]
}
return cur || fallback
}
function isColorDark(c) {
return (0.299 * c.r + 0.587 * c.g + 0.114 * c.b) < 0.5
}
Component.onCompleted: {
matugenCheck.running = true
checkGtkThemingAvailability()
checkQtThemingAvailability()
if (typeof SessionData !== "undefined")
SessionData.isLightModeChanged.connect(root.onLightModeChanged)
}
Process {
id: matugenCheck
command: ["which", "matugen"]
onExited: code => {
matugenAvailable = (code === 0)
if (!matugenAvailable) {
ToastService.wallpaperErrorStatus = "matugen_missing"
ToastService.showWarning(
"matugen not found - dynamic theming disabled")
return
}
if (extractionRequested) {
fileChecker.running = true
}
}
}
Process {
id: fileChecker
command: ["test", "-r", wallpaperPath]
onExited: code => {
if (code === 0) {
matugenProcess.running = true
} else {
ToastService.wallpaperErrorStatus = "error"
ToastService.showError("Wallpaper processing failed")
}
}
}
Process {
id: matugenProcess
command: ["matugen", "image", wallpaperPath, "--json", "hex"]
stdout: StdioCollector {
id: matugenCollector
onStreamFinished: {
if (!matugenCollector.text) {
ToastService.wallpaperErrorStatus = "error"
ToastService.showError(
"Wallpaper Processing Failed: Empty JSON extracted from matugen output.")
return
}
const extractedJson = extractJsonFromText(matugenCollector.text)
if (!extractedJson) {
ToastService.wallpaperErrorStatus = "error"
ToastService.showError(
"Wallpaper Processing Failed: Invalid JSON extracted from matugen output.")
console.log("Raw matugen output:", matugenCollector.text)
return
}
try {
root.matugenColors = JSON.parse(extractedJson)
root.colorsUpdated()
generateAppConfigs()
ToastService.clearWallpaperError()
} catch (e) {
ToastService.wallpaperErrorStatus = "error"
ToastService.showError(
"Wallpaper processing failed (JSON parse error after extraction)")
}
}
}
onExited: code => {
if (code !== 0) {
ToastService.wallpaperErrorStatus = "error"
ToastService.showError(
"Matugen command failed with exit code " + code)
}
}
}
function generateAppConfigs() {
if (!matugenColors || !matugenColors.colors) {
return
}
generateNiriConfig()
generateGhosttyConfig()
if (gtkThemingEnabled && typeof SettingsData !== "undefined"
&& SettingsData.gtkThemingEnabled) {
generateSystemThemes()
} else if (qtThemingEnabled && typeof SettingsData !== "undefined"
&& SettingsData.qtThemingEnabled) {
generateSystemThemes()
}
}
function generateNiriConfig() {
var dark = matugenColors.colors.dark
if (!dark)
return
var bg = dark.background || "#1a1c1e"
var primary = dark.primary || "#42a5f5"
var secondary = dark.secondary || "#8ab4f8"
var inverse = dark.inverse_primary || "#6200ea"
var content = `layout {
border {
active-color "${primary}"
inactive-color "${secondary}"
}
focus-ring {
active-color "${inverse}"
}
background-color "${bg}"
}`
Quickshell.execDetached(
["bash", "-c", `echo '${content}' > niri-colors.generated.kdl`])
}
function generateGhosttyConfig() {
var dark = matugenColors.colors.dark
var light = matugenColors.colors.light
if (!dark || !light)
return
var bg = dark.background || "#1a1c1e"
var fg = dark.on_background || "#e3e8ef"
var primary = dark.primary || "#42a5f5"
var secondary = dark.secondary || "#8ab4f8"
var tertiary = dark.tertiary || "#bb86fc"
var tertiary_ctr = dark.tertiary_container || "#3700b3"
var error = dark.error || "#cf6679"
var inverse = dark.inverse_primary || "#6200ea"
var bg_b = light.background || "#fef7ff"
var fg_b = light.on_background || "#1d1b20"
var primary_b = light.primary || "#1976d2"
var secondary_b = light.secondary || "#1565c0"
var tertiary_b = light.tertiary || "#7b1fa2"
var tertiary_ctr_b = light.tertiary_container || "#e1bee7"
var error_b = light.error || "#b00020"
var inverse_b = light.inverse_primary || "#bb86fc"
var content = `background = ${bg}
foreground = ${fg}
cursor-color = ${inverse}
selection-background = ${secondary}
selection-foreground = #ffffff
palette = 0=${bg}
palette = 1=${error}
palette = 2=${tertiary}
palette = 3=${secondary}
palette = 4=${primary}
palette = 5=${tertiary_ctr}
palette = 6=${inverse}
palette = 7=${fg}
palette = 8=${bg_b}
palette = 9=${error_b}
palette = 10=${tertiary_b}
palette = 11=${secondary_b}
palette = 12=${primary_b}
palette = 13=${tertiary_ctr_b}
palette = 14=${inverse_b}
palette = 15=${fg_b}`
var ghosttyConfigDir = configDir + "/ghostty"
var ghosttyConfigPath = ghosttyConfigDir + "/config-dankcolors"
Quickshell.execDetached(
["bash", "-c", `mkdir -p '${ghosttyConfigDir}' && echo '${content}' > '${ghosttyConfigPath}'`])
}
function checkGtkThemingAvailability() {
gtkAvailabilityChecker.running = true
}
function checkQtThemingAvailability() {
qtAvailabilityChecker.running = true
}
function generateSystemThemes() {
if (systemThemeGenerationInProgress) {
return
}
if (!matugenAvailable) {
return
}
if (!wallpaperPath || wallpaperPath === "") {
return
}
const isLight = (typeof SessionData !== "undefined"
&& SessionData.isLightMode) ? "true" : "false"
const iconTheme = (typeof SettingsData !== "undefined"
&& SettingsData.iconTheme) ? SettingsData.iconTheme : "System Default"
const gtkTheming = (typeof SettingsData !== "undefined"
&& SettingsData.gtkThemingEnabled) ? "true" : "false"
const qtTheming = (typeof SettingsData !== "undefined"
&& SettingsData.qtThemingEnabled) ? "true" : "false"
systemThemeGenerationInProgress = true
systemThemeGenerator.command = [shellDir + "/generate-themes.sh", wallpaperPath, shellDir, configDir, "generate", isLight, iconTheme, gtkTheming, qtTheming]
systemThemeGenerator.running = true
}
function restoreSystemThemes() {
const shellDir = root.shellDir
if (!shellDir) {
return
}
const isLight = (typeof SessionData !== "undefined"
&& SessionData.isLightMode) ? "true" : "false"
const iconTheme = (typeof SettingsData !== "undefined"
&& SettingsData.iconTheme) ? SettingsData.iconTheme : "System Default"
const gtkTheming = (typeof SettingsData !== "undefined"
&& SettingsData.gtkThemingEnabled) ? "true" : "false"
const qtTheming = (typeof SettingsData !== "undefined"
&& SettingsData.qtThemingEnabled) ? "true" : "false"
systemThemeRestoreProcess.command = [shellDir + "/generate-themes.sh", "", shellDir, configDir, "restore", isLight, iconTheme, gtkTheming, qtTheming]
systemThemeRestoreProcess.running = true
}
// Returns the first complete JSON substring (object or array) or null.
function extractJsonFromText(text) {
if (!text)
return null
const start = text.search(/[{\[]/)
if (start === -1)
return null
const open = text[start]
const pairs = {
"{": '}',
"[": ']'
}
const close = pairs[open]
if (!close)
return null
let inString = false
let escape = false
const stack = [open]
for (var i = start + 1; i < text.length; i++) {
const ch = text[i]
if (inString) {
if (escape) {
escape = false
} else if (ch === '\\') {
escape = true
} else if (ch === '"') {
inString = false
}
continue
}
if (ch === '"') {
inString = true
continue
}
if (ch === '{' || ch === '[') {
stack.push(ch)
continue
}
if (ch === '}' || ch === ']') {
const last = stack.pop()
if (!last || pairs[last] !== ch) {
return null
}
if (stack.length === 0) {
return text.slice(start, i + 1)
}
}
}
return null
}
Process {
id: gtkAvailabilityChecker
command: ["bash", "-c", "command -v gsettings >/dev/null && [ -d "
+ configDir + "/gtk-3.0 -o -d " + configDir + "/gtk-4.0 ]"]
running: false
onExited: exitCode => {
gtkThemingEnabled = (exitCode === 0)
}
}
Process {
id: qtAvailabilityChecker
command: ["bash", "-c", "command -v qt5ct >/dev/null || command -v qt6ct >/dev/null"]
running: false
onExited: exitCode => {
qtThemingEnabled = (exitCode === 0)
}
}
Process {
id: systemThemeGenerator
running: false
stdout: StdioCollector {
id: systemThemeStdout
}
stderr: StdioCollector {
id: systemThemeStderr
}
onExited: exitCode => {
systemThemeGenerationInProgress = false
if (exitCode !== 0) {
ToastService.showError(
"Failed to generate system themes: " + systemThemeStderr.text)
}
}
}
Process {
id: systemThemeRestoreProcess
running: false
stdout: StdioCollector {
id: restoreThemeStdout
}
stderr: StdioCollector {
id: restoreThemeStderr
}
onExited: exitCode => {
if (exitCode === 0) {
ToastService.showInfo("System themes restored to default")
} else {
ToastService.showWarning(
"Failed to restore system themes: " + restoreThemeStderr.text)
}
}
}
}

View File

@@ -129,9 +129,9 @@ Singleton {
wallpaperPath = imagePath
saveSettings()
if (typeof Colors !== "undefined" && typeof SettingsData !== "undefined"
if (typeof Theme !== "undefined" && typeof SettingsData !== "undefined"
&& SettingsData.wallpaperDynamicTheming) {
Colors.extractColors()
Theme.extractColors()
}
}

View File

@@ -10,8 +10,8 @@ pragma ComponentBehavior
Singleton {
id: root
property int themeIndex: 0
property bool themeIsDynamic: false
// Theme settings
property string currentThemeName: "blue"
property real topBarTransparency: 0.75
property real topBarWidgetTransparency: 0.85
property real popupTransparency: 0.92
@@ -114,9 +114,18 @@ Singleton {
try {
if (content && content.trim()) {
var settings = JSON.parse(content)
themeIndex = settings.themeIndex !== undefined ? settings.themeIndex : 0
themeIsDynamic = settings.themeIsDynamic
!== undefined ? settings.themeIsDynamic : false
// Auto-migrate from old theme system
if (settings.themeIndex !== undefined || settings.themeIsDynamic !== undefined) {
const themeNames = ["blue", "deepBlue", "purple", "green", "orange", "red", "cyan", "pink", "amber", "coral"]
if (settings.themeIsDynamic) {
currentThemeName = "dynamic"
} else if (settings.themeIndex >= 0 && settings.themeIndex < themeNames.length) {
currentThemeName = themeNames[settings.themeIndex]
}
console.log("Auto-migrated theme from index", settings.themeIndex, "to", currentThemeName)
} else {
currentThemeName = settings.currentThemeName !== undefined ? settings.currentThemeName : "blue"
}
topBarTransparency = settings.topBarTransparency
!== undefined ? (settings.topBarTransparency
> 1 ? settings.topBarTransparency
@@ -278,8 +287,7 @@ Singleton {
function saveSettings() {
settingsFile.setText(JSON.stringify({
"themeIndex": themeIndex,
"themeIsDynamic": themeIsDynamic,
"currentThemeName": currentThemeName,
"topBarTransparency": topBarTransparency,
"topBarWidgetTransparency": topBarWidgetTransparency,
"popupTransparency": popupTransparency,
@@ -438,18 +446,16 @@ Singleton {
function applyStoredTheme() {
if (typeof Theme !== "undefined")
Theme.switchTheme(themeIndex, themeIsDynamic, false)
Theme.switchTheme(currentThemeName, false)
else
Qt.callLater(() => {
if (typeof Theme !== "undefined")
Theme.switchTheme(themeIndex,
themeIsDynamic, false)
Theme.switchTheme(currentThemeName, false)
})
}
function setTheme(index, isDynamic) {
themeIndex = index
themeIsDynamic = isDynamic
function setTheme(themeName) {
currentThemeName = themeName
saveSettings()
}
@@ -717,9 +723,8 @@ Singleton {
updateGtkIconTheme(themeName)
updateQtIconTheme(themeName)
saveSettings()
if (typeof Theme !== "undefined" && Theme.isDynamicTheme
&& typeof Colors !== "undefined")
Colors.generateSystemThemes()
if (typeof Theme !== "undefined" && Theme.isDynamicTheme)
Theme.generateSystemThemes()
}
function updateGtkIconTheme(themeName) {

380
Common/StockThemes.js Normal file
View File

@@ -0,0 +1,380 @@
// Stock theme definitions for DankMaterialShell
// Separated from Theme.qml to keep that file clean
const StockThemes = {
DARK: {
blue: {
name: "Blue",
primary: "#42a5f5",
primaryText: "#ffffff",
primaryContainer: "#1976d2",
secondary: "#8ab4f8",
surface: "#1a1c1e",
surfaceText: "#e3e8ef",
surfaceVariant: "#44464f",
surfaceVariantText: "#c4c7c5",
surfaceTint: "#8ab4f8",
background: "#1a1c1e",
backgroundText: "#e3e8ef",
outline: "#8e918f",
surfaceContainer: "#1e2023",
surfaceContainerHigh: "#292b2f"
},
deepBlue: {
name: "Deep Blue",
primary: "#0061a4",
primaryText: "#ffffff",
primaryContainer: "#004881",
secondary: "#42a5f5",
surface: "#1a1c1e",
surfaceText: "#e3e8ef",
surfaceVariant: "#44464f",
surfaceVariantText: "#c4c7c5",
surfaceTint: "#8ab4f8",
background: "#1a1c1e",
backgroundText: "#e3e8ef",
outline: "#8e918f",
surfaceContainer: "#1e2023",
surfaceContainerHigh: "#292b2f"
},
purple: {
name: "Purple",
primary: "#D0BCFF",
primaryText: "#381E72",
primaryContainer: "#4F378B",
secondary: "#CCC2DC",
surface: "#10121E",
surfaceText: "#E6E0E9",
surfaceVariant: "#49454F",
surfaceVariantText: "#CAC4D0",
surfaceTint: "#D0BCFF",
background: "#10121E",
backgroundText: "#E6E0E9",
outline: "#938F99",
surfaceContainer: "#1D1B20",
surfaceContainerHigh: "#2B2930"
},
green: {
name: "Green",
primary: "#4caf50",
primaryText: "#ffffff",
primaryContainer: "#388e3c",
secondary: "#81c995",
surface: "#0f1411",
surfaceText: "#e1f5e3",
surfaceVariant: "#404943",
surfaceVariantText: "#c1cbc4",
surfaceTint: "#81c995",
background: "#0f1411",
backgroundText: "#e1f5e3",
outline: "#8b938c",
surfaceContainer: "#1a1f1b",
surfaceContainerHigh: "#252a26"
},
orange: {
name: "Orange",
primary: "#ff6d00",
primaryText: "#ffffff",
primaryContainer: "#e65100",
secondary: "#ffb74d",
surface: "#1c1410",
surfaceText: "#f5f1ea",
surfaceVariant: "#4a453a",
surfaceVariantText: "#cbc5b8",
surfaceTint: "#ffb74d",
background: "#1c1410",
backgroundText: "#f5f1ea",
outline: "#958f84",
surfaceContainer: "#211e17",
surfaceContainerHigh: "#2c291f"
},
red: {
name: "Red",
primary: "#f44336",
primaryText: "#ffffff",
primaryContainer: "#d32f2f",
secondary: "#f28b82",
surface: "#1c1011",
surfaceText: "#f5e8ea",
surfaceVariant: "#4a3f41",
surfaceVariantText: "#cbc2c4",
surfaceTint: "#f28b82",
background: "#1c1011",
backgroundText: "#f5e8ea",
outline: "#958b8d",
surfaceContainer: "#211b1c",
surfaceContainerHigh: "#2c2426"
},
cyan: {
name: "Cyan",
primary: "#00bcd4",
primaryText: "#ffffff",
primaryContainer: "#0097a7",
secondary: "#4dd0e1",
surface: "#0f1617",
surfaceText: "#e8f4f5",
surfaceVariant: "#3f474a",
surfaceVariantText: "#c2c9cb",
surfaceTint: "#4dd0e1",
background: "#0f1617",
backgroundText: "#e8f4f5",
outline: "#8c9194",
surfaceContainer: "#1a1f20",
surfaceContainerHigh: "#252b2c"
},
pink: {
name: "Pink",
primary: "#e91e63",
primaryText: "#ffffff",
primaryContainer: "#c2185b",
secondary: "#f8bbd9",
surface: "#1a1014",
surfaceText: "#f3e8ee",
surfaceVariant: "#483f45",
surfaceVariantText: "#c9c2c7",
surfaceTint: "#f8bbd9",
background: "#1a1014",
backgroundText: "#f3e8ee",
outline: "#938a90",
surfaceContainer: "#1f1b1e",
surfaceContainerHigh: "#2a2428"
},
amber: {
name: "Amber",
primary: "#ffc107",
primaryText: "#000000",
primaryContainer: "#ff8f00",
secondary: "#ffd54f",
surface: "#1a1710",
surfaceText: "#f3f0e8",
surfaceVariant: "#49453a",
surfaceVariantText: "#cac5b8",
surfaceTint: "#ffd54f",
background: "#1a1710",
backgroundText: "#f3f0e8",
outline: "#949084",
surfaceContainer: "#1f1e17",
surfaceContainerHigh: "#2a281f"
},
coral: {
name: "Coral",
primary: "#ffb4ab",
primaryText: "#5f1412",
primaryContainer: "#8c1d18",
secondary: "#f9dedc",
surface: "#1a1110",
surfaceText: "#f1e8e7",
surfaceVariant: "#4a4142",
surfaceVariantText: "#cdc2c1",
surfaceTint: "#ffb4ab",
background: "#1a1110",
backgroundText: "#f1e8e7",
outline: "#968b8a",
surfaceContainer: "#201a19",
surfaceContainerHigh: "#2b2221"
}
},
LIGHT: {
blue: {
name: "Blue Light",
primary: "#1976d2",
primaryText: "#ffffff",
primaryContainer: "#e3f2fd",
secondary: "#42a5f5",
surface: "#fefefe",
surfaceText: "#1a1c1e",
surfaceVariant: "#e7e0ec",
surfaceVariantText: "#49454f",
surfaceTint: "#1976d2",
background: "#fefefe",
backgroundText: "#1a1c1e",
outline: "#79747e",
surfaceContainer: "#f3f3f3",
surfaceContainerHigh: "#ececec"
},
deepBlue: {
name: "Deep Blue Light",
primary: "#0061a4",
primaryText: "#ffffff",
primaryContainer: "#cfe5ff",
secondary: "#1976d2",
surface: "#fefefe",
surfaceText: "#1a1c1e",
surfaceVariant: "#e7e0ec",
surfaceVariantText: "#49454f",
surfaceTint: "#0061a4",
background: "#fefefe",
backgroundText: "#1a1c1e",
outline: "#79747e",
surfaceContainer: "#f3f3f3",
surfaceContainerHigh: "#ececec"
},
purple: {
name: "Purple Light",
primary: "#6750A4",
primaryText: "#ffffff",
primaryContainer: "#EADDFF",
secondary: "#625B71",
surface: "#FFFBFE",
surfaceText: "#1C1B1F",
surfaceVariant: "#E7E0EC",
surfaceVariantText: "#49454F",
surfaceTint: "#6750A4",
background: "#FFFBFE",
backgroundText: "#1C1B1F",
outline: "#79747E",
surfaceContainer: "#F3EDF7",
surfaceContainerHigh: "#ECE6F0"
},
green: {
name: "Green Light",
primary: "#2e7d32",
primaryText: "#ffffff",
primaryContainer: "#e8f5e8",
secondary: "#4caf50",
surface: "#fefefe",
surfaceText: "#1a1c1e",
surfaceVariant: "#e7e0ec",
surfaceVariantText: "#49454f",
surfaceTint: "#2e7d32",
background: "#fefefe",
backgroundText: "#1a1c1e",
outline: "#79747e",
surfaceContainer: "#f3f3f3",
surfaceContainerHigh: "#ececec"
},
orange: {
name: "Orange Light",
primary: "#e65100",
primaryText: "#ffffff",
primaryContainer: "#ffecb3",
secondary: "#ff9800",
surface: "#fefefe",
surfaceText: "#1a1c1e",
surfaceVariant: "#e7e0ec",
surfaceVariantText: "#49454f",
surfaceTint: "#e65100",
background: "#fefefe",
backgroundText: "#1a1c1e",
outline: "#79747e",
surfaceContainer: "#f3f3f3",
surfaceContainerHigh: "#ececec"
},
red: {
name: "Red Light",
primary: "#d32f2f",
primaryText: "#ffffff",
primaryContainer: "#ffebee",
secondary: "#f44336",
surface: "#fefefe",
surfaceText: "#1a1c1e",
surfaceVariant: "#e7e0ec",
surfaceVariantText: "#49454f",
surfaceTint: "#d32f2f",
background: "#fefefe",
backgroundText: "#1a1c1e",
outline: "#79747e",
surfaceContainer: "#f3f3f3",
surfaceContainerHigh: "#ececec"
},
cyan: {
name: "Cyan Light",
primary: "#0097a7",
primaryText: "#ffffff",
primaryContainer: "#e0f2f1",
secondary: "#00bcd4",
surface: "#fefefe",
surfaceText: "#1a1c1e",
surfaceVariant: "#e7e0ec",
surfaceVariantText: "#49454f",
surfaceTint: "#0097a7",
background: "#fefefe",
backgroundText: "#1a1c1e",
outline: "#79747e",
surfaceContainer: "#f3f3f3",
surfaceContainerHigh: "#ececec"
},
pink: {
name: "Pink Light",
primary: "#c2185b",
primaryText: "#ffffff",
primaryContainer: "#fce4ec",
secondary: "#e91e63",
surface: "#fefefe",
surfaceText: "#1a1c1e",
surfaceVariant: "#e7e0ec",
surfaceVariantText: "#49454f",
surfaceTint: "#c2185b",
background: "#fefefe",
backgroundText: "#1a1c1e",
outline: "#79747e",
surfaceContainer: "#f3f3f3",
surfaceContainerHigh: "#ececec"
},
amber: {
name: "Amber Light",
primary: "#ff8f00",
primaryText: "#000000",
primaryContainer: "#fff8e1",
secondary: "#ffc107",
surface: "#fefefe",
surfaceText: "#1a1c1e",
surfaceVariant: "#e7e0ec",
surfaceVariantText: "#49454f",
surfaceTint: "#ff8f00",
background: "#fefefe",
backgroundText: "#1a1c1e",
outline: "#79747e",
surfaceContainer: "#f3f3f3",
surfaceContainerHigh: "#ececec"
},
coral: {
name: "Coral Light",
primary: "#8c1d18",
primaryText: "#ffffff",
primaryContainer: "#ffdad6",
secondary: "#ff5449",
surface: "#fefefe",
surfaceText: "#1a1c1e",
surfaceVariant: "#e7e0ec",
surfaceVariantText: "#49454f",
surfaceTint: "#8c1d18",
background: "#fefefe",
backgroundText: "#1a1c1e",
outline: "#79747e",
surfaceContainer: "#f3f3f3",
surfaceContainerHigh: "#ececec"
}
}
}
const ThemeNames = {
BLUE: "blue",
DEEP_BLUE: "deepBlue",
PURPLE: "purple",
GREEN: "green",
ORANGE: "orange",
RED: "red",
CYAN: "cyan",
PINK: "pink",
AMBER: "amber",
CORAL: "coral",
DYNAMIC: "dynamic"
}
function isStockTheme(themeName) {
return Object.keys(StockThemes.DARK).includes(themeName)
}
function getAvailableThemes(isLight = false) {
return isLight ? StockThemes.LIGHT : StockThemes.DARK
}
function getThemeByName(themeName, isLight = false) {
const themes = getAvailableThemes(isLight)
return themes[themeName] || themes.blue
}
function getAllThemeNames() {
return Object.keys(StockThemes.DARK)
}

File diff suppressed because it is too large Load Diff

View File

@@ -625,9 +625,9 @@ Item {
enabled: ToastService.wallpaperErrorStatus !== "matugen_missing"
onToggled: toggled => {
if (toggled)
Theme.switchTheme(10, true)
Theme.switchTheme(Theme.dynamic)
else
Theme.switchTheme(0)
Theme.switchTheme("blue")
}
}
}

View File

@@ -138,7 +138,7 @@ Item {
spacing: Theme.spacingS
StyledText {
text: "Current Theme: " + (Theme.isDynamicTheme ? "Auto" : (Theme.currentThemeIndex < Theme.themes.length ? Theme.themes[Theme.currentThemeIndex].name : "Blue"))
text: "Current Theme: " + (Theme.isDynamicTheme ? "Dynamic" : Theme.getThemeColors(Theme.currentThemeName).name)
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
@@ -150,9 +150,19 @@ Item {
if (Theme.isDynamicTheme)
return "Wallpaper-based dynamic colors"
var descriptions = ["Material blue inspired by modern interfaces", "Deep blue inspired by material 3", "Rich purple tones for BB elegance", "Natural green for productivity", "Energetic orange for creativity", "Bold red for impact", "Cool cyan for tranquility", "Vibrant pink for expression", "Warm amber for comfort", "Soft coral for gentle warmth"]
return descriptions[Theme.currentThemeIndex]
|| "Select a theme"
var descriptions = {
"blue": "Material blue inspired by modern interfaces",
"deepBlue": "Deep blue inspired by material 3",
"purple": "Rich purple tones for elegance",
"green": "Natural green for productivity",
"orange": "Energetic orange for creativity",
"red": "Bold red for impact",
"cyan": "Cool cyan for tranquility",
"pink": "Vibrant pink for expression",
"amber": "Warm amber for comfort",
"coral": "Soft coral for gentle warmth"
}
return descriptions[Theme.currentThemeName] || "Select a theme"
}
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
@@ -172,17 +182,18 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter
Repeater {
model: 5
model: Theme.availableThemeNames.slice(0, 5)
Rectangle {
property string themeName: modelData
width: 32
height: 32
radius: 16
color: Theme.themes[index].primary
color: Theme.getThemeColors(themeName).primary
border.color: Theme.outline
border.width: (Theme.currentThemeIndex === index
border.width: (Theme.currentThemeName === themeName
&& !Theme.isDynamicTheme) ? 2 : 1
scale: (Theme.currentThemeIndex === index
scale: (Theme.currentThemeName === themeName
&& !Theme.isDynamicTheme) ? 1.1 : 1
Rectangle {
@@ -200,7 +211,7 @@ Item {
StyledText {
id: nameText
text: Theme.themes[index].name
text: Theme.getThemeColors(themeName).name
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
anchors.centerIn: parent
@@ -214,7 +225,7 @@ Item {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
Theme.switchTheme(index, false)
Theme.switchTheme(themeName, false)
}
}
@@ -240,19 +251,19 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter
Repeater {
model: 5
model: Theme.availableThemeNames.slice(5, 10)
Rectangle {
property int themeIndex: index + 5
property string themeName: modelData
width: 32
height: 32
radius: 16
color: themeIndex < Theme.themes.length ? Theme.themes[themeIndex].primary : "transparent"
color: Theme.getThemeColors(themeName).primary
border.color: Theme.outline
border.width: Theme.currentThemeIndex === themeIndex ? 2 : 1
visible: themeIndex < Theme.themes.length
scale: Theme.currentThemeIndex === themeIndex ? 1.1 : 1
border.width: Theme.currentThemeName === themeName ? 2 : 1
visible: true
scale: Theme.currentThemeName === themeName ? 1.1 : 1
Rectangle {
width: nameText2.contentWidth + Theme.spacingS * 2
@@ -265,12 +276,11 @@ Item {
anchors.bottomMargin: Theme.spacingXS
anchors.horizontalCenter: parent.horizontalCenter
visible: mouseArea2.containsMouse
&& themeIndex < Theme.themes.length
StyledText {
id: nameText2
text: themeIndex < Theme.themes.length ? Theme.themes[themeIndex].name : ""
text: Theme.getThemeColors(themeName).name
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
anchors.centerIn: parent
@@ -284,8 +294,7 @@ Item {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (themeIndex < Theme.themes.length)
Theme.switchTheme(themeIndex)
Theme.switchTheme(themeName)
}
}
@@ -404,7 +413,7 @@ Item {
ToastService.showError(
"Wallpaper processing failed - check wallpaper path")
else
Theme.switchTheme(10, true)
Theme.switchTheme(Theme.dynamic)
}
}
@@ -691,7 +700,7 @@ Item {
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
Theme.outline.b, 0.2)
border.width: 1
visible: Theme.isDynamicTheme && Colors.matugenAvailable
visible: Theme.isDynamicTheme && Theme.matugenAvailable
Column {
id: systemThemingSection
@@ -723,9 +732,9 @@ Item {
DankToggle {
width: parent.width
text: "Theme GTK Applications"
description: Colors.gtkThemingEnabled ? "File managers, text editors, and system dialogs will match your theme" : "GTK theming not available (install gsettings)"
enabled: Colors.gtkThemingEnabled
checked: Colors.gtkThemingEnabled
description: Theme.gtkThemingEnabled ? "File managers, text editors, and system dialogs will match your theme" : "GTK theming not available (install gsettings)"
enabled: Theme.gtkThemingEnabled
checked: Theme.gtkThemingEnabled
&& SettingsData.gtkThemingEnabled
onToggled: function (checked) {
SettingsData.setGtkThemingEnabled(checked)
@@ -735,9 +744,9 @@ Item {
DankToggle {
width: parent.width
text: "Theme Qt Applications"
description: Colors.qtThemingEnabled ? "Qt applications will match your theme colors" : "Qt theming not available (install qt5ct or qt6ct)"
enabled: Colors.qtThemingEnabled
checked: Colors.qtThemingEnabled
description: Theme.qtThemingEnabled ? "Qt applications will match your theme colors" : "Qt theming not available (install qt5ct or qt6ct)"
enabled: Theme.qtThemingEnabled
checked: Theme.qtThemingEnabled
&& SettingsData.qtThemingEnabled
onToggled: function (checked) {
SettingsData.setQtThemingEnabled(checked)