summaryrefslogtreecommitdiff
path: root/components/effects/ColouredIcon.qml
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-08-14 16:25:46 +1000
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-08-14 16:25:46 +1000
commit04ce9ccbb4a1b4ee8ee1850f90af886412852b9f (patch)
treeaa2ebf44dc59b5bb56c6c0fd9557f7e82e71d1d4 /components/effects/ColouredIcon.qml
parentnix: extend `hm-module` for CLI config options and add `extraRuntimeDeps` to ... (diff)
downloadcaelestia-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.qml83
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;
+ }
+ }
+}