| 1 | import QtQuick |
| 2 | |
| 3 | // Level slider (control panel): a pill whose filled part is white with the icon in it, the rest a row of dots, |
| 4 | // the value in a chip on the right. Click/drag sets, the wheel steps, the icon end toggles mute (iconClicked). |
| 5 | // Ported from glyph-rice (github.com/Nebelung-cloud/glyph-rice, GPL-3.0), quick/Quick.qml (Slider). |
| 6 | Item { |
| 7 | id: r |
| 8 | property string icon: "" |
| 9 | property real value: 0 |
| 10 | property bool muted: false |
| 11 | property string valueText: Math.round(shown * 100) + "%" |
| 12 | signal moved(real v) |
| 13 | signal iconClicked() |
| 14 | |
| 15 | readonly property real shown: area.pressed ? area.v : value |
| 16 | |
| 17 | implicitWidth: 300 |
| 18 | implicitHeight: 52 |
| 19 | |
| 20 | Rectangle { |
| 21 | anchors.fill: parent |
| 22 | radius: height / 2 |
| 23 | color: Theme.s2 |
| 24 | } |
| 25 | // the empty part: a dot every 11px (the fill covers the rest) |
| 26 | Row { |
| 27 | x: 10 |
| 28 | anchors.verticalCenter: parent.verticalCenter |
| 29 | spacing: 11 - 2.8 |
| 30 | Repeater { |
| 31 | model: Math.max(0, Math.floor((r.width - 20) / 11) + 1) |
| 32 | Rectangle { width: 2.8; height: 2.8; radius: 1.4; color: Theme.mute } |
| 33 | } |
| 34 | } |
| 35 | Rectangle { |
| 36 | width: Math.max(height, r.width * Math.max(0, Math.min(1, r.shown))) |
| 37 | height: parent.height |
| 38 | radius: height / 2 |
| 39 | color: r.muted ? Theme.grey : Theme.fill |
| 40 | Icon { |
| 41 | x: 17 |
| 42 | anchors.verticalCenter: parent.verticalCenter |
| 43 | text: r.icon |
| 44 | font.pixelSize: 20 |
| 45 | color: Theme.fillFg |
| 46 | } |
| 47 | } |
| 48 | Rectangle { |
| 49 | anchors.right: parent.right |
| 50 | anchors.rightMargin: 10 |
| 51 | anchors.verticalCenter: parent.verticalCenter |
| 52 | width: val.implicitWidth + 16 |
| 53 | height: val.implicitHeight + 8 |
| 54 | radius: 10 |
| 55 | color: Theme.s2 |
| 56 | Lb { id: val; anchors.centerIn: parent; text: r.valueText } |
| 57 | } |
| 58 | |
| 59 | MouseArea { |
| 60 | id: area |
| 61 | property real v: 0 |
| 62 | anchors.fill: parent |
| 63 | preventStealing: true |
| 64 | cursorShape: Qt.PointingHandCursor |
| 65 | function set(x) { v = Math.max(0, Math.min(1, x / width)); r.moved(v) } |
| 66 | onPressed: e => set(e.x) |
| 67 | onPositionChanged: e => { if (pressed) set(e.x) } |
| 68 | onWheel: w => r.moved(Math.max(0, Math.min(1, r.value + (w.angleDelta.y > 0 ? 0.02 : -0.02)))) |
| 69 | } |
| 70 | // the icon end: mute |
| 71 | MouseArea { |
| 72 | width: r.height |
| 73 | height: r.height |
| 74 | cursorShape: Qt.PointingHandCursor |
| 75 | onClicked: r.iconClicked() |
| 76 | } |
| 77 | } |