mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Make it repaint after downloading the image
This commit is contained in:
parent
6223e3461e
commit
a56d6b084c
|
@ -24,6 +24,7 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
// Duration between each check of every Image instance
|
// Duration between each check of every Image instance
|
||||||
const auto IMAGE_POOL_CLEANUP_INTERVAL = std::chrono::minutes(1);
|
const auto IMAGE_POOL_CLEANUP_INTERVAL = std::chrono::minutes(1);
|
||||||
|
@ -423,7 +424,7 @@ bool Image::loaded() const
|
||||||
return this->frames_->current().has_value();
|
return this->frames_->current().has_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<QPixmap> Image::pixmapOrLoad() const
|
std::optional<QPixmap> Image::pixmapOrLoad(std::function<void()> cb)
|
||||||
{
|
{
|
||||||
assertInGuiThread();
|
assertInGuiThread();
|
||||||
|
|
||||||
|
@ -432,6 +433,10 @@ std::optional<QPixmap> Image::pixmapOrLoad() const
|
||||||
// See src/messages/layouts/MessageLayoutElement.cpp ImageLayoutElement::paint, for example.
|
// See src/messages/layouts/MessageLayoutElement.cpp ImageLayoutElement::paint, for example.
|
||||||
this->lastUsed_ = std::chrono::steady_clock::now();
|
this->lastUsed_ = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
if (cb != nullptr)
|
||||||
|
{
|
||||||
|
this->finishedLoadingCb_ = std::move(cb);
|
||||||
|
}
|
||||||
this->load();
|
this->load();
|
||||||
|
|
||||||
return this->frames_->current();
|
return this->frames_->current();
|
||||||
|
@ -574,6 +579,20 @@ void Image::actuallyLoad()
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
.finally([weak]() {
|
||||||
|
postToThread([weak]() {
|
||||||
|
auto shared = weak.lock();
|
||||||
|
if (!shared)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shared->finishedLoadingCb_ != nullptr)
|
||||||
|
{
|
||||||
|
shared->finishedLoadingCb_();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "common/Aliases.hpp"
|
#include "common/Aliases.hpp"
|
||||||
#include "common/Common.hpp"
|
#include "common/Common.hpp"
|
||||||
|
#include "common/NetworkResult.hpp"
|
||||||
|
|
||||||
#include <boost/variant.hpp>
|
#include <boost/variant.hpp>
|
||||||
#include <pajlada/signals/signal.hpp>
|
#include <pajlada/signals/signal.hpp>
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -80,7 +82,7 @@ public:
|
||||||
const Url &url() const;
|
const Url &url() const;
|
||||||
bool loaded() const;
|
bool loaded() const;
|
||||||
// either returns the current pixmap, or triggers loading it (lazy loading)
|
// either returns the current pixmap, or triggers loading it (lazy loading)
|
||||||
std::optional<QPixmap> pixmapOrLoad() const;
|
std::optional<QPixmap> pixmapOrLoad(std::function<void()> cb = nullptr);
|
||||||
void load() const;
|
void load() const;
|
||||||
qreal scale() const;
|
qreal scale() const;
|
||||||
bool isEmpty() const;
|
bool isEmpty() const;
|
||||||
|
@ -111,6 +113,8 @@ private:
|
||||||
// gui thread only
|
// gui thread only
|
||||||
std::unique_ptr<detail::Frames> frames_{};
|
std::unique_ptr<detail::Frames> frames_{};
|
||||||
|
|
||||||
|
std::function<void()> finishedLoadingCb_;
|
||||||
|
|
||||||
friend class ImageExpirationPool;
|
friend class ImageExpirationPool;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,26 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/QLogging.hpp"
|
||||||
#include "messages/Image.hpp"
|
#include "messages/Image.hpp"
|
||||||
#include "messages/ImageSet.hpp"
|
#include "messages/ImageSet.hpp"
|
||||||
|
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
#include <qnamespace.h>
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QStyledItemDelegate>
|
#include <QStyledItemDelegate>
|
||||||
|
#include <Qt>
|
||||||
|
#include <QTableView>
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
class ImagePtrItemDelegate : public QStyledItemDelegate
|
class ImagePtrItemDelegate : public QStyledItemDelegate
|
||||||
{
|
{
|
||||||
std::map<QString, ImagePtr> ownedImages_;
|
std::map<QString, ImagePtr> ownedImages_;
|
||||||
|
QTableView *view_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
ImagePtrItemDelegate(QTableView *view)
|
||||||
|
: view_(view)
|
||||||
|
{
|
||||||
|
}
|
||||||
static constexpr auto IMAGE_URL_ROLE = Qt::UserRole + 1;
|
static constexpr auto IMAGE_URL_ROLE = Qt::UserRole + 1;
|
||||||
|
|
||||||
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||||
|
@ -27,6 +34,14 @@ public:
|
||||||
auto opt = img->pixmapOrLoad();
|
auto opt = img->pixmapOrLoad();
|
||||||
if (!opt) // wait for next time
|
if (!opt) // wait for next time
|
||||||
{
|
{
|
||||||
|
if (img->isEmpty())
|
||||||
|
{
|
||||||
|
painter->drawText(option.rect, "[Error]");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
painter->drawText(option.rect, "Loading");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto pixmap = *opt;
|
auto pixmap = *opt;
|
||||||
|
@ -56,7 +71,14 @@ public:
|
||||||
}
|
}
|
||||||
auto img = Image::fromUrl(Url{url});
|
auto img = Image::fromUrl(Url{url});
|
||||||
|
|
||||||
img->pixmapOrLoad();
|
img->pixmapOrLoad([this, index]() {
|
||||||
|
// wait for it to parse
|
||||||
|
QTimer::singleShot(100, [this, index]() {
|
||||||
|
this->view_->repaint();
|
||||||
|
this->view_->update(index);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// You cannot stop me, clang-tidy
|
// You cannot stop me, clang-tidy
|
||||||
auto *bleh = const_cast<ImagePtrItemDelegate *>(this);
|
auto *bleh = const_cast<ImagePtrItemDelegate *>(this);
|
||||||
bleh->ownedImages_[url] = img;
|
bleh->ownedImages_[url] = img;
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
ImageUploaderPage::ImageUploaderPage()
|
ImageUploaderPage::ImageUploaderPage()
|
||||||
: imgDelegate_(new ImagePtrItemDelegate())
|
|
||||||
{
|
{
|
||||||
LayoutCreator<ImageUploaderPage> layoutCreator(this);
|
LayoutCreator<ImageUploaderPage> layoutCreator(this);
|
||||||
auto tabs = layoutCreator.emplace<QTabWidget>();
|
auto tabs = layoutCreator.emplace<QTabWidget>();
|
||||||
|
@ -42,6 +41,7 @@ ImageUploaderPage::ImageUploaderPage()
|
||||||
|
|
||||||
auto *view = layout.emplace<QTableView>().getElement();
|
auto *view = layout.emplace<QTableView>().getElement();
|
||||||
view->setModel(model);
|
view->setModel(model);
|
||||||
|
this->imgDelegate_ = new ImagePtrItemDelegate(view);
|
||||||
|
|
||||||
view->setItemDelegateForColumn(0, this->imgDelegate_);
|
view->setItemDelegateForColumn(0, this->imgDelegate_);
|
||||||
view->setSelectionMode(QAbstractItemView::SingleSelection);
|
view->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
|
|
Loading…
Reference in a new issue