summaryrefslogtreecommitdiff
path: root/components/effects/ColouredIcon.qml
blob: 8ba6c5de432f997dc48831422a70e049f3c59551 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
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;
        }
    }
}