mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-14 23:34:01 -04:00
97 lines
3.4 KiB
QML
97 lines
3.4 KiB
QML
import QtQuick
|
|
import QtQuick.Window
|
|
import "../../Common/WidgetPlacement.js" as Placement
|
|
|
|
Item {
|
|
id: root
|
|
|
|
required property Item sourceItem
|
|
property string renderKey: ""
|
|
property bool ready: false
|
|
property bool busy: false
|
|
property string capturedKey: ""
|
|
property var capture: null
|
|
readonly property size sourceSize: Qt.size(sourceItem.width, sourceItem.height)
|
|
readonly property real sampleScale: 128 / Math.max(1, sourceItem.width, sourceItem.height)
|
|
readonly property int sampleWidth: Math.max(1, Math.round(sourceItem.width * sampleScale))
|
|
readonly property int sampleHeight: Math.max(1, Math.round(sourceItem.height * sampleScale))
|
|
readonly property bool sourceVisible: sourceItem.visible && (sourceItem.Window.window?.visible ?? false)
|
|
|
|
signal sampled(var luminances, int sampleWidth, int sampleHeight)
|
|
signal failed
|
|
|
|
onRenderKeyChanged: schedule.restart()
|
|
onReadyChanged: schedule.restart()
|
|
onSourceVisibleChanged: schedule.restart()
|
|
onSourceSizeChanged: schedule.restart()
|
|
Component.onCompleted: schedule.restart()
|
|
|
|
function finish() {
|
|
if (capture)
|
|
canvas.unloadImage(capture.url);
|
|
capture = null;
|
|
busy = false;
|
|
if (capturedKey !== renderKey)
|
|
schedule.restart();
|
|
}
|
|
|
|
Timer {
|
|
id: schedule
|
|
interval: 0
|
|
onTriggered: {
|
|
if (!root.ready || !root.sourceVisible || root.busy || !canvas.available || root.sourceItem.width <= 0 || root.sourceItem.height <= 0)
|
|
return;
|
|
root.capturedKey = root.renderKey;
|
|
root.busy = true;
|
|
const started = root.sourceItem.grabToImage(result => {
|
|
if (!root.ready || root.capturedKey !== root.renderKey) {
|
|
root.finish();
|
|
return;
|
|
}
|
|
root.capture = result;
|
|
canvas.loadImage(result.url);
|
|
if (canvas.isImageLoaded(result.url))
|
|
canvas.requestPaint();
|
|
}, Qt.size(root.sampleWidth, root.sampleHeight));
|
|
if (!started) {
|
|
root.finish();
|
|
root.failed();
|
|
}
|
|
}
|
|
}
|
|
|
|
Canvas {
|
|
id: canvas
|
|
width: root.sampleWidth
|
|
height: root.sampleHeight
|
|
opacity: 0
|
|
onAvailableChanged: schedule.restart()
|
|
onImageLoaded: requestPaint()
|
|
onPaint: {
|
|
if (!root.capture)
|
|
return;
|
|
if (isImageError(root.capture.url)) {
|
|
root.finish();
|
|
root.failed();
|
|
return;
|
|
}
|
|
if (!root.ready || root.capturedKey !== root.renderKey) {
|
|
root.finish();
|
|
return;
|
|
}
|
|
if (!isImageLoaded(root.capture.url))
|
|
return;
|
|
const context = getContext("2d");
|
|
context.clearRect(0, 0, width, height);
|
|
context.drawImage(root.capture.url, 0, 0, width, height);
|
|
const pixels = context.getImageData(0, 0, width, height).data;
|
|
const luminances = [];
|
|
for (let i = 0; i < pixels.length; i += 4)
|
|
luminances.push(Placement.luminance(pixels[i] / 255, pixels[i + 1] / 255, pixels[i + 2] / 255));
|
|
context.clearRect(0, 0, width, height);
|
|
root.finish();
|
|
root.sampled(luminances, width, height);
|
|
}
|
|
}
|
|
}
|