From 9aa51c86da67fcb1c6a3efb5c77b6c3aa55148d9 Mon Sep 17 00:00:00 2001 From: kossLAN Date: Tue, 10 Jun 2025 21:46:33 -0400 Subject: [PATCH] update settings schema --- ShellSettings.qml | 12 +- bar/ActiveWindow.qml | 2 +- bar/Bar.qml | 17 +- bar/HyprWorkspaces.qml | 6 +- bar/battery/BatteryIndicator.qml | 6 +- bar/control/ControlPanel.qml | 24 +-- bar/control/volume/Card.qml | 4 +- bar/control/volume/Mixer.qml | 6 +- bar/notifications/NotificationButton.qml | 4 +- bar/popups/MenuWindow.qml | 2 +- bar/systray/SysTray.qml | 2 +- bar/systray/TrayMenuEntry.qml | 8 +- bar/systray/TrayMenuItem.qml | 2 +- launcher/Controller.qml | 12 +- notifications/ActiveToast.qml | 10 +- notifications/NotificationCenter.qml | 8 +- settings/Controller.qml | 10 +- shell.qml | 1 + volume-osd/Controller.qml | 88 ++++++---- wallpaper/Controller.qml | 2 +- widgets/IconButton.qml | 6 +- widgets/MaterialButton.qml | 3 + widgets/RoundSlider.qml | 4 +- widgets/Separator.qml | 2 +- widgets/TextButton.qml | 204 +++++++++++++++++++++++ 25 files changed, 342 insertions(+), 103 deletions(-) create mode 100644 widgets/MaterialButton.qml create mode 100644 widgets/TextButton.qml diff --git a/ShellSettings.qml b/ShellSettings.qml index d76856e..db756cb 100644 --- a/ShellSettings.qml +++ b/ShellSettings.qml @@ -5,7 +5,8 @@ import Quickshell import Quickshell.Io Singleton { - property alias settings: jsonAdapter + property alias settings: jsonAdapter.settings + property alias colors: jsonAdapter.colors FileView { path: `${Quickshell.env("XDG_DATA_HOME")}/quickshell/settings.json` @@ -16,9 +17,12 @@ Singleton { JsonAdapter { id: jsonAdapter - property int barHeight: 25 - property string wallpaperUrl: Qt.resolvedUrl("root:resources/wallpapers/pixelart0.jpg") - property string colorScheme: "scheme-fruit-salad" + + property QtObject settings: QtObject { + property int barHeight: 25 + property string wallpaperUrl: Qt.resolvedUrl("root:resources/wallpapers/pixelart0.jpg") + property string colorScheme: "scheme-fruit-salad" + } property var colors: { "background": "#131313", diff --git a/bar/ActiveWindow.qml b/bar/ActiveWindow.qml index 849433f..ecf7b46 100644 --- a/bar/ActiveWindow.qml +++ b/bar/ActiveWindow.qml @@ -5,7 +5,7 @@ import ".." Text { id: windowText text: ToplevelManager.activeToplevel?.title ?? "" - color: ShellSettings.settings.colors["inverse_surface"] + color: ShellSettings.colors["inverse_surface"] font.pointSize: 11 visible: text !== "" elide: Text.ElideRight diff --git a/bar/Bar.qml b/bar/Bar.qml index 4015632..7c1785c 100644 --- a/bar/Bar.qml +++ b/bar/Bar.qml @@ -11,7 +11,7 @@ import ".." PanelWindow { id: root - color: ShellSettings.settings.colors["surface"] + color: ShellSettings.colors["surface"] implicitHeight: ShellSettings.settings.barHeight property alias popup: popupWindow @@ -75,6 +75,19 @@ PanelWindow { // bar: root // } + // Text { + // text: "home" + // color: "white" + // font.family: "Material Symbols Rounded" + // renderType: Text.NativeRendering + // textFormat: Text.PlainText + // font.pointSize: 12 + // + // font.variableAxes: { + // "FILL": 1 + // } + // } + BatteryIndicator { id: batteryIndicator popup: root.popup @@ -89,7 +102,7 @@ PanelWindow { Clock { id: clock - color: ShellSettings.settings.colors["inverse_surface"] + color: ShellSettings.colors["inverse_surface"] } } } diff --git a/bar/HyprWorkspaces.qml b/bar/HyprWorkspaces.qml index c8df3b9..4347bfe 100644 --- a/bar/HyprWorkspaces.qml +++ b/bar/HyprWorkspaces.qml @@ -33,15 +33,15 @@ RowLayout { } color: { - let value = Qt.color(ShellSettings.settings.colors["secondary"]).darker(2); + let value = Qt.color(ShellSettings.colors["secondary"]).darker(2); if (!modelData?.id || !Hyprland.focusedMonitor?.activeWorkspace?.id) return value; if (workspaceButton.containsMouse) { - value = ShellSettings.settings.colors["on_primary"]; + value = ShellSettings.colors["on_primary"]; } else if (Hyprland.focusedMonitor.activeWorkspace.id == modelData.id) { - value = ShellSettings.settings.colors["primary"]; + value = ShellSettings.colors["primary"]; } return value; diff --git a/bar/battery/BatteryIndicator.qml b/bar/battery/BatteryIndicator.qml index 804a6f9..fed696f 100644 --- a/bar/battery/BatteryIndicator.qml +++ b/bar/battery/BatteryIndicator.qml @@ -59,7 +59,7 @@ Item { Rectangle { id: highlight - color: batteryButton.containsMouse ? ShellSettings.settings.colors["primary"] : "transparent" + color: batteryButton.containsMouse ? ShellSettings.colors["primary"] : "transparent" // radius: width / 2 radius: 10 @@ -96,7 +96,7 @@ Item { Rectangle { id: batteryBackground - color: Qt.color(ShellSettings.settings.colors["surface"]).lighter(4) + color: Qt.color(ShellSettings.colors["surface"]).lighter(4) opacity: 0.75 anchors { fill: parent @@ -107,7 +107,7 @@ Item { Rectangle { id: batteryPercentage width: (parent.width - 4) * UPower.displayDevice.percentage - color: ShellSettings.settings.colors["inverse_surface"] + color: ShellSettings.colors["inverse_surface"] anchors { left: batteryBackground.left diff --git a/bar/control/ControlPanel.qml b/bar/control/ControlPanel.qml index e7182e8..9342dec 100644 --- a/bar/control/ControlPanel.qml +++ b/bar/control/ControlPanel.qml @@ -48,7 +48,7 @@ PopupWindow { // Add drop shadow effect // Rectangle { // id: shadowSource - // color: ShellSettings.settings.colors["surface"] + // color: ShellSettings.colors["surface"] // radius: 8 // opacity: container.opacity // width: container.width @@ -97,7 +97,7 @@ PopupWindow { Rectangle { id: container - color: ShellSettings.settings.colors["surface"] + color: ShellSettings.colors["surface"] radius: 18 opacity: 0 width: parent.width - 10 @@ -133,7 +133,7 @@ PopupWindow { // // Rectangle { // radius: 20 - // color: ShellSettings.settings.colors["surface_container_high"] + // color: ShellSettings.colors["surface_container_high"] // Layout.fillWidth: true // Layout.fillHeight: true // @@ -153,7 +153,7 @@ PopupWindow { // // Text { // text: "kossLAN" - // color: ShellSettings.settings.colors["inverse_surface"] + // color: ShellSettings.colors["inverse_surface"] // font.pointSize: 12 // verticalAlignment: Text.AlignVCenter // Layout.fillWidth: true @@ -165,7 +165,7 @@ PopupWindow { // // Rectangle { // radius: 20 - // color: ShellSettings.settings.colors["surface_container_high"] + // color: ShellSettings.colors["surface_container_high"] // Layout.preferredWidth: powerButtons.implicitWidth + 10 // Layout.fillHeight: true // @@ -195,7 +195,7 @@ PopupWindow { // // Rectangle { // radius: 20 - // color: ShellSettings.settings.colors["surface_bright"] + // color: ShellSettings.colors["surface_bright"] // Layout.preferredWidth: 2 // Layout.fillHeight: true // Layout.topMargin: 4 @@ -217,7 +217,7 @@ PopupWindow { Layout.fillWidth: true Rectangle { - color: ShellSettings.settings.colors["surface_container_high"] + color: ShellSettings.colors["surface_container_high"] radius: 12 Layout.fillWidth: true Layout.preferredHeight: 30 @@ -232,7 +232,7 @@ PopupWindow { Repeater { model: [1, 2, 3, 4, 5] delegate: Rectangle { - color: ShellSettings.settings.colors["surface_container_high"] + color: ShellSettings.colors["surface_container_high"] radius: width / 2 Layout.preferredWidth: 45 Layout.preferredHeight: 45 @@ -250,14 +250,14 @@ PopupWindow { Layout.preferredHeight: 55 Rectangle { - color: ShellSettings.settings.colors["primary"] + color: ShellSettings.colors["primary"] radius: width / 2 Layout.fillWidth: true Layout.fillHeight: true } Rectangle { - color: ShellSettings.settings.colors["primary"] + color: ShellSettings.colors["primary"] radius: width / 2 Layout.fillWidth: true Layout.fillHeight: true @@ -270,14 +270,14 @@ PopupWindow { Layout.preferredHeight: 55 Rectangle { - color: ShellSettings.settings.colors["surface_container_high"] + color: ShellSettings.colors["surface_container_high"] radius: width / 2 Layout.fillWidth: true Layout.fillHeight: true } Rectangle { - color: ShellSettings.settings.colors["surface_container_high"] + color: ShellSettings.colors["surface_container_high"] radius: width / 2 Layout.fillWidth: true Layout.fillHeight: true diff --git a/bar/control/volume/Card.qml b/bar/control/volume/Card.qml index 2af17e1..fd6f561 100644 --- a/bar/control/volume/Card.qml +++ b/bar/control/volume/Card.qml @@ -9,7 +9,7 @@ Rectangle { id: root required property PwNode node required property var isSink - color: ShellSettings.settings.colors["surface_container_high"] + color: ShellSettings.colors["surface_container_high"] PwObjectTracker { id: defaultSourceTracker @@ -27,7 +27,7 @@ Rectangle { spacing: 10 Text { - color: ShellSettings.settings.colors["inverse_surface"] + color: ShellSettings.colors["inverse_surface"] text: { // Taken from quickshell-examples diff --git a/bar/control/volume/Mixer.qml b/bar/control/volume/Mixer.qml index 0b48931..729af1d 100644 --- a/bar/control/volume/Mixer.qml +++ b/bar/control/volume/Mixer.qml @@ -42,7 +42,7 @@ Rectangle { anchors.fill: parent Rectangle { - color: ShellSettings.settings.colors["surface_container_high"] + color: ShellSettings.colors["surface_container_high"] Widgets.IconButton { id: arrowButton @@ -80,7 +80,7 @@ Rectangle { Rectangle { id: divider - color: ShellSettings.settings.colors["surface_bright"] + color: ShellSettings.colors["surface_bright"] height: 2 width: parent.width anchors.top: headerSection.bottom @@ -140,7 +140,7 @@ Rectangle { height: root.baseHeight Rectangle { - color: ShellSettings.settings.colors["surface_container_high"] + color: ShellSettings.colors["surface_container_high"] IconImage { implicitSize: 32 diff --git a/bar/notifications/NotificationButton.qml b/bar/notifications/NotificationButton.qml index f2c0972..028244f 100644 --- a/bar/notifications/NotificationButton.qml +++ b/bar/notifications/NotificationButton.qml @@ -19,7 +19,7 @@ Item { } Rectangle { - color: mouseArea.containsMouse ? ShellSettings.settings.colors["primary"] : "transparent" + color: mouseArea.containsMouse ? ShellSettings.colors["primary"] : "transparent" radius: 5 anchors { @@ -61,7 +61,7 @@ Item { } Rectangle { - color: mouseArea.containsMouse ? ShellSettings.settings.colors["inverse_primary"] : ShellSettings.settings.colors["inverse_surface"] + color: mouseArea.containsMouse ? ShellSettings.colors["inverse_primary"] : ShellSettings.colors["inverse_surface"] anchors.fill: parent } } diff --git a/bar/popups/MenuWindow.qml b/bar/popups/MenuWindow.qml index 62a23bd..abf2218 100644 --- a/bar/popups/MenuWindow.qml +++ b/bar/popups/MenuWindow.qml @@ -102,7 +102,7 @@ PopupWindow { WrapperRectangle { id: popupContainer - color: ShellSettings.settings.colors["surface"] + color: ShellSettings.colors["surface"] radius: 12 margin: 8 clip: true diff --git a/bar/systray/SysTray.qml b/bar/systray/SysTray.qml index a45446a..916af47 100644 --- a/bar/systray/SysTray.qml +++ b/bar/systray/SysTray.qml @@ -77,7 +77,7 @@ RowLayout { Rectangle { id: trayContainer - color: trayButton.containsMouse ? ShellSettings.settings.colors["primary"] : "transparent" + color: trayButton.containsMouse ? ShellSettings.colors["primary"] : "transparent" radius: width / 2 implicitHeight: parent.height - 2 implicitWidth: parent.height - 2 diff --git a/bar/systray/TrayMenuEntry.qml b/bar/systray/TrayMenuEntry.qml index d4a6063..b15114e 100644 --- a/bar/systray/TrayMenuEntry.qml +++ b/bar/systray/TrayMenuEntry.qml @@ -31,7 +31,7 @@ ColumnLayout { return "transparent"; if (entryArea.containsMouse) - return ShellSettings.settings.colors["primary"]; + return ShellSettings.colors["primary"]; return "transparent"; } @@ -92,13 +92,13 @@ ColumnLayout { text: root.menuData?.text ?? "" verticalAlignment: Text.AlignVCenter color: { - let color = Qt.color(ShellSettings.settings.colors["inverse_surface"]); + let color = Qt.color(ShellSettings.colors["inverse_surface"]); if (!root.menuData?.enabled) return color.darker(2); if (entryArea.containsMouse) - return Qt.color(ShellSettings.settings.colors["inverse_primary"]); + return Qt.color(ShellSettings.colors["inverse_primary"]); return color; } @@ -141,7 +141,7 @@ ColumnLayout { WrapperRectangle { id: subTrayMenu - color: ShellSettings.settings.colors["surface_container"] + color: ShellSettings.colors["surface_container"] radius: 8 visible: false Layout.fillWidth: true diff --git a/bar/systray/TrayMenuItem.qml b/bar/systray/TrayMenuItem.qml index c72e5fa..590cf4c 100644 --- a/bar/systray/TrayMenuItem.qml +++ b/bar/systray/TrayMenuItem.qml @@ -12,7 +12,7 @@ ColumnLayout { Rectangle { visible: (root.modelData?.isSeparator ?? false) - color: ShellSettings.settings.colors["surface_container_high"] + color: ShellSettings.colors["surface_container_high"] Layout.fillWidth: true Layout.preferredHeight: 2 Layout.leftMargin: 8 diff --git a/launcher/Controller.qml b/launcher/Controller.qml index aff6a2c..b7cbab7 100644 --- a/launcher/Controller.qml +++ b/launcher/Controller.qml @@ -44,7 +44,7 @@ Singleton { Rectangle { id: container - color: ShellSettings.settings.colors["surface"] + color: ShellSettings.colors["surface"] radius: 18 anchors { @@ -71,8 +71,8 @@ Singleton { Layout.fillWidth: true implicitHeight: searchbox.implicitHeight + 15 radius: 10 - color: ShellSettings.settings.colors["surface_container"] - border.color: ShellSettings.settings.colors["secondary"] + color: ShellSettings.colors["surface_container"] + border.color: ShellSettings.colors["secondary"] RowLayout { id: searchbox @@ -82,7 +82,7 @@ Singleton { TextInput { id: search Layout.fillWidth: true - color: ShellSettings.settings.colors["inverse_surface"] + color: ShellSettings.colors["inverse_surface"] focus: true Keys.forwardTo: [list] @@ -256,7 +256,7 @@ Singleton { highlight: Rectangle { radius: 12 - color: ShellSettings.settings.colors["primary"] + color: ShellSettings.colors["primary"] } keyNavigationEnabled: true @@ -297,7 +297,7 @@ Singleton { } Text { text: modelData.name - color: ShellSettings.settings.colors["inverse_surface"] + color: ShellSettings.colors["inverse_surface"] Layout.alignment: Qt.AlignVCenter } } diff --git a/notifications/ActiveToast.qml b/notifications/ActiveToast.qml index 3eaea01..0816308 100644 --- a/notifications/ActiveToast.qml +++ b/notifications/ActiveToast.qml @@ -19,7 +19,7 @@ Item { Rectangle { id: container radius: 10 - color: ShellSettings.settings.colors["surface_container"] + color: ShellSettings.colors["surface_container"] anchors.fill: parent Item { @@ -110,7 +110,7 @@ Item { Text { id: appName text: root.notification.appName - color: ShellSettings.settings.colors["inverse_surface"] + color: ShellSettings.colors["inverse_surface"] font.pointSize: 11 font.bold: true elide: Text.ElideRight @@ -124,7 +124,7 @@ Item { Text { id: summaryText text: root.notification.summary - color: ShellSettings.settings.colors["inverse_surface"] + color: ShellSettings.colors["inverse_surface"] font.pointSize: 11 elide: Text.ElideRight maximumLineCount: 1 @@ -156,7 +156,7 @@ Item { ctx.beginPath(); ctx.arc(centerX, centerY, radius, -Math.PI / 2, -Math.PI / 2 + 2 * Math.PI * progress); - ctx.strokeStyle = ShellSettings.settings.colors["primary"]; + ctx.strokeStyle = ShellSettings.colors["primary"]; ctx.lineWidth = 2; ctx.stroke(); } @@ -204,7 +204,7 @@ Item { Text { id: bodyText text: root.notification.body - color: ShellSettings.settings.colors["inverse_surface"] + color: ShellSettings.colors["inverse_surface"] font.pointSize: 11 wrapMode: Text.Wrap elide: Text.ElideRight diff --git a/notifications/NotificationCenter.qml b/notifications/NotificationCenter.qml index bd254ca..b682f68 100644 --- a/notifications/NotificationCenter.qml +++ b/notifications/NotificationCenter.qml @@ -140,7 +140,7 @@ Singleton { required property int index Layout.fillWidth: true Layout.preferredHeight: groupContent.implicitHeight + 24 - color: ShellSettings.settings.colors["surface_container"] + color: ShellSettings.colors["surface_container"] antialiasing: true topLeftRadius: index === 0 ? 25 : 5 @@ -207,7 +207,7 @@ Singleton { text: summaryGroup.modelData.summary font.pixelSize: 16 font.weight: Font.Medium - color: ShellSettings.settings.colors["on_surface"] + color: ShellSettings.colors["on_surface"] wrapMode: Text.WordWrap maximumLineCount: 2 elide: Text.ElideRight @@ -218,7 +218,7 @@ Singleton { Text { text: "now" font.pixelSize: 14 - color: ShellSettings.settings.colors["on_surface_variant"] + color: ShellSettings.colors["on_surface_variant"] Layout.alignment: Qt.AlignVCenter } } @@ -242,7 +242,7 @@ Singleton { Layout.fillWidth: true text: bodyDelegate.modelData.body font.pixelSize: 14 - color: ShellSettings.settings.colors["on_surface_variant"] + color: ShellSettings.colors["on_surface_variant"] wrapMode: Text.WordWrap maximumLineCount: 4 elide: Text.ElideRight diff --git a/settings/Controller.qml b/settings/Controller.qml index 23a0b37..987d47f 100644 --- a/settings/Controller.qml +++ b/settings/Controller.qml @@ -37,7 +37,7 @@ Singleton { activeAsync: persist.windowOpen FloatingWindow { - color: ShellSettings.settings.colors["surface"] + color: ShellSettings.colors["surface"] implicitWidth: 840 implicitHeight: 845 @@ -90,7 +90,7 @@ Singleton { } Rectangle { - color: ShellSettings.settings.colors["surface_container"] + color: ShellSettings.colors["surface_container"] radius: 20 Layout.fillWidth: true Layout.fillHeight: true @@ -122,7 +122,7 @@ Singleton { width: 100 height: 100 - color: paletteSelect.containsMouse ? ShellSettings.settings.colors["surface_container_highest"] : ShellSettings.settings.colors["surface_container_high"] + color: paletteSelect.containsMouse ? ShellSettings.colors["surface_container_highest"] : ShellSettings.colors["surface_container_high"] radius: 20 MouseArea { @@ -214,7 +214,7 @@ Singleton { } Rectangle { - color: ShellSettings.settings.colors["surface_container_high"] + color: ShellSettings.colors["surface_container_high"] Layout.fillWidth: true Layout.preferredHeight: 1 } @@ -251,7 +251,7 @@ Singleton { radius: 20 border { - color: ShellSettings.settings.colors["primary"] + color: ShellSettings.colors["primary"] width: 2 } diff --git a/shell.qml b/shell.qml index f2e6544..5eb81ad 100644 --- a/shell.qml +++ b/shell.qml @@ -1,5 +1,6 @@ //@ pragma UseQApplication //@ pragma IconTheme Papirus-Dark + import Quickshell import QtQuick import "bar" as Bar diff --git a/volume-osd/Controller.qml b/volume-osd/Controller.qml index fabf6bc..96b59c8 100644 --- a/volume-osd/Controller.qml +++ b/volume-osd/Controller.qml @@ -52,26 +52,10 @@ Scope { Rectangle { anchors.fill: parent radius: width / 2 - color: ShellSettings.settings.colors["surface"] + color: ShellSettings.colors["surface"] - Item { - id: sliderContainer - layer.enabled: true - layer.effect: OpacityMask { - source: Rectangle { - width: sliderContainer.width - height: sliderContainer.height - radius: sliderContainer.width / 2 - color: "white" - } - - maskSource: Rectangle { - width: sliderContainer.width - height: sliderContainer.height - radius: sliderContainer.width / 2 - color: "black" - } - } + ColumnLayout { + spacing: 10 anchors { fill: parent @@ -80,24 +64,54 @@ Scope { Rectangle { radius: width / 2 - color: ShellSettings.settings.colors["primary"] - implicitHeight: Math.max(parent.width, parent.height * (Pipewire.defaultAudioSink?.audio.volume ?? 0)) + Layout.fillWidth: true + Layout.preferredHeight: width + } - anchors { - bottom: parent.bottom - left: parent.left - right: parent.right + Rectangle { + id: sliderContainer + color: "gray" + Layout.fillWidth: true + Layout.fillHeight: true + + layer.enabled: true + layer.effect: OpacityMask { + source: Rectangle { + width: sliderContainer.width + height: sliderContainer.height + radius: sliderContainer.width / 2 + color: "white" + } + + maskSource: Rectangle { + width: sliderContainer.width + height: sliderContainer.height + radius: sliderContainer.width / 2 + color: "black" + } } - // replace with material icon - // IconImage { - // implicitSize: parent.width - 4 - // source: "root:resources/volume/volume-full.svg" - // - // anchors { - // horizontalCenter: parent.horizontalCenter - // } - // } + Rectangle { + radius: width / 2 + color: ShellSettings.colors["primary"] + implicitHeight: Math.max(parent.width, parent.height * (Pipewire.defaultAudioSink?.audio.volume ?? 0)) + + anchors { + bottom: parent.bottom + left: parent.left + right: parent.right + } + + // replace with material icon + // IconImage { + // implicitSize: parent.width - 4 + // source: "root:resources/volume/volume-full.svg" + // + // anchors { + // horizontalCenter: parent.horizontalCenter + // } + // } + } } } } @@ -106,7 +120,7 @@ Scope { // anchors.fill: parent // radius: 8 // color: { - // let color = ShellSettings.settings.colors["surface"]; + // let color = ShellSettings.colors["surface"]; // return Qt.rgba(color.r, color.g, color.b, 0.8); // } // @@ -128,7 +142,7 @@ Scope { // implicitHeight: 10 // radius: 20 // color: { - // let color = ShellSettings.settings.colors["inverse_surface"]; + // let color = ShellSettings.colors["inverse_surface"]; // return Qt.rgba(color.r, color.g, color.b, 0.5); // } // @@ -143,7 +157,7 @@ Scope { // } // // Rectangle { - // color: ShellSettings.settings.colors["primary"] + // color: ShellSettings.colors["primary"] // anchors { // left: parent.left // top: parent.top diff --git a/wallpaper/Controller.qml b/wallpaper/Controller.qml index 21e25e4..129a21a 100644 --- a/wallpaper/Controller.qml +++ b/wallpaper/Controller.qml @@ -61,7 +61,7 @@ Scope { onRead: data => { console.log(ShellSettings.settings.colorScheme); try { - ShellSettings.settings.colors = JSON.parse(data)['colors']['dark']; + ShellSettings.colors = JSON.parse(data)['colors']['dark']; } catch (e) {} } } diff --git a/widgets/IconButton.qml b/widgets/IconButton.qml index 110a026..119c971 100644 --- a/widgets/IconButton.qml +++ b/widgets/IconButton.qml @@ -10,8 +10,8 @@ Item { property var padding: 0 property var radius: 20 property var activeRectangle: true - property var color: ShellSettings.settings.colors["inverse_surface"] - property var activeColor: ShellSettings.settings.colors["inverse_primary"] + property var color: ShellSettings.colors["inverse_surface"] + property var activeColor: ShellSettings.colors["inverse_primary"] signal clicked implicitWidth: implicitSize @@ -19,7 +19,7 @@ Item { Rectangle { id: iconBackground - color: ShellSettings.settings.colors["primary"] + color: ShellSettings.colors["primary"] radius: root.radius visible: iconButton.containsMouse && root.activeRectangle anchors.fill: parent diff --git a/widgets/MaterialButton.qml b/widgets/MaterialButton.qml new file mode 100644 index 0000000..7ff6793 --- /dev/null +++ b/widgets/MaterialButton.qml @@ -0,0 +1,3 @@ +import QtQuick + +Rectangle {} diff --git a/widgets/RoundSlider.qml b/widgets/RoundSlider.qml index abdfdd9..0317963 100644 --- a/widgets/RoundSlider.qml +++ b/widgets/RoundSlider.qml @@ -8,13 +8,13 @@ import ".." Slider { id: slider implicitHeight: 8 - property var accentColor: ShellSettings.settings.colors["primary"] + property var accentColor: ShellSettings.colors["primary"] background: Rectangle { id: sliderContainer width: slider.availableWidth height: slider.implicitHeight - color: ShellSettings.settings.colors["inverse_surface"] + color: ShellSettings.colors["inverse_surface"] radius: 4 anchors.verticalCenter: parent.verticalCenter diff --git a/widgets/Separator.qml b/widgets/Separator.qml index 46519cd..b5341a0 100644 --- a/widgets/Separator.qml +++ b/widgets/Separator.qml @@ -2,7 +2,7 @@ import QtQuick import ".." Rectangle { - color: ShellSettings.settings.colors["primary"] + color: ShellSettings.colors["primary"] radius: 5 width: 7.5 height: 7.5 diff --git a/widgets/TextButton.qml b/widgets/TextButton.qml new file mode 100644 index 0000000..25038aa --- /dev/null +++ b/widgets/TextButton.qml @@ -0,0 +1,204 @@ +import QtQuick +import Qt5Compat.GraphicalEffects +import Quickshell +import Quickshell.Widgets +import ".." + +Item { + id: root + property string icon + property bool enabled: true + property bool highlight: true + property bool clickable: false + property bool useMask: true + property bool useVariableFill: false + property real size: 18 + property real outerSize: size + property color hoverColor: ShellSettings.colors["inverse_primary"] + property color iconColor: ShellSettings.colors["primary"] + property real buttonRadius: 6 + property real padding: 4 + + property real fillValue: 0.0 + property real fillTarget: 0.0 + property real fillHover: 1.0 + property real fillNormal: 0.0 + property int fillDuration: 300 + + signal clicked(var mouse) + + implicitWidth: outerSize + (padding * 2) + implicitHeight: outerSize + (padding * 2) + + Rectangle { + id: backgroundRect + anchors.fill: parent + radius: root.buttonRadius + color: mouseArea.containsMouse && root.highlight ? root.hoverColor : "transparent" + visible: root.highlight + + Behavior on color { + ColorAnimation { + duration: 200 + easing.type: Easing.InOutCubic + } + } + } + + NumberAnimation { + id: fillAnimation + target: root + property: "fillValue" + duration: root.fillDuration + easing.type: Easing.OutCubic + to: root.fillTarget + } + + Text { + id: variableFillIcon + visible: root.useVariableFill + anchors.centerIn: parent + font.family: "Material Symbols Outlined" + renderType: Text.NativeRendering + textFormat: Text.PlainText + font.pointSize: root.size * 0.8 + text: root.icon + color: root.enabled ?? root.iconColor + opacity: root.enabled ? 1.0 : 0.5 + + font.variableAxes: { + "FILL": root.fillValue.toFixed(1) + } + + Behavior on color { + ColorAnimation { + duration: 200 + easing.type: Easing.InOutCubic + } + } + } + + Item { + id: maskedIcon + visible: root.useMask && !root.useVariableFill + anchors.centerIn: parent + width: root.size + height: root.size + smooth: true + layer.enabled: true + layer.effect: OpacityMask { + source: Rectangle { + width: root.size + height: root.size + color: "white" + } + maskSource: IconImage { + mipmap: true + implicitSize: root.size + source: Quickshell.iconPath(root.icon) + opacity: root.enabled ? 1.0 : 0.5 + smooth: true + } + } + + transform: Translate { + x: mouseArea.containsMouse ? -1 : 0 + y: mouseArea.containsMouse ? -2 : 0 + + Behavior on x { + NumberAnimation { + duration: 450 + easing.type: Easing.OutElastic + easing.amplitude: 1.0 + easing.period: 0.3 + } + } + + Behavior on y { + NumberAnimation { + duration: 450 + easing.type: Easing.OutElastic + easing.amplitude: 1.0 + easing.period: 0.3 + } + } + } + + Rectangle { + anchors.fill: parent + color: root.enabled ?? root.iconColor + + Behavior on color { + ColorAnimation { + duration: 200 + easing.type: Easing.InOutCubic + } + } + } + } + + IconImage { + id: unmaskedIcon + visible: !root.useMask && !root.useVariableFill + anchors.centerIn: parent + source: Quickshell.iconPath(root.icon) + implicitSize: root.size + opacity: root.enabled ? 1.0 : 0.5 + + transform: Translate { + x: mouseArea.containsMouse ? -1 : 0 + y: mouseArea.containsMouse ? -2 : 0 + + Behavior on x { + NumberAnimation { + duration: 350 + easing.type: Easing.OutElastic + easing.amplitude: 1.0 + easing.period: 0.6 + } + } + + Behavior on y { + NumberAnimation { + duration: 350 + easing.type: Easing.OutElastic + easing.amplitude: 1.0 + easing.period: 0.6 + } + } + } + + Behavior on opacity { + NumberAnimation { + duration: 200 + easing.type: Easing.InOutCubic + } + } + } + + MouseArea { + id: mouseArea + anchors.fill: parent + cursorShape: root.clickable ? Qt.PointingHandCursor : "" + enabled: root.clickable && root.enabled + hoverEnabled: true + acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton + + onClicked: function (mouse) { + root.clicked(mouse); + } + + onContainsMouseChanged: { + if (root.useVariableFill) { + root.fillTarget = containsMouse ? root.fillHover : root.fillNormal; + fillAnimation.restart(); + } + } + } + + Component.onCompleted: { + if (useVariableFill) { + fillValue = fillNormal; + } + } +}