From f75ebb4b5f366274cfa2e9cabdef03dcb042c9e6 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Sat, 7 Nov 2026 11:56:01 +0100 Subject: island: the panel slider as its own file, for the Sonix panel too Co-Authored-By: Claude Sonnet 5.5 --- desktop/island/PanelSlider.qml | 106 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 desktop/island/PanelSlider.qml (limited to 'desktop/island/PanelSlider.qml') 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. +// +// 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 + } +} -- cgit v1.2.3