diff options
| author | 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> | 2025-08-14 16:25:46 +1000 |
|---|---|---|
| committer | 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> | 2025-08-14 16:25:46 +1000 |
| commit | 04ce9ccbb4a1b4ee8ee1850f90af886412852b9f (patch) | |
| tree | aa2ebf44dc59b5bb56c6c0fd9557f7e82e71d1d4 /components/effects/ColouredIcon.qml | |
| parent | nix: extend `hm-module` for CLI config options and add `extraRuntimeDeps` to ... (diff) | |
| download | caelestia-shell-04ce9ccbb4a1b4ee8ee1850f90af886412852b9f.tar.gz caelestia-shell-04ce9ccbb4a1b4ee8ee1850f90af886412852b9f.tar.bz2 caelestia-shell-04ce9ccbb4a1b4ee8ee1850f90af886412852b9f.zip | |
internal: better colourisation
Diffstat (limited to 'components/effects/ColouredIcon.qml')
| -rw-r--r-- | components/effects/ColouredIcon.qml | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/components/effects/ColouredIcon.qml b/components/effects/ColouredIcon.qml new file mode 100644 index 0000000..8ba6c5d --- /dev/null +++ b/components/effects/ColouredIcon.qml @@ -0,0 +1,83 @@ +pragma ComponentBehavior: Bound + +import Quickshell.Widgets +import QtQuick + +IconImage { + id: root + + required property color colour + property color sourceColour + property url lastSource + + asynchronous: true + + layer.enabled: true + layer.effect: Colouriser { + sourceColor: root.sourceColour + colorizationColor: root.colour + } + + layer.onEnabledChanged: { + if (layer.enabled) + canvas.requestPaint(); + } + + onStatusChanged: { + if (layer.enabled && status === Image.Ready) + canvas.requestPaint(); + } + + Canvas { + id: canvas + + property int retryCount + + implicitWidth: 32 + implicitHeight: 32 + visible: false + + onPaint: { + if (!root.layer.enabled) + return; + + const ctx = getContext("2d"); + ctx.reset(); + ctx.drawImage(root.backer, 0, 0, width, height); + + const colours = {} as Object; + const data = ctx.getImageData(0, 0, width, height).data; + + for (let i = 0; i < data.length; i += 4) { + if (data[i + 3] === 0) + continue; + + const c = `${data[i]},${data[i + 1]},${data[i + 2]}`; + if (colours.hasOwnProperty(c)) + colours[c]++; + else + colours[c] = 1; + } + + // Canvas is empty, try again next frame + if (retryCount < 5 && !Object.keys(colours).length) { + retryCount++; + Qt.callLater(() => requestPaint()); + return; + } + + let max = 0; + let maxColour = "0,0,0"; + for (const [colour, occurences] of Object.entries(colours)) { + if (occurences > max) { + max = occurences; + maxColour = colour; + } + } + + const [r, g, b] = maxColour.split(","); + root.sourceColour = Qt.rgba(r / 255, g / 255, b / 255, 1); + retryCount = 0; + } + } +} |