diff --git a/Assets/ColorSchemes/Nord.json b/Assets/ColorSchemes/Nord.json new file mode 100644 index 0000000..a0dc572 --- /dev/null +++ b/Assets/ColorSchemes/Nord.json @@ -0,0 +1,19 @@ +{ + "mPrimary": "#8fbcbb", + "mOnPrimary": "#2e3440", + "mSecondary": "#88c0d0", + "mOnSecondary": "#2e3440", + "mTertiary": "#5e81ac", + "mOnTertiary": "#2e3440", + + "mError": "#bf616a", + "mOnError": "#2e3440", + + "mSurface": "#2e3440", + "mOnSurface": "#d8dee9", + "mSurfaceVariant": "#3b4252", + "mOnSurfaceVariant": "#e5e9f0", + "mOutline": "#434c5e", + "mOutlineVariant": "#4c566a", + "mShadow": "#2e3440" +} diff --git a/Assets/ColorSchemes/Rosepine.json b/Assets/ColorSchemes/Rosepine.json new file mode 100644 index 0000000..cd7a688 --- /dev/null +++ b/Assets/ColorSchemes/Rosepine.json @@ -0,0 +1,19 @@ +{ + "mPrimary": "#ebbcba", + "mOnPrimary": "#191724", + "mSecondary": "#31748f", + "mOnSecondary": "#e0def4", + "mTertiary": "#9ccfd8", + "mOnTertiary": "#191724", + + "mError": "#eb6f92", + "mOnError": "#191724", + + "mSurface": "#191724", + "mOnSurface": "#e0def4", + "mSurfaceVariant": "#26233a", + "mOnSurfaceVariant": "#908caa", + "mOutline": "#44415a", + "mOutlineVariant": "#514e6c", + "mShadow": "#191724" +} diff --git a/Assets/ColorSchemes/rosepine.json b/Assets/ColorSchemes/rosepine.json deleted file mode 100644 index 1b00997..0000000 --- a/Assets/ColorSchemes/rosepine.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "backgroundPrimary": "#191724", - "backgroundSecondary": "#1f1d2e", - "backgroundTertiary": "#26233a", - - "surface": "#1b1927", - "surfaceVariant": "#262337", - - "textPrimary": "#e0def4", - "textSecondary": "#908caa", - "textDisabled": "#6e6a86", - - "accentPrimary": "#ebbcba", - "accentSecondary": "#31748f", - "accentTertiary": "#9ccfd8", - - "error": "#eb6f92", - "warning": "#f6c177", - - "hover": "#c4a7e7", - "onAccent": "#191724", - "outline": "#44415a", - - "shadow": "#191724", - "overlay": "#191724" -} \ No newline at end of file diff --git a/Modules/Settings/Tabs/ColorSchemeTab.qml b/Modules/Settings/Tabs/ColorSchemeTab.qml index 72ba676..dcdf589 100644 --- a/Modules/Settings/Tabs/ColorSchemeTab.qml +++ b/Modules/Settings/Tabs/ColorSchemeTab.qml @@ -39,6 +39,19 @@ ColumnLayout { color: Colors.mOnSurface } + // Use Wallpaper Colors + NToggle { + label: "Use Wallpaper Colors" + description: "Automatically generate colors from you active wallpaper (requires Matugen)" + value: Settings.data.colorSchemes.useWallpaperColors + onToggled: function (newValue) { + Settings.data.colorSchemes.useWallpaperColors = newValue + if (Settings.data.colorSchemes.useWallpaperColors) { + ColorSchemes.changedWallpaper() + } + } + } + ButtonGroup { id: schemesGroup } @@ -48,9 +61,18 @@ ColumnLayout { NRadioButton { property string schemePath: modelData ButtonGroup.group: schemesGroup - //checked: Audio.sink?.id === modelData.id - //onClicked: Audio.setAudioSink(modelData) - text: schemePath + text: { + // Remove json and the full path + var chunks = schemePath.replace(".json", "").split("/") + return chunks[chunks.length - 1] + } + checked: Settings.data.colorSchemes.predefinedScheme == schemePath + onClicked: { + // Disable useWallpaperColors when picking a predefined color scheme + Settings.data.colorSchemes.useWallpaperColors = false + Settings.data.colorSchemes.predefinedScheme = schemePath + ColorSchemes.applyScheme(schemePath) + } } } } diff --git a/Modules/Settings/Tabs/WallpaperTab.qml b/Modules/Settings/Tabs/WallpaperTab.qml index 41288d9..50e6377 100644 --- a/Modules/Settings/Tabs/WallpaperTab.qml +++ b/Modules/Settings/Tabs/WallpaperTab.qml @@ -92,16 +92,6 @@ ColumnLayout { } } - // Use Wallpaper Theme - NToggle { - label: "Use Wallpaper Colors" - description: "Automatically adjust UI colors based on wallpaper using Matugen" - value: Settings.data.wallpaper.generateColors - onToggled: function (newValue) { - Settings.data.wallpaper.generateColors = newValue - } - } - // Interval ColumnLayout { RowLayout { diff --git a/Services/ColorSchemes.qml b/Services/ColorSchemes.qml index 2075510..eddd275 100644 --- a/Services/ColorSchemes.qml +++ b/Services/ColorSchemes.qml @@ -15,6 +15,8 @@ Singleton { property var schemes: [] property bool scanning: false + property string schemesDirectory: Quickshell.shellDir + "/Assets/ColorSchemes" + property string colorsJsonFilePath: Settings.configDir + "colors.json" function loadColorSchemes() { console.log("[ColorSchemes] Load ColorSchemes") @@ -22,7 +24,20 @@ Singleton { schemes = [] // Unsetting, then setting the folder will re-trigger the parsing! folderModel.folder = "" - folderModel.folder = "file://" + Quickshell.shellDir + "/Assets/ColorSchemes" + folderModel.folder = "file://" + schemesDirectory + } + + function applyScheme(filePath) { + Quickshell.execDetached(["cp", filePath, colorsJsonFilePath]) + } + + function changedWallpaper() { + if (Settings.data.colorSchemes.useWallpaperColors) { + console.log("[ColorSchemes] Starting color generation process") + generateColorsProcess.running = true + // Invalidate potential predefined scheme + Settings.data.colorSchemes.predefinedScheme = "" + } } FolderListModel { @@ -34,12 +49,30 @@ Singleton { if (status === FolderListModel.Ready) { var files = [] for (var i = 0; i < count; i++) { - var filepath = folderModel.folder + "/" + get(i, "fileName") + var filepath = schemesDirectory + "/" + get(i, "fileName") files.push(filepath) } schemes = files scanning = false - console.log(schemes) + } + } + } + + Process { + id: generateColorsProcess + command: ["matugen", "image", Wallpapers.currentWallpaper, "--config", Quickshell.shellDir + "/Assets/Matugen/matugen.toml"] + workingDirectory: Quickshell.shellDir + running: false + stdout: StdioCollector { + onStreamFinished: { + console.log("[ColorSchemes] Generated colors from wallpaper") + } + } + stderr: StdioCollector { + onStreamFinished: { + if (this.text !== "") { + console.error(this.text) + } } } } diff --git a/Services/Colors.qml b/Services/Colors.qml index d77af2d..b866ff1 100644 --- a/Services/Colors.qml +++ b/Services/Colors.qml @@ -13,29 +13,25 @@ Singleton { id: root // --- Key Colors: These are the main accent colors that define your app's style - property color mPrimary: useCustom ? customColors.mPrimary : defaultColors.mPrimary - property color mOnPrimary: useCustom ? customColors.mOnPrimary : defaultColors.mOnPrimary - property color mSecondary: useCustom ? customColors.mSecondary : defaultColors.mSecondary - property color mOnSecondary: useCustom ? customColors.mOnSecondary : defaultColors.mOnSecondary - property color mTertiary: useCustom ? customColors.mTertiary : defaultColors.mTertiary - property color mOnTertiary: useCustom ? customColors.mOnTertiary : defaultColors.mOnTertiary + property color mPrimary: customColors.mPrimary + property color mOnPrimary: customColors.mOnPrimary + property color mSecondary: customColors.mSecondary + property color mOnSecondary: customColors.mOnSecondary + property color mTertiary: customColors.mTertiary + property color mOnTertiary: customColors.mOnTertiary // --- Utility Colors: These colors serve specific, universal purposes like indicating errors - property color mError: useCustom ? customColors.mError : defaultColors.mError - property color mOnError: useCustom ? customColors.mOnError : defaultColors.mOnError + property color mError: customColors.mError + property color mOnError: customColors.mOnError // --- Surface and Variant Colors: These provide additional options for surfaces and their contents, creating visual hierarchy - property color mSurface: useCustom ? customColors.mSurface : defaultColors.mSurface - property color mOnSurface: useCustom ? customColors.mOnSurface : defaultColors.mOnSurface - property color mSurfaceVariant: useCustom ? customColors.mSurfaceVariant : defaultColors.mSurfaceVariant - property color mOnSurfaceVariant: useCustom ? customColors.mOnSurfaceVariant : defaultColors.mOnSurfaceVariant - property color mOutline: useCustom ? customColors.mOutline : defaultColors.mOutline - property color mOutlineVariant: useCustom ? customColors.mOutlineVariant : defaultColors.mOutlineVariant - property color mShadow: useCustom ? customColors.mShadow : defaultColors.mShadow - - // ----------- - // Check if we should use custom colors - property bool useCustom: (Settings.data.wallpaper.generateColors && customColorsFile.loaded) + property color mSurface: customColors.mSurface + property color mOnSurface: customColors.mOnSurface + property color mSurfaceVariant: customColors.mSurfaceVariant + property color mOnSurfaceVariant: customColors.mOnSurfaceVariant + property color mOutline: customColors.mOutline + property color mOutlineVariant: customColors.mOutlineVariant + property color mShadow: customColors.mShadow // ----------- function applyOpacity(color, opacity) { @@ -98,11 +94,11 @@ Singleton { path: Settings.configDir + "colors.json" watchChanges: true onFileChanged: { - console.log("[Colors] reloading colors file from disk") + console.log("[Colors] Reloading colors from disk") reload() } onAdapterUpdated: { - console.log("[Colors] writing colors to disk, primary color:", mPrimary) + console.log("[Colors] Writing colors to disk") writeAdapter() } onLoadFailed: function (error) { diff --git a/Services/Settings.qml b/Services/Settings.qml index c2f77af..d982699 100644 --- a/Services/Settings.qml +++ b/Services/Settings.qml @@ -119,7 +119,6 @@ Singleton { property string current: "" property bool isRandom: false property int randomInterval: 300 - property bool generateColors: false property JsonObject swww onDirectoryChanged: Wallpapers.loadWallpapers() @@ -190,6 +189,13 @@ Singleton { property list monitorBrightness: [] property int brightnessStep: 5 } + + property JsonObject colorSchemes + + colorSchemes: JsonObject { + property bool useWallpaperColors: false + property string predefinedScheme: "" + } } } } diff --git a/Services/Wallpapers.qml b/Services/Wallpapers.qml index 301ab50..448df02 100644 --- a/Services/Wallpapers.qml +++ b/Services/Wallpapers.qml @@ -39,7 +39,7 @@ Singleton { } function setCurrentWallpaper(path, isInitial) { - // Only generate colors if the wallpaper actually changed + // Only regenerate colors if the wallpaper actually changed var wallpaperChanged = currentWallpaper !== path currentWallpaper = path @@ -64,9 +64,9 @@ Singleton { randomWallpaperTimer.restart() } - // Only generate colors if the wallpaper actually changed + // Only notify ColorSchemes service if the wallpaper actually changed if (wallpaperChanged) { - generateColors() + ColorSchemes.changedWallpaper() } } @@ -95,14 +95,6 @@ Singleton { } } - function generateColors() { - console.log("[Wallpapers] generateColors() called, generateColors setting:", Settings.data.wallpaper.generateColors) - if (Settings.data.wallpaper.generateColors) { - console.log("[Wallpapers] Starting color generation process") - generateThemeProcess.running = true - } - } - function startSWWWDaemon() { if (Settings.data.wallpaper.swww.enabled) { console.log("[SWWW] Requesting swww-daemon") @@ -160,25 +152,6 @@ Singleton { } } - Process { - id: generateThemeProcess - command: ["matugen", "image", currentWallpaper, "--config", Quickshell.shellDir + "/Assets/Matugen/matugen.toml"] - workingDirectory: Quickshell.shellDir - running: false - stdout: StdioCollector { - onStreamFinished: { - console.log("[Wallpapers] generated colors from image") - } - } - stderr: StdioCollector { - onStreamFinished: { - if (this.text !== "") { - console.error(this.text) - } - } - } - } - Process { id: startDaemonProcess command: ["swww-daemon", "--format", "xrgb"]