fancier radiobuttons

This commit is contained in:
end-4
2025-04-21 11:05:18 +02:00
parent eca98598cf
commit 073e35381c
5 changed files with 92 additions and 21 deletions
@@ -26,6 +26,7 @@ Button {
(button.down ? Appearance.colors.colSurfaceContainerHighestActive :
button.hovered ? Appearance.colors.colSurfaceContainerHighestHover :
Appearance.m3colors.m3surfaceContainerHighest)
}
contentItem: StyledText {
@@ -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) :
@@ -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) => {
@@ -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
}
}
@@ -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
}
}
}