diff --git a/gui/main-kf5.qml b/gui/main-kf5.qml index a5a4cad..0c96d3f 100644 --- a/gui/main-kf5.qml +++ b/gui/main-kf5.qml @@ -48,31 +48,21 @@ ApplicationWindow { font.bold: true } - Label { - text: "Uses KDE Breeze color schemes" - opacity: 0.6 - wrapMode: Text.Wrap + ComboBox { + id: schemeCombo Layout.fillWidth: true - font.pixelSize: Qt.application.font.pixelSize * 0.9 - } - - ColumnLayout { - spacing: 8 - - RadioButton { - text: "Use system theme" - checked: theme.mode === "system" - onClicked: theme.mode = "system" + model: ["System"].concat(theme.availableSchemes) + currentIndex: { + if (theme.mode === "system") return 0 + var idx = theme.availableSchemes.indexOf(theme.mode) + return idx >= 0 ? idx + 1 : 0 } - RadioButton { - text: "Breeze Light" - checked: theme.mode === "light" - onClicked: theme.mode = "light" - } - RadioButton { - text: "Breeze Dark" - checked: theme.mode === "dark" - onClicked: theme.mode = "dark" + onActivated: { + if (currentIndex === 0) { + theme.mode = "system" + } else { + theme.mode = theme.availableSchemes[currentIndex - 1] + } } } diff --git a/gui/main.qml b/gui/main.qml index 3c683e8..ac602a7 100644 --- a/gui/main.qml +++ b/gui/main.qml @@ -51,34 +51,21 @@ ApplicationWindow { font.bold: true } - Label { - text: "Uses KDE Breeze color schemes from /usr/share/color-schemes/" - opacity: 0.6 - wrapMode: Text.Wrap + ComboBox { + id: schemeCombo Layout.fillWidth: true - font.pixelSize: Qt.application.font.pixelSize * 0.9 - } - - ColumnLayout { - spacing: 8 - - RadioButton { - id: systemRadio - text: "Use system theme" - checked: theme.mode === "system" - onClicked: theme.mode = "system" + model: ["System"].concat(theme.availableSchemes) + currentIndex: { + if (theme.mode === "system") return 0 + let idx = theme.availableSchemes.indexOf(theme.mode) + return idx >= 0 ? idx + 1 : 0 } - RadioButton { - id: lightRadio - text: "Breeze Light" - checked: theme.mode === "light" - onClicked: theme.mode = "light" - } - RadioButton { - id: darkRadio - text: "Breeze Dark" - checked: theme.mode === "dark" - onClicked: theme.mode = "dark" + onActivated: { + if (currentIndex === 0) { + theme.mode = "system" + } else { + theme.mode = theme.availableSchemes[currentIndex - 1] + } } } diff --git a/gui/thememanager.cpp b/gui/thememanager.cpp index bffaa7d..640cfd1 100644 --- a/gui/thememanager.cpp +++ b/gui/thememanager.cpp @@ -40,13 +40,10 @@ QString ThemeManager::mode() const void ThemeManager::setMode(const QString &mode) { - QString m = mode.toLower(); - if (m != "system" && m != "light" && m != "dark") - return; - if (m == m_mode) + if (mode == m_mode) return; - m_mode = m; + m_mode = mode; saveSettings(); applyPalette(); emit modeChanged(); @@ -56,11 +53,16 @@ void ThemeManager::setMode(const QString &mode) QStringList ThemeManager::availableSchemes() const { QStringList schemes; - QDir dir(SCHEMES_DIR); - const auto entries = dir.entryInfoList({"*.colors"}, QDir::Files, QDir::Name); - for (const auto &entry : entries) { - schemes << entry.baseName(); + QStringList dirs = schemeDirs(); + for (const QString &dirPath : dirs) { + QDir dir(dirPath); + const auto entries = dir.entryInfoList({"*.colors"}, QDir::Files, QDir::Name); + for (const auto &entry : entries) { + if (!schemes.contains(entry.baseName())) + schemes << entry.baseName(); + } } + schemes.sort(Qt::CaseInsensitive); return schemes; } @@ -76,12 +78,12 @@ bool ThemeManager::isDark() const void ThemeManager::applyPalette() { QString path; - if (m_mode == "light") { - path = schemePath("BreezeLight"); - } else if (m_mode == "dark") { - path = schemePath("BreezeDark"); - } else { + if (m_mode == "system") { path = systemSchemePath(); + } else { + // Mode is a scheme name (e.g. "BreezeLight", "BreezeDark", + // "CatppuccinMochaMauve", etc.) + path = schemePath(m_mode); } if (path.isEmpty() || !QFile::exists(path)) { @@ -279,9 +281,27 @@ QString ThemeManager::systemSchemePath() const QString ThemeManager::schemePath(const QString &name) const { + for (const QString &dir : schemeDirs()) { + QString path = QString("%1/%2.colors").arg(dir, name); + if (QFile::exists(path)) + return path; + } + // Fallback to system dir even if file doesn't exist return QString("%1/%2.colors").arg(SCHEMES_DIR, name); } +QStringList ThemeManager::schemeDirs() const +{ + QStringList dirs; + // User dir first (higher priority) + QString userDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + + "/color-schemes"; + if (QDir(userDir).exists()) + dirs << userDir; + dirs << SCHEMES_DIR; + return dirs; +} + // --- Font methods --- QString ThemeManager::fontFamily() const @@ -405,9 +425,7 @@ void ThemeManager::loadSettings() if (QFile::exists(configFile)) { QSettings settings(configFile, QSettings::IniFormat); - m_mode = settings.value("General/mode", "system").toString().toLower(); - if (m_mode != "system" && m_mode != "light" && m_mode != "dark") - m_mode = "system"; + m_mode = settings.value("General/mode", "system").toString(); m_fontFamily = settings.value("Font/family", "").toString(); m_fontSize = settings.value("Font/size", 0).toInt(); diff --git a/gui/thememanager.h b/gui/thememanager.h index 1ba69c4..1053b50 100644 --- a/gui/thememanager.h +++ b/gui/thememanager.h @@ -107,6 +107,7 @@ private: QColor parseColor(const QVariant &value) const; QString systemSchemePath() const; QString schemePath(const QString &name) const; + QStringList schemeDirs() const; void loadSettings(); void saveSettings();