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.
This commit is contained in:
John Preston 2017-06-06 12:15:13 +03:00
parent 68ddabea5c
commit 6869cc7d04
3 changed files with 30 additions and 17 deletions

View File

@ -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) {

View File

@ -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<Image*>(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)));
}

View File

@ -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;