From 6869cc7d04f5f8074a7cdd3e199af5d3b5d6902d Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 6 Jun 2017 12:15:13 +0300 Subject: [PATCH] Fix non-square reply preview in selected messages. After introducing video messages and sticker reply previews they may be not a rounded rectangle but any transparent image. So instead of painting a selected rounded rect over them we just colorize them with an overlay color like it is done with the selected sticker images. --- .../SourceFiles/history/history_message.cpp | 10 +++---- Telegram/SourceFiles/ui/images.cpp | 27 ++++++++++++++----- Telegram/SourceFiles/ui/images.h | 10 +++---- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index 939493f69..9b8561b7c 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -271,11 +271,11 @@ void HistoryMessageReply::paint(Painter &p, const HistoryItem *holder, int x, in if (hasPreview) { ImagePtr replyPreview = replyToMsg->getMedia()->replyPreview(); if (!replyPreview->isNull()) { - QRect to(rtlrect(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height(), w + 2 * x)); - p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small)); - if (selected) { - App::roundRect(p, to, p.textPalette().selectOverlay, SelectedOverlaySmallCorners); - } + auto to = rtlrect(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height(), w + 2 * x); + auto previewWidth = replyPreview->width() / cIntRetinaFactor(); + auto previewHeight = replyPreview->height() / cIntRetinaFactor(); + auto preview = replyPreview->pixSingle(previewWidth, previewHeight, to.width(), to.height(), ImageRoundRadius::Small, ImageRoundCorner::All, selected ? &st::msgStickerOverlay : nullptr); + p.drawPixmap(to.x(), to.y(), preview); } } if (w > st::msgReplyBarSkip + previewSkip) { diff --git a/Telegram/SourceFiles/ui/images.cpp b/Telegram/SourceFiles/ui/images.cpp index 389a088a7..c1a711bf8 100644 --- a/Telegram/SourceFiles/ui/images.cpp +++ b/Telegram/SourceFiles/ui/images.cpp @@ -293,7 +293,7 @@ QImage prepareOpaque(QImage image) { return image; } -QImage prepare(QImage img, int w, int h, Images::Options options, int outerw, int outerh) { +QImage prepare(QImage img, int w, int h, Images::Options options, int outerw, int outerh, const style::color *colored) { t_assert(!img.isNull()); if (options.testFlag(Images::Option::Blurred)) { img = prepareBlur(std::move(img)); @@ -341,6 +341,10 @@ QImage prepare(QImage img, int w, int h, Images::Options options, int outerw, in prepareRound(img, ImageRoundRadius::Small, corners(options)); t_assert(!img.isNull()); } + if (options.testFlag(Images::Option::Colored)) { + t_assert(colored != nullptr); + img = prepareColored(*colored, std::move(img)); + } img.setDevicePixelRatio(cRetinaFactor()); return img; } @@ -605,7 +609,7 @@ const QPixmap &Image::pixBlurredColored(style::color add, int32 w, int32 h) cons return i.value(); } -const QPixmap &Image::pixSingle(int32 w, int32 h, int32 outerw, int32 outerh, ImageRoundRadius radius, ImageRoundCorners corners) const { +const QPixmap &Image::pixSingle(int32 w, int32 h, int32 outerw, int32 outerh, ImageRoundRadius radius, ImageRoundCorners corners, const style::color *colored) const { checkload(); if (w <= 0 || !width() || !height()) { @@ -629,6 +633,9 @@ const QPixmap &Image::pixSingle(int32 w, int32 h, int32 outerw, int32 outerh, Im } else if (radius == ImageRoundRadius::Ellipse) { options |= Images::Option::Circled | cornerOptions(corners); } + if (colored) { + options |= Images::Option::Colored; + } auto k = SinglePixKey(options); auto i = _sizesCache.constFind(k); @@ -636,7 +643,7 @@ const QPixmap &Image::pixSingle(int32 w, int32 h, int32 outerw, int32 outerh, Im if (i != _sizesCache.cend()) { globalAcquiredSize -= int64(i->width()) * i->height() * 4; } - auto p = pixNoCache(w, h, options, outerw, outerh); + auto p = pixNoCache(w, h, options, outerw, outerh, colored); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); i = _sizesCache.insert(k, p); if (!p.isNull()) { @@ -687,7 +694,7 @@ const QPixmap &Image::pixBlurredSingle(int w, int h, int32 outerw, int32 outerh, return i.value(); } -QPixmap Image::pixNoCache(int w, int h, Images::Options options, int outerw, int outerh) const { +QPixmap Image::pixNoCache(int w, int h, Images::Options options, int outerw, int outerh, const style::color *colored) const { if (!loading()) const_cast(this)->load(); restore(); @@ -731,10 +738,14 @@ QPixmap Image::pixNoCache(int w, int h, Images::Options options, int outerw, int } else if (options.testFlag(Images::Option::RoundedSmall)) { Images::prepareRound(result, ImageRoundRadius::Small, corners(options)); } + if (options.testFlag(Images::Option::Colored)) { + t_assert(colored != nullptr); + result = Images::prepareColored(*colored, std::move(result)); + } return App::pixmapFromImageInPlace(std::move(result)); } - return Images::pixmap(_data.toImage(), w, h, options, outerw, outerh); + return Images::pixmap(_data.toImage(), w, h, options, outerw, outerh, colored); } QPixmap Image::pixColoredNoCache(style::color add, int32 w, int32 h, bool smooth) const { @@ -742,8 +753,10 @@ QPixmap Image::pixColoredNoCache(style::color add, int32 w, int32 h, bool smooth restore(); if (_data.isNull()) return blank()->pix(); - QImage img = _data.toImage(); - if (w <= 0 || !width() || !height() || (w == width() && (h <= 0 || h == height()))) return App::pixmapFromImageInPlace(Images::prepareColored(add, img)); + auto img = _data.toImage(); + if (w <= 0 || !width() || !height() || (w == width() && (h <= 0 || h == height()))) { + return App::pixmapFromImageInPlace(Images::prepareColored(add, std::move(img))); + } if (h <= 0) { return App::pixmapFromImageInPlace(Images::prepareColored(add, img.scaledToWidth(w, smooth ? Qt::SmoothTransformation : Qt::FastTransformation))); } diff --git a/Telegram/SourceFiles/ui/images.h b/Telegram/SourceFiles/ui/images.h index 6df39345e..3435bd150 100644 --- a/Telegram/SourceFiles/ui/images.h +++ b/Telegram/SourceFiles/ui/images.h @@ -201,10 +201,10 @@ enum class Option { Q_DECLARE_FLAGS(Options, Option); Q_DECLARE_OPERATORS_FOR_FLAGS(Options); -QImage prepare(QImage img, int w, int h, Options options, int outerw, int outerh); +QImage prepare(QImage img, int w, int h, Options options, int outerw, int outerh, const style::color *colored = nullptr); -inline QPixmap pixmap(QImage img, int w, int h, Options options, int outerw, int outerh) { - return QPixmap::fromImage(prepare(img, w, h, options, outerw, outerh), Qt::ColorOnly); +inline QPixmap pixmap(QImage img, int w, int h, Options options, int outerw, int outerh, const style::color *colored = nullptr) { + return QPixmap::fromImage(prepare(img, w, h, options, outerw, outerh, colored), Qt::ColorOnly); } } // namespace Images @@ -247,11 +247,11 @@ public: const QPixmap &pixBlurred(int32 w = 0, int32 h = 0) const; const QPixmap &pixColored(style::color add, int32 w = 0, int32 h = 0) const; const QPixmap &pixBlurredColored(style::color add, int32 w = 0, int32 h = 0) const; - const QPixmap &pixSingle(int32 w, int32 h, int32 outerw, int32 outerh, ImageRoundRadius radius, ImageRoundCorners corners = ImageRoundCorner::All) const; + const QPixmap &pixSingle(int32 w, int32 h, int32 outerw, int32 outerh, ImageRoundRadius radius, ImageRoundCorners corners = ImageRoundCorner::All, const style::color *colored = nullptr) const; const QPixmap &pixBlurredSingle(int32 w, int32 h, int32 outerw, int32 outerh, ImageRoundRadius radius, ImageRoundCorners corners = ImageRoundCorner::All) const; const QPixmap &pixCircled(int32 w = 0, int32 h = 0) const; const QPixmap &pixBlurredCircled(int32 w = 0, int32 h = 0) const; - QPixmap pixNoCache(int w = 0, int h = 0, Images::Options options = 0, int outerw = -1, int outerh = -1) const; + QPixmap pixNoCache(int w = 0, int h = 0, Images::Options options = 0, int outerw = -1, int outerh = -1, const style::color *colored = nullptr) const; QPixmap pixColoredNoCache(style::color add, int32 w = 0, int32 h = 0, bool smooth = false) const; QPixmap pixBlurredColoredNoCache(style::color add, int32 w, int32 h = 0) const;