Nice reactions panel expanding.

This commit is contained in:
John Preston 2022-08-23 17:47:26 +03:00
parent 20d4d00634
commit 0277d765bb
17 changed files with 253 additions and 175 deletions

View file

@ -1268,13 +1268,12 @@ void StickerSetBox::Inner::paintSticker(
(_singleSize.height() - size.height()) / 2);
auto lottieFrame = QImage();
if (element.emoji) {
element.emoji->paint(
p,
ppos.x(),
ppos.y(),
now,
st::windowBgOver->c,
paused);
element.emoji->paint(p, {
.preview = st::windowBgOver->c,
.now = now,
.position = ppos,
.paused = paused,
});
} else if (element.lottie && element.lottie->ready()) {
lottieFrame = element.lottie->frame();
p.drawImage(

View file

@ -40,6 +40,7 @@ namespace ChatHelpers {
namespace {
constexpr auto kCollapsedRows = 3;
constexpr auto kAppearDuration = 0.3;
using Core::RecentEmojiId;
using Core::RecentEmojiDocument;
@ -486,15 +487,19 @@ auto EmojiListWidget::premiumChosen() const
void EmojiListWidget::paintExpanding(
QPainter &p,
QRect clip,
int finalBottom,
float64 progress,
RectPart origin) {
const auto shift = clip.topLeft();
const auto adjusted = clip.translated(-shift);
const auto finalHeight = (finalBottom - clip.y());
p.translate(shift);
p.setClipRect(adjusted);
const auto context = ExpandingContext{
paint(p, ExpandingContext{
.progress = progress,
.finalHeight = finalHeight,
.expanding = true,
};
paint(p, context, adjusted);
}, adjusted);
p.translate(-shift);
}
@ -778,7 +783,7 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
void EmojiListWidget::paint(
QPainter &p,
const ExpandingContext &context,
ExpandingContext context,
QRect clip) {
auto fromColumn = floorclamp(
clip.x() - _rowsLeft,
@ -796,6 +801,7 @@ void EmojiListWidget::paint(
toColumn = _columnCount - toColumn;
}
const auto expandProgress = context.progress;
const auto paused = this->paused();
const auto now = crl::now();
auto selectedButton = std::get_if<OverButton>(!v::is_null(_pressed)
@ -866,10 +872,26 @@ void EmojiListWidget::paint(
const auto selected = (state == _selected)
|| (!_picker->isHidden()
&& state == _pickerSelected);
auto w = QPoint(
const auto position = QPoint(
_rowsLeft + j * _singleSize.width(),
info.rowsTop + i * _singleSize.height()
) + _areaPosition;
);
const auto w = position + _areaPosition;
if (context.expanding) {
const auto y = (position.y() - st().padding.top());
const auto x = (position.x() - _rowsLeft);
const auto sum = y
+ std::max(std::min(y, width()) - x, 0);
const auto maxSum = context.finalHeight
+ std::min(context.finalHeight, width());
const auto started = (sum / float64(maxSum))
- kAppearDuration;
context.progress = (expandProgress <= started)
? 0.
: (expandProgress >= started + kAppearDuration)
? 1.
: ((expandProgress - started) / kAppearDuration);
}
if (info.collapsed
&& index + 1 == _columnCount * kCollapsedRows) {
drawCollapsedBadge(p, w - _areaPosition, info.count);
@ -883,12 +905,12 @@ void EmojiListWidget::paint(
_overBg.paint(p, QRect(tl, st::emojiPanArea));
}
if (info.section == int(Section::Recent)) {
drawRecent(p, w, now, paused, index);
drawRecent(p, context, w, now, paused, index);
} else if (info.section < _staticCount) {
drawEmoji(p, w, _emoji[info.section][index]);
drawEmoji(p, context, w, _emoji[info.section][index]);
} else {
const auto set = info.section - _staticCount;
drawCustom(p, w, now, paused, set, index);
drawCustom(p, context, w, now, paused, set, index);
}
}
}
@ -919,6 +941,7 @@ void EmojiListWidget::drawCollapsedBadge(
void EmojiListWidget::drawRecent(
QPainter &p,
const ExpandingContext &context,
QPoint position,
crl::time now,
bool paused,
@ -932,23 +955,25 @@ void EmojiListWidget::drawRecent(
) - _areaPosition;
p.drawImage(position, _premiumIcon->image());
} else {
drawEmoji(p, position, *emoji);
drawEmoji(p, context, position, *emoji);
}
} else {
Assert(_recent[index].custom != nullptr);
position += _innerPosition + _customPosition;
_recent[index].custom->paint(
p,
position.x(),
position.y(),
now,
st::windowBgRipple->c,
paused);
_recent[index].custom->paint(p, {
.preview = st::windowBgRipple->c,
.now = now,
.scale = context.progress,
.position = position,
.paused = paused,
.scaled = context.expanding,
});
}
}
void EmojiListWidget::drawEmoji(
QPainter &p,
const ExpandingContext &context,
QPoint position,
EmojiPtr emoji) {
position += _innerPosition;
@ -962,6 +987,7 @@ void EmojiListWidget::drawEmoji(
void EmojiListWidget::drawCustom(
QPainter &p,
const ExpandingContext &context,
QPoint position,
crl::time now,
bool paused,
@ -969,13 +995,14 @@ void EmojiListWidget::drawCustom(
int index) {
position += _innerPosition + _customPosition;
_custom[set].painted = true;
_custom[set].list[index].custom->paint(
p,
position.x(),
position.y(),
now,
st::windowBgRipple->c,
paused);
_custom[set].list[index].custom->paint(p, {
.preview = st::windowBgRipple->c,
.now = now,
.scale = context.progress,
.position = position,
.paused = paused,
.scaled = context.expanding,
});
}
bool EmojiListWidget::checkPickerHide() {

View file

@ -112,7 +112,12 @@ public:
[[nodiscard]] auto premiumChosen() const
-> rpl::producer<not_null<DocumentData*>>;
void paintExpanding(QPainter &p, QRect clip, RectPart origin);
void paintExpanding(
QPainter &p,
QRect clip,
int finalBottom,
float64 progress,
RectPart origin);
protected:
void visibleTopBottomUpdated(
@ -208,6 +213,8 @@ private:
OverSet,
OverButton>;
struct ExpandingContext {
float64 progress = 0.;
int finalHeight = 0;
bool expanding = false;
};
@ -235,20 +242,23 @@ private:
[[nodiscard]] EmojiPtr lookupOverEmoji(const OverEmoji *over) const;
void selectEmoji(EmojiPtr emoji);
void selectCustom(not_null<DocumentData*> document);
void paint(QPainter &p, const ExpandingContext &context, QRect clip);
void paint(QPainter &p, ExpandingContext context, QRect clip);
void drawCollapsedBadge(QPainter &p, QPoint position, int count);
void drawRecent(
QPainter &p,
const ExpandingContext &context,
QPoint position,
crl::time now,
bool paused,
int index);
void drawEmoji(
QPainter &p,
const ExpandingContext &context,
QPoint position,
EmojiPtr emoji);
void drawCustom(
QPainter &p,
const ExpandingContext &context,
QPoint position,
crl::time now,
bool paused,

View file

@ -351,7 +351,11 @@ void SuggestionsWidget::paintEvent(QPaintEvent *e) {
const auto x = i * _oneWidth + (_oneWidth - size) / 2;
const auto y = (_oneWidth - size) / 2;
if (row.custom) {
row.custom->paint(p, x, y, now, preview, false);
row.custom->paint(p, {
.preview = preview,
.now = now,
.position = { x, y },
});
} else {
Ui::Emoji::Draw(p, emoji, esize, x, y);
}

View file

@ -1217,19 +1217,29 @@ void StickersListFooter::paintSetIcon(
crl::time now,
bool paused) const {
const auto &icon = _icons[info.index];
if (context.expanding) {
p.save();
const auto center = QPoint(
info.adjustedLeft + _singleWidth / 2,
_iconsTop + st().footer / 2);
const auto shift = QPoint(0, anim::interpolate(height() / 2, 0, context.progress));
p.translate(shift + center);
p.scale(context.progress, context.progress);
p.translate(-center);
}
const auto expandingShift = context.expanding
? QPoint(
0,
anim::interpolate(height() / 2, 0, context.progress))
: QPoint();
if (icon.sticker) {
icon.ensureMediaCreated();
const_cast<StickersListFooter*>(this)->validateIconAnimation(icon);
}
if (context.expanding) {
if (icon.custom) {
p.translate(expandingShift);
} else {
p.save();
const auto center = QPoint(
info.adjustedLeft + _singleWidth / 2,
_iconsTop + st().footer / 2);
p.translate(expandingShift + center);
p.scale(context.progress, context.progress);
p.translate(-center);
}
}
if (icon.sticker) {
const auto origin = icon.sticker->stickerSetOrigin();
const auto thumb = icon.thumbnailMedia
? icon.thumbnailMedia->image()
@ -1239,7 +1249,15 @@ void StickersListFooter::paintSetIcon(
const auto x = info.adjustedLeft + (_singleWidth - icon.pixw) / 2;
const auto y = _iconsTop + (st().footer - icon.pixh) / 2;
if (icon.custom) {
icon.custom->paint(p, x, y, now, st::emojiIconFg->c, paused);
icon.custom->paint(p, Ui::Text::CustomEmoji::Context{
.preview = st::emojiIconFg->c,
.size = QSize(icon.pixw, icon.pixh),
.now = now,
.scale = context.progress,
.position = { x, y },
.paused = paused,
.scaled = context.expanding,
});
} else if (icon.lottie && icon.lottie->ready()) {
const auto frame = icon.lottie->frame();
const auto size = frame.size() / cIntRetinaFactor();
@ -1368,7 +1386,11 @@ void StickersListFooter::paintSetIcon(
}
}
if (context.expanding) {
p.restore();
if (icon.custom) {
p.translate(-expandingShift);
} else {
p.restore();
}
}
}

View file

@ -356,12 +356,7 @@ void BottomInfo::paintReactions(
y += st::msgDateFont->height;
widthLeft = availableWidth;
}
if (!reaction.custom && reaction.image.isNull()) {
reaction.custom = _reactionsOwner->resolveCustomFor(
reaction.id,
::Data::Reactions::ImageSize::BottomInfo);
}
if (!reaction.custom && reaction.image.isNull()) {
if (reaction.image.isNull()) {
reaction.image = _reactionsOwner->resolveImageFor(
reaction.id,
::Data::Reactions::ImageSize::BottomInfo);
@ -375,9 +370,6 @@ void BottomInfo::paintReactions(
&& (reaction.count < 2 || !reaction.animation->flying());
if (!reaction.image.isNull() && !skipImage) {
p.drawImage(image.topLeft(), reaction.image);
} else if (reaction.custom && !skipImage) {
const auto size = Ui::Text::AdjustCustomEmojiSize(st::emojiSize);
reaction.custom->paint(p, x + (st::reactionInfoSize - size) / 2, y + (st::msgDateFont->height - size) / 2, crl::now(), Qt::white, false);
}
if (animating) {
animations.push_back({

View file

@ -16,10 +16,6 @@ namespace Ui {
struct ChatPaintContext;
} // namespace Ui
namespace Ui::Text {
class CustomEmoji;
} // namespace Ui::Text
namespace Data {
class Reactions;
} // namespace Data
@ -105,7 +101,6 @@ private:
struct Reaction {
mutable std::unique_ptr<Reactions::Animation> animation;
mutable QImage image;
mutable std::unique_ptr<Ui::Text::CustomEmoji> custom;
ReactionId id;
QString countText;
int count = 0;

View file

@ -298,16 +298,15 @@ void StickerToast::setupEmojiPreview(
widget->paintRequest(
) | rpl::start_with_next([=] {
auto p = QPainter(widget);
const auto paused = false;
const auto size = Ui::Emoji::GetSizeLarge()
/ style::DevicePixelRatio();
instance->object.paint(
p,
(widget->width() - size) / 2,
(widget->height() - size) / 2,
crl::now(),
st::toastBg->c,
paused);
instance->object.paint(p, Ui::Text::CustomEmoji::Context{
.preview = st::toastBg->c,
.now = crl::now(),
.position = QPoint(
(widget->width() - size) / 2,
(widget->height() - size) / 2),
});
}, widget->lifetime());
}

View file

@ -277,7 +277,11 @@ void CustomEmoji::paintCustom(
}
_selectedFrame.fill(Qt::transparent);
auto q = QPainter(&_selectedFrame);
emoji->paint(q, 0, 0, context.now, preview, paused);
emoji->paint(q, {
.preview = preview,
.now = context.now,
.paused = paused,
});
q.end();
_selectedFrame = Images::Colored(
@ -285,7 +289,12 @@ void CustomEmoji::paintCustom(
context.st->msgStickerOverlay()->c);
p.drawImage(x, y, _selectedFrame);
} else {
emoji->paint(p, x, y, context.now, preview, paused);
emoji->paint(p, {
.preview = preview,
.now = context.now,
.position = { x, y },
.paused = paused,
});
}
}

View file

@ -148,7 +148,11 @@ void LargeEmoji::paintCustom(
}
_selectedFrame.fill(Qt::transparent);
auto q = QPainter(&_selectedFrame);
emoji->paint(q, 0, 0, context.now, preview, paused);
emoji->paint(q, {
.preview = preview,
.now = context.now,
.paused = paused,
});
q.end();
_selectedFrame = Images::Colored(
@ -156,7 +160,12 @@ void LargeEmoji::paintCustom(
context.st->msgStickerOverlay()->c);
p.drawImage(x + skip, y + skip, _selectedFrame);
} else {
emoji->paint(p, x + skip, y + skip, context.now, preview, paused);
emoji->paint(p, {
.preview = preview,
.now = context.now,
.position = { x + skip, y + skip },
.paused = paused,
});
}
}

View file

@ -18,12 +18,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "chat_helpers/emoji_list_widget.h"
#include "chat_helpers/stickers_list_footer.h"
#include "window/window_session_controller.h"
#include "base/call_delayed.h"
#include "styles/style_chat_helpers.h"
#include "styles/style_chat.h"
namespace HistoryView::Reactions {
namespace {
constexpr auto kExpandDuration = crl::time(300);
constexpr auto kScaleDuration = crl::time(120);
constexpr auto kFullDuration = kExpandDuration + kScaleDuration;
constexpr auto kExpandDelay = crl::time(40);
class ShiftedEmoji final : public Ui::Text::CustomEmoji {
public:
ShiftedEmoji(
@ -33,13 +39,7 @@ public:
QPoint shift);
QString entityData() override;
void paint(
QPainter &p,
int x,
int y,
crl::time now,
const QColor &preview,
bool paused) override;
void paint(QPainter &p, const Context &context) override;
void unload() override;
private:
@ -64,14 +64,10 @@ QString ShiftedEmoji::entityData() {
return _real->entityData();
}
void ShiftedEmoji::paint(
QPainter &p,
int x,
int y,
crl::time now,
const QColor &preview,
bool paused) {
_real->paint(p, x + _shift.x(), y + _shift.y(), now, preview, paused);
void ShiftedEmoji::paint(QPainter &p, const Context &context) {
auto copy = context;
copy.position += _shift;
_real->paint(p, copy);
}
void ShiftedEmoji::unload() {
@ -270,6 +266,7 @@ void Selector::paintCollapsed(QPainter &p) {
void Selector::paintExpanding(Painter &p, float64 progress) {
const auto rects = paintExpandingBg(p, progress);
//paintStripWithoutExpand(p);
progress /= kFullDuration;
paintFadingExpandIcon(p, progress);
if (_footer) {
_footer->paintExpanding(
@ -281,11 +278,16 @@ void Selector::paintExpanding(Painter &p, float64 progress) {
_list->paintExpanding(
p,
rects.list.marginsRemoved(st::reactPanelEmojiPan.margin),
rects.finalBottom,
progress,
RectPart::TopRight);
}
auto Selector::paintExpandingBg(QPainter &p, float64 progress)
-> ExpandingRects {
progress = (progress >= kExpandDuration)
? 1.
: (progress / kExpandDuration);
constexpr auto kFramesCount = Ui::RoundAreaWithShadow::kFramesCount;
const auto frame = int(base::SafeRound(progress * (kFramesCount - 1)));
const auto radiusStart = st::reactStripHeight / 2.;
@ -318,6 +320,7 @@ auto Selector::paintExpandingBg(QPainter &p, float64 progress)
.categories = QRect(inner.x(), inner.y(), inner.width(), categories),
.list = inner.marginsRemoved({ 0, categories, 0, 0 }),
.radius = radius,
.finalBottom = height() - extents.bottom(),
};
}
@ -393,7 +396,8 @@ void Selector::paintEvent(QPaintEvent *e) {
paintAppearing(p);
} else if (!_expanded) {
paintCollapsed(p);
} else if (const auto progress = _expanding.value(1.); progress < 1.) {
} else if (const auto progress = _expanding.value(kFullDuration)
; progress < kFullDuration) {
paintExpanding(p, progress);
} else {
paintExpanded(p);
@ -468,9 +472,14 @@ void Selector::expand() {
createList(strong);
cacheExpandIcon();
_paintBuffer = _cachedRound.PrepareImage(size());
_expanded = true;
_expanding.start([=] { update(); }, 0., 1., st::slideDuration);
[[maybe_unused]] const auto grabbed = Ui::GrabWidget(_scroll);
base::call_delayed(kExpandDelay, this, [=] {
_paintBuffer = _cachedRound.PrepareImage(size());
_expanded = true;
const auto full = kExpandDuration + kScaleDuration;
_expanding.start([=] { update(); }, 0., full, full);
});
}
void Selector::cacheExpandIcon() {

View file

@ -70,6 +70,7 @@ private:
QRect categories;
QRect list;
float64 radius = 0.;
int finalBottom = 0;
};
void paintEvent(QPaintEvent *e) override;

View file

@ -148,13 +148,11 @@ void BadgeView::setBadge(Badge badge, DocumentId emojiStatusId) {
_view->paintRequest(
) | rpl::start_with_next([=, check = _view.data()]{
Painter p(check);
_emojiStatus->paint(
p,
0,
0,
crl::now(),
st::windowBgOver->c,
_animationPaused && _animationPaused());
_emojiStatus->paint(p, {
.preview = st::windowBgOver->c,
.now = crl::now(),
.paused = _animationPaused && _animationPaused(),
});
}, _view->lifetime());
} else {
const auto icon = (_badge == Badge::Verified)

View file

@ -30,6 +30,32 @@ struct CacheHeader {
int length = 0;
};
void PaintScaledImage(
QPainter &p,
const QRect &target,
const Cache::Frame &frame,
const Context &context) {
if (context.scaled) {
const auto sx = anim::interpolate(
target.width() / 2,
0,
context.scale);
const auto sy = (target.height() == target.width())
? sx
: anim::interpolate(target.height() / 2, 0, context.scale);
const auto scaled = target.marginsRemoved({ sx, sy, sx, sy });
if (frame.source.isNull()) {
p.drawImage(scaled, *frame.image);
} else {
p.drawImage(scaled, *frame.image, frame.source);
}
} else if (frame.source.isNull()) {
p.drawImage(target, *frame.image);
} else {
p.drawImage(target, *frame.image, frame.source);
}
}
} // namespace
Preview::Preview(QPainterPath path, float64 scale)
@ -40,15 +66,14 @@ Preview::Preview(QImage image, bool exact)
: _data(Image{ .data = std::move(image), .exact = exact }) {
}
void Preview::paint(QPainter &p, int x, int y, const QColor &preview) {
void Preview::paint(QPainter &p, const Context &context) {
if (const auto path = std::get_if<ScaledPath>(&_data)) {
paintPath(p, x, y, preview, *path);
paintPath(p, context, *path);
} else if (const auto image = std::get_if<Image>(&_data)) {
const auto &data = image->data;
const auto factor = style::DevicePixelRatio();
const auto width = data.width() / factor;
const auto height = data.height() / factor;
p.drawImage(QRect(x, y, width, height), data);
const auto rect = QRect(context.position, data.size() / factor);
PaintScaledImage(p, rect, { .image = &data }, context);
}
}
@ -72,27 +97,33 @@ QImage Preview::image() const {
void Preview::paintPath(
QPainter &p,
int x,
int y,
const QColor &preview,
const Context &context,
const ScaledPath &path) {
auto hq = PainterHighQualityEnabler(p);
p.setBrush(preview);
p.setBrush(context.preview);
p.setPen(Qt::NoPen);
const auto scale = path.scale;
const auto required = (scale != 1.);
const auto required = (scale != 1.) || context.scaled;
if (required) {
p.save();
}
p.translate(x, y);
p.translate(context.position);
if (required) {
p.scale(scale, scale);
const auto center = QPoint(
context.size.width() / 2,
context.size.height() / 2);
if (context.scaled) {
p.translate(center);
p.scale(context.scale, context.scale);
p.translate(-center);
}
}
p.drawPath(path.path);
if (required) {
p.restore();
} else {
p.translate(-x, -y);
p.translate(-context.position);
}
}
@ -306,12 +337,11 @@ void Cache::finish() {
PaintFrameResult Cache::paintCurrentFrame(
QPainter &p,
int x,
int y,
crl::time now) {
const Context &context) {
if (!_frames) {
return {};
}
const auto now = context.paused ? 0 : context.now;
const auto finishes = now ? currentFrameFinishes() : 0;
if (finishes && now >= finishes) {
++_frame;
@ -324,7 +354,8 @@ PaintFrameResult Cache::paintCurrentFrame(
}
const auto info = frame(std::min(_frame, _frames - 1));
const auto size = _size / style::DevicePixelRatio();
p.drawImage(QRect(x, y, size, size), *info.image, info.source);
const auto rect = QRect(context.position, QSize(size, size));
PaintScaledImage(p, rect, info, context);
const auto next = currentFrameFinishes();
const auto duration = next ? (next - _shown) : 0;
return {
@ -360,8 +391,8 @@ QString Cached::entityData() const {
return _entityData;
}
PaintFrameResult Cached::paint(QPainter &p, int x, int y, crl::time now) {
return _cache.paintCurrentFrame(p, x, y, now);
PaintFrameResult Cached::paint(QPainter &p, const Context &context) {
return _cache.paintCurrentFrame(p, context);
}
Preview Cached::makePreview() const {
@ -469,8 +500,8 @@ void Renderer::finish() {
}
}
PaintFrameResult Renderer::paint(QPainter &p, int x, int y, crl::time now) {
const auto result = _cache.paintCurrentFrame(p, x, y, now);
PaintFrameResult Renderer::paint(QPainter &p, const Context &context) {
const auto result = _cache.paintCurrentFrame(p, context);
if (_generator
&& (!result.painted
|| _cache.currentFrame() + kPreloadFrames >= _cache.frames())) {
@ -526,13 +557,13 @@ bool Loading::loading() const {
return _loader->loading();
}
void Loading::paint(QPainter &p, int x, int y, const QColor &preview) {
void Loading::paint(QPainter &p, const Context &context) {
if (!_preview) {
if (auto preview = _loader->preview()) {
_preview = std::move(preview);
}
}
_preview.paint(p, x, y, preview);
_preview.paint(p, context);
}
bool Loading::hasImagePreview() const {
@ -578,15 +609,9 @@ QString Instance::entityData() const {
Unexpected("State in Instance::entityData.");
}
void Instance::paint(
QPainter &p,
int x,
int y,
crl::time now,
const QColor &preview,
bool paused) {
void Instance::paint(QPainter &p, const Context &context) {
if (const auto loading = std::get_if<Loading>(&_state)) {
loading->paint(p, x, y, preview);
loading->paint(p, context);
loading->load([=](Loader::LoadResult result) {
if (auto caching = std::get_if<Caching>(&result)) {
caching->renderer->setRepaintCallback([=] { repaint(); });
@ -599,14 +624,14 @@ void Instance::paint(
}
});
} else if (const auto caching = std::get_if<Caching>(&_state)) {
auto result = caching->renderer->paint(p, x, y, paused ? 0 : now);
auto result = caching->renderer->paint(p, context);
if (!result.painted) {
caching->preview.paint(p, x, y, preview);
caching->preview.paint(p, context);
} else {
if (!caching->preview.isExactImage()) {
caching->preview = caching->renderer->makePreview();
}
if (result.next > now) {
if (result.next > context.now) {
_repaintLater(this, { result.next, result.duration });
}
}
@ -614,8 +639,8 @@ void Instance::paint(
_state = std::move(*cached);
}
} else if (const auto cached = std::get_if<Cached>(&_state)) {
const auto result = cached->paint(p, x, y, paused ? 0 : now);
if (result.next > now) {
const auto result = cached->paint(p, context);
if (result.next > context.now) {
_repaintLater(this, { result.next, result.duration });
}
}
@ -695,18 +720,12 @@ QString Object::entityData() {
return _instance->entityData();
}
void Object::paint(
QPainter &p,
int x,
int y,
crl::time now,
const QColor &preview,
bool paused) {
void Object::paint(QPainter &p, const Context &context) {
if (!_using) {
_using = true;
_instance->incrementUsage(this);
}
_instance->paint(p, x, y, now, preview, paused);
_instance->paint(p, context);
}
void Object::unload() {

View file

@ -21,13 +21,15 @@ class FrameGenerator;
namespace Ui::CustomEmoji {
using Context = Ui::Text::CustomEmoji::Context;
class Preview final {
public:
Preview() = default;
Preview(QImage image, bool exact);
Preview(QPainterPath path, float64 scale);
void paint(QPainter &p, int x, int y, const QColor &preview);
void paint(QPainter &p, const Context &context);
[[nodiscard]] bool isImage() const;
[[nodiscard]] bool isExactImage() const;
[[nodiscard]] QImage image() const;
@ -48,9 +50,7 @@ private:
void paintPath(
QPainter &p,
int x,
int y,
const QColor &preview,
const Context &context,
const ScaledPath &path);
std::variant<v::null_t, ScaledPath, Image> _data;
@ -86,11 +86,7 @@ public:
[[nodiscard]] Preview makePreview() const;
PaintFrameResult paintCurrentFrame(
QPainter &p,
int x,
int y,
crl::time now);
PaintFrameResult paintCurrentFrame(QPainter &p, const Context &context);
[[nodiscard]] int currentFrame() const;
private:
@ -123,7 +119,7 @@ public:
[[nodiscard]] QString entityData() const;
[[nodiscard]] Preview makePreview() const;
PaintFrameResult paint(QPainter &p, int x, int y, crl::time now);
PaintFrameResult paint(QPainter &p, const Context &context);
[[nodiscard]] Loading unload();
private:
@ -145,7 +141,7 @@ public:
explicit Renderer(RendererDescriptor &&descriptor);
virtual ~Renderer();
PaintFrameResult paint(QPainter &p, int x, int y, crl::time now);
PaintFrameResult paint(QPainter &p, const Context &context);
[[nodiscard]] std::optional<Cached> ready(const QString &entityData);
[[nodiscard]] std::unique_ptr<Loader> cancel();
@ -199,7 +195,7 @@ public:
void load(Fn<void(Loader::LoadResult)> done);
[[nodiscard]] bool loading() const;
void paint(QPainter &p, int x, int y, const QColor &preview);
void paint(QPainter &p, const Context &context);
[[nodiscard]] bool hasImagePreview() const;
[[nodiscard]] Preview imagePreview() const;
void updatePreview(Preview preview);
@ -226,13 +222,7 @@ public:
Instance &operator=(const Instance&) = delete;
[[nodiscard]] QString entityData() const;
void paint(
QPainter &p,
int x,
int y,
crl::time now,
const QColor &preview,
bool paused);
void paint(QPainter &p, const Context &context);
[[nodiscard]] bool hasImagePreview() const;
[[nodiscard]] Preview imagePreview() const;
void updatePreview(Preview preview);
@ -261,13 +251,7 @@ public:
~Object();
QString entityData() override;
void paint(
QPainter &p,
int x,
int y,
crl::time now,
const QColor &preview,
bool paused) override;
void paint(QPainter &p, const Context &context) override;
void unload() override;
void repaint();

View file

@ -180,13 +180,14 @@ int PeerBadge::drawGetWidth(
id,
descriptor.customEmojiRepaint);
}
_emojiStatus->emoji->paint(
p,
iconx - 2 * _emojiStatus->skip,
icony + _emojiStatus->skip,
descriptor.now,
descriptor.preview,
descriptor.paused);
_emojiStatus->emoji->paint(p, {
.preview = descriptor.preview,
.now = descriptor.now,
.position = QPoint(
iconx - 2 * _emojiStatus->skip,
icony + _emojiStatus->skip),
.paused = descriptor.paused,
});
return iconw - 4 * _emojiStatus->skip;
}
return 0;

@ -1 +1 @@
Subproject commit 8162619cb17456f31d1be378a7ed72dc928e0831
Subproject commit 01c4ba869a07eabc9eea2b633542a53e9ff6ff4c