diff --git a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp index 88351f8d5a..28b1f5f66f 100644 --- a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp +++ b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp @@ -2148,10 +2148,19 @@ void ListWidget::performDrag() { auto mimeData = std::make_unique(); mimeData->setUrls({ QUrl::fromLocalFile(filepath) }); + auto pixmap = QPixmap(); + if (const auto layout = _provider->lookupLayout(_pressState.item)) { + if (const auto file = dynamic_cast( + layout)) { + pixmap = Ui::PixmapFromImage(file->dragPreviewImage()); + } + } + // This call enters event loop and can destroy any QObject. _controller->parentController()->widget()->launchDrag( std::move(mimeData), - crl::guard(this, [=] { mouseActionUpdate(QCursor::pos()); })); + crl::guard(this, [=] { mouseActionUpdate(QCursor::pos()); }), + std::move(pixmap)); } void ListWidget::mouseActionFinish( diff --git a/Telegram/SourceFiles/overview/overview_layout.cpp b/Telegram/SourceFiles/overview/overview_layout.cpp index b02785e41f..0098f16c03 100644 --- a/Telegram/SourceFiles/overview/overview_layout.cpp +++ b/Telegram/SourceFiles/overview/overview_layout.cpp @@ -1385,54 +1385,7 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con QRect rthumb(style::rtlrect(0, st::linksBorder + _st.filePadding.top(), _st.fileThumbSize, _st.fileThumbSize, _width)); if (clip.intersects(rthumb)) { - if (wthumb) { - ensureDataMediaCreated(); - const auto good = _data->isSvgImage() - ? _dataMedia->goodThumbnail() - : nullptr; - const auto thumbnail = good - ? good - : _dataMedia->thumbnail(); - const auto blurred = _dataMedia->thumbnailInline(); - if (thumbnail || blurred) { - if (_thumb.isNull() || (thumbnail && !_thumbLoaded)) { - _thumbLoaded = (thumbnail != nullptr); - const auto options = Images::Option::RoundSmall - | (_thumbLoaded - ? Images::Option() - : Images::Option::Blur); - const auto image = thumbnail ? thumbnail : blurred; - _thumb = image->pixNoCache( - _thumbw * style::DevicePixelRatio(), - { - .options = options, - .outer = QSize( - _st.fileThumbSize, - _st.fileThumbSize), - }); - } - p.drawPixmap(rthumb.topLeft(), _thumb); - } else { - p.setPen(Qt::NoPen); - p.setBrush(st::overviewFileThumbBg); - p.drawRoundedRect( - rthumb, - st::roundRadiusSmall, - st::roundRadiusSmall); - } - } else { - p.setPen(Qt::NoPen); - p.setBrush(_generic.color); - p.drawRoundedRect( - rthumb, - st::roundRadiusSmall, - st::roundRadiusSmall); - if (!radial && loaded && !_ext.isEmpty()) { - p.setFont(st::overviewFileExtFont); - p.setPen(st::overviewFileExtFg); - p.drawText(rthumb.left() + (rthumb.width() - _extw) / 2, rthumb.top() + st::overviewFileExtTop + st::overviewFileExtFont->ascent, _ext); - } - } + paintThumbnail(p, rthumb, wthumb, !radial && loaded); if (selected) { p.setPen(Qt::NoPen); p.setBrush(st::defaultTextPalette.selectOverlay); @@ -1516,6 +1469,85 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con paintCheckbox(p, { checkLeft, checkTop }, selected, context); } +void Document::paintThumbnail( + Painter &p, + QRect rthumb, + bool wthumb, + bool withExt) { + if (wthumb) { + ensureDataMediaCreated(); + const auto good = _data->isSvgImage() + ? _dataMedia->goodThumbnail() + : nullptr; + const auto thumbnail = good + ? good + : _dataMedia->thumbnail(); + const auto blurred = _dataMedia->thumbnailInline(); + if (thumbnail || blurred) { + if (_thumb.isNull() || (thumbnail && !_thumbLoaded)) { + _thumbLoaded = (thumbnail != nullptr); + const auto options = Images::Option::RoundSmall + | (_thumbLoaded + ? Images::Option() + : Images::Option::Blur); + const auto image = thumbnail ? thumbnail : blurred; + _thumb = image->pixNoCache( + _thumbw * style::DevicePixelRatio(), + { + .options = options, + .outer = QSize( + _st.fileThumbSize, + _st.fileThumbSize), + }); + } + p.drawPixmap(rthumb.topLeft(), _thumb); + } else { + p.setPen(Qt::NoPen); + p.setBrush(st::overviewFileThumbBg); + p.drawRoundedRect( + rthumb, + st::roundRadiusSmall, + st::roundRadiusSmall); + } + } else { + p.setPen(Qt::NoPen); + p.setBrush(_generic.color); + p.drawRoundedRect( + rthumb, + st::roundRadiusSmall, + st::roundRadiusSmall); + if (withExt && !_ext.isEmpty()) { + p.setFont(st::overviewFileExtFont); + p.setPen(st::overviewFileExtFg); + p.drawText( + rthumb.left() + (rthumb.width() - _extw) / 2, + rthumb.top() + + st::overviewFileExtTop + + st::overviewFileExtFont->ascent, + _ext); + } + } +} + +QImage Document::dragPreviewImage() { + ensureDataMediaCreated(); + const auto ratio = style::DevicePixelRatio(); + auto result = QImage( + QSize(_st.fileThumbSize, _st.fileThumbSize) * ratio, + QImage::Format_ARGB32_Premultiplied); + result.setDevicePixelRatio(ratio); + result.fill(Qt::transparent); + + auto p = Painter(&result); + auto hq = PainterHighQualityEnabler(p); + paintThumbnail( + p, + QRect(0, 0, _st.fileThumbSize, _st.fileThumbSize), + withThumb(), + true); + return result; +} + void Document::drawCornerDownload(QPainter &p, bool selected, const PaintContext *context) const { if (dataLoaded() || _data->loadedInMediaCache() diff --git a/Telegram/SourceFiles/overview/overview_layout.h b/Telegram/SourceFiles/overview/overview_layout.h index 70096a32ff..6613d8fdad 100644 --- a/Telegram/SourceFiles/overview/overview_layout.h +++ b/Telegram/SourceFiles/overview/overview_layout.h @@ -422,6 +422,8 @@ public: void clearHeavyPart() override; + [[nodiscard]] QImage dragPreviewImage(); + protected: float64 dataProgress() const override; bool dataFinished() const override; @@ -438,6 +440,7 @@ private: [[nodiscard]] bool songLayout() const; void ensureDataMediaCreated() const; + void paintThumbnail(Painter &p, QRect rthumb, bool wthumb, bool withExt); not_null _data; mutable std::shared_ptr _dataMedia;