// The fifteen seconds a display change has left, drawn as a ring. // // Repainted once per second, when `secondsLeft` changes, and never otherwise: // this shell has no idle animation, and a countdown that redraws every frame // would be one -- on a 240 Hz panel it is 240 repaints to move a number that // changes once. import QtQuick import qs.config Item { id: root property int secondsLeft: 0 property int totalSeconds: 15 implicitWidth: 40 implicitHeight: 40 onSecondsLeftChanged: ring.requestPaint() onTotalSecondsChanged: ring.requestPaint() onVisibleChanged: if (root.visible) ring.requestPaint() Canvas { id: ring anchors.fill: parent onPaint: { const context = ring.getContext("2d"); context.reset(); const stroke = 3.5; const radius = Math.min(ring.width, ring.height) / 2 - stroke / 2 - 1; const centreX = ring.width / 2; const centreY = ring.height / 2; if (radius <= 0) return; context.lineWidth = stroke; context.lineCap = "round"; context.strokeStyle = Theme.alpha(Theme.warn, 0.18); context.beginPath(); context.arc(centreX, centreY, radius, 0, Math.PI * 2); context.stroke(); const remaining = root.totalSeconds > 0 ? Math.max(0, Math.min(1, root.secondsLeft / root.totalSeconds)) : 0; if (remaining <= 0) return; // Twelve o'clock, clockwise, so the arc empties the way a clock // face does rather than unwinding backwards. context.strokeStyle = Theme.warn; context.beginPath(); context.arc(centreX, centreY, radius, -Math.PI / 2, -Math.PI / 2 + remaining * Math.PI * 2); context.stroke(); } } Text { anchors.centerIn: parent text: String(Math.max(0, root.secondsLeft)) color: Theme.warn font.family: Theme.fontFamily font.features: Theme.tabularFigures font.pixelSize: Theme.fontSizeSmall font.weight: Font.DemiBold } }