diff --git a/.config/quickshell/modules/common/widgets/StyledSlider.qml b/.config/quickshell/modules/common/widgets/StyledSlider.qml new file mode 100644 index 00000000..17433c59 --- /dev/null +++ b/.config/quickshell/modules/common/widgets/StyledSlider.qml @@ -0,0 +1,105 @@ +import "root:/modules/common" +import "root:/modules/common/widgets" +import "root:/services" +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell.Widgets + +// Material 3 slider. See https://m3.material.io/components/sliders/overview +Slider { + id: slider + property real scale: 0.85 + property real backgroundDotSize: 4 * scale + property real backgroundDotMargins: 4 * scale + property real handleMargins: (slider.pressed ? 3 : 6) * scale + property real handleWidth: (slider.pressed ? 3 : 5) * scale + property real handleHeight: 44 * scale + property real handleLimit: slider.backgroundDotMargins * scale + + property real limitedHandleRangeWidth: (slider.availableWidth - handleWidth - slider.handleLimit * 2) + Layout.fillWidth: true + from: 0 + to: 1 + + Behavior on value { // This makes the adjusted value (like volume) shift smoothly + SmoothedAnimation { + velocity: Appearance.animation.elementDecel.velocity + } + } + + Behavior on handleMargins { + NumberAnimation { + duration: Appearance.animation.elementDecel.duration + easing.type: Appearance.animation.elementDecel.type + } + } + + MouseArea { + anchors.fill: parent + onPressed: (mouse) => mouse.accepted = false + cursorShape: slider.pressed ? Qt.ClosedHandCursor : Qt.PointingHandCursor + } + + background: Item { + anchors.verticalCenter: parent.verticalCenter + implicitHeight: 12 // Somehow binding this makes it fill height. Must be set with a constant like this + + // Fill left + Rectangle { + anchors.left: parent.left + width: slider.handleLimit + slider.visualPosition * slider.limitedHandleRangeWidth - (slider.handleMargins + slider.handleWidth / 2) + height: parent.height + color: Appearance.m3colors.m3primary + topLeftRadius: Appearance.rounding.full + bottomLeftRadius: Appearance.rounding.full + topRightRadius: Appearance.rounding.unsharpen + bottomRightRadius: Appearance.rounding.unsharpen + } + + // Fill right + Rectangle { + anchors.right: parent.right + width: slider.handleLimit + (1 - slider.visualPosition) * slider.limitedHandleRangeWidth - (slider.handleMargins + slider.handleWidth / 2) + height: parent.height + color: Appearance.m3colors.m3secondaryContainer + topLeftRadius: Appearance.rounding.unsharpen + bottomLeftRadius: Appearance.rounding.unsharpen + topRightRadius: Appearance.rounding.full + bottomRightRadius: Appearance.rounding.full + } + + // Dot at the end + Rectangle { + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: slider.backgroundDotMargins + width: slider.backgroundDotSize + height: slider.backgroundDotSize + radius: Appearance.rounding.full + color: Appearance.m3colors.m3onSecondaryContainer + } + } + + handle: Rectangle { + id: handle + x: slider.leftPadding + slider.handleLimit + slider.visualPosition * slider.limitedHandleRangeWidth + y: slider.topPadding + slider.availableHeight / 2 - height / 2 + implicitWidth: slider.handleWidth + implicitHeight: slider.handleHeight + radius: Appearance.rounding.full + color: Appearance.m3colors.m3onSecondaryContainer + + Behavior on implicitWidth { + NumberAnimation { + duration: Appearance.animation.elementDecel.duration + easing.type: Appearance.animation.elementDecel.type + } + } + + StyledToolTip { + extraVisibleCondition: slider.pressed + content: `${Math.round(slider.value * 100)}%` + } + } +} \ No newline at end of file diff --git a/.config/quickshell/modules/sidebarRight/volumeMixer/VolumeMixer.qml b/.config/quickshell/modules/sidebarRight/volumeMixer/VolumeMixer.qml index 998cdd48..68b96dea 100644 --- a/.config/quickshell/modules/sidebarRight/volumeMixer/VolumeMixer.qml +++ b/.config/quickshell/modules/sidebarRight/volumeMixer/VolumeMixer.qml @@ -15,6 +15,16 @@ Item { id: flickable anchors.fill: parent contentHeight: volumeMixerColumnLayout.height + + layer.enabled: true + layer.effect: OpacityMask { + maskSource: Rectangle { + width: flickable.width + height: flickable.height + radius: Appearance.rounding.normal + } + } + ColumnLayout { id: volumeMixerColumnLayout anchors.top: parent.top diff --git a/.config/quickshell/modules/sidebarRight/volumeMixer/VolumeMixerEntry.qml b/.config/quickshell/modules/sidebarRight/volumeMixer/VolumeMixerEntry.qml index a3898df9..79975135 100644 --- a/.config/quickshell/modules/sidebarRight/volumeMixer/VolumeMixerEntry.qml +++ b/.config/quickshell/modules/sidebarRight/volumeMixer/VolumeMixerEntry.qml @@ -44,101 +44,9 @@ RowLayout { } RowLayout { - Slider { - id: slider - property real backgroundDotSize: 4 - property real backgroundDotMargins: 4 - property real handleMargins: slider.pressed ? 3 : 6 - property real handleWidth: slider.pressed ? 3 : 5 - property real handleHeight: 44 - property real handleLimit: slider.backgroundDotMargins - property real limitedHandleWidth: (slider.availableWidth - handleWidth - slider.handleLimit * 2) - Layout.fillWidth: true + StyledSlider { value: node.audio.volume onValueChanged: node.audio.volume = value - from: 0 - to: 1 - - Behavior on value { // This makes the volume shift smoothly - SmoothedAnimation { - velocity: Appearance.animation.elementDecel.velocity - } - } - - Behavior on handleMargins { - NumberAnimation { - duration: Appearance.animation.elementDecel.duration - easing.type: Appearance.animation.elementDecel.type - } - } - - MouseArea { - anchors.fill: parent - onPressed: (mouse) => mouse.accepted = false - cursorShape: slider.pressed ? Qt.ClosedHandCursor : Qt.PointingHandCursor - } - - background: Item { - anchors.verticalCenter: parent.verticalCenter - implicitHeight: 16 - - // Fill left - Rectangle { - anchors.left: parent.left - width: slider.handleLimit + slider.visualPosition * slider.limitedHandleWidth - (slider.handleMargins + slider.handleWidth / 2) - height: parent.height - color: Appearance.m3colors.m3primary - topLeftRadius: Appearance.rounding.full - bottomLeftRadius: Appearance.rounding.full - topRightRadius: Appearance.rounding.unsharpen - bottomRightRadius: Appearance.rounding.unsharpen - } - - // Fill right - Rectangle { - anchors.right: parent.right - width: slider.handleLimit + (1 - slider.visualPosition) * slider.limitedHandleWidth - (slider.handleMargins + slider.handleWidth / 2) - height: parent.height - color: Appearance.m3colors.m3secondaryContainer - topLeftRadius: Appearance.rounding.unsharpen - bottomLeftRadius: Appearance.rounding.unsharpen - topRightRadius: Appearance.rounding.full - bottomRightRadius: Appearance.rounding.full - } - - // Dot at the end - Rectangle { - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: slider.backgroundDotMargins - width: slider.backgroundDotSize - height: slider.backgroundDotSize - radius: Appearance.rounding.full - color: Appearance.m3colors.m3onSecondaryContainer - } - } - - handle: Rectangle { - id: handle - x: slider.leftPadding + slider.handleLimit + slider.visualPosition * slider.limitedHandleWidth - y: slider.topPadding + slider.availableHeight / 2 - height / 2 - implicitWidth: slider.handleWidth - implicitHeight: slider.handleHeight - radius: Appearance.rounding.full - color: Appearance.m3colors.m3onSecondaryContainer - - Behavior on implicitWidth { - NumberAnimation { - duration: Appearance.animation.elementDecel.duration - easing.type: Appearance.animation.elementDecel.type - } - } - - StyledToolTip { - extraVisibleCondition: slider.pressed - content: `${Math.round(slider.value * 100)}%` - } - } } } }