diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2017-12-28 11:26:59 +0900 |
---|---|---|
committer | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2017-12-28 11:26:59 +0900 |
commit | a3b9fe1ddd2d3b0a0cbb07ffc42317b30a1a3899 (patch) | |
tree | 206628e68b5f19db48b6bcc03cbaa00ae151fc29 | |
parent | 1dce783c4ac9ca37343648114885d332bdfe7fa1 (diff) | |
download | libquotient-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.cpp | 43 | ||||
-rw-r--r-- | avatar.h | 3 | ||||
-rw-r--r-- | jobs/mediathumbnailjob.cpp | 11 | ||||
-rw-r--r-- | jobs/mediathumbnailjob.h | 6 | ||||
-rw-r--r-- | room.cpp | 7 | ||||
-rw-r--r-- | room.h | 13 | ||||
-rw-r--r-- | user.cpp | 7 | ||||
-rw-r--r-- | user.h | 3 |
8 files changed, 61 insertions, 32 deletions
@@ -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; } @@ -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 @@ -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(); }); @@ -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 @@ -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); }); } @@ -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; |