blob: bbc087270628e3a885dc30b7367e394ff4cc7b61 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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
}
}
|