aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2017-12-28 11:26:59 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2017-12-28 11:26:59 +0900
commita3b9fe1ddd2d3b0a0cbb07ffc42317b30a1a3899 (patch)
tree206628e68b5f19db48b6bcc03cbaa00ae151fc29
parent1dce783c4ac9ca37343648114885d332bdfe7fa1 (diff)
downloadlibquotient-a3b9fe1ddd2d3b0a0cbb07ffc42317b30a1a3899.tar.gz
libquotient-a3b9fe1ddd2d3b0a0cbb07ffc42317b30a1a3899.zip
Switch from QPixmap to QImage; add convenience avatar() overloads to Room and User
The switch is necessary because MediaThumbnailJob is supposed to return something that can be worked on in non-GUI threads (as is the case of QML image providers), and QPixmap is not supposed for usage out of the main thread.
-rw-r--r--avatar.cpp43
-rw-r--r--avatar.h3
-rw-r--r--jobs/mediathumbnailjob.cpp11
-rw-r--r--jobs/mediathumbnailjob.h6
-rw-r--r--room.cpp7
-rw-r--r--room.h13
-rw-r--r--user.cpp7
-rw-r--r--user.h3
8 files changed, 61 insertions, 32 deletions
diff --git a/avatar.cpp b/avatar.cpp
index b2f50a67..9490347d 100644
--- a/avatar.cpp
+++ b/avatar.cpp
@@ -22,20 +22,22 @@
#include "events/eventcontent.h"
#include "connection.h"
+#include <QtGui/QPainter>
+
using namespace QMatrixClient;
class Avatar::Private
{
public:
Private(Connection* c, QIcon di) : _connection(c), _defaultIcon(di) { }
- QPixmap get(int width, int height, Avatar::notifier_t notifier);
+ QImage get(QSize size, Avatar::notifier_t notifier);
Connection* _connection;
const QIcon _defaultIcon;
QUrl _url;
- QPixmap _originalPixmap;
+ QImage _originalImage;
- std::vector<QPair<QSize, QPixmap>> _scaledPixmaps;
+ std::vector<QPair<QSize, QImage>> _scaledImages;
QSize _requestedSize;
bool _valid = false;
@@ -49,22 +51,25 @@ Avatar::Avatar(Connection* connection, QIcon defaultIcon)
Avatar::~Avatar() = default;
-QPixmap Avatar::get(int width, int height, Avatar::notifier_t notifier)
+QImage Avatar::get(int dimension, Avatar::notifier_t notifier)
{
- return d->get(width, height, notifier);
+ return d->get({dimension, dimension}, notifier);
}
-QPixmap Avatar::Private::get(int width, int height, Avatar::notifier_t notifier)
+QImage Avatar::get(int width, int height, Avatar::notifier_t notifier)
{
- QSize size(width, height);
+ return d->get({width, height}, notifier);
+}
+QImage Avatar::Private::get(QSize size, Avatar::notifier_t notifier)
+{
// FIXME: Alternating between longer-width and longer-height requests
// is a sure way to trick the below code into constantly getting another
// image from the server because the existing one is alleged unsatisfactory.
// This is plain abuse by the client, though; so not critical for now.
if( ( !(_valid || _ongoingRequest)
- || width > _requestedSize.width()
- || height > _requestedSize.height() ) && _url.isValid() )
+ || size.width() > _requestedSize.width()
+ || size.height() > _requestedSize.height() ) && _url.isValid() )
{
qCDebug(MAIN) << "Getting avatar from" << _url.toString();
_requestedSize = size;
@@ -77,8 +82,9 @@ QPixmap Avatar::Private::get(int width, int height, Avatar::notifier_t notifier)
if (_ongoingRequest->status().good())
{
_valid = true;
- _originalPixmap = _ongoingRequest->scaledThumbnail(_requestedSize);
- _scaledPixmaps.clear();
+ _originalImage =
+ _ongoingRequest->scaledThumbnail(_requestedSize);
+ _scaledImages.clear();
for (auto n: notifiers)
n();
}
@@ -86,21 +92,22 @@ QPixmap Avatar::Private::get(int width, int height, Avatar::notifier_t notifier)
});
}
- if( _originalPixmap.isNull() )
+ if( _originalImage.isNull() )
{
if (_defaultIcon.isNull())
- return _originalPixmap;
+ return _originalImage;
- _originalPixmap = _defaultIcon.pixmap(size);
+ QPainter p { &_originalImage };
+ _defaultIcon.paint(&p, { QPoint(), _defaultIcon.actualSize(size) });
}
- for (auto p: _scaledPixmaps)
+ for (auto p: _scaledImages)
if (p.first == size)
return p.second;
- auto pixmap = _originalPixmap.scaled(size,
+ auto result = _originalImage.scaled(size,
Qt::KeepAspectRatio, Qt::SmoothTransformation);
- _scaledPixmaps.emplace_back(size, pixmap);
- return pixmap;
+ _scaledImages.emplace_back(size, result);
+ return result;
}
QUrl Avatar::url() const { return d->_url; }
diff --git a/avatar.h b/avatar.h
index e71fecd7..d8b4b206 100644
--- a/avatar.h
+++ b/avatar.h
@@ -36,7 +36,8 @@ namespace QMatrixClient
using notifier_t = std::function<void()>;
- QPixmap get(int w, int h, notifier_t notifier);
+ QImage get(int dimension, notifier_t notifier);
+ QImage get(int w, int h, notifier_t notifier);
QUrl url() const;
bool updateUrl(const QUrl& newUrl);
diff --git a/jobs/mediathumbnailjob.cpp b/jobs/mediathumbnailjob.cpp
index 5945493a..c0d67a63 100644
--- a/jobs/mediathumbnailjob.cpp
+++ b/jobs/mediathumbnailjob.cpp
@@ -36,19 +36,20 @@ MediaThumbnailJob::MediaThumbnailJob(QUrl url, QSize requestedSize,
}))
{ }
-QPixmap MediaThumbnailJob::thumbnail() const
+QImage MediaThumbnailJob::thumbnail() const
{
- return pixmap;
+ return _thumbnail;
}
-QPixmap MediaThumbnailJob::scaledThumbnail(QSize toSize) const
+QImage MediaThumbnailJob::scaledThumbnail(QSize toSize) const
{
- return pixmap.scaled(toSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ return _thumbnail.scaled(toSize,
+ Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
BaseJob::Status MediaThumbnailJob::parseReply(QByteArray data)
{
- if( !pixmap.loadFromData(data) )
+ if( !_thumbnail.loadFromData(data) )
{
qCDebug(JOBS) << "MediaThumbnailJob: could not read image data";
}
diff --git a/jobs/mediathumbnailjob.h b/jobs/mediathumbnailjob.h
index 292e7f14..f8f36fe9 100644
--- a/jobs/mediathumbnailjob.h
+++ b/jobs/mediathumbnailjob.h
@@ -32,13 +32,13 @@ namespace QMatrixClient
MediaThumbnailJob(QUrl url, QSize requestedSize,
ThumbnailType thumbnailType = ThumbnailType::Scale);
- QPixmap thumbnail() const;
- QPixmap scaledThumbnail(QSize toSize) const;
+ QImage thumbnail() const;
+ QImage scaledThumbnail(QSize toSize) const;
protected:
Status parseReply(QByteArray data) override;
private:
- QPixmap pixmap;
+ QImage _thumbnail;
};
} // namespace QMatrixClient
diff --git a/room.cpp b/room.cpp
index 0024683d..1e159fd5 100644
--- a/room.cpp
+++ b/room.cpp
@@ -214,7 +214,12 @@ QString Room::topic() const
return d->topic;
}
-QPixmap Room::avatar(int width, int height)
+QImage Room::avatar(int dimension)
+{
+ return avatar(dimension, dimension);
+}
+
+QImage Room::avatar(int width, int height)
{
if (!d->avatar.url().isEmpty())
return d->avatar.get(width, height, [=] { emit avatarChanged(); });
diff --git a/room.h b/room.h
index 9a458c4e..f863d41b 100644
--- a/room.h
+++ b/room.h
@@ -108,11 +108,20 @@ namespace QMatrixClient
Q_INVOKABLE int timelineSize() const;
/**
- * Returns a room avatar and requests it from the network if needed
+ * Returns a square room avatar with the given size and requests it
+ * from the network if needed
* @return a pixmap with the avatar or a placeholder if there's none
* available yet
*/
- Q_INVOKABLE QPixmap avatar(int width, int height);
+ Q_INVOKABLE QImage avatar(int dimension);
+ /**
+ * Returns a room avatar with the given dimensions and requests it
+ * from the network if needed
+ * @return a pixmap with the avatar or a placeholder if there's none
+ * available yet
+ */
+ Q_INVOKABLE QImage avatar(int width, int height);
+
/**
* @brief Produces a disambiguated name for a given user in
* the context of the room
diff --git a/user.cpp b/user.cpp
index faad6231..6d2a2030 100644
--- a/user.cpp
+++ b/user.cpp
@@ -95,7 +95,12 @@ Avatar& User::avatarObject()
return d->avatar;
}
-QPixmap User::avatar(int width, int height)
+QImage User::avatar(int dimension)
+{
+ return avatar(dimension, dimension);
+}
+
+QImage User::avatar(int width, int height)
{
return d->avatar.get(width, height, [=] { emit avatarChanged(this); });
}
diff --git a/user.h b/user.h
index 148ed64d..b7d67fb2 100644
--- a/user.h
+++ b/user.h
@@ -54,7 +54,8 @@ namespace QMatrixClient
Q_INVOKABLE QString bridged() const;
Avatar& avatarObject();
- QPixmap avatar(int requestedWidth, int requestedHeight);
+ QImage avatar(int dimension);
+ QImage avatar(int requestedWidth, int requestedHeight);
QUrl avatarUrl() const;