import QtQuick import QtQuick.Shapes import qs.widgets.theme // Horizontal meter in the Slant language: a chamfered track whose fill is a // clipped copy of the SAME hexagon, so empty and full always share one // silhouette (the trick the sidebar's volume meter uses vertically). Item { id: bar property real value: 0 // 0..1 property real warn: 0.85 // fraction at which the fill goes hot property bool unknown: false // no reading — draw an empty, dimmed track readonly property real frac: bar.unknown ? 0 : Math.max(0, Math.min(1, bar.value)) readonly property bool hot: !bar.unknown && bar.frac >= bar.warn implicitWidth: 200 implicitHeight: 13 readonly property int chamfer: 5 // Track. Shape { anchors.fill: parent preferredRendererType: Shape.CurveRenderer ShapePath { strokeWidth: 1 strokeColor: bar.unknown ? Theme.disabled : Theme.muted fillColor: Theme.raised startX: bar.chamfer startY: 0 PathLine { x: bar.width; y: 0 } PathLine { x: bar.width; y: bar.height - bar.chamfer } PathLine { x: bar.width - bar.chamfer; y: bar.height } PathLine { x: 0; y: bar.height } PathLine { x: 0; y: bar.chamfer } PathLine { x: bar.chamfer; y: 0 } } } // Fill — revealed from the left. Item { id: fillClip anchors.left: parent.left anchors.leftMargin: 2 anchors.top: parent.top anchors.topMargin: 2 anchors.bottom: parent.bottom anchors.bottomMargin: 2 clip: true width: bar.frac * (bar.width - 4) Behavior on width { NumberAnimation { duration: 220 easing.type: Easing.OutCubic } } Shape { id: fill width: bar.width - 4 height: bar.height - 4 preferredRendererType: Shape.CurveRenderer readonly property int chamfer: bar.chamfer - 2 ShapePath { strokeWidth: 0 fillColor: bar.hot ? Theme.hot : Theme.accent Behavior on fillColor { ColorAnimation { duration: 200 } } startX: fill.chamfer startY: 0 PathLine { x: fill.width; y: 0 } PathLine { x: fill.width; y: fill.height - fill.chamfer } PathLine { x: fill.width - fill.chamfer; y: fill.height } PathLine { x: 0; y: fill.height } PathLine { x: 0; y: fill.chamfer } PathLine { x: fill.chamfer; y: 0 } } } } }