From 63eeb40c643ebe9283c41d48d1b02dd745c120a0 Mon Sep 17 00:00:00 2001 From: quadbyte Date: Wed, 6 Aug 2025 20:03:41 -0400 Subject: [PATCH] Settings: better horizontal dividers --- Widgets/SettingsWindow/SettingsWindow.qml | 600 +++++++++--------- Widgets/SettingsWindow/Tabs/About.qml | 637 +++++++++++--------- Widgets/SettingsWindow/Tabs/General.qml | 62 +- Widgets/SettingsWindow/Tabs/Network.qml | 21 +- Widgets/SettingsWindow/Tabs/TimeWeather.qml | 55 +- Widgets/SettingsWindow/Tabs/Wallpaper.qml | 461 +++++++------- 6 files changed, 980 insertions(+), 856 deletions(-) diff --git a/Widgets/SettingsWindow/SettingsWindow.qml b/Widgets/SettingsWindow/SettingsWindow.qml index 156d5e0..b7d9cce 100644 --- a/Widgets/SettingsWindow/SettingsWindow.qml +++ b/Widgets/SettingsWindow/SettingsWindow.qml @@ -1,156 +1,163 @@ -import Quickshell -import Quickshell.Wayland import QtQuick import QtQuick.Controls -import QtQuick.Layouts import QtQuick.Effects +import QtQuick.Layouts +import Quickshell +import Quickshell.Wayland +import qs.Components import qs.Settings import qs.Widgets.SettingsWindow.Tabs import qs.Widgets.SettingsWindow.Tabs.Components -import qs.Components PanelWithOverlay { id: panelMain - - property int activeTabIndex: 0 - WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand + property int activeTabIndex: 0 // Function to show wallpaper selector function showWallpaperSelector() { - if (wallpaperSelector) { + if (wallpaperSelector) wallpaperSelector.show(); - } + } // Function to show settings window function showSettings() { show(); } - - - - - - // Handle activeTabIndex changes - onActiveTabIndexChanged: { - if (activeTabIndex >= 0 && activeTabIndex <= 8) { - loadComponentForTab(activeTabIndex); - } - } // Function to load component for a specific tab function loadComponentForTab(tabIndex) { const componentMap = { - 0: generalSettings, - 1: barSettings, - 2: timeWeatherSettings, - 3: recordingSettings, - 4: networkSettings, - 5: displaySettings, - 6: wallpaperSettings, - 7: miscSettings, - 8: aboutSettings + "0": generalSettings, + "1": barSettings, + "2": timeWeatherSettings, + "3": recordingSettings, + "4": networkSettings, + "5": displaySettings, + "6": wallpaperSettings, + "7": miscSettings, + "8": aboutSettings }; - - const tabNames = [ - "General", - "Bar", - "Time & Weather", - "Screen Recorder", - "Network", - "Display", - "Wallpaper", - "Misc", - "About" - ]; - + const tabNames = ["General", "Bar", "Time & Weather", "Screen Recorder", "Network", "Display", "Wallpaper", "Misc", "About"]; if (componentMap[tabIndex]) { settingsLoader.sourceComponent = componentMap[tabIndex]; - if (tabName) { + if (tabName) tabName.text = tabNames[tabIndex]; - } - } } + WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand + // Handle activeTabIndex changes + onActiveTabIndexChanged: { + if (activeTabIndex >= 0 && activeTabIndex <= 8) + loadComponentForTab(activeTabIndex); + + } // Add safety checks for component loading Component.onCompleted: { // Ensure we start with a valid tab - if (activeTabIndex < 0 || activeTabIndex > 8) { + if (activeTabIndex < 0 || activeTabIndex > 8) activeTabIndex = 0; - } - } + } // Cleanup when window is hidden onVisibleChanged: { if (!visible) { // Reset to default tab when hiding to prevent state issues activeTabIndex = 0; - if (tabName) { + if (tabName) tabName.text = "General"; - } + } } Component { id: generalSettings - General {} + + General { + } + } Component { id: barSettings - Bar {} + + Bar { + } + } Component { id: timeWeatherSettings - TimeWeather {} + + TimeWeather { + } + } Component { id: recordingSettings - Recording {} + + Recording { + } + } Component { id: networkSettings - Network {} + + Network { + } + } Component { id: miscSettings - Misc {} + + Misc { + } + } Component { id: aboutSettings - About {} + + About { + } + } Component { id: displaySettings - Display {} + + Display { + } + } Component { id: wallpaperSettings - Wallpaper {} + + Wallpaper { + } + } Rectangle { id: settingsWindowRect + implicitWidth: Quickshell.screens.length > 0 ? Quickshell.screens[0].width / 2 : 600 implicitHeight: Quickshell.screens.length > 0 ? Quickshell.screens[0].height / 2 : 400 visible: parent.visible color: "transparent" - // Center the settings window on screen anchors.centerIn: parent Rectangle { id: background + color: Theme.backgroundPrimary anchors.fill: parent radius: 20 @@ -167,11 +174,16 @@ PanelWithOverlay { shadowVerticalOffset: 2 shadowBlur: 12 } + } Rectangle { id: settings + color: Theme.backgroundPrimary + topRightRadius: 20 + bottomRightRadius: 20 + anchors { left: tabs.right top: parent.top @@ -179,151 +191,159 @@ PanelWithOverlay { right: parent.right margins: 12 } - topRightRadius: 20 - bottomRightRadius: 20 - Rectangle { - id: headerArea - anchors { - top: parent.top - left: parent.left - right: parent.right - margins: 16 - } - height: 48 - color: "transparent" + Rectangle { + id: headerArea - RowLayout { - anchors.fill: parent - spacing: 12 + height: 48 + color: "transparent" - Text { - id: tabName - text: wallpaperSelector.visible ? "Select Wallpaper" : (activeTabIndex === 0 ? "General" : - activeTabIndex === 1 ? "Bar" : - activeTabIndex === 2 ? "Time & Weather" : - activeTabIndex === 3 ? "Screen Recorder" : - activeTabIndex === 4 ? "Network" : - activeTabIndex === 5 ? "Display" : - activeTabIndex === 6 ? "Wallpaper" : - activeTabIndex === 7 ? "Misc" : - activeTabIndex === 8 ? "About" : "General") - font.pixelSize: 18 - font.bold: true - color: Theme.textPrimary - Layout.fillWidth: true + anchors { + top: parent.top + left: parent.left + right: parent.right + margins: 16 } - // Wallpaper Selection Button (only visible on Wallpaper tab) - Rectangle { - width: 160 - height: 32 - radius: 16 - color: wallpaperButtonArea.containsMouse ? Theme.accentPrimary : "transparent" - border.color: Theme.accentPrimary - border.width: 1 - visible: activeTabIndex === 6 // Wallpaper tab index - - Row { - anchors.centerIn: parent - spacing: 6 - - Text { - text: "image" - font.family: wallpaperButtonArea.containsMouse ? "Material Symbols Rounded" : "Material Symbols Outlined" - font.pixelSize: 16 - color: wallpaperButtonArea.containsMouse ? Theme.onAccent : Theme.accentPrimary - anchors.verticalCenter: parent.verticalCenter - } - - Text { - text: "Select Wallpaper" - font.pixelSize: 13 - font.bold: true - color: wallpaperButtonArea.containsMouse ? Theme.onAccent : Theme.accentPrimary - anchors.verticalCenter: parent.verticalCenter - } - } - - MouseArea { - id: wallpaperButtonArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - // Show the wallpaper selector - wallpaperSelector.show(); - } - } - } - - Rectangle { - width: 32 - height: 32 - radius: 16 - color: closeButtonArea.containsMouse ? Theme.accentPrimary : "transparent" - border.color: Theme.accentPrimary - border.width: 1 + RowLayout { + anchors.fill: parent + spacing: 12 Text { - anchors.centerIn: parent - text: "close" - font.family: closeButtonArea.containsMouse ? "Material Symbols Rounded" : "Material Symbols Outlined" + id: tabName + + text: wallpaperSelector.visible ? "Select Wallpaper" : (activeTabIndex === 0 ? "General" : activeTabIndex === 1 ? "Bar" : activeTabIndex === 2 ? "Time & Weather" : activeTabIndex === 3 ? "Screen Recorder" : activeTabIndex === 4 ? "Network" : activeTabIndex === 5 ? "Display" : activeTabIndex === 6 ? "Wallpaper" : activeTabIndex === 7 ? "Misc" : activeTabIndex === 8 ? "About" : "General") font.pixelSize: 18 - color: closeButtonArea.containsMouse ? Theme.onAccent : Theme.accentPrimary + font.bold: true + color: Theme.textPrimary + Layout.fillWidth: true } - MouseArea { - id: closeButtonArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: panelMain.dismiss() + // Wallpaper Selection Button (only visible on Wallpaper tab) + Rectangle { + width: 160 + height: 32 + radius: 16 + color: wallpaperButtonArea.containsMouse ? Theme.accentPrimary : "transparent" + border.color: Theme.accentPrimary + border.width: 1 + visible: activeTabIndex === 6 // Wallpaper tab index + + Row { + anchors.centerIn: parent + spacing: 6 + + Text { + text: "image" + font.family: wallpaperButtonArea.containsMouse ? "Material Symbols Rounded" : "Material Symbols Outlined" + font.pixelSize: 16 + color: wallpaperButtonArea.containsMouse ? Theme.onAccent : Theme.accentPrimary + anchors.verticalCenter: parent.verticalCenter + } + + Text { + text: "Select Wallpaper" + font.pixelSize: 13 + font.bold: true + color: wallpaperButtonArea.containsMouse ? Theme.onAccent : Theme.accentPrimary + anchors.verticalCenter: parent.verticalCenter + } + + } + + MouseArea { + id: wallpaperButtonArea + + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + // Show the wallpaper selector + wallpaperSelector.show(); + } + } + } + + Rectangle { + width: 32 + height: 32 + radius: 16 + color: closeButtonArea.containsMouse ? Theme.accentPrimary : "transparent" + border.color: Theme.accentPrimary + border.width: 1 + + Text { + anchors.centerIn: parent + text: "close" + font.family: closeButtonArea.containsMouse ? "Material Symbols Rounded" : "Material Symbols Outlined" + font.pixelSize: 18 + color: closeButtonArea.containsMouse ? Theme.onAccent : Theme.accentPrimary + } + + MouseArea { + id: closeButtonArea + + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: panelMain.dismiss() + } + + } + } + } + + Rectangle { + height: 1 + color: Theme.outline + opacity: 0.3 + + anchors { + top: headerArea.bottom + left: parent.left + right: parent.right + margins: 16 + } + + } + + Item { + id: settingsContainer + + anchors { + top: headerArea.bottom + left: parent.left + right: parent.right + bottom: parent.bottom + margins: 16 + topMargin: 32 + } + + // Simplified single loader approach + Loader { + id: settingsLoader + + anchors.fill: parent + sourceComponent: generalSettings + } + + // Wallpaper Selector Component + WallpaperSelector { + id: wallpaperSelector + + anchors.fill: parent + } + + } + } - Rectangle { - anchors { - top: headerArea.bottom - left: parent.left - right: parent.right - margins: 16 - } - height: 1 - color: Theme.outline - opacity: 0.3 - } - - Item { - id: settingsContainer - anchors { - top: headerArea.bottom - left: parent.left - right: parent.right - bottom: parent.bottom - margins: 16 - topMargin: 32 - } - - // Simplified single loader approach - Loader { - id: settingsLoader - anchors.fill: parent - sourceComponent: generalSettings - } - - // Wallpaper Selector Component - WallpaperSelector { - id: wallpaperSelector - anchors.fill: parent - } - } - } - Rectangle { id: tabs + color: Theme.surface width: Quickshell.screens.length > 0 ? Quickshell.screens[0].width / 9 : 100 height: settingsWindowRect.height @@ -332,101 +352,135 @@ PanelWithOverlay { border.color: Theme.outline border.width: 1 - Column { - width: parent.width - spacing: 0 - topPadding: 8 - bottomPadding: 8 + Column { + width: parent.width + spacing: 0 + topPadding: 8 + bottomPadding: 8 - Repeater { - id: repeater - model: [ - { icon: "tune", text: "General" }, - { icon: "space_dashboard", text: "Bar" }, - { icon: "schedule", text: "Time & Weather" }, - { icon: "photo_camera", text: "Screen Recorder" }, - { icon: "wifi", text: "Network" }, - { icon: "monitor", text: "Display" }, - { icon: "wallpaper", text: "Wallpaper" }, - { icon: "settings_suggest", text: "Misc" }, - { icon: "info", text: "About" } - ] + Repeater { + id: repeater - delegate: Rectangle { - width: tabs.width - height: 48 - color: "transparent" + model: [{ + "icon": "tune", + "text": "General" + }, { + "icon": "space_dashboard", + "text": "Bar" + }, { + "icon": "schedule", + "text": "Time & Weather" + }, { + "icon": "photo_camera", + "text": "Screen Recorder" + }, { + "icon": "wifi", + "text": "Network" + }, { + "icon": "monitor", + "text": "Display" + }, { + "icon": "wallpaper", + "text": "Wallpaper" + }, { + "icon": "settings_suggest", + "text": "Misc" + }, { + "icon": "info", + "text": "About" + }] - RowLayout { - anchors.fill: parent - spacing: 8 + delegate: Rectangle { + width: tabs.width + height: 48 + color: "transparent" + + RowLayout { + anchors.fill: parent + spacing: 8 + + Rectangle { + id: activeIndicator + + Layout.leftMargin: 8 + Layout.preferredWidth: 3 + Layout.preferredHeight: 24 + Layout.alignment: Qt.AlignVCenter + radius: 2 + color: Theme.accentPrimary + opacity: index === activeTabIndex ? 1 : 0 + + Behavior on opacity { + NumberAnimation { + duration: 200 + } + + } + + } + + Label { + id: icon + + text: modelData.icon + font.family: "Material Symbols Outlined" + font.pixelSize: 24 + color: index === activeTabIndex ? Theme.accentPrimary : Theme.textPrimary + opacity: index === activeTabIndex ? 1 : 0.8 + Layout.leftMargin: 20 + Layout.preferredWidth: 24 + Layout.preferredHeight: 24 + Layout.alignment: Qt.AlignVCenter + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + Label { + id: label + + text: modelData.text + font.pixelSize: 16 + color: index === activeTabIndex ? Theme.accentPrimary : (tabMouseArea.containsMouse ? Theme.accentPrimary : Theme.textSecondary) + font.weight: index === activeTabIndex ? Font.DemiBold : (tabMouseArea.containsMouse ? Font.DemiBold : Font.Normal) + Layout.fillWidth: true + Layout.preferredHeight: 24 + Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter + Layout.leftMargin: 4 + Layout.rightMargin: 16 + verticalAlignment: Text.AlignVCenter + } + + } + + MouseArea { + id: tabMouseArea + + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + activeTabIndex = index; + loadComponentForTab(index); + } + } Rectangle { - id: activeIndicator - Layout.leftMargin: 8 - Layout.preferredWidth: 3 - Layout.preferredHeight: 24 - Layout.alignment: Qt.AlignVCenter - radius: 2 - color: Theme.accentPrimary - opacity: index === activeTabIndex ? 1 : 0 - Behavior on opacity { NumberAnimation { duration: 200 } } + width: parent.width + height: 1 + color: Theme.outline + opacity: 0.6 + visible: index < (repeater.count - 1) + anchors.bottom: parent.bottom } - Label { - id: icon - text: modelData.icon - font.family: "Material Symbols Outlined" - font.pixelSize: 24 - color: index === activeTabIndex ? Theme.accentPrimary : Theme.textPrimary - opacity: index === activeTabIndex ? 1 : 0.8 - Layout.leftMargin: 20 - Layout.preferredWidth: 24 - Layout.preferredHeight: 24 - Layout.alignment: Qt.AlignVCenter - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - } - - Label { - id: label - text: modelData.text - font.pixelSize: 16 - color: index === activeTabIndex ? Theme.accentPrimary : - (tabMouseArea.containsMouse ? Theme.accentPrimary : Theme.textSecondary) - font.weight: index === activeTabIndex ? Font.DemiBold : - (tabMouseArea.containsMouse ? Font.DemiBold : Font.Normal) - Layout.fillWidth: true - Layout.preferredHeight: 24 - Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter - Layout.leftMargin: 4 - Layout.rightMargin: 16 - verticalAlignment: Text.AlignVCenter - } } - MouseArea { - id: tabMouseArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - activeTabIndex = index; - loadComponentForTab(index); - } - } - - Rectangle { - width: parent.width - height: 1 - color: Theme.outline - opacity: 0.6 - visible: index < (repeater.count - 1) - anchors.bottom: parent.bottom - } } + } + } + } - } -} \ No newline at end of file + +} diff --git a/Widgets/SettingsWindow/Tabs/About.qml b/Widgets/SettingsWindow/Tabs/About.qml index 14d3bc0..cdcdc11 100644 --- a/Widgets/SettingsWindow/Tabs/About.qml +++ b/Widgets/SettingsWindow/Tabs/About.qml @@ -1,11 +1,11 @@ import QtQuick import QtQuick.Controls -import QtQuick.Layouts import QtQuick.Effects +import QtQuick.Layouts import Quickshell import Quickshell.Io -import qs.Settings import qs.Components +import qs.Settings Item { id: root @@ -15,391 +15,430 @@ Item { property var contributors: [] property string githubDataPath: Settings.settingsDir + "github_data.json" + function loadFromFile() { + const now = Date.now(); + const data = githubData; + if (!data.timestamp || (now - data.timestamp > 3.6e+06)) { + console.log("[About] Cache expired or missing, fetching new data from GitHub..."); + fetchFromGitHub(); + return ; + } + console.log("[About] Loading cached GitHub data (age: " + Math.round((now - data.timestamp) / 60000) + " minutes)"); + if (data.version) + root.latestVersion = data.version; + + if (data.contributors) + root.contributors = data.contributors; + + } + + function fetchFromGitHub() { + versionProcess.running = true; + contributorsProcess.running = true; + } + + function saveData() { + githubData.timestamp = Date.now(); + Qt.callLater(() => { + githubDataFile.writeAdapter(); + }); + } + Process { id: currentVersionProcess + command: ["sh", "-c", "cd " + Quickshell.shellDir + " && git describe --tags --abbrev=0 2>/dev/null || echo 'Unknown'"] + Component.onCompleted: { + running = true; + } + stdout: StdioCollector { onStreamFinished: { - const version = text.trim() + const version = text.trim(); if (version && version !== "Unknown") { - root.currentVersion = version + root.currentVersion = version; } else { - - currentVersionProcess.command = ["sh", "-c", "cd " + Quickshell.shellDir + " && cat package.json 2>/dev/null | grep '\"version\"' | cut -d'\"' -f4 || echo 'Unknown'"] - currentVersionProcess.running = true + currentVersionProcess.command = ["sh", "-c", "cd " + Quickshell.shellDir + " && cat package.json 2>/dev/null | grep '\"version\"' | cut -d'\"' -f4 || echo 'Unknown'"]; + currentVersionProcess.running = true; } } } - Component.onCompleted: { - running = true - } + } FileView { id: githubDataFile + path: root.githubDataPath blockLoading: true printErrors: true watchChanges: true + onFileChanged: githubDataFile.reload() + onLoaded: loadFromFile() + onLoadFailed: function(error) { + console.log("GitHub data file doesn't exist yet, creating it..."); + githubData.version = "Unknown"; + githubData.contributors = []; + githubData.timestamp = 0; + githubDataFile.writeAdapter(); + fetchFromGitHub(); + } + Component.onCompleted: { + if (path) + reload(); + + } JsonAdapter { id: githubData + property string version: "Unknown" property var contributors: [] property double timestamp: 0 } - onFileChanged: githubDataFile.reload() - onLoaded: loadFromFile() - onLoadFailed: function(error) { - console.log("GitHub data file doesn't exist yet, creating it...") - githubData.version = "Unknown" - githubData.contributors = [] - githubData.timestamp = 0 - githubDataFile.writeAdapter() - fetchFromGitHub() - } - Component.onCompleted: if (path) reload() - } - - function loadFromFile() { - const now = Date.now() - const data = githubData - - if (!data.timestamp || (now - data.timestamp > 3600000)) { - console.log("[About] Cache expired or missing, fetching new data from GitHub...") - fetchFromGitHub() - return - } - console.log("[About] Loading cached GitHub data (age: " + Math.round((now - data.timestamp) / 60000) + " minutes)") - if (data.version) { - root.latestVersion = data.version - } - if (data.contributors) { - root.contributors = data.contributors - } } Process { id: versionProcess + command: ["curl", "-s", "https://api.github.com/repos/Ly-sec/Noctalia/releases/latest"] + stdout: StdioCollector { onStreamFinished: { try { - const data = JSON.parse(text) + const data = JSON.parse(text); if (data.tag_name) { - const version = data.tag_name - githubData.version = version - root.latestVersion = version - console.log("[About] Latest version fetched from GitHub:", version) + const version = data.tag_name; + githubData.version = version; + root.latestVersion = version; + console.log("[About] Latest version fetched from GitHub:", version); } else { - console.log("No tag_name in GitHub response") + console.log("No tag_name in GitHub response"); } - saveData() + saveData(); } catch (e) { - console.error("Failed to parse version:", e) + console.error("Failed to parse version:", e); } } } + } Process { id: contributorsProcess + command: ["curl", "-s", "https://api.github.com/repos/Ly-sec/Noctalia/contributors?per_page=100"] + stdout: StdioCollector { onStreamFinished: { try { - const data = JSON.parse(text) - githubData.contributors = data || [] - root.contributors = githubData.contributors - console.log("[About] Contributors data fetched from GitHub:", githubData.contributors.length, "contributors") - saveData() + const data = JSON.parse(text); + githubData.contributors = data || []; + root.contributors = githubData.contributors; + console.log("[About] Contributors data fetched from GitHub:", githubData.contributors.length, "contributors"); + saveData(); } catch (e) { - console.error("Failed to parse contributors:", e) - root.contributors = [] + console.error("Failed to parse contributors:", e); + root.contributors = []; } } } - } - function fetchFromGitHub() { - versionProcess.running = true - contributorsProcess.running = true - } - - function saveData() { - githubData.timestamp = Date.now() - Qt.callLater(() => { - githubDataFile.writeAdapter() - }) } Item { anchors.fill: parent - ColumnLayout { id: mainLayout + anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top spacing: 8 - Item { - Layout.fillWidth: true - Layout.preferredHeight: 32 - } - - Text { - text: "Noctalia" - font.pixelSize: 24 - font.bold: true - color: Theme.textPrimary - Layout.alignment: Qt.AlignCenter - } - - GridLayout { - Layout.alignment: Qt.AlignCenter - columns: 2 - rowSpacing: 4 - columnSpacing: 8 - - Text { - text: "Latest Version:" - font.pixelSize: 16 - color: Theme.textSecondary - Layout.alignment: Qt.AlignRight - } - - Text { - text: root.latestVersion - font.pixelSize: 16 - color: Theme.textPrimary - font.bold: true - } - - Text { - text: "Installed Version:" - font.pixelSize: 16 - color: Theme.textSecondary - Layout.alignment: Qt.AlignRight - } - - Text { - text: root.currentVersion - font.pixelSize: 16 - color: Theme.textPrimary - font.bold: true - } - } - - - Rectangle { - Layout.alignment: Qt.AlignCenter - Layout.topMargin: 8 - Layout.preferredWidth: updateText.implicitWidth + 46 - Layout.preferredHeight: 32 - radius: 20 - color: updateArea.containsMouse ? Theme.accentPrimary : "transparent" - border.color: Theme.accentPrimary - border.width: 1 - visible: { - if (root.currentVersion === "Unknown" || root.latestVersion === "Unknown") { - return false - } - const latest = root.latestVersion.replace("v", "").split(".") - const current = root.currentVersion.replace("v", "").split(".") - - - for (let i = 0; i < Math.max(latest.length, current.length); i++) { - const l = parseInt(latest[i] || "0") - const c = parseInt(current[i] || "0") - if (l > c) return true - if (l < c) return false - } - return false - } - - RowLayout { - anchors.centerIn: parent - spacing: 8 - - Text { - text: "system_update" - font.family: "Material Symbols Outlined" - font.pixelSize: 18 - color: updateArea.containsMouse ? Theme.backgroundPrimary : Theme.accentPrimary - } - - Text { - id: updateText - text: "Download latest release" - font.pixelSize: 14 - color: updateArea.containsMouse ? Theme.backgroundPrimary : Theme.accentPrimary - } - } - - MouseArea { - id: updateArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - Quickshell.execDetached(["xdg-open", "https://github.com/Ly-sec/Noctalia/releases/latest"]) - } - } - } - - Text { - text: "Description something something <.< I hate writing text..." - font.pixelSize: 14 - color: Theme.textSecondary - Layout.alignment: Qt.AlignCenter - Layout.topMargin: 24 - } - - - ColumnLayout { - Layout.fillWidth: true - Layout.topMargin: 32 - Layout.leftMargin: 32 - Layout.rightMargin: 32 - spacing: 16 - - RowLayout { - Layout.alignment: Qt.AlignCenter - spacing: 8 - - Text { - text: "Contributors" - font.pixelSize: 18 - font.bold: true - color: Theme.textPrimary - } - - Text { - text: "(" + root.contributors.length + ")" - font.pixelSize: 14 - color: Theme.textSecondary - } - } - - ScrollView { + Item { Layout.fillWidth: true - Layout.preferredHeight: 300 - clip: true + Layout.preferredHeight: 16 + } + + Text { + text: "Noctalia" + font.pixelSize: 24 + font.bold: true + color: Theme.textPrimary + Layout.alignment: Qt.AlignCenter + } + + GridLayout { + Layout.alignment: Qt.AlignCenter + columns: 2 + rowSpacing: 4 + columnSpacing: 8 + + Text { + text: "Latest Version:" + font.pixelSize: 16 + color: Theme.textSecondary + Layout.alignment: Qt.AlignRight + } + + Text { + text: root.latestVersion + font.pixelSize: 16 + color: Theme.textPrimary + font.bold: true + } + + Text { + text: "Installed Version:" + font.pixelSize: 16 + color: Theme.textSecondary + Layout.alignment: Qt.AlignRight + } + + Text { + text: root.currentVersion + font.pixelSize: 16 + color: Theme.textPrimary + font.bold: true + } + + } + + Rectangle { + Layout.alignment: Qt.AlignCenter + Layout.topMargin: 8 + Layout.preferredWidth: updateText.implicitWidth + 46 + Layout.preferredHeight: 32 + radius: 20 + color: updateArea.containsMouse ? Theme.accentPrimary : "transparent" + border.color: Theme.accentPrimary + border.width: 1 + visible: { + if (root.currentVersion === "Unknown" || root.latestVersion === "Unknown") + return false; + + const latest = root.latestVersion.replace("v", "").split("."); + const current = root.currentVersion.replace("v", "").split("."); + for (let i = 0; i < Math.max(latest.length, current.length); i++) { + const l = parseInt(latest[i] || "0"); + const c = parseInt(current[i] || "0"); + if (l > c) + return true; + + if (l < c) + return false; + + } + return false; + } + + RowLayout { + anchors.centerIn: parent + spacing: 8 + + Text { + text: "system_update" + font.family: "Material Symbols Outlined" + font.pixelSize: 18 + color: updateArea.containsMouse ? Theme.backgroundPrimary : Theme.accentPrimary + } + + Text { + id: updateText + + text: "Download latest release" + font.pixelSize: 14 + color: updateArea.containsMouse ? Theme.backgroundPrimary : Theme.accentPrimary + } + + } + + MouseArea { + id: updateArea - Item { anchors.fill: parent - - GridView { - id: contributorsGrid - anchors.centerIn: parent - width: Math.min(parent.width, Math.ceil(root.contributors.length / 3) * 200) - height: parent.height - cellWidth: 200 - cellHeight: 110 - model: root.contributors + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + Quickshell.execDetached(["xdg-open", "https://github.com/Ly-sec/Noctalia/releases/latest"]); + } + } - delegate: Rectangle { - width: contributorsGrid.cellWidth - 4 - height: contributorsGrid.cellHeight - 10 - radius: 20 - color: contributorArea.containsMouse ? Theme.highlight : "transparent" + } - RowLayout { - anchors.fill: parent - anchors.margins: 8 - spacing: 12 + Text { + text: "Description something something <.< I hate writing text..." + font.pixelSize: 14 + color: Theme.textSecondary + Layout.alignment: Qt.AlignCenter + Layout.topMargin: 24 + } - - Item { - Layout.alignment: Qt.AlignVCenter - Layout.preferredWidth: 40 - Layout.preferredHeight: 40 + Rectangle { + Layout.fillWidth: true + Layout.topMargin: 26 + Layout.bottomMargin: 18 + height: 1 + color: Theme.outline + opacity: 0.3 + } - Image { - id: avatarImage + ColumnLayout { + Layout.fillWidth: true + Layout.leftMargin: 32 + Layout.rightMargin: 32 + spacing: 16 + + RowLayout { + Layout.alignment: Qt.AlignCenter + spacing: 8 + + Text { + text: "Contributors" + font.pixelSize: 18 + font.bold: true + color: Theme.textPrimary + } + + Text { + text: "(" + root.contributors.length + ")" + font.pixelSize: 14 + color: Theme.textSecondary + } + + } + + ScrollView { + Layout.fillWidth: true + Layout.preferredHeight: 300 + clip: true + + Item { + anchors.fill: parent + + GridView { + id: contributorsGrid + + anchors.centerIn: parent + width: Math.min(parent.width, Math.ceil(root.contributors.length / 3) * 200) + height: parent.height + cellWidth: 200 + cellHeight: 100 + model: root.contributors + + delegate: Rectangle { + width: contributorsGrid.cellWidth - 4 + height: contributorsGrid.cellHeight - 10 + radius: 20 + color: contributorArea.containsMouse ? Theme.highlight : "transparent" + + RowLayout { anchors.fill: parent - source: modelData.avatar_url || "" - sourceSize: Qt.size(80, 80) - visible: false - mipmap: true - smooth: true - asynchronous: true - fillMode: Image.PreserveAspectCrop - cache: true + anchors.margins: 8 + spacing: 12 + + Item { + Layout.alignment: Qt.AlignVCenter + Layout.preferredWidth: 40 + Layout.preferredHeight: 40 + + Image { + id: avatarImage + + anchors.fill: parent + source: modelData.avatar_url || "" + sourceSize: Qt.size(80, 80) + visible: false + mipmap: true + smooth: true + asynchronous: true + fillMode: Image.PreserveAspectCrop + cache: true + } + + MultiEffect { + anchors.fill: parent + source: avatarImage + maskEnabled: true + maskSource: mask + } + + Item { + id: mask + + anchors.fill: parent + layer.enabled: true + visible: false + + Rectangle { + anchors.fill: parent + radius: avatarImage.width / 2 + } + + } + + Text { + anchors.centerIn: parent + text: "person" + font.family: "Material Symbols Outlined" + font.pixelSize: 24 + color: contributorArea.containsMouse ? Theme.backgroundPrimary : Theme.textPrimary + visible: !avatarImage.source || avatarImage.status !== Image.Ready + } + + } + + ColumnLayout { + spacing: 4 + Layout.alignment: Qt.AlignVCenter + Layout.fillWidth: true + + Text { + text: modelData.login || "Unknown" + font.pixelSize: 13 + color: contributorArea.containsMouse ? Theme.backgroundPrimary : Theme.textPrimary + elide: Text.ElideRight + Layout.fillWidth: true + } + + Text { + text: (modelData.contributions || 0) + " commits" + font.pixelSize: 11 + color: contributorArea.containsMouse ? Theme.backgroundPrimary : Theme.textSecondary + } + + } + } - MultiEffect { - anchors.fill: parent - source: avatarImage - maskEnabled: true - maskSource: mask - } + MouseArea { + id: contributorArea - Item { - id: mask anchors.fill: parent - layer.enabled: true - visible: false - Rectangle { - anchors.fill: parent - radius: avatarImage.width / 2 + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + if (modelData.html_url) + Quickshell.execDetached(["xdg-open", modelData.html_url]); + } } - - Text { - anchors.centerIn: parent - text: "person" - font.family: "Material Symbols Outlined" - font.pixelSize: 24 - color: contributorArea.containsMouse ? Theme.backgroundPrimary : Theme.textPrimary - visible: !avatarImage.source || avatarImage.status !== Image.Ready - } } - - ColumnLayout { - spacing: 4 - Layout.alignment: Qt.AlignVCenter - Layout.fillWidth: true - - Text { - text: modelData.login || "Unknown" - font.pixelSize: 13 - color: contributorArea.containsMouse ? Theme.backgroundPrimary : Theme.textPrimary - elide: Text.ElideRight - Layout.fillWidth: true - } - - Text { - text: (modelData.contributions || 0) + " commits" - font.pixelSize: 11 - color: contributorArea.containsMouse ? Theme.backgroundPrimary : Theme.textSecondary - } - } } - MouseArea { - id: contributorArea - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { - if (modelData.html_url) { - Quickshell.execDetached(["xdg-open", modelData.html_url]) - } - } - } } + } - } + } + } - - } } - } \ No newline at end of file + +} diff --git a/Widgets/SettingsWindow/Tabs/General.qml b/Widgets/SettingsWindow/Tabs/General.qml index 66a88e2..b03c1bd 100644 --- a/Widgets/SettingsWindow/Tabs/General.qml +++ b/Widgets/SettingsWindow/Tabs/General.qml @@ -1,11 +1,12 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts -import qs.Settings import qs.Components +import qs.Settings ColumnLayout { id: root + spacing: 0 anchors.fill: parent anchors.margins: 0 @@ -15,7 +16,6 @@ ColumnLayout { Layout.preferredHeight: 0 } - ColumnLayout { spacing: 4 Layout.fillWidth: true @@ -28,7 +28,6 @@ ColumnLayout { Layout.bottomMargin: 8 } - ColumnLayout { spacing: 2 Layout.fillWidth: true @@ -67,7 +66,9 @@ ColumnLayout { z: 2 } - Avatar {} + Avatar { + } + } Rectangle { @@ -80,6 +81,7 @@ ColumnLayout { TextInput { id: profileImageInput + anchors.fill: parent anchors.leftMargin: 12 anchors.rightMargin: 12 @@ -96,25 +98,27 @@ ColumnLayout { onTextChanged: { Settings.settings.profileImage = text; } + MouseArea { anchors.fill: parent cursorShape: Qt.IBeamCursor onClicked: profileImageInput.forceActiveFocus() } + } + } + } + } + } Rectangle { + Layout.fillWidth: true Layout.topMargin: 26 Layout.bottomMargin: 18 - anchors { - top: headerArea.bottom - left: parent.left - right: parent.right - } height: 1 color: Theme.outline opacity: 0.3 @@ -124,7 +128,6 @@ ColumnLayout { spacing: 4 Layout.fillWidth: true - Text { text: "User Interface" font.pixelSize: 18 @@ -133,7 +136,6 @@ ColumnLayout { Layout.bottomMargin: 8 } - ColumnLayout { spacing: 4 Layout.fillWidth: true @@ -160,10 +162,12 @@ ColumnLayout { wrapMode: Text.WordWrap Layout.fillWidth: true } + } Rectangle { id: cornersSwitch + width: 52 height: 32 radius: 16 @@ -173,6 +177,7 @@ ColumnLayout { Rectangle { id: cornersThumb + width: 28 height: 28 radius: 14 @@ -187,7 +192,9 @@ ColumnLayout { duration: 200 easing.type: Easing.OutCubic } + } + } MouseArea { @@ -197,10 +204,12 @@ ColumnLayout { Settings.settings.showCorners = !Settings.settings.showCorners; } } - } - } - } + } + + } + + } ColumnLayout { spacing: 8 @@ -229,10 +238,12 @@ ColumnLayout { wrapMode: Text.WordWrap Layout.fillWidth: true } + } Rectangle { id: dockSwitch + width: 52 height: 32 radius: 16 @@ -242,6 +253,7 @@ ColumnLayout { Rectangle { id: dockThumb + width: 28 height: 28 radius: 14 @@ -256,7 +268,9 @@ ColumnLayout { duration: 200 easing.type: Easing.OutCubic } + } + } MouseArea { @@ -266,10 +280,12 @@ ColumnLayout { Settings.settings.showDock = !Settings.settings.showDock; } } - } - } - } + } + + } + + } ColumnLayout { spacing: 8 @@ -298,10 +314,12 @@ ColumnLayout { wrapMode: Text.WordWrap Layout.fillWidth: true } + } Rectangle { id: dimSwitch + width: 52 height: 32 radius: 16 @@ -311,6 +329,7 @@ ColumnLayout { Rectangle { id: dimThumb + width: 28 height: 28 radius: 14 @@ -325,7 +344,9 @@ ColumnLayout { duration: 200 easing.type: Easing.OutCubic } + } + } MouseArea { @@ -335,13 +356,18 @@ ColumnLayout { Settings.settings.dimPanels = !Settings.settings.dimPanels; } } + } + } + } + } Item { Layout.fillWidth: true Layout.fillHeight: true } -} \ No newline at end of file + +} diff --git a/Widgets/SettingsWindow/Tabs/Network.qml b/Widgets/SettingsWindow/Tabs/Network.qml index b159f78..4a2f2c4 100644 --- a/Widgets/SettingsWindow/Tabs/Network.qml +++ b/Widgets/SettingsWindow/Tabs/Network.qml @@ -97,19 +97,14 @@ ColumnLayout { } } - Rectangle { - Layout.topMargin: 26 - Layout.bottomMargin: 18 - anchors { - top: headerArea.bottom - left: parent.left - right: parent.right - } - height: 1 - color: Theme.outline - opacity: 0.3 - } - + Rectangle { + Layout.fillWidth: true + Layout.topMargin: 26 + Layout.bottomMargin: 18 + height: 1 + color: Theme.outline + opacity: 0.3 + } ColumnLayout { spacing: 16 diff --git a/Widgets/SettingsWindow/Tabs/TimeWeather.qml b/Widgets/SettingsWindow/Tabs/TimeWeather.qml index 926b4c3..497784d 100644 --- a/Widgets/SettingsWindow/Tabs/TimeWeather.qml +++ b/Widgets/SettingsWindow/Tabs/TimeWeather.qml @@ -1,12 +1,13 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts -import qs.Settings import qs.Components +import qs.Settings import qs.Widgets.SettingsWindow.Tabs.Components ColumnLayout { id: root + spacing: 0 anchors.fill: parent anchors.margins: 0 @@ -16,7 +17,6 @@ ColumnLayout { Layout.preferredHeight: 0 } - ColumnLayout { spacing: 4 Layout.fillWidth: true @@ -29,7 +29,6 @@ ColumnLayout { Layout.bottomMargin: 8 } - ColumnLayout { spacing: 8 Layout.fillWidth: true @@ -57,10 +56,12 @@ ColumnLayout { wrapMode: Text.WordWrap Layout.fillWidth: true } + } Rectangle { id: use12HourClockSwitch + width: 52 height: 32 radius: 16 @@ -70,6 +71,7 @@ ColumnLayout { Rectangle { id: use12HourClockThumb + width: 28 height: 28 radius: 14 @@ -84,7 +86,9 @@ ColumnLayout { duration: 200 easing.type: Easing.OutCubic } + } + } MouseArea { @@ -94,10 +98,12 @@ ColumnLayout { Settings.settings.use12HourClock = !Settings.settings.use12HourClock; } } - } - } - } + } + + } + + } ColumnLayout { spacing: 8 @@ -126,10 +132,12 @@ ColumnLayout { wrapMode: Text.WordWrap Layout.fillWidth: true } + } Rectangle { id: reverseDayMonthSwitch + width: 52 height: 32 radius: 16 @@ -139,6 +147,7 @@ ColumnLayout { Rectangle { id: reverseDayMonthThumb + width: 28 height: 28 radius: 14 @@ -153,7 +162,9 @@ ColumnLayout { duration: 200 easing.type: Easing.OutCubic } + } + } MouseArea { @@ -163,25 +174,24 @@ ColumnLayout { Settings.settings.reverseDayMonth = !Settings.settings.reverseDayMonth; } } + } + } + } + } Rectangle { + Layout.fillWidth: true Layout.topMargin: 26 Layout.bottomMargin: 18 - anchors { - top: headerArea.bottom - left: parent.left - right: parent.right - } height: 1 color: Theme.outline opacity: 0.3 } - ColumnLayout { spacing: 4 Layout.fillWidth: true @@ -194,7 +204,6 @@ ColumnLayout { Layout.bottomMargin: 8 } - ColumnLayout { spacing: 8 Layout.fillWidth: true @@ -223,6 +232,7 @@ ColumnLayout { TextInput { id: cityInput + anchors.fill: parent anchors.leftMargin: 12 anchors.rightMargin: 12 @@ -237,7 +247,6 @@ ColumnLayout { selectByMouse: true activeFocusOnTab: true inputMethodHints: Qt.ImhNone - onTextChanged: { Settings.settings.weatherCity = text; } @@ -249,10 +258,12 @@ ColumnLayout { cityInput.forceActiveFocus(); } } - } - } - } + } + + } + + } ColumnLayout { spacing: 8 @@ -281,15 +292,21 @@ ColumnLayout { wrapMode: Text.WordWrap Layout.fillWidth: true } + + } + + UnitSelector { } - UnitSelector {} } + } + } Item { Layout.fillWidth: true Layout.fillHeight: true } -} \ No newline at end of file + +} diff --git a/Widgets/SettingsWindow/Tabs/Wallpaper.qml b/Widgets/SettingsWindow/Tabs/Wallpaper.qml index cb5d964..58b5571 100644 --- a/Widgets/SettingsWindow/Tabs/Wallpaper.qml +++ b/Widgets/SettingsWindow/Tabs/Wallpaper.qml @@ -122,264 +122,101 @@ ColumnLayout { } } + } - Rectangle { - Layout.topMargin: 26 - Layout.bottomMargin: 18 - anchors { - top: headerArea.bottom - left: parent.left - right: parent.right - } - height: 1 - color: Theme.outline - opacity: 0.3 + } + + Rectangle { + Layout.fillWidth: true + Layout.topMargin: 26 + Layout.bottomMargin: 18 + height: 1 + color: Theme.outline + opacity: 0.3 + } + + ColumnLayout { + spacing: 4 + Layout.fillWidth: true + + Text { + text: "Automation" + font.pixelSize: 18 + font.bold: true + color: Theme.textPrimary + Layout.bottomMargin: 8 } + // Random Wallpaper ColumnLayout { - spacing: 4 + spacing: 8 Layout.fillWidth: true + Layout.topMargin: 8 - Text { - text: "Automation" - font.pixelSize: 18 - font.bold: true - color: Theme.textPrimary - Layout.bottomMargin: 8 - } - - // Random Wallpaper - ColumnLayout { + RowLayout { spacing: 8 Layout.fillWidth: true - Layout.topMargin: 8 - RowLayout { - spacing: 8 - Layout.fillWidth: true - - ColumnLayout { - spacing: 4 - Layout.fillWidth: true - - Text { - text: "Random Wallpaper" - font.pixelSize: 13 - font.bold: true - color: Theme.textPrimary - } - - Text { - text: "Automatically select random wallpapers from the folder" - font.pixelSize: 12 - color: Theme.textSecondary - wrapMode: Text.WordWrap - Layout.fillWidth: true - } - - } - - Rectangle { - id: randomWallpaperSwitch - - width: 52 - height: 32 - radius: 16 - color: Settings.settings.randomWallpaper ? Theme.accentPrimary : Theme.surfaceVariant - border.color: Settings.settings.randomWallpaper ? Theme.accentPrimary : Theme.outline - border.width: 2 - - Rectangle { - id: randomWallpaperThumb - - width: 28 - height: 28 - radius: 14 - color: Theme.surface - border.color: Theme.outline - border.width: 1 - y: 2 - x: Settings.settings.randomWallpaper ? randomWallpaperSwitch.width - width - 2 : 2 - - Behavior on x { - NumberAnimation { - duration: 200 - easing.type: Easing.OutCubic - } - - } - - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: { - Settings.settings.randomWallpaper = !Settings.settings.randomWallpaper; - } - } - - } - - } - - } - - // Use Wallpaper Theme - ColumnLayout { - spacing: 8 - Layout.fillWidth: true - Layout.topMargin: 8 - - RowLayout { - spacing: 8 - Layout.fillWidth: true - - ColumnLayout { - spacing: 4 - Layout.fillWidth: true - - Text { - text: "Use Wallpaper Theme" - font.pixelSize: 13 - font.bold: true - color: Theme.textPrimary - } - - Text { - text: "Automatically adjust theme colors based on wallpaper" - font.pixelSize: 12 - color: Theme.textSecondary - wrapMode: Text.WordWrap - Layout.fillWidth: true - } - - } - - Rectangle { - id: wallpaperThemeSwitch - - width: 52 - height: 32 - radius: 16 - color: Settings.settings.useWallpaperTheme ? Theme.accentPrimary : Theme.surfaceVariant - border.color: Settings.settings.useWallpaperTheme ? Theme.accentPrimary : Theme.outline - border.width: 2 - - Rectangle { - id: wallpaperThemeThumb - - width: 28 - height: 28 - radius: 14 - color: Theme.surface - border.color: Theme.outline - border.width: 1 - y: 2 - x: Settings.settings.useWallpaperTheme ? wallpaperThemeSwitch.width - width - 2 : 2 - - Behavior on x { - NumberAnimation { - duration: 200 - easing.type: Easing.OutCubic - } - - } - - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: { - Settings.settings.useWallpaperTheme = !Settings.settings.useWallpaperTheme; - } - } - - } - - } - - } - - // Wallpaper Interval - ColumnLayout { - spacing: 8 - Layout.fillWidth: true - Layout.topMargin: 8 - - Text { - text: "Wallpaper Interval" - font.pixelSize: 13 - font.bold: true - color: Theme.textPrimary - } - - Text { - text: "How often to change wallpapers automatically (in seconds)" - font.pixelSize: 12 - color: Theme.textSecondary - wrapMode: Text.WordWrap - Layout.fillWidth: true - } - - RowLayout { + ColumnLayout { + spacing: 4 Layout.fillWidth: true Text { - text: Settings.settings.wallpaperInterval + " seconds" + text: "Random Wallpaper" font.pixelSize: 13 + font.bold: true color: Theme.textPrimary } - Item { + Text { + text: "Automatically select random wallpapers from the folder" + font.pixelSize: 12 + color: Theme.textSecondary + wrapMode: Text.WordWrap Layout.fillWidth: true } } - Slider { - id: intervalSlider + Rectangle { + id: randomWallpaperSwitch - Layout.fillWidth: true - from: 10 - to: 900 - stepSize: 10 - value: Settings.settings.wallpaperInterval - snapMode: Slider.SnapAlways - onMoved: { - Settings.settings.wallpaperInterval = Math.round(value); - } + width: 52 + height: 32 + radius: 16 + color: Settings.settings.randomWallpaper ? Theme.accentPrimary : Theme.surfaceVariant + border.color: Settings.settings.randomWallpaper ? Theme.accentPrimary : Theme.outline + border.width: 2 - background: Rectangle { - x: intervalSlider.leftPadding - y: intervalSlider.topPadding + intervalSlider.availableHeight / 2 - height / 2 - implicitWidth: 200 - implicitHeight: 4 - width: intervalSlider.availableWidth - height: implicitHeight - radius: 2 - color: Theme.surfaceVariant + Rectangle { + id: randomWallpaperThumb + + width: 28 + height: 28 + radius: 14 + color: Theme.surface + border.color: Theme.outline + border.width: 1 + y: 2 + x: Settings.settings.randomWallpaper ? randomWallpaperSwitch.width - width - 2 : 2 + + Behavior on x { + NumberAnimation { + duration: 200 + easing.type: Easing.OutCubic + } - Rectangle { - width: intervalSlider.visualPosition * parent.width - height: parent.height - color: Theme.accentPrimary - radius: 2 } } - handle: Rectangle { - x: intervalSlider.leftPadding + intervalSlider.visualPosition * (intervalSlider.availableWidth - width) - y: intervalSlider.topPadding + intervalSlider.availableHeight / 2 - height / 2 - implicitWidth: 20 - implicitHeight: 20 - radius: 10 - color: intervalSlider.pressed ? Theme.surfaceVariant : Theme.surface - border.color: Theme.accentPrimary - border.width: 2 + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: { + Settings.settings.randomWallpaper = !Settings.settings.randomWallpaper; + } } } @@ -388,16 +225,172 @@ ColumnLayout { } + // Use Wallpaper Theme + ColumnLayout { + spacing: 8 + Layout.fillWidth: true + Layout.topMargin: 8 + + RowLayout { + spacing: 8 + Layout.fillWidth: true + + ColumnLayout { + spacing: 4 + Layout.fillWidth: true + + Text { + text: "Use Wallpaper Theme" + font.pixelSize: 13 + font.bold: true + color: Theme.textPrimary + } + + Text { + text: "Automatically adjust theme colors based on wallpaper" + font.pixelSize: 12 + color: Theme.textSecondary + wrapMode: Text.WordWrap + Layout.fillWidth: true + } + + } + + Rectangle { + id: wallpaperThemeSwitch + + width: 52 + height: 32 + radius: 16 + color: Settings.settings.useWallpaperTheme ? Theme.accentPrimary : Theme.surfaceVariant + border.color: Settings.settings.useWallpaperTheme ? Theme.accentPrimary : Theme.outline + border.width: 2 + + Rectangle { + id: wallpaperThemeThumb + + width: 28 + height: 28 + radius: 14 + color: Theme.surface + border.color: Theme.outline + border.width: 1 + y: 2 + x: Settings.settings.useWallpaperTheme ? wallpaperThemeSwitch.width - width - 2 : 2 + + Behavior on x { + NumberAnimation { + duration: 200 + easing.type: Easing.OutCubic + } + + } + + } + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: { + Settings.settings.useWallpaperTheme = !Settings.settings.useWallpaperTheme; + } + } + + } + + } + + } + + // Wallpaper Interval + ColumnLayout { + spacing: 8 + Layout.fillWidth: true + Layout.topMargin: 8 + + Text { + text: "Wallpaper Interval" + font.pixelSize: 13 + font.bold: true + color: Theme.textPrimary + } + + Text { + text: "How often to change wallpapers automatically (in seconds)" + font.pixelSize: 12 + color: Theme.textSecondary + wrapMode: Text.WordWrap + Layout.fillWidth: true + } + + RowLayout { + Layout.fillWidth: true + + Text { + text: Settings.settings.wallpaperInterval + " seconds" + font.pixelSize: 13 + color: Theme.textPrimary + } + + Item { + Layout.fillWidth: true + } + + } + + Slider { + id: intervalSlider + + Layout.fillWidth: true + from: 10 + to: 900 + stepSize: 10 + value: Settings.settings.wallpaperInterval + snapMode: Slider.SnapAlways + onMoved: { + Settings.settings.wallpaperInterval = Math.round(value); + } + + background: Rectangle { + x: intervalSlider.leftPadding + y: intervalSlider.topPadding + intervalSlider.availableHeight / 2 - height / 2 + implicitWidth: 200 + implicitHeight: 4 + width: intervalSlider.availableWidth + height: implicitHeight + radius: 2 + color: Theme.surfaceVariant + + Rectangle { + width: intervalSlider.visualPosition * parent.width + height: parent.height + color: Theme.accentPrimary + radius: 2 + } + + } + + handle: Rectangle { + x: intervalSlider.leftPadding + intervalSlider.visualPosition * (intervalSlider.availableWidth - width) + y: intervalSlider.topPadding + intervalSlider.availableHeight / 2 - height / 2 + implicitWidth: 20 + implicitHeight: 20 + radius: 10 + color: intervalSlider.pressed ? Theme.surfaceVariant : Theme.surface + border.color: Theme.accentPrimary + border.width: 2 + } + + } + + } + } Rectangle { + Layout.fillWidth: true Layout.topMargin: 26 Layout.bottomMargin: 18 - anchors { - top: headerArea.bottom - left: parent.left - right: parent.right - } height: 1 color: Theme.outline opacity: 0.3