Allow stopping LimitedLoopsEmoji on last frame.

This commit is contained in:
John Preston 2023-01-20 20:43:30 +04:00
parent 6e3cc8c769
commit 335f8050d9
3 changed files with 32 additions and 8 deletions

View file

@ -383,20 +383,28 @@ PaintFrameResult Cache::paintCurrentFrame(
return {}; return {};
} }
const auto first = context.internal.forceFirstFrame; const auto first = context.internal.forceFirstFrame;
if (!first) { auto last = context.internal.forceLastFrame;
if (!first && !last) {
const auto now = context.paused ? 0 : context.now; const auto now = context.paused ? 0 : context.now;
const auto finishes = now ? currentFrameFinishes() : 0; const auto finishes = now ? currentFrameFinishes() : 0;
if (finishes && now >= finishes) { if (finishes && now >= finishes) {
++_frame; ++_frame;
if (_finished && _frame == _frames) { if (_finished && _frame == _frames) {
_frame = 0; _frame = 0;
if (context.internal.overrideFirstWithLastFrame) {
last = true;
}
} }
_shown = now; _shown = now;
} else if (!_shown) { } else if (!_shown) {
_shown = now; _shown = now;
} }
} }
const auto index = first ? 0 : std::min(_frame, _frames - 1); const auto index = first
? 0
: last
? (_frames - 1)
: std::min(_frame, _frames - 1);
const auto info = frame(index); const auto info = frame(index);
const auto size = _size / style::DevicePixelRatio(); const auto size = _size / style::DevicePixelRatio();
const auto rect = QRect(context.position, QSize(size, size)); const auto rect = QRect(context.position, QSize(size, size));

View file

@ -70,9 +70,11 @@ bool FirstFrameEmoji::readyInDefaultState() {
LimitedLoopsEmoji::LimitedLoopsEmoji( LimitedLoopsEmoji::LimitedLoopsEmoji(
std::unique_ptr<CustomEmoji> wrapped, std::unique_ptr<CustomEmoji> wrapped,
int limit) int limit,
bool stopOnLast)
: _wrapped(std::move(wrapped)) : _wrapped(std::move(wrapped))
, _limit(limit) { , _limit(limit)
, _stopOnLast(stopOnLast) {
} }
QString LimitedLoopsEmoji::entityData() { QString LimitedLoopsEmoji::entityData() {
@ -91,10 +93,18 @@ void LimitedLoopsEmoji::paint(QPainter &p, const Context &context) {
} }
} }
if (_played == _limit) { if (_played == _limit) {
const auto was = context.internal.forceFirstFrame; const auto wasFirst = context.internal.forceFirstFrame;
context.internal.forceFirstFrame = true; const auto wasLast = context.internal.forceLastFrame;
(_stopOnLast
? context.internal.forceLastFrame
: context.internal.forceFirstFrame) = true;
_wrapped->paint(p, context); _wrapped->paint(p, context);
context.internal.forceFirstFrame = was; context.internal.forceFirstFrame = wasFirst;
context.internal.forceLastFrame = wasLast;
} else if (_played + 1 == _limit && _inLoop && _stopOnLast) {
const auto wasLast = context.internal.overrideFirstWithLastFrame;
_wrapped->paint(p, context);
context.internal.overrideFirstWithLastFrame = wasLast;
} else { } else {
_wrapped->paint(p, context); _wrapped->paint(p, context);
} }

View file

@ -31,6 +31,8 @@ struct CustomEmojiPaintContext {
mutable struct { mutable struct {
bool colorized = false; bool colorized = false;
bool forceFirstFrame = false; bool forceFirstFrame = false;
bool forceLastFrame = false;
bool overrideFirstWithLastFrame = false;
} internal; } internal;
}; };
@ -85,7 +87,10 @@ private:
class LimitedLoopsEmoji final : public CustomEmoji { class LimitedLoopsEmoji final : public CustomEmoji {
public: public:
LimitedLoopsEmoji(std::unique_ptr<CustomEmoji> wrapped, int limit); LimitedLoopsEmoji(
std::unique_ptr<CustomEmoji> wrapped,
int limit,
bool stopOnLast = false);
QString entityData() override; QString entityData() override;
void paint(QPainter &p, const Context &context) override; void paint(QPainter &p, const Context &context) override;
@ -98,6 +103,7 @@ private:
const int _limit = 0; const int _limit = 0;
int _played = 0; int _played = 0;
bool _inLoop = false; bool _inLoop = false;
bool _stopOnLast = false;
}; };