1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-07 05:55:37 -05:00

settings: redesign

This commit is contained in:
bbedward
2025-07-24 16:02:53 -04:00
parent c6df2bc11d
commit 0e968d910d
16 changed files with 1623 additions and 1549 deletions

View File

@@ -7,10 +7,8 @@ import Qt.labs.folderlistmodel
import Quickshell.Io import Quickshell.Io
import qs.Common import qs.Common
import qs.Widgets import qs.Widgets
import qs.Modals
DankModal { DankModal {
id: fileBrowser id: fileBrowserModal
signal fileSelected(string path) signal fileSelected(string path)
@@ -119,9 +117,13 @@ DankModal {
spacing: Theme.spacingS spacing: Theme.spacingS
// Header // Header
Row { Item {
width: parent.width width: parent.width
height: 40
Row {
spacing: Theme.spacingM spacing: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
DankIcon { DankIcon {
name: browserIcon name: browserIcon
@@ -137,18 +139,18 @@ DankModal {
font.weight: Font.Medium font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Item {
width: parent.width - 200
height: 1
} }
// Close button // Close button positioned at right
DankActionButton { DankActionButton {
circular: false
iconName: "close" iconName: "close"
iconSize: Theme.iconSizeSmall iconSize: Theme.iconSize - 4
iconColor: Theme.surfaceText iconColor: Theme.surfaceText
onClicked: fileBrowser.visible = false hoverColor: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12)
onClicked: fileBrowserModal.visible = false
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
} }
} }
@@ -182,7 +184,7 @@ DankModal {
} }
StyledText { StyledText {
text: "Current folder: " + fileBrowser.currentPath text: "Current folder: " + fileBrowserModal.currentPath
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText color: Theme.surfaceVariantText
width: parent.width - 40 - Theme.spacingS width: parent.width - 40 - Theme.spacingS

View File

@@ -77,31 +77,31 @@ DankModal {
anchors.margins: Theme.spacingXL anchors.margins: Theme.spacingXL
spacing: Theme.spacingL spacing: Theme.spacingL
Row { RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
height: 40 height: 40
spacing: Theme.spacingM
StyledText { StyledText {
anchors.verticalCenter: parent.verticalCenter
text: "System Monitor" text: "System Monitor"
font.pixelSize: Theme.fontSizeLarge + 4 font.pixelSize: Theme.fontSizeLarge + 4
font.weight: Font.Bold font.weight: Font.Bold
color: Theme.surfaceText color: Theme.surfaceText
Layout.alignment: Qt.AlignVCenter
} }
Item { Item {
width: parent.width - 280 Layout.fillWidth: true // Spacer to push close button to the right
height: 1
} }
StyledText { // Close button
anchors.verticalCenter: parent.verticalCenter DankActionButton {
text: SysMonitorService.processes.length + " processes" circular: false
font.pixelSize: Theme.fontSizeMedium iconName: "close"
color: Theme.surfaceVariantText iconSize: Theme.iconSize - 4
width: Math.min(implicitWidth, 120) iconColor: Theme.surfaceText
elide: Text.ElideRight hoverColor: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12)
onClicked: processListModal.hide()
Layout.alignment: Qt.AlignVCenter
} }
} }

View File

@@ -23,7 +23,6 @@ DankModal {
width: 650 width: 650
height: 750 height: 750
keyboardFocus: "ondemand" keyboardFocus: "ondemand"
enableShadow: true
onBackgroundClicked: { onBackgroundClicked: {
settingsVisible = false; settingsVisible = false;
} }
@@ -101,6 +100,12 @@ DankModal {
width: parent.width width: parent.width
height: parent.height - settingsTabBar.height height: parent.height - settingsTabBar.height
// Content container with proper padding
Rectangle {
anchors.fill: parent
anchors.margins: Theme.spacingL
color: "transparent"
// Personalization Tab // Personalization Tab
Loader { Loader {
anchors.fill: parent anchors.fill: parent
@@ -119,24 +124,7 @@ DankModal {
visible: active visible: active
asynchronous: true asynchronous: true
sourceComponent: Component { sourceComponent: Component {
Column { TimeWeatherTab {}
spacing: Theme.spacingL
topPadding: Theme.spacingM
ClockTab {
width: parent.width
}
Rectangle {
width: parent.width
height: Theme.spacingL
color: "transparent"
}
WeatherTab {
width: parent.width
}
}
} }
} }
@@ -147,7 +135,7 @@ DankModal {
visible: active visible: active
asynchronous: true asynchronous: true
sourceComponent: Component { sourceComponent: Component {
SystemTab {} WidgetsTab {}
} }
} }
@@ -163,6 +151,7 @@ DankModal {
} }
} }
} }
}
} }

View File

@@ -665,10 +665,32 @@ PanelWindow {
} }
// Display Tab // Display Tab
DisplayTab { Column {
anchors.fill: parent anchors.fill: parent
anchors.margins: Theme.spacingM anchors.margins: Theme.spacingM
visible: root.currentTab === "display" visible: root.currentTab === "display"
spacing: Theme.spacingL
DankToggle {
width: parent.width
text: "Night Mode"
description: "Apply warm color temperature to reduce eye strain"
checked: Prefs.nightModeEnabled
onToggled: (checked) => {
Prefs.setNightModeEnabled(checked);
}
}
DankToggle {
width: parent.width
text: "Light Mode"
description: "Use light theme instead of dark theme"
checked: Prefs.isLightMode
onToggled: (checked) => {
Prefs.setLightMode(checked);
Theme.isLightMode = checked;
}
}
} }
Behavior on height { Behavior on height {

View File

@@ -1,30 +1,42 @@
pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import Quickshell.Io
import qs.Common import qs.Common
import qs.Services
import qs.Widgets import qs.Widgets
ScrollView { ScrollView {
id: root id: appearanceTab
contentWidth: availableWidth
contentHeight: column.implicitHeight + Theme.spacingXL
clip: true clip: true
ScrollBar.vertical.policy: ScrollBar.AsNeeded
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
Column { Column {
width: root.width - 20 id: column
spacing: Theme.spacingL
topPadding: Theme.spacingM
bottomPadding: Theme.spacingL
// Display Settings
Column {
width: parent.width width: parent.width
spacing: Theme.spacingXL
topPadding: Theme.spacingL
bottomPadding: Theme.spacingXL
// Display Settings Section
StyledRect {
width: parent.width
height: displaySection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadiusLarge
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 1
Column {
id: displaySection
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM spacing: Theme.spacingM
Row { Row {
spacing: Theme.spacingS width: parent.width
spacing: Theme.spacingM
DankIcon { DankIcon {
name: "monitor" name: "monitor"
@@ -33,24 +45,510 @@ ScrollView {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Text { StyledText {
text: "Display" text: "Display Settings"
font.pixelSize: Theme.fontSizeLarge font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
DankToggle {
width: parent.width
text: "Night Mode"
description: "Apply warm color temperature to reduce eye strain"
checked: Prefs.nightModeEnabled
onToggled: (checked) => {
Prefs.setNightModeEnabled(checked);
if (checked)
nightModeEnableProcess.running = true;
else
nightModeDisableProcess.running = true;
}
}
DankToggle {
width: parent.width
text: "Light Mode"
description: "Use light theme instead of dark theme"
checked: Prefs.isLightMode
onToggled: (checked) => {
Prefs.setLightMode(checked);
Theme.isLightMode = checked;
}
}
DankDropdown {
width: parent.width
text: "Icon Theme"
description: "Select icon theme (requires restart)"
currentValue: Prefs.iconTheme
options: Prefs.availableIconThemes
onValueChanged: (value) => {
Prefs.setIconTheme(value);
}
}
}
}
// Transparency Settings Section
StyledRect {
width: parent.width
height: transparencySection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadiusLarge
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 1
Column {
id: transparencySection
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM
Row {
width: parent.width
spacing: Theme.spacingM
DankIcon {
name: "opacity"
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Transparency Settings"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
Column {
width: parent.width
spacing: Theme.spacingS
StyledText {
text: "Top Bar Transparency"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
}
DankSlider {
width: parent.width
height: 24
value: Math.round(Prefs.topBarTransparency * 100)
minimum: 0
maximum: 100
unit: ""
showValue: false
onSliderValueChanged: (newValue) => {
Prefs.setTopBarTransparency(newValue / 100);
}
}
}
Column {
width: parent.width
spacing: Theme.spacingS
StyledText {
text: "Popup Transparency"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
font.weight: Font.Medium
}
DankSlider {
width: parent.width
height: 24
value: Math.round(Prefs.popupTransparency * 100)
minimum: 0
maximum: 100
unit: ""
showValue: false
onSliderValueChanged: (newValue) => {
Prefs.setPopupTransparency(newValue / 100);
}
}
}
}
}
// Theme Picker Section
StyledRect {
width: parent.width
height: themeSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadiusLarge
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 1
Column {
id: themeSection
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM
Row {
width: parent.width
spacing: Theme.spacingM
DankIcon {
name: "palette"
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Theme Color"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
Column {
width: parent.width
spacing: Theme.spacingS
StyledText {
text: "Current Theme: " + (Theme.isDynamicTheme ? "Auto" : (Theme.currentThemeIndex < Theme.themes.length ? Theme.themes[Theme.currentThemeIndex].name : "Blue"))
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: {
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";
}
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter
wrapMode: Text.WordWrap
width: Math.min(parent.width, 400)
horizontalAlignment: Text.AlignHCenter
}
}
// Theme Grid
Column {
spacing: Theme.spacingS
anchors.horizontalCenter: parent.horizontalCenter
// First row - Blue, Deep Blue, Purple, Green, Orange
Row {
spacing: Theme.spacingM
anchors.horizontalCenter: parent.horizontalCenter
Repeater {
model: 5
Rectangle {
width: 32
height: 32
radius: 16
color: Theme.themes[index].primary
border.color: Theme.outline
border.width: (Theme.currentThemeIndex === index && !Theme.isDynamicTheme) ? 2 : 1
scale: (Theme.currentThemeIndex === index && !Theme.isDynamicTheme) ? 1.1 : 1
// Theme name tooltip
Rectangle {
width: nameText.contentWidth + Theme.spacingS * 2
height: nameText.contentHeight + Theme.spacingXS * 2
color: Theme.surfaceContainer
border.color: Theme.outline
border.width: 1
radius: Theme.cornerRadiusSmall
anchors.bottom: parent.top
anchors.bottomMargin: Theme.spacingXS
anchors.horizontalCenter: parent.horizontalCenter
visible: mouseArea.containsMouse
StyledText {
id: nameText
text: Theme.themes[index].name
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
anchors.centerIn: parent
}
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
Theme.switchTheme(index, false);
}
}
Behavior on scale {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on border.width {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.emphasizedEasing
}
}
}
}
}
// Second row - Red, Cyan, Pink, Amber, Coral
Row {
spacing: Theme.spacingM
anchors.horizontalCenter: parent.horizontalCenter
Repeater {
model: 5
Rectangle {
property int themeIndex: index + 5
width: 32
height: 32
radius: 16
color: themeIndex < Theme.themes.length ? Theme.themes[themeIndex].primary : "transparent"
border.color: Theme.outline
border.width: Theme.currentThemeIndex === themeIndex ? 2 : 1
visible: themeIndex < Theme.themes.length
scale: Theme.currentThemeIndex === themeIndex ? 1.1 : 1
// Theme name tooltip
Rectangle {
width: nameText2.contentWidth + Theme.spacingS * 2
height: nameText2.contentHeight + Theme.spacingXS * 2
color: Theme.surfaceContainer
border.color: Theme.outline
border.width: 1
radius: Theme.cornerRadiusSmall
anchors.bottom: parent.top
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 : ""
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
anchors.centerIn: parent
}
}
MouseArea {
id: mouseArea2
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (themeIndex < Theme.themes.length)
Theme.switchTheme(themeIndex);
}
}
Behavior on scale {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on border.width {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.emphasizedEasing
}
}
}
}
}
// Spacer
Item {
width: 1
height: Theme.spacingM
}
// Auto theme button
Rectangle {
width: 120
height: 40
radius: 20
anchors.horizontalCenter: parent.horizontalCenter
color: {
if (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing")
return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12);
else
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3);
}
border.color: {
if (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing")
return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.5);
else if (Theme.isDynamicTheme)
return Theme.primary;
else
return Theme.outline;
}
border.width: Theme.isDynamicTheme ? 2 : 1
scale: Theme.isDynamicTheme ? 1.1 : (autoMouseArea.containsMouse ? 1.02 : 1)
Row {
anchors.centerIn: parent
spacing: Theme.spacingS
DankIcon {
name: {
if (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing")
return "error";
else
return "palette";
}
size: 16
color: {
if (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing")
return Theme.error;
else
return Theme.surfaceText;
}
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: {
if (ToastService.wallpaperErrorStatus === "error")
return "Error";
else if (ToastService.wallpaperErrorStatus === "matugen_missing")
return "No matugen";
else
return "Auto";
}
font.pixelSize: Theme.fontSizeMedium
color: {
if (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing")
return Theme.error;
else
return Theme.surfaceText;
}
font.weight: Font.Medium font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
} }
Rectangle { MouseArea {
width: parent.width id: autoMouseArea
height: 1 anchors.fill: parent
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (ToastService.wallpaperErrorStatus === "matugen_missing") {
ToastService.showError("matugen not found - install matugen package for dynamic theming");
} else if (ToastService.wallpaperErrorStatus === "error") {
ToastService.showError("Wallpaper processing failed - check wallpaper path");
} else {
Theme.switchTheme(10, true);
}
}
} }
DisplayTab { // Tooltip for Auto button
width: parent.width Rectangle {
width: autoTooltipText.contentWidth + Theme.spacingM * 2
height: autoTooltipText.contentHeight + Theme.spacingS * 2
color: Theme.surfaceContainer
border.color: Theme.outline
border.width: 1
radius: Theme.cornerRadiusSmall
anchors.bottom: parent.top
anchors.bottomMargin: Theme.spacingS
anchors.horizontalCenter: parent.horizontalCenter
visible: autoMouseArea.containsMouse && (!Theme.isDynamicTheme || ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing")
StyledText {
id: autoTooltipText
text: {
if (ToastService.wallpaperErrorStatus === "error")
return "Wallpaper symlink missing at ~/quickshell/current_wallpaper";
else if (ToastService.wallpaperErrorStatus === "matugen_missing")
return "Install matugen package for dynamic themes";
else
return "Dynamic wallpaper-based colors";
} }
font.pixelSize: Theme.fontSizeSmall
color: (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing") ? Theme.error : Theme.surfaceText
anchors.centerIn: parent
wrapMode: Text.WordWrap
width: Math.min(implicitWidth, 250)
horizontalAlignment: Text.AlignHCenter
}
}
Behavior on scale {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on color {
ColorAnimation {
duration: Theme.mediumDuration
easing.type: Theme.standardEasing
}
}
Behavior on border.color {
ColorAnimation {
duration: Theme.mediumDuration
easing.type: Theme.standardEasing
}
}
}
}
}
}
}
// Night mode processes
Process {
id: nightModeEnableProcess
command: ["bash", "-c", "if command -v wlsunset > /dev/null; then pkill wlsunset; wlsunset -t 3000 & elif command -v redshift > /dev/null; then pkill redshift; redshift -P -O 3000 & else echo 'No night mode tool available'; fi"]
running: false
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("Failed to enable night mode");
Prefs.setNightModeEnabled(false);
}
}
}
Process {
id: nightModeDisableProcess
command: ["bash", "-c", "pkill wlsunset; pkill redshift; if command -v wlsunset > /dev/null; then wlsunset -t 6500 -T 6500 & sleep 1; pkill wlsunset; elif command -v redshift > /dev/null; then redshift -P -O 6500; redshift -x; fi"]
running: false
onExited: (exitCode) => {
if (exitCode !== 0)
console.warn("Failed to disable night mode");
} }
} }
} }

View File

@@ -1,18 +0,0 @@
import QtQuick
import qs.Common
import qs.Widgets
Column {
width: parent.width
spacing: Theme.spacingM
DankToggle {
text: "24-Hour Format"
description: "Use 24-hour time format instead of 12-hour AM/PM"
checked: Prefs.use24HourClock
onToggled: (checked) => {
return Prefs.setClockFormat(checked);
}
}
}

View File

@@ -1,163 +0,0 @@
import QtQuick
import Quickshell.Io
import qs.Common
import qs.Widgets
Column {
id: root
width: parent.width
spacing: Theme.spacingL
DankToggle {
text: "Night Mode"
description: "Apply warm color temperature to reduce eye strain"
checked: Prefs.nightModeEnabled
onToggled: (checked) => {
Prefs.setNightModeEnabled(checked);
if (checked)
nightModeEnableProcess.running = true;
else
nightModeDisableProcess.running = true;
}
}
DankToggle {
text: "Light Mode"
description: "Use light theme instead of dark theme"
checked: Prefs.isLightMode
onToggled: (checked) => {
Prefs.setLightMode(checked);
Theme.isLightMode = checked;
}
}
DankDropdown {
text: "Icon Theme"
description: "Select icon theme (requires restart)"
currentValue: Prefs.iconTheme
options: Prefs.availableIconThemes
onValueChanged: (value) => {
Prefs.setIconTheme(value);
}
}
// Top Bar Transparency
Column {
width: parent.width
spacing: Theme.spacingS
Text {
text: "Top Bar Transparency"
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
}
DankSlider {
width: parent.width
value: Math.round(Prefs.topBarTransparency * 100)
minimum: 0
maximum: 100
leftIcon: "opacity"
rightIcon: "circle"
unit: "%"
showValue: true
onSliderDragFinished: (finalValue) => {
let transparencyValue = finalValue / 100;
Prefs.setTopBarTransparency(transparencyValue);
}
}
Text {
text: "Adjust the transparency of the top bar background"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
width: parent.width
}
}
// Popup Transparency
Column {
width: parent.width
spacing: Theme.spacingS
Text {
text: "Popup Transparency"
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
}
DankSlider {
width: parent.width
value: Math.round(Prefs.popupTransparency * 100)
minimum: 0
maximum: 100
leftIcon: "blur_on"
rightIcon: "circle"
unit: "%"
showValue: true
onSliderDragFinished: (finalValue) => {
let transparencyValue = finalValue / 100;
Prefs.setPopupTransparency(transparencyValue);
}
}
Text {
text: "Adjust transparency for dialogs, menus, and popups"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
width: parent.width
}
}
// Theme Picker
Column {
width: parent.width
spacing: Theme.spacingS
Text {
text: "Theme Color"
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
}
ThemePicker {
anchors.horizontalCenter: parent.horizontalCenter
}
}
// Night mode processes
Process {
id: nightModeEnableProcess
command: ["bash", "-c", "if command -v wlsunset > /dev/null; then pkill wlsunset; wlsunset -t 3000 & elif command -v redshift > /dev/null; then pkill redshift; redshift -P -O 3000 & else echo 'No night mode tool available'; fi"]
running: false
onExited: (exitCode) => {
if (exitCode !== 0) {
console.warn("Failed to enable night mode");
Prefs.setNightModeEnabled(false);
}
}
}
Process {
id: nightModeDisableProcess
command: ["bash", "-c", "pkill wlsunset; pkill redshift; if command -v wlsunset > /dev/null; then wlsunset -t 6500 -T 6500 & sleep 1; pkill wlsunset; elif command -v redshift > /dev/null; then redshift -P -O 6500; redshift -x; fi"]
running: false
onExited: (exitCode) => {
if (exitCode !== 0)
console.warn("Failed to disable night mode");
}
}
}

View File

@@ -1,30 +1,42 @@
pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Effects
import Quickshell
import qs.Common import qs.Common
import qs.Services
import qs.Widgets import qs.Widgets
import qs.Modals
ScrollView { ScrollView {
id: root id: personalizationTab
contentWidth: availableWidth
contentHeight: column.implicitHeight
clip: true clip: true
ScrollBar.vertical.policy: ScrollBar.AsNeeded
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
Column { Column {
width: root.width - 20 id: column
spacing: Theme.spacingL width: parent.width
topPadding: Theme.spacingM spacing: Theme.spacingXL
bottomPadding: Theme.spacingL
// Profile Section // Profile Section
Column { StyledRect {
width: parent.width width: parent.width
height: profileSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadiusLarge
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 1
Column {
id: profileSection
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM spacing: Theme.spacingM
Row { Row {
spacing: Theme.spacingS width: parent.width
spacing: Theme.spacingM
DankIcon { DankIcon {
name: "person" name: "person"
@@ -33,33 +45,226 @@ ScrollView {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Text { StyledText {
text: "Profile" text: "Profile Image"
font.pixelSize: Theme.fontSizeLarge font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
} }
Rectangle { Row {
width: parent.width width: parent.width
height: 1 spacing: Theme.spacingL
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
// Circular profile image preview
Item {
id: avatarContainer
property bool hasImage: avatarImageSource.status === Image.Ready
width: 80
height: 80
Rectangle {
anchors.fill: parent
radius: width / 2
color: "transparent"
border.color: Theme.primary
border.width: 1
visible: parent.hasImage
} }
ProfileTab { Image {
id: avatarImageSource
source: {
if (Prefs.profileImage === "")
return "";
if (Prefs.profileImage.startsWith("/"))
return "file://" + Prefs.profileImage;
return Prefs.profileImage;
}
smooth: true
asynchronous: true
mipmap: true
cache: true
visible: false
}
MultiEffect {
anchors.fill: parent
anchors.margins: 5
source: avatarImageSource
maskEnabled: true
maskSource: settingsCircularMask
visible: avatarContainer.hasImage
maskThresholdMin: 0.5
maskSpreadAtMin: 1
}
Item {
id: settingsCircularMask
width: 70
height: 70
layer.enabled: true
layer.smooth: true
visible: false
Rectangle {
anchors.fill: parent
radius: width / 2
color: "black"
antialiasing: true
}
}
Rectangle {
anchors.fill: parent
radius: width / 2
color: Theme.primary
visible: !parent.hasImage
DankIcon {
anchors.centerIn: parent
name: "person"
size: Theme.iconSizeLarge + 8
color: Theme.primaryText
}
}
DankIcon {
anchors.centerIn: parent
name: "warning"
size: Theme.iconSizeLarge
color: Theme.error
visible: Prefs.profileImage !== "" && avatarImageSource.status === Image.Error
}
}
Column {
width: parent.width - 80 - Theme.spacingL
spacing: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: Prefs.profileImage ? Prefs.profileImage.split('/').pop() : "No profile image selected"
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
elide: Text.ElideMiddle
width: parent.width width: parent.width
} }
StyledText {
text: Prefs.profileImage ? Prefs.profileImage : ""
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
elide: Text.ElideMiddle
width: parent.width
visible: Prefs.profileImage !== ""
}
Row {
spacing: Theme.spacingS
StyledRect {
width: 100
height: 32
radius: Theme.cornerRadius
color: Theme.primary
Row {
anchors.centerIn: parent
spacing: Theme.spacingXS
DankIcon {
name: "folder_open"
size: Theme.iconSizeSmall
color: Theme.primaryText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Browse"
color: Theme.primaryText
font.pixelSize: Theme.fontSizeSmall
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
profileBrowserLoader.active = true;
profileBrowser.visible = true;
}
}
}
StyledRect {
width: 80
height: 32
radius: Theme.cornerRadius
color: Theme.surfaceVariant
opacity: Prefs.profileImage !== "" ? 1.0 : 0.5
Row {
anchors.centerIn: parent
spacing: Theme.spacingXS
DankIcon {
name: "clear"
size: Theme.iconSizeSmall
color: Theme.surfaceVariantText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Clear"
color: Theme.surfaceVariantText
font.pixelSize: Theme.fontSizeSmall
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
anchors.fill: parent
enabled: Prefs.profileImage !== ""
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: {
Prefs.setProfileImage("");
}
}
}
}
}
}
}
} }
// Wallpaper Section // Wallpaper Section
Column { StyledRect {
width: parent.width width: parent.width
height: wallpaperSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadiusLarge
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 1
Column {
id: wallpaperSection
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM spacing: Theme.spacingM
Row { Row {
spacing: Theme.spacingS width: parent.width
spacing: Theme.spacingM
DankIcon { DankIcon {
name: "wallpaper" name: "wallpaper"
@@ -68,24 +273,272 @@ ScrollView {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Text { StyledText {
text: "Wallpaper" text: "Wallpaper"
font.pixelSize: Theme.fontSizeLarge font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
} }
Rectangle { Row {
width: parent.width width: parent.width
height: 1 spacing: Theme.spacingL
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
// Wallpaper Preview
StyledRect {
width: 160
height: 90
radius: Theme.cornerRadius
color: Theme.surfaceVariant
border.color: Theme.outline
border.width: 1
CachingImage {
anchors.fill: parent
anchors.margins: 1
imagePath: Prefs.wallpaperPath || ""
fillMode: Image.PreserveAspectCrop
visible: Prefs.wallpaperPath !== ""
maxCacheSize: 160
layer.enabled: true
layer.effect: MultiEffect {
maskEnabled: true
maskSource: wallpaperMask
maskThresholdMin: 0.5
maskSpreadAtMin: 1.0
}
} }
WallpaperTab { Rectangle {
id: wallpaperMask
anchors.fill: parent
anchors.margins: 1
radius: Theme.cornerRadius - 1
color: "black"
visible: false
layer.enabled: true
}
DankIcon {
anchors.centerIn: parent
name: "image"
size: Theme.iconSizeLarge + 8
color: Theme.surfaceVariantText
visible: Prefs.wallpaperPath === ""
}
}
Column {
width: parent.width - 160 - Theme.spacingL
spacing: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: Prefs.wallpaperPath ? Prefs.wallpaperPath.split('/').pop() : "No wallpaper selected"
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
elide: Text.ElideMiddle
width: parent.width
}
StyledText {
text: Prefs.wallpaperPath ? Prefs.wallpaperPath : ""
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
elide: Text.ElideMiddle
width: parent.width
visible: Prefs.wallpaperPath !== ""
}
Row {
spacing: Theme.spacingS
StyledRect {
width: 100
height: 32
radius: Theme.cornerRadius
color: Theme.primary
Row {
anchors.centerIn: parent
spacing: Theme.spacingXS
DankIcon {
name: "folder_open"
size: Theme.iconSizeSmall
color: Theme.primaryText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Browse"
color: Theme.primaryText
font.pixelSize: Theme.fontSizeSmall
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
wallpaperBrowserLoader.active = true;
wallpaperBrowser.visible = true;
}
}
}
StyledRect {
width: 80
height: 32
radius: Theme.cornerRadius
color: Theme.surfaceVariant
opacity: Prefs.wallpaperPath !== "" ? 1.0 : 0.5
Row {
anchors.centerIn: parent
spacing: Theme.spacingXS
DankIcon {
name: "clear"
size: Theme.iconSizeSmall
color: Theme.surfaceVariantText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Clear"
color: Theme.surfaceVariantText
font.pixelSize: Theme.fontSizeSmall
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
anchors.fill: parent
enabled: Prefs.wallpaperPath !== ""
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: {
Prefs.setWallpaperPath("");
}
}
}
}
}
}
}
}
// Dynamic Theming Section
StyledRect {
width: parent.width
height: dynamicThemeSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadiusLarge
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 1
Column {
id: dynamicThemeSection
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM
Row {
width: parent.width
spacing: Theme.spacingM
DankIcon {
name: "palette"
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
Column {
width: parent.width - Theme.iconSize - Theme.spacingM - toggle.width - Theme.spacingM
spacing: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: "Dynamic Theming"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: "Automatically extract colors from wallpaper"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
width: parent.width width: parent.width
} }
} }
DankToggle {
id: toggle
anchors.verticalCenter: parent.verticalCenter
checked: Theme.isDynamicTheme
enabled: ToastService.wallpaperErrorStatus !== "matugen_missing"
onToggled: (toggled) => {
if (toggled) {
Theme.switchTheme(10, true)
} else {
Theme.switchTheme(0)
} }
}
}
}
StyledText {
text: "matugen not detected - dynamic theming unavailable"
font.pixelSize: Theme.fontSizeSmall
color: Theme.error
visible: ToastService.wallpaperErrorStatus === "matugen_missing"
width: parent.width
leftPadding: Theme.iconSize + Theme.spacingM
}
}
}
}
LazyLoader {
id: profileBrowserLoader
active: false
FileBrowserModal {
id: profileBrowser
browserTitle: "Select Profile Image"
browserIcon: "person"
browserType: "profile"
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
onFileSelected: (path) => {
Prefs.setProfileImage(path);
visible = false;
}
}
}
LazyLoader {
id: wallpaperBrowserLoader
active: false
FileBrowserModal {
id: wallpaperBrowser
browserTitle: "Select Wallpaper"
browserIcon: "wallpaper"
browserType: "wallpaper"
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
onFileSelected: (path) => {
Prefs.setWallpaperPath(path);
visible = false;
}
}
}
property alias profileBrowser: profileBrowserLoader.item
property alias wallpaperBrowser: wallpaperBrowserLoader.item
} }

View File

@@ -1,241 +0,0 @@
import QtQuick
import QtQuick.Effects
import Quickshell
import qs.Common
import qs.Widgets
Column {
width: parent.width
spacing: Theme.spacingM
// Profile Image Preview and Input
Column {
width: parent.width
spacing: Theme.spacingM
StyledText {
text: "Profile Image"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
// Profile Image Preview with circular crop
Row {
width: parent.width
spacing: Theme.spacingM
// Circular profile image preview
Item {
id: avatarContainer
property bool hasImage: avatarImageSource.status === Image.Ready
width: 54
height: 54
Rectangle {
anchors.fill: parent
radius: width / 2
color: "transparent"
border.color: Theme.primary
border.width: 1
visible: parent.hasImage
}
CachingImage {
id: avatarImageSource
imagePath: {
if (Prefs.profileImage === "")
return "";
if (Prefs.profileImage.startsWith("/"))
return Prefs.profileImage;
return Prefs.profileImage;
}
smooth: true
asynchronous: true
maxCacheSize: 80
cache: true
visible: false
}
MultiEffect {
anchors.fill: parent
anchors.margins: 5
source: avatarImageSource
maskEnabled: true
maskSource: settingsCircularMask
visible: avatarContainer.hasImage
maskThresholdMin: 0.5
maskSpreadAtMin: 1
}
Item {
id: settingsCircularMask
width: 54 - 10
height: 54 - 10
layer.enabled: true
layer.smooth: true
visible: false
Rectangle {
anchors.fill: parent
radius: width / 2
color: "black"
antialiasing: true
}
}
Rectangle {
anchors.fill: parent
radius: width / 2
color: Theme.primary
visible: !parent.hasImage
DankIcon {
anchors.centerIn: parent
name: "person"
size: Theme.iconSize + 8
color: Theme.primaryText
}
}
DankIcon {
anchors.centerIn: parent
name: "warning"
size: Theme.iconSize + 8
color: Theme.primaryText
visible: Prefs.profileImage !== "" && avatarImageSource.status === Image.Error
}
}
Column {
width: parent.width - 54 - Theme.spacingM
spacing: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: Prefs.profileImage ? Prefs.profileImage.split('/').pop() : "No profile image selected"
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
elide: Text.ElideMiddle
width: parent.width
}
StyledText {
text: Prefs.profileImage ? Prefs.profileImage : ""
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
elide: Text.ElideMiddle
width: parent.width
visible: Prefs.profileImage !== ""
}
}
}
Row {
width: parent.width
spacing: Theme.spacingS
StyledRect {
width: 100
height: 32
radius: Theme.cornerRadius
color: Theme.primary
Row {
anchors.centerIn: parent
spacing: Theme.spacingXS
DankIcon {
name: "folder_open"
size: Theme.iconSizeSmall
color: Theme.primaryText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Browse..."
color: Theme.primaryText
font.pixelSize: Theme.fontSizeSmall
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
profileBrowserLoader.active = true;
profileBrowser.visible = true;
}
}
}
StyledRect {
width: 80
height: 32
radius: Theme.cornerRadius
color: Theme.surfaceVariant
opacity: Prefs.profileImage !== "" ? 1.0 : 0.5
Row {
anchors.centerIn: parent
spacing: Theme.spacingXS
DankIcon {
name: "clear"
size: Theme.iconSizeSmall
color: Theme.surfaceVariantText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Clear"
color: Theme.surfaceVariantText
font.pixelSize: Theme.fontSizeSmall
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
anchors.fill: parent
enabled: Prefs.profileImage !== ""
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: {
Prefs.setProfileImage("");
}
}
}
}
}
LazyLoader {
id: profileBrowserLoader
active: false
DankFileBrowser {
id: profileBrowser
browserTitle: "Select Profile Image"
browserIcon: "person"
browserType: "profile"
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
onFileSelected: (path) => {
Prefs.setProfileImage(path);
visible = false;
}
}
}
property alias profileBrowser: profileBrowserLoader.item
}

View File

@@ -1,91 +0,0 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Controls
import qs.Common
import qs.Widgets
ScrollView {
id: root
clip: true
ScrollBar.vertical.policy: ScrollBar.AsNeeded
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
Column {
width: root.width - 20
spacing: Theme.spacingL
topPadding: Theme.spacingM
bottomPadding: Theme.spacingL
// Top Bar Widgets
Column {
width: parent.width
spacing: Theme.spacingM
Row {
spacing: Theme.spacingS
DankIcon {
name: "widgets"
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: "Top Bar Widgets"
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
}
Rectangle {
width: parent.width
height: 1
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
}
WidgetsTab {
width: parent.width
}
}
// Workspaces
Column {
width: parent.width
spacing: Theme.spacingM
Row {
spacing: Theme.spacingS
DankIcon {
name: "tab"
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: "Workspaces"
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
}
Rectangle {
width: parent.width
height: 1
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
}
WorkspaceTab {
width: parent.width
}
}
}
}

View File

@@ -1,345 +0,0 @@
import QtQuick
import qs.Common
import qs.Services
import qs.Widgets
Column {
id: themePicker
spacing: Theme.spacingS
Text {
text: "Current Theme: " + (Theme.isDynamicTheme ? "Auto" : (Theme.currentThemeIndex < Theme.themes.length ? Theme.themes[Theme.currentThemeIndex].name : "Blue"))
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
anchors.horizontalCenter: parent.horizontalCenter
}
// Theme description
Text {
text: {
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";
}
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter
wrapMode: Text.WordWrap
width: Math.min(parent.width, 200)
horizontalAlignment: Text.AlignHCenter
}
// Grid layout for 10 themes (2 rows of 5)
Column {
spacing: Theme.spacingS
anchors.horizontalCenter: parent.horizontalCenter
// First row - Blue, Deep Blue, Purple, Green, Orange
Row {
spacing: Theme.spacingM
anchors.horizontalCenter: parent.horizontalCenter
Repeater {
model: 5
Rectangle {
width: 32
height: 32
radius: 16
color: Theme.themes[index].primary
border.color: Theme.outline
border.width: (Theme.currentThemeIndex === index && !Theme.isDynamicTheme) ? 2 : 1
scale: (Theme.currentThemeIndex === index && !Theme.isDynamicTheme) ? 1.1 : 1
// Theme name tooltip
Rectangle {
width: nameText.contentWidth + Theme.spacingS * 2
height: nameText.contentHeight + Theme.spacingXS * 2
color: Theme.surfaceContainer
border.color: Theme.outline
border.width: 1
radius: Theme.cornerRadiusSmall
anchors.bottom: parent.top
anchors.bottomMargin: Theme.spacingXS
anchors.horizontalCenter: parent.horizontalCenter
visible: mouseArea.containsMouse
Text {
id: nameText
text: Theme.themes[index].name
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
anchors.centerIn: parent
}
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
Theme.switchTheme(index, false);
}
}
Behavior on scale {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on border.width {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.emphasizedEasing
}
}
}
}
}
// Second row - Red, Cyan, Pink, Amber, Coral
Row {
spacing: Theme.spacingM
anchors.horizontalCenter: parent.horizontalCenter
Repeater {
model: 5
Rectangle {
property int themeIndex: index + 5
width: 32
height: 32
radius: 16
color: themeIndex < Theme.themes.length ? Theme.themes[themeIndex].primary : "transparent"
border.color: Theme.outline
border.width: Theme.currentThemeIndex === themeIndex ? 2 : 1
visible: themeIndex < Theme.themes.length
scale: Theme.currentThemeIndex === themeIndex ? 1.1 : 1
// Theme name tooltip
Rectangle {
width: nameText2.contentWidth + Theme.spacingS * 2
height: nameText2.contentHeight + Theme.spacingXS * 2
color: Theme.surfaceContainer
border.color: Theme.outline
border.width: 1
radius: Theme.cornerRadiusSmall
anchors.bottom: parent.top
anchors.bottomMargin: Theme.spacingXS
anchors.horizontalCenter: parent.horizontalCenter
visible: mouseArea2.containsMouse && themeIndex < Theme.themes.length
Text {
id: nameText2
text: themeIndex < Theme.themes.length ? Theme.themes[themeIndex].name : ""
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
anchors.centerIn: parent
}
}
MouseArea {
id: mouseArea2
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (themeIndex < Theme.themes.length)
Theme.switchTheme(themeIndex);
}
}
Behavior on scale {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on border.width {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.emphasizedEasing
}
}
}
}
}
// Spacer for better visual separation
Item {
width: 1
height: Theme.spacingM
}
// Auto theme button - prominent oval below the grid
Rectangle {
width: 120
height: 40
radius: 20
anchors.horizontalCenter: parent.horizontalCenter
color: {
if (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing")
return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12);
else
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3);
}
border.color: {
if (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing")
return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.5);
else if (Theme.isDynamicTheme)
return Theme.primary;
else
return Theme.outline;
}
border.width: Theme.isDynamicTheme ? 2 : 1
scale: Theme.isDynamicTheme ? 1.1 : (autoMouseArea.containsMouse ? 1.02 : 1)
Row {
anchors.centerIn: parent
spacing: Theme.spacingS
DankIcon {
name: {
if (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing")
return "error";
else
return "palette";
}
size: 16
color: {
if (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing")
return Theme.error;
else
return Theme.surfaceText;
}
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: {
if (ToastService.wallpaperErrorStatus === "error")
return "Error";
else if (ToastService.wallpaperErrorStatus === "matugen_missing")
return "No matugen";
else
return "Auto";
}
font.pixelSize: Theme.fontSizeMedium
color: {
if (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing")
return Theme.error;
else
return Theme.surfaceText;
}
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: autoMouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
if (ToastService.wallpaperErrorStatus === "matugen_missing") {
ToastService.showError("matugen not found - install matugen package for dynamic theming");
} else if (ToastService.wallpaperErrorStatus === "error") {
ToastService.showError("Wallpaper processing failed - check wallpaper path");
} else {
Theme.switchTheme(10, true);
}
}
}
// Tooltip for Auto button
Rectangle {
width: autoTooltipText.contentWidth + Theme.spacingM * 2
height: autoTooltipText.contentHeight + Theme.spacingS * 2
color: Theme.surfaceContainer
border.color: Theme.outline
border.width: 1
radius: Theme.cornerRadiusSmall
anchors.bottom: parent.top
anchors.bottomMargin: Theme.spacingS
anchors.horizontalCenter: parent.horizontalCenter
visible: autoMouseArea.containsMouse && (!Theme.isDynamicTheme || ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing")
Text {
id: autoTooltipText
text: {
if (ToastService.wallpaperErrorStatus === "error")
return "Wallpaper symlink missing at ~/quickshell/current_wallpaper";
else if (ToastService.wallpaperErrorStatus === "matugen_missing")
return "Install matugen package for dynamic themes";
else
return "Dynamic wallpaper-based colors";
}
font.pixelSize: Theme.fontSizeSmall
color: (ToastService.wallpaperErrorStatus === "error" || ToastService.wallpaperErrorStatus === "matugen_missing") ? Theme.error : Theme.surfaceText
anchors.centerIn: parent
wrapMode: Text.WordWrap
width: Math.min(implicitWidth, 250)
horizontalAlignment: Text.AlignHCenter
}
}
Behavior on scale {
NumberAnimation {
duration: Theme.shortDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on color {
ColorAnimation {
duration: Theme.mediumDuration
easing.type: Theme.standardEasing
}
}
Behavior on border.color {
ColorAnimation {
duration: Theme.mediumDuration
easing.type: Theme.standardEasing
}
}
}
}
}

View File

@@ -0,0 +1,161 @@
import QtQuick
import QtQuick.Controls
import qs.Common
import qs.Widgets
ScrollView {
id: timeWeatherTab
contentWidth: availableWidth
contentHeight: column.implicitHeight
clip: true
Column {
id: column
width: parent.width
spacing: Theme.spacingXL
// Time Settings Section
StyledRect {
width: parent.width
height: timeSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadiusLarge
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 1
Column {
id: timeSection
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM
Row {
width: parent.width
spacing: Theme.spacingM
DankIcon {
name: "schedule"
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Time Format"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
DankToggle {
width: parent.width
text: "24-Hour Format"
description: "Use 24-hour time format instead of 12-hour AM/PM"
checked: Prefs.use24HourClock
onToggled: (checked) => {
return Prefs.setClockFormat(checked);
}
}
}
}
// Weather Settings Section
StyledRect {
width: parent.width
height: weatherSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadiusLarge
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 1
Column {
id: weatherSection
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM
Row {
width: parent.width
spacing: Theme.spacingM
DankIcon {
name: "cloud"
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Weather"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
DankToggle {
width: parent.width
text: "Fahrenheit"
description: "Use Fahrenheit instead of Celsius for temperature"
checked: Prefs.useFahrenheit
onToggled: (checked) => {
return Prefs.setTemperatureUnit(checked);
}
}
DankToggle {
width: parent.width
text: "Override Location"
description: "Use a specific location instead of auto-detection"
checked: Prefs.weatherLocationOverrideEnabled
onToggled: (checked) => {
return Prefs.setWeatherLocationOverrideEnabled(checked);
}
}
// Location input - only visible when override is enabled
Column {
width: parent.width
spacing: Theme.spacingS
visible: Prefs.weatherLocationOverrideEnabled
opacity: visible ? 1 : 0
StyledText {
text: "Location"
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
}
DankLocationSearch {
width: parent.width
currentLocation: Prefs.weatherLocationOverride
placeholderText: "Search for a location..."
onLocationSelected: (displayName, coordinates) => {
Prefs.setWeatherLocationOverride(coordinates);
}
}
StyledText {
text: "Examples: \"New York\", \"Tokyo\", \"44511\""
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
width: parent.width
}
Behavior on opacity {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
}
}
}
}
}

View File

@@ -1,248 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Effects
import Quickshell
import qs.Common
import qs.Services
import qs.Widgets
Column {
id: wallpaperTab
width: parent.width
spacing: Theme.spacingM
// Current Wallpaper Section
Column {
width: parent.width
spacing: Theme.spacingS
StyledText {
text: "Current Wallpaper"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
Row {
width: parent.width
spacing: Theme.spacingM
// Wallpaper Preview
StyledRect {
width: 120
height: 67
radius: Theme.cornerRadius
color: Theme.surfaceVariant
border.color: Theme.outline
border.width: 1
CachingImage {
anchors.fill: parent
anchors.margins: 1
imagePath: Prefs.wallpaperPath || ""
fillMode: Image.PreserveAspectCrop
visible: Prefs.wallpaperPath !== ""
maxCacheSize: 120
layer.enabled: true
layer.effect: MultiEffect {
maskEnabled: true
maskSource: mask
maskThresholdMin: 0.5
maskSpreadAtMin: 1.0
}
}
Rectangle {
id: mask
anchors.fill: parent
anchors.margins: 1
radius: Theme.cornerRadius - 1
color: "black"
visible: false
layer.enabled: true
}
DankIcon {
anchors.centerIn: parent
name: "image"
size: Theme.iconSizeLarge
color: Theme.surfaceVariantText
visible: Prefs.wallpaperPath === ""
}
}
Column {
width: parent.width - 120 - Theme.spacingM
spacing: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: Prefs.wallpaperPath ? Prefs.wallpaperPath.split('/').pop() : "No wallpaper selected"
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
elide: Text.ElideMiddle
width: parent.width
}
StyledText {
text: Prefs.wallpaperPath ? Prefs.wallpaperPath : ""
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
elide: Text.ElideMiddle
width: parent.width
visible: Prefs.wallpaperPath !== ""
}
}
}
Row {
width: parent.width
spacing: Theme.spacingS
StyledRect {
width: 100
height: 32
radius: Theme.cornerRadius
color: Theme.primary
Row {
anchors.centerIn: parent
spacing: Theme.spacingXS
DankIcon {
name: "folder_open"
size: Theme.iconSizeSmall
color: Theme.primaryText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Browse..."
color: Theme.primaryText
font.pixelSize: Theme.fontSizeSmall
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
wallpaperBrowserLoader.active = true;
wallpaperBrowser.visible = true;
}
}
}
StyledRect {
width: 80
height: 32
radius: Theme.cornerRadius
color: Theme.surfaceVariant
opacity: Prefs.wallpaperPath !== "" ? 1.0 : 0.5
Row {
anchors.centerIn: parent
spacing: Theme.spacingXS
DankIcon {
name: "clear"
size: Theme.iconSizeSmall
color: Theme.surfaceVariantText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Clear"
color: Theme.surfaceVariantText
font.pixelSize: Theme.fontSizeSmall
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
anchors.fill: parent
enabled: Prefs.wallpaperPath !== ""
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: {
Prefs.setWallpaperPath("");
}
}
}
}
}
// Dynamic Theming Section
Column {
width: parent.width
spacing: Theme.spacingS
Row {
width: parent.width
spacing: Theme.spacingM
Column {
width: parent.width - toggle.width - Theme.spacingM
spacing: Theme.spacingXS
StyledText {
text: "Dynamic Theming"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
}
StyledText {
text: "Automatically extract colors from wallpaper"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
width: parent.width
}
}
DankToggle {
id: toggle
anchors.verticalCenter: parent.verticalCenter
checked: Theme.isDynamicTheme
enabled: ToastService.wallpaperErrorStatus !== "matugen_missing"
onToggled: (toggled) => {
if (toggled) {
Theme.switchTheme(10, true)
} else {
Theme.switchTheme(0)
}
}
}
}
StyledText {
text: "matugen not detected"
font.pixelSize: Theme.fontSizeSmall
color: Theme.error
visible: ToastService.wallpaperErrorStatus === "matugen_missing"
width: parent.width
}
}
LazyLoader {
id: wallpaperBrowserLoader
active: false
DankFileBrowser {
id: wallpaperBrowser
browserTitle: "Select Wallpaper"
browserIcon: "wallpaper"
browserType: "wallpaper"
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
onFileSelected: (path) => {
Prefs.setWallpaperPath(path);
visible = false;
}
}
}
property alias wallpaperBrowser: wallpaperBrowserLoader.item
}

View File

@@ -1,75 +0,0 @@
import QtQuick
import qs.Common
import qs.Widgets
Column {
width: parent.width
spacing: Theme.spacingM
DankToggle {
text: "Fahrenheit"
description: "Use Fahrenheit instead of Celsius for temperature"
checked: Prefs.useFahrenheit
onToggled: (checked) => {
return Prefs.setTemperatureUnit(checked);
}
}
// Weather Location Override
Column {
width: parent.width
spacing: Theme.spacingM
DankToggle {
text: "Override Location"
description: "Use a specific location instead of auto-detection"
checked: Prefs.weatherLocationOverrideEnabled
onToggled: (checked) => {
return Prefs.setWeatherLocationOverrideEnabled(checked);
}
}
// Location input - only visible when override is enabled
Column {
width: parent.width
spacing: Theme.spacingS
visible: Prefs.weatherLocationOverrideEnabled
opacity: visible ? 1 : 0
Text {
text: "Location"
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
}
DankLocationSearch {
width: parent.width
currentLocation: Prefs.weatherLocationOverride
placeholderText: "Search for a location..."
onLocationSelected: (displayName, coordinates) => {
Prefs.setWeatherLocationOverride(coordinates);
}
}
Text {
text: "Examples: \"New York\", \"Tokyo\", \"44511\""
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
wrapMode: Text.WordWrap
width: parent.width
}
Behavior on opacity {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
}
}
}

View File

@@ -1,12 +1,59 @@
import QtQuick import QtQuick
import QtQuick.Controls
import qs.Common import qs.Common
import qs.Widgets import qs.Widgets
Column { ScrollView {
id: widgetsTab
contentWidth: availableWidth
contentHeight: column.implicitHeight + Theme.spacingXL
clip: true
Column {
id: column
width: parent.width
spacing: Theme.spacingXL
topPadding: Theme.spacingL
bottomPadding: Theme.spacingXL
// Top Bar Widgets Section
StyledRect {
width: parent.width
height: topBarSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadiusLarge
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 1
Column {
id: topBarSection
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM
Row {
width: parent.width width: parent.width
spacing: Theme.spacingM spacing: Theme.spacingM
DankIcon {
name: "widgets"
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Top Bar Widgets"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
DankToggle { DankToggle {
width: parent.width
text: "Focused Window" text: "Focused Window"
description: "Show the currently focused application in the top bar" description: "Show the currently focused application in the top bar"
checked: Prefs.showFocusedWindow checked: Prefs.showFocusedWindow
@@ -16,6 +63,7 @@ Column {
} }
DankToggle { DankToggle {
width: parent.width
text: "Weather Widget" text: "Weather Widget"
description: "Display weather information in the top bar" description: "Display weather information in the top bar"
checked: Prefs.showWeather checked: Prefs.showWeather
@@ -25,6 +73,7 @@ Column {
} }
DankToggle { DankToggle {
width: parent.width
text: "Media Controls" text: "Media Controls"
description: "Show currently playing media in the top bar" description: "Show currently playing media in the top bar"
checked: Prefs.showMusic checked: Prefs.showMusic
@@ -34,6 +83,7 @@ Column {
} }
DankToggle { DankToggle {
width: parent.width
text: "Clipboard Button" text: "Clipboard Button"
description: "Show clipboard access button in the top bar" description: "Show clipboard access button in the top bar"
checked: Prefs.showClipboard checked: Prefs.showClipboard
@@ -43,6 +93,7 @@ Column {
} }
DankToggle { DankToggle {
width: parent.width
text: "System Resources" text: "System Resources"
description: "Display CPU and RAM usage indicators" description: "Display CPU and RAM usage indicators"
checked: Prefs.showSystemResources checked: Prefs.showSystemResources
@@ -52,6 +103,7 @@ Column {
} }
DankToggle { DankToggle {
width: parent.width
text: "System Tray" text: "System Tray"
description: "Show system tray icons in the top bar" description: "Show system tray icons in the top bar"
checked: Prefs.showSystemTray checked: Prefs.showSystemTray
@@ -59,8 +111,103 @@ Column {
return Prefs.setShowSystemTray(checked); return Prefs.setShowSystemTray(checked);
} }
} }
}
}
// Workspace Section
StyledRect {
width: parent.width
height: workspaceSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadiusLarge
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 1
Column {
id: workspaceSection
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM
Row {
width: parent.width
spacing: Theme.spacingM
DankIcon {
name: "view_module"
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "Workspace Settings"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
DankToggle { DankToggle {
width: parent.width
text: "Workspace Index Numbers"
description: "Show workspace index numbers in the top bar workspace switcher"
checked: Prefs.showWorkspaceIndex
onToggled: (checked) => {
return Prefs.setShowWorkspaceIndex(checked);
}
}
DankToggle {
width: parent.width
text: "Workspace Padding"
description: "Always show a minimum of 3 workspaces, even if fewer are available"
checked: Prefs.showWorkspacePadding
onToggled: (checked) => {
return Prefs.setShowWorkspacePadding(checked);
}
}
}
}
// App Launcher Section
StyledRect {
width: parent.width
height: appLauncherSection.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadiusLarge
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
border.width: 1
Column {
id: appLauncherSection
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM
Row {
width: parent.width
spacing: Theme.spacingM
DankIcon {
name: "apps"
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: "App Launcher"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
DankToggle {
width: parent.width
text: "Use OS Logo for App Launcher" text: "Use OS Logo for App Launcher"
description: "Display operating system logo instead of apps icon" description: "Display operating system logo instead of apps icon"
checked: Prefs.useOSLogo checked: Prefs.useOSLogo
@@ -69,37 +216,43 @@ Column {
} }
} }
Column { // OS Logo Customization - only visible when OS logo is enabled
StyledRect {
width: parent.width width: parent.width
spacing: Theme.spacingS height: logoCustomization.implicitHeight + Theme.spacingM * 2
radius: Theme.cornerRadius
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.5)
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.3)
border.width: 1
visible: Prefs.useOSLogo visible: Prefs.useOSLogo
opacity: visible ? 1 : 0
Item { Column {
width: parent.width id: logoCustomization
height: Theme.spacingS anchors.fill: parent
} anchors.margins: Theme.spacingM
spacing: Theme.spacingM
Text { StyledText {
text: "OS Logo Customization" text: "OS Logo Customization"
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText color: Theme.surfaceText
font.weight: Font.Medium font.weight: Font.Medium
} }
Row { Column {
width: parent.width width: parent.width
spacing: Theme.spacingM spacing: Theme.spacingS
Text { StyledText {
text: "Color Override:" text: "Color Override"
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter font.weight: Font.Medium
width: 90
} }
DankTextField { DankTextField {
width: 120 width: 160
height: 36 height: 36
placeholderText: "#ffffff" placeholderText: "#ffffff"
text: Prefs.osLogoColorOverride text: Prefs.osLogoColorOverride
@@ -115,23 +268,21 @@ Column {
text = Prefs.osLogoColorOverride; text = Prefs.osLogoColorOverride;
} }
} }
} }
Row { Column {
width: parent.width width: parent.width
spacing: Theme.spacingM spacing: Theme.spacingS
Text { StyledText {
text: "Brightness:" text: "Brightness"
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter font.weight: Font.Medium
width: 90
} }
DankSlider { DankSlider {
width: 120 width: parent.width
height: 24 height: 24
minimum: 0 minimum: 0
maximum: 100 maximum: 100
@@ -142,23 +293,21 @@ Column {
Prefs.setOSLogoBrightness(newValue / 100); Prefs.setOSLogoBrightness(newValue / 100);
} }
} }
} }
Row { Column {
width: parent.width width: parent.width
spacing: Theme.spacingM spacing: Theme.spacingS
Text { StyledText {
text: "Contrast:" text: "Contrast"
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter font.weight: Font.Medium
width: 90
} }
DankSlider { DankSlider {
width: 120 width: parent.width
height: 24 height: 24
minimum: 0 minimum: 0
maximum: 200 maximum: 200
@@ -169,9 +318,17 @@ Column {
Prefs.setOSLogoContrast(newValue / 100); Prefs.setOSLogoContrast(newValue / 100);
} }
} }
}
} }
Behavior on opacity {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
}
}
}
} }
} }

View File

@@ -1,27 +0,0 @@
import QtQuick
import qs.Common
import qs.Widgets
Column {
width: parent.width
spacing: Theme.spacingM
DankToggle {
text: "Workspace Index Numbers"
description: "Show workspace index numbers in the top bar workspace switcher"
checked: Prefs.showWorkspaceIndex
onToggled: (checked) => {
return Prefs.setShowWorkspaceIndex(checked);
}
}
DankToggle {
text: "Workspace Padding"
description: "Always show a minimum of 3 workspaces, even if fewer are available"
checked: Prefs.showWorkspacePadding
onToggled: (checked) => {
return Prefs.setShowWorkspacePadding(checked);
}
}
}