import QtQuick
import org.kde.kirigami as Kirigami
import "Lambent.js" as L
// One place (or device) as a dot. Lit, it is cut into wedges, one per
// preview pixel of whatever is driving it, so a rainbow reads as a rainbow
// rather than averaging out to grey; dark, it is a hollow ring. A clamp
// still walking toward its target pulses a halo.
Item {
id: circle
property bool lit: false
property var pixels: []
property real level: 1 // 0..1, both clamps multiplied
property bool walking: false
property bool highlighted: false
implicitWidth: Kirigami.Units.iconSizes.small
implicitHeight: implicitWidth
// Never draw a lit circle fully black: a dim room should still read
// as "on" next to one that is off.
readonly property real shown: 0.3 + 0.7 * Math.max(0, Math.min(1, level))
onPixelsChanged: canvas.requestPaint()
onLitChanged: canvas.requestPaint()
onShownChanged: canvas.requestPaint()
Rectangle {
id: halo
anchors.centerIn: parent
width: parent.width
height: width
radius: width / 2
color: "transparent"
border.color: Kirigami.Theme.highlightColor
border.width: 1
opacity: 0
visible: circle.walking
SequentialAnimation on opacity {
running: halo.visible
loops: Animation.Infinite
NumberAnimation { from: 0.8; to: 0; duration: 1200; easing.type: Easing.OutQuad }
}
SequentialAnimation on scale {
running: halo.visible
loops: Animation.Infinite
NumberAnimation { from: 0.7; to: 1.3; duration: 1200; easing.type: Easing.OutQuad }
}
}
Canvas {
id: canvas
anchors.centerIn: parent
width: parent.width * (circle.highlighted ? 0.85 : 0.7)
height: width
onWidthChanged: requestPaint()
Behavior on width { NumberAnimation { duration: Kirigami.Units.shortDuration } }
onPaint: {
var ctx = getContext("2d")
ctx.reset()
var r = width / 2
if (r <= 0) return
if (!circle.lit) {
var lw = Math.max(1.5, width / 6)
ctx.beginPath()
ctx.arc(r, r, r - lw / 2, 0, Math.PI * 2)
ctx.lineWidth = lw
ctx.strokeStyle = Kirigami.Theme.disabledTextColor
ctx.stroke()
return
}
var px = circle.pixels || []
if (px.length === 0) {
ctx.beginPath()
ctx.arc(r, r, r, 0, Math.PI * 2)
var c = Kirigami.Theme.highlightColor
ctx.fillStyle = L.cssRgb([c.r * 255, c.g * 255, c.b * 255], circle.shown)
ctx.fill()
return
}
var step = Math.PI * 2 / px.length
var start = -Math.PI / 2
for (var i = 0; i < px.length; i++) {
ctx.beginPath()
ctx.moveTo(r, r)
// a hair of overlap so antialiasing leaves no seams
ctx.arc(r, r, r, start + i * step, start + (i + 1) * step + 0.02)
ctx.closePath()
ctx.fillStyle = L.cssRgb(px[i], circle.shown)
ctx.fill()
}
// a thin rim so a near-black frame still has an edge
ctx.beginPath()
ctx.arc(r, r, r - 0.5, 0, Math.PI * 2)
ctx.lineWidth = 1
ctx.strokeStyle = Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.35)
ctx.stroke()
}
}
}
neiam
/lambent-ex-plasmoid
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
3.6 KiB · text
History
e43831b