Skip to content
1 change: 1 addition & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ qt_add_library(quickshell-core STATIC
scriptmodel.cpp
colorquantizer.cpp
toolsupport.cpp
itemimagegrab.cpp
)

qt_add_qml_module(quickshell-core
Expand Down
67 changes: 67 additions & 0 deletions src/core/itemimagegrab.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include "itemimagegrab.hpp"

#include <qobject.h>
#include <qquickitem.h>
#include <qquickitemgrabresult.h>
#include <qsize.h>
#include <qthreadpool.h>
#include <qtmetamacros.h>

void ItemImageGrab::grab(QQuickItem* target, const QUrl& path) {
this->grab(target, path, QSize());
}

void ItemImageGrab::grab(QQuickItem* target, const QUrl& path, const QSize& targetSize) {
this->cropAndGrab(target, path, QRect(), targetSize);
}

void ItemImageGrab::cropAndGrab(QQuickItem* target, const QUrl& path, const QRect& rect) {
this->cropAndGrab(target, path, rect, QSize());
}

void ItemImageGrab::cropAndGrab(
QQuickItem* target,
const QUrl& path,
const QRect& rect,
const QSize& targetSize
) {
if (!target) {
qWarning() << "ItemImageGrab: a target is required";
return;
}

if (!path.isLocalFile()) {
qWarning() << "ItemImageGrab: can only save to a file on the local filesystem";
return;
}

QSharedPointer<QQuickItemGrabResult> grabResult;
if (targetSize.isEmpty()) {
grabResult = target->grabToImage();
} else {
grabResult = target->grabToImage(targetSize);
}

QObject::connect(
grabResult.data(),
&QQuickItemGrabResult::ready,
this,
[grabResult, rect, path, this]() {
QThreadPool::globalInstance()->start([grabResult, rect, path, this] {
QImage image = grabResult->image();

if (!rect.isEmpty()) {
image = image.copy(rect);
}

const QString localFile = path.toLocalFile();

if (image.save(localFile)) {
emit this->saved(localFile, path);
} else {
emit this->failed(path);
}
});
}
);
}
25 changes: 25 additions & 0 deletions src/core/itemimagegrab.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <qobject.h>
#include <qquickitem.h>
#include <qsize.h>

/// Allows for saving an item grab to an file asynchronously.
class ItemImageGrab: public QObject {
Q_OBJECT;
QML_ELEMENT;

public:
explicit ItemImageGrab(QObject* parent = nullptr): QObject(parent) {};

Q_INVOKABLE void grab(QQuickItem* target, const QUrl& path);
Q_INVOKABLE void grab(QQuickItem* target, const QUrl& path, const QSize& targetSize);

Q_INVOKABLE void cropAndGrab(QQuickItem* target, const QUrl& path, const QRect& rect);
Q_INVOKABLE void
cropAndGrab(QQuickItem* target, const QUrl& path, const QRect& rect, const QSize& targetSize);

signals:
void saved(const QString& file, const QUrl& path);
void failed(const QUrl& path);
};
1 change: 1 addition & 0 deletions src/core/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ headers = [
"clock.hpp",
"scriptmodel.hpp",
"colorquantizer.hpp",
"itemimagegrab.hpp",
]
-----
Loading