aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/island/PanelSlider.qml
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/island/PanelSlider.qml')
-rw-r--r--desktop/island/PanelSlider.qml106
1 files changed, 106 insertions, 0 deletions
diff --git a/desktop/island/PanelSlider.qml b/desktop/island/PanelSlider.qml
new file mode 100644
index 0000000..bbc0872
--- /dev/null
+++ b/desktop/island/PanelSlider.qml
@@ -0,0 +1,106 @@
+// Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+import Quickshell
+import Quickshell.Widgets
+import QtQuick
+import ".."
+
+// An icon, a track and a label: drag or click sets, the wheel steps one per
+// notch. Shared by the headphones and Sonix panels. The width is the user's.
+Row {
+ id: row
+ property int cp: 0
+ property string icon: ""
+ property real value: 0
+ property bool muted: false
+ property string label: ""
+ signal moved(real v)
+ signal stepped(int d)
+ signal iconClicked()
+
+ spacing: 10
+
+ Item {
+ anchors.verticalCenter: parent.verticalCenter
+ width: 20
+ height: 20
+
+ Text {
+ visible: row.icon === ""
+ anchors.centerIn: parent
+ text: String.fromCodePoint(row.cp)
+ font { family: Theme.iconFamily; pixelSize: 20 }
+ color: Theme.subtext
+ }
+
+ IconImage {
+ visible: row.icon !== ""
+ anchors.centerIn: parent
+ implicitSize: 18
+ source: row.icon !== "" ? Quickshell.iconPath(row.icon, true) : ""
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ enabled: row.enabled
+ cursorShape: Qt.PointingHandCursor
+ onClicked: row.iconClicked()
+ }
+ }
+
+ Rectangle {
+ anchors.verticalCenter: parent.verticalCenter
+ width: row.width - 20 - 44 - row.spacing * 2
+ height: 8
+ radius: 4
+ color: Theme.surface
+
+ Rectangle {
+ height: parent.height
+ radius: parent.radius
+ width: parent.width * Math.max(0, Math.min(1, row.value))
+ color: row.muted ? Theme.red : Theme.accent
+ opacity: row.muted ? 0.5 : 1
+ }
+
+ // Taller than the track so it is easy to hit. A MouseArea for the
+ // wheel, not a WheelHandler (AGENTS.md); one step per notch (120),
+ // since a touchpad sends many small deltas.
+ MouseArea {
+ anchors { fill: parent; topMargin: -8; bottomMargin: -8 }
+ enabled: row.enabled
+ preventStealing: true
+ cursorShape: Qt.PointingHandCursor
+ property real acc: 0
+ function at(x) { return Math.max(0, Math.min(1, x / width)); }
+ onPressed: mouse => row.moved(at(mouse.x))
+ onPositionChanged: mouse => { if (pressed) row.moved(at(mouse.x)); }
+ onWheel: wheel => {
+ acc += wheel.angleDelta.y;
+ while (Math.abs(acc) >= 120) {
+ row.stepped(acc > 0 ? 1 : -1);
+ acc -= acc > 0 ? 120 : -120;
+ }
+ wheel.accepted = true;
+ }
+ }
+ }
+
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ width: 44
+ horizontalAlignment: Text.AlignRight
+ text: row.label
+ font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 }
+ color: row.muted ? Theme.red : Theme.subtext
+ }
+}