Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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