From 073e35381ca481ae957d263a95703a2e184122d8 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Mon, 21 Apr 2025 11:05:18 +0200 Subject: [PATCH] fancier radiobuttons --- .../widgets/NotificationActionButton.qml | 1 + .../common/widgets/NotificationWidget.qml | 8 +- .../common/widgets/notification_utils.js | 9 +- .../volumeMixer/AudioDeviceSelectorButton.qml | 2 +- .../sidebarRight/volumeMixer/VolumeMixer.qml | 93 +++++++++++++++---- 5 files changed, 92 insertions(+), 21 deletions(-) diff --git a/.config/quickshell/modules/common/widgets/NotificationActionButton.qml b/.config/quickshell/modules/common/widgets/NotificationActionButton.qml index 28088d744..a907f3b31 100644 --- a/.config/quickshell/modules/common/widgets/NotificationActionButton.qml +++ b/.config/quickshell/modules/common/widgets/NotificationActionButton.qml @@ -26,6 +26,7 @@ Button { (button.down ? Appearance.colors.colSurfaceContainerHighestActive : button.hovered ? Appearance.colors.colSurfaceContainerHighestHover : Appearance.m3colors.m3surfaceContainerHighest) + } contentItem: StyledText { diff --git a/.config/quickshell/modules/common/widgets/NotificationWidget.qml b/.config/quickshell/modules/common/widgets/NotificationWidget.qml index e3425efc7..5e2763c3f 100644 --- a/.config/quickshell/modules/common/widgets/NotificationWidget.qml +++ b/.config/quickshell/modules/common/widgets/NotificationWidget.qml @@ -251,8 +251,12 @@ Item { color: Appearance.m3colors.m3secondaryContainer MaterialSymbol { visible: notificationObject.appIcon == "" - text: (notificationObject.urgency == NotificationUrgency.Critical) ? "release_alert" : - NotificationUtils.guessMessageType(notificationObject.summary) + text: { + const defaultIcon = NotificationUtils.findSuitableMaterialSymbol("") + const guessedIcon = NotificationUtils.findSuitableMaterialSymbol(notificationObject.summary) + return (notificationObject.urgency == NotificationUrgency.Critical && guessedIcon === defaultIcon) ? + "release_alert" : guessedIcon + } anchors.fill: parent color: (notificationObject.urgency == NotificationUrgency.Critical) ? Appearance.mix(Appearance.m3colors.m3onSecondary, Appearance.m3colors.m3onSecondaryContainer, 0.1) : diff --git a/.config/quickshell/modules/common/widgets/notification_utils.js b/.config/quickshell/modules/common/widgets/notification_utils.js index e7b82cc8e..af97229c1 100644 --- a/.config/quickshell/modules/common/widgets/notification_utils.js +++ b/.config/quickshell/modules/common/widgets/notification_utils.js @@ -1,4 +1,9 @@ -function guessMessageType(summary) { + + +function findSuitableMaterialSymbol(summary = "") { + const defaultType = 'chat'; + if(summary.length === 0) return defaultType; + const keywordsToTypes = { 'reboot': 'restart_alt', 'recording': 'screen_record', @@ -26,7 +31,7 @@ function guessMessageType(summary) { } } - return 'chat'; + return defaultType; } // const getFriendlyNotifTimeString = (timeObject) => { diff --git a/.config/quickshell/modules/sidebarRight/volumeMixer/AudioDeviceSelectorButton.qml b/.config/quickshell/modules/sidebarRight/volumeMixer/AudioDeviceSelectorButton.qml index fc2dd17e7..4b28980f8 100644 --- a/.config/quickshell/modules/sidebarRight/volumeMixer/AudioDeviceSelectorButton.qml +++ b/.config/quickshell/modules/sidebarRight/volumeMixer/AudioDeviceSelectorButton.qml @@ -56,7 +56,7 @@ Button { Layout.fillWidth: true elide: Text.ElideRight font.pixelSize: Appearance.font.pixelSize.smaller - text: input ? Pipewire.defaultAudioSource?.description : Pipewire.defaultAudioSink?.description + text: (input ? Pipewire.defaultAudioSource?.description : Pipewire.defaultAudioSink?.description) ?? "Unknown" color: Appearance.m3colors.m3outline } } diff --git a/.config/quickshell/modules/sidebarRight/volumeMixer/VolumeMixer.qml b/.config/quickshell/modules/sidebarRight/volumeMixer/VolumeMixer.qml index 447422e43..5656cc908 100644 --- a/.config/quickshell/modules/sidebarRight/volumeMixer/VolumeMixer.qml +++ b/.config/quickshell/modules/sidebarRight/volumeMixer/VolumeMixer.qml @@ -200,25 +200,33 @@ Item { ColumnLayout { id: devicesColumnLayout - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right + anchors.fill: parent Layout.fillWidth: true + spacing: 0 Repeater { model: Pipewire.nodes.values.filter(node => { return !node.isStream && node.isSink !== root.deviceSelectorInput && node.audio }) + // This could and should be refractored, but all data becomes null when passed wtf delegate: RadioButton { + id: radioButton Layout.leftMargin: root.dialogMargins Layout.rightMargin: root.dialogMargins Layout.fillWidth: true - leftInset: 4 - rightInset: 4 - topInset: 4 - bottomInset: 4 - checked: modelData.id === Pipewire.defaultAudioSink.id + implicitHeight: 40 + checked: modelData.id === Pipewire.defaultAudioSink?.id + + Connections { + target: root + function onShowDeviceSelectorChanged() { + if(!root.showDeviceSelector) return; + radioButton.checked = (modelData.id === Pipewire.defaultAudioSink?.id) + } + } + + PointingHandInteraction {} onCheckedChanged: { if (checked) { @@ -230,25 +238,75 @@ Item { contentItem: RowLayout { Layout.fillWidth: true - spacing: 8 + spacing: 12 Rectangle { id: radio Layout.fillWidth: false Layout.alignment: Qt.AlignVCenter width: 20 height: 20 - radius: 10 - border.color: checked ? Appearance.m3colors.m3primary : Appearance.m3colors.m3outline + radius: Appearance.rounding.full + border.color: checked ? Appearance.m3colors.m3primary : Appearance.m3colors.m3onSurfaceVariant border.width: 2 color: "transparent" + // Checked indicator Rectangle { anchors.centerIn: parent - width: 10 - height: 10 - radius: 5 - color: checked ? Appearance.m3colors.m3primary : "transparent" - visible: checked + width: checked ? 10 : 4 + height: checked ? 10 : 4 + radius: Appearance.rounding.full + color: Appearance.m3colors.m3primary + opacity: checked ? 1 : 0 + + Behavior on opacity { + NumberAnimation { + duration: Appearance.animation.elementDecelFast.duration + easing.type: Appearance.animation.elementDecelFast.type + } + } + Behavior on width { + NumberAnimation { + duration: Appearance.animation.elementDecelFast.duration + easing.type: Appearance.animation.elementDecelFast.type + } + } + Behavior on height { + NumberAnimation { + duration: Appearance.animation.elementDecelFast.duration + easing.type: Appearance.animation.elementDecelFast.type + } + } + + } + + // Hover + Rectangle { + anchors.centerIn: parent + width: radioButton.hovered ? 40 : 20 + height: radioButton.hovered ? 40 : 20 + radius: Appearance.rounding.full + color: Appearance.m3colors.m3onSurface + opacity: radioButton.hovered ? 0.1 : 0 + + Behavior on opacity { + NumberAnimation { + duration: Appearance.animation.elementDecelFast.duration + easing.type: Appearance.animation.elementDecelFast.type + } + } + Behavior on width { + NumberAnimation { + duration: Appearance.animation.elementDecelFast.duration + easing.type: Appearance.animation.elementDecelFast.type + } + } + Behavior on height { + NumberAnimation { + duration: Appearance.animation.elementDecelFast.duration + easing.type: Appearance.animation.elementDecelFast.type + } + } } } StyledText { @@ -261,6 +319,9 @@ Item { } } } + Item { + implicitHeight: dialogMargins + } } }