diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5d453f707..aa91ecd83 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -636,6 +636,7 @@ set(SOURCE_FILES widgets/listview/GenericListModel.hpp widgets/listview/GenericListView.cpp widgets/listview/GenericListView.hpp + widgets/listview/ImagePtrItemDelegate.hpp widgets/settingspages/AboutPage.cpp widgets/settingspages/AboutPage.hpp diff --git a/src/widgets/listview/ImagePtrItemDelegate.hpp b/src/widgets/listview/ImagePtrItemDelegate.hpp new file mode 100644 index 000000000..7b7a5163e --- /dev/null +++ b/src/widgets/listview/ImagePtrItemDelegate.hpp @@ -0,0 +1,70 @@ +#pragma once + +#include "messages/Image.hpp" +#include "messages/ImageSet.hpp" + +#include +#include +#include +#include + +namespace chatterino { +class ImagePtrItemDelegate : public QStyledItemDelegate +{ + std::map ownedImages_; + +public: + static constexpr auto IMAGE_URL_ROLE = Qt::UserRole + 1; + + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const override + { + auto url = index.data(IMAGE_URL_ROLE).toString(); + if (auto it = this->ownedImages_.find(url); + it != this->ownedImages_.end()) + { + auto img = it->second; + auto opt = img->pixmapOrLoad(); + if (!opt) // wait for next time + { + return; + } + auto pixmap = *opt; + double aspectRatio = + double(pixmap.width()) / double(pixmap.height()); + int width = int(option.rect.height() * aspectRatio); + auto outputRect = QRect(option.rect.topLeft(), + QSize(width, option.rect.height())); + if (option.rect.width() < width) + { + // too wide? + + double revAspectRatio = + double(pixmap.height()) / double(pixmap.width()); + int height = int(option.rect.width() * revAspectRatio); + + outputRect = QRect(option.rect.topLeft(), + QSize(option.rect.width(), height)); + if (option.rect.height() < height) + { + // give up and squish the image + outputRect = option.rect; + } + } + + painter->drawPixmap(outputRect, pixmap, pixmap.rect()); + } + auto img = Image::fromUrl(Url{url}); + + img->pixmapOrLoad(); + // You cannot stop me, clang-tidy + auto *bleh = const_cast(this); + bleh->ownedImages_[url] = img; + } + QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const override + { + return {32, 32}; + } +}; +} // namespace chatterino