Moved out HistoryView::StickerPlayer implementations to separate file.

This commit is contained in:
23rd 2022-08-31 18:54:39 +03:00 committed by John Preston
parent 010b5e3949
commit e34b61d56b
6 changed files with 224 additions and 173 deletions

View File

@ -660,6 +660,9 @@ PRIVATE
history/view/media/history_view_slot_machine.cpp
history/view/media/history_view_sticker.h
history/view/media/history_view_sticker.cpp
history/view/media/history_view_sticker_player.cpp
history/view/media/history_view_sticker_player.h
history/view/media/history_view_sticker_player_abstract.h
history/view/media/history_view_theme_document.h
history/view/media/history_view_theme_document.cpp
history/view/media/history_view_web_page.h

View File

@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_element.h"
#include "history/view/history_view_cursor_state.h"
#include "history/view/media/history_view_media_common.h"
#include "history/view/media/history_view_sticker_player.h"
#include "ui/image/image.h"
#include "ui/chat/chat_style.h"
#include "ui/effects/path_shift_gradient.h"
@ -27,8 +28,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document_media.h"
#include "data/data_file_click_handler.h"
#include "data/data_file_origin.h"
#include "lottie/lottie_single_player.h"
#include "media/clip/media_clip_reader.h"
#include "chat_helpers/stickers_lottie.h"
#include "styles/style_chat.h"
@ -40,8 +39,6 @@ constexpr auto kMaxEmojiSizeFixed = 256;
constexpr auto kPremiumMultiplier = (1 + 0.245 * 2);
constexpr auto kEmojiMultiplier = 3;
using ClipNotification = ::Media::Clip::Notification;
[[nodiscard]] QImage CacheDiceImage(
const QString &emoji,
int index,
@ -56,154 +53,6 @@ using ClipNotification = ::Media::Clip::Notification;
return image;
}
class LottiePlayer final : public StickerPlayer {
public:
explicit LottiePlayer(std::unique_ptr<Lottie::SinglePlayer> lottie);
void setRepaintCallback(Fn<void()> callback) override;
bool ready() override;
int framesCount() override;
FrameInfo frame(
QSize size,
QColor colored,
bool mirrorHorizontal,
crl::time now,
bool paused) override;
bool markFrameShown() override;
private:
std::unique_ptr<Lottie::SinglePlayer> _lottie;
rpl::lifetime _repaintLifetime;
};
LottiePlayer::LottiePlayer(std::unique_ptr<Lottie::SinglePlayer> lottie)
: _lottie(std::move(lottie)) {
}
void LottiePlayer::setRepaintCallback(Fn<void()> callback) {
_repaintLifetime = _lottie->updates(
) | rpl::start_with_next([=](Lottie::Update update) {
v::match(update.data, [&](const Lottie::Information &information) {
callback();
//markFramesTillExternal();
}, [&](const Lottie::DisplayFrameRequest &request) {
callback();
});
});
}
bool LottiePlayer::ready() {
return _lottie->ready();
}
int LottiePlayer::framesCount() {
return _lottie->information().framesCount;
}
LottiePlayer::FrameInfo LottiePlayer::frame(
QSize size,
QColor colored,
bool mirrorHorizontal,
crl::time now,
bool paused) {
auto request = Lottie::FrameRequest();
request.box = size * style::DevicePixelRatio();
request.colored = colored;
request.mirrorHorizontal = mirrorHorizontal;
const auto info = _lottie->frameInfo(request);
return { .image = info.image, .index = info.index };
}
bool LottiePlayer::markFrameShown() {
return _lottie->markFrameShown();
}
class WebmPlayer final : public StickerPlayer {
public:
WebmPlayer(
const Core::FileLocation &location,
const QByteArray &data,
QSize size);
void setRepaintCallback(Fn<void()> callback) override;
bool ready() override;
int framesCount() override;
FrameInfo frame(
QSize size,
QColor colored,
bool mirrorHorizontal,
crl::time now,
bool paused) override;
bool markFrameShown() override;
private:
void clipCallback(ClipNotification notification);
::Media::Clip::ReaderPointer _reader;
Fn<void()> _repaintCallback;
QSize _size;
};
WebmPlayer::WebmPlayer(
const Core::FileLocation &location,
const QByteArray &data,
QSize size)
: _reader(
::Media::Clip::MakeReader(location, data, [=](ClipNotification update) {
clipCallback(update);
}))
, _size(size) {
}
void WebmPlayer::clipCallback(ClipNotification notification) {
switch (notification) {
case ClipNotification::Reinit: {
if (_reader->state() == ::Media::Clip::State::Error) {
_reader.setBad();
} else if (_reader->ready() && !_reader->started()) {
_reader->start({ .frame = _size, .keepAlpha = true });
}
} break;
case ClipNotification::Repaint: break;
}
_repaintCallback();
}
void WebmPlayer::setRepaintCallback(Fn<void()> callback) {
_repaintCallback = std::move(callback);
}
bool WebmPlayer::ready() {
return _reader && _reader->started();
}
int WebmPlayer::framesCount() {
return -1;
}
WebmPlayer::FrameInfo WebmPlayer::frame(
QSize size,
QColor colored,
bool mirrorHorizontal,
crl::time now,
bool paused) {
auto request = ::Media::Clip::FrameRequest();
request.frame = size;
request.factor = style::DevicePixelRatio();
request.keepAlpha = true;
request.colored = colored;
const auto info = _reader->frameInfo(request, paused ? 0 : now);
return { .image = info.image, .index = info.index };
}
bool WebmPlayer::markFrameShown() {
return _reader->moveToNextFrame();
}
} // namespace
Sticker::Sticker(

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "history/view/media/history_view_media_unwrapped.h"
#include "history/view/media/history_view_sticker_player_abstract.h"
#include "base/weak_ptr.h"
namespace Main {
@ -20,7 +21,6 @@ class DocumentMedia;
} // namespace Data
namespace Lottie {
class SinglePlayer;
struct ColorReplacements;
} // namespace Lottie
@ -30,26 +30,6 @@ enum class StickerLottieSize : uint8;
namespace HistoryView {
class StickerPlayer {
public:
virtual ~StickerPlayer() = default;
struct FrameInfo {
QImage image;
int index = 0;
};
virtual void setRepaintCallback(Fn<void()> callback) = 0;
[[nodiscard]] virtual bool ready() = 0;
[[nodiscard]] virtual int framesCount() = 0;
[[nodiscard]] virtual FrameInfo frame(
QSize size,
QColor colored,
bool mirrorHorizontal,
crl::time now,
bool paused) = 0;
virtual bool markFrameShown() = 0;
};
class Sticker final
: public UnwrappedMedia::Content
, public base::has_weak_ptr {

View File

@ -0,0 +1,117 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "history/view/media/history_view_sticker_player.h"
namespace HistoryView {
namespace {
using ClipNotification = ::Media::Clip::Notification;
} // namespace
LottiePlayer::LottiePlayer(std::unique_ptr<Lottie::SinglePlayer> lottie)
: _lottie(std::move(lottie)) {
}
void LottiePlayer::setRepaintCallback(Fn<void()> callback) {
_repaintLifetime = _lottie->updates(
) | rpl::start_with_next([=](Lottie::Update update) {
v::match(update.data, [&](const Lottie::Information &) {
callback();
//markFramesTillExternal();
}, [&](const Lottie::DisplayFrameRequest &) {
callback();
});
});
}
bool LottiePlayer::ready() {
return _lottie->ready();
}
int LottiePlayer::framesCount() {
return _lottie->information().framesCount;
}
LottiePlayer::FrameInfo LottiePlayer::frame(
QSize size,
QColor colored,
bool mirrorHorizontal,
crl::time now,
bool paused) {
auto request = Lottie::FrameRequest();
request.box = size * style::DevicePixelRatio();
request.colored = colored;
request.mirrorHorizontal = mirrorHorizontal;
const auto info = _lottie->frameInfo(request);
return { .image = info.image, .index = info.index };
}
bool LottiePlayer::markFrameShown() {
return _lottie->markFrameShown();
}
WebmPlayer::WebmPlayer(
const Core::FileLocation &location,
const QByteArray &data,
QSize size)
: _reader(
::Media::Clip::MakeReader(location, data, [=](ClipNotification update) {
clipCallback(update);
}))
, _size(size) {
}
void WebmPlayer::clipCallback(ClipNotification notification) {
switch (notification) {
case ClipNotification::Reinit: {
if (_reader->state() == ::Media::Clip::State::Error) {
_reader.setBad();
} else if (_reader->ready() && !_reader->started()) {
_reader->start({ .frame = _size, .keepAlpha = true });
}
} break;
case ClipNotification::Repaint: break;
}
_repaintCallback();
}
void WebmPlayer::setRepaintCallback(Fn<void()> callback) {
_repaintCallback = std::move(callback);
}
bool WebmPlayer::ready() {
return _reader && _reader->started();
}
int WebmPlayer::framesCount() {
return -1;
}
WebmPlayer::FrameInfo WebmPlayer::frame(
QSize size,
QColor colored,
bool mirrorHorizontal,
crl::time now,
bool paused) {
auto request = ::Media::Clip::FrameRequest();
request.frame = size;
request.factor = style::DevicePixelRatio();
request.keepAlpha = true;
request.colored = colored;
const auto info = _reader->frameInfo(request, paused ? 0 : now);
return { .image = info.image, .index = info.index };
}
bool WebmPlayer::markFrameShown() {
return _reader->moveToNextFrame();
}
} // namespace HistoryView

View File

@ -0,0 +1,69 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "history/view/media/history_view_sticker_player_abstract.h"
#include "lottie/lottie_single_player.h"
#include "media/clip/media_clip_reader.h"
namespace Core {
class FileLocation;
} // namespace Core
namespace HistoryView {
class LottiePlayer final : public StickerPlayer {
public:
explicit LottiePlayer(std::unique_ptr<Lottie::SinglePlayer> lottie);
void setRepaintCallback(Fn<void()> callback) override;
bool ready() override;
int framesCount() override;
FrameInfo frame(
QSize size,
QColor colored,
bool mirrorHorizontal,
crl::time now,
bool paused) override;
bool markFrameShown() override;
private:
std::unique_ptr<Lottie::SinglePlayer> _lottie;
rpl::lifetime _repaintLifetime;
};
class WebmPlayer final : public StickerPlayer {
public:
WebmPlayer(
const Core::FileLocation &location,
const QByteArray &data,
QSize size);
void setRepaintCallback(Fn<void()> callback) override;
bool ready() override;
int framesCount() override;
FrameInfo frame(
QSize size,
QColor colored,
bool mirrorHorizontal,
crl::time now,
bool paused) override;
bool markFrameShown() override;
private:
void clipCallback(::Media::Clip::Notification notification);
::Media::Clip::ReaderPointer _reader;
Fn<void()> _repaintCallback;
QSize _size;
};
} // namespace HistoryView

View File

@ -0,0 +1,33 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
namespace HistoryView {
class StickerPlayer {
public:
virtual ~StickerPlayer() = default;
struct FrameInfo {
QImage image;
int index = 0;
};
virtual void setRepaintCallback(Fn<void()> callback) = 0;
[[nodiscard]] virtual bool ready() = 0;
[[nodiscard]] virtual int framesCount() = 0;
[[nodiscard]] virtual FrameInfo frame(
QSize size,
QColor colored,
bool mirrorHorizontal,
crl::time now,
bool paused) = 0;
virtual bool markFrameShown() = 0;
};
} // namespace HistoryView