Added display of video message in transcribed view.

This commit is contained in:
23rd 2022-10-24 08:32:13 +03:00 committed by John Preston
parent dec47eafb8
commit 1cd02fc3c9
4 changed files with 112 additions and 52 deletions

View file

@ -25,6 +25,10 @@ namespace Data {
class Session;
} // namespace Data
namespace Media::Player {
class RoundPainter;
} // namespace Media::Player
namespace Images {
struct CornersMaskRef;
} // namespace Images
@ -508,6 +512,7 @@ public:
std::unique_ptr<HistoryView::TranscribeButton> transcribe;
Ui::Text::String transcribeText;
std::unique_ptr<Media::Player::RoundPainter> round;
private:
bool _seeking = false;

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "storage/localstorage.h"
#include "main/main_session.h"
#include "media/player/media_player_float.h" // Media::Player::RoundPainter.
#include "media/audio/media_audio.h"
#include "media/player/media_player_instance.h"
#include "history/history_item_components.h"
@ -255,6 +256,10 @@ void Document::createComponents(bool caption) {
voice->seekl = std::make_shared<VoiceSeekClickHandler>(
_data,
[](FullMsgId) {});
if (_transcribedRound) {
voice->round = std::make_unique<::Media::Player::RoundPainter>(
_realParent);
}
}
}
@ -542,9 +547,26 @@ void Document::draw(
inner,
context.selected());
if (!coverDrawn) {
PainterHighQualityEnabler hq(p);
p.setBrush(stm->msgFileBg);
p.drawEllipse(inner);
if (_transcribedRound) {
if (const auto voice = Get<HistoryDocumentVoice>()) {
if (const auto &round = voice->round) {
if (round->fillFrame(inner.size())) {
p.drawImage(inner.topLeft(), round->frame());
} else {
DrawThumbnailAsSongCover(
p,
st::transparent,
_dataMedia,
inner,
context.selected());
}
}
}
} else {
PainterHighQualityEnabler hq(p);
p.setBrush(stm->msgFileBg);
p.drawEllipse(inner);
}
}
const auto &icon = [&]() -> const style::icon& {
@ -812,7 +834,9 @@ void Document::ensureDataMediaCreated() const {
return;
}
_dataMedia = _data->createMediaView();
if (Get<HistoryDocumentThumbed>() || _data->isSongWithCover()) {
if (Get<HistoryDocumentThumbed>()
|| _data->isSongWithCover()
|| _transcribedRound) {
_dataMedia->thumbnailWanted(_realParent->fullId());
}
history()->owner().registerHeavyViewPart(_parent);

View file

@ -38,6 +38,55 @@ namespace Player {
using DoubleClickedCallback = Fn<void(not_null<const HistoryItem*>)>;
RoundPainter::RoundPainter(not_null<HistoryItem*> item)
: _item(item) {
}
bool RoundPainter::fillFrame(const QSize &size) {
auto creating = _frame.isNull();
const auto ratio = style::DevicePixelRatio();
if (creating) {
_frame = QImage(
size * ratio,
QImage::Format_ARGB32_Premultiplied);
_frame.setDevicePixelRatio(ratio);
}
auto frameInner = [&] {
return QRect(QPoint(), _frame.size() / ratio);
};
if (const auto streamed = instance()->roundVideoStreamed(_item)) {
auto request = Streaming::FrameRequest::NonStrict();
request.outer = request.resize = _frame.size();
if (_roundingMask.size() != request.outer) {
_roundingMask = Images::EllipseMask(frameInner().size());
}
request.mask = _roundingMask;
auto frame = streamed->frame(request);
if (!frame.isNull()) {
_frame.fill(Qt::transparent);
auto p = QPainter(&_frame);
PainterHighQualityEnabler hq(p);
p.drawImage(frameInner(), frame);
return true;
}
}
if (creating) {
_frame.fill(Qt::transparent);
auto p = QPainter(&_frame);
PainterHighQualityEnabler hq(p);
p.setPen(Qt::NoPen);
p.setBrush(st::imageBg);
p.drawEllipse(frameInner());
}
return false;
}
const QImage &RoundPainter::frame() const {
return _frame;
}
Float::Float(
QWidget *parent,
not_null<HistoryItem*> item,
@ -60,6 +109,7 @@ Float::Float(
auto size = 2 * margin + st::mediaPlayerFloatSize;
resize(size, size);
_roundPainter = std::make_unique<RoundPainter>(item);
prepareShadow();
document->session().data().itemRepaintRequest(
@ -156,6 +206,7 @@ void Float::pauseResume() {
void Float::detach() {
if (_item) {
_item = nullptr;
_roundPainter = nullptr;
if (_toggleCallback) {
_toggleCallback(false);
}
@ -163,9 +214,12 @@ void Float::detach() {
}
void Float::prepareShadow() {
auto shadow = QImage(size() * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
const auto ratio = style::DevicePixelRatio();
auto shadow = QImage(
size() * ratio,
QImage::Format_ARGB32_Premultiplied);
shadow.fill(Qt::transparent);
shadow.setDevicePixelRatio(cRetinaFactor());
shadow.setDevicePixelRatio(ratio);
{
auto p = QPainter(&shadow);
PainterHighQualityEnabler hq(p);
@ -188,12 +242,15 @@ void Float::paintEvent(QPaintEvent *e) {
p.setOpacity(_opacity);
p.drawPixmap(0, 0, _shadow);
if (!fillFrame() && _toggleCallback) {
const auto inner = getInnerRect();
if (!(_roundPainter && _roundPainter->fillFrame(inner.size()))
&& _toggleCallback) {
_toggleCallback(false);
}
auto inner = getInnerRect();
p.drawImage(inner.topLeft(), _frame);
if (_roundPainter) {
p.drawImage(inner.topLeft(), _roundPainter->frame());
}
const auto playback = getPlayback();
const auto progress = playback ? playback->value() : 1.;
@ -230,46 +287,6 @@ bool Float::hasFrame() const {
return (getStreamed() != nullptr);
}
bool Float::fillFrame() {
auto creating = _frame.isNull();
if (creating) {
_frame = QImage(
getInnerRect().size() * cIntRetinaFactor(),
QImage::Format_ARGB32_Premultiplied);
_frame.setDevicePixelRatio(cRetinaFactor());
}
auto frameInner = [&] {
return QRect(QPoint(), _frame.size() / cIntRetinaFactor());
};
if (const auto streamed = getStreamed()) {
auto request = Streaming::FrameRequest::NonStrict();
request.outer = request.resize = _frame.size();
if (_roundingMask.size() != request.outer) {
_roundingMask = Images::EllipseMask(frameInner().size());
}
request.mask = _roundingMask;
auto frame = streamed->frame(request);
if (!frame.isNull()) {
_frame.fill(Qt::transparent);
auto p = QPainter(&_frame);
PainterHighQualityEnabler hq(p);
p.drawImage(frameInner(), frame);
return true;
}
}
if (creating) {
_frame.fill(Qt::transparent);
auto p = QPainter(&_frame);
PainterHighQualityEnabler hq(p);
p.setPen(Qt::NoPen);
p.setBrush(st::imageBg);
p.drawEllipse(frameInner());
}
return false;
}
void Float::repaintItem() {
update();
if (hasFrame() && _toggleCallback) {

View file

@ -33,6 +33,21 @@ class Instance;
namespace Media {
namespace Player {
class RoundPainter {
public:
RoundPainter(not_null<HistoryItem*> item);
bool fillFrame(const QSize &size);
const QImage &frame() const;
private:
const not_null<HistoryItem*> _item;
QImage _roundingMask;
QImage _frame;
};
class Float : public Ui::RpWidget, private base::Subscriber {
public:
Float(
@ -85,7 +100,6 @@ private:
void repaintItem();
void prepareShadow();
bool hasFrame() const;
bool fillFrame();
[[nodiscard]] QRect getInnerRect() const;
void finishDrag(bool closed);
void pauseResume();
@ -93,11 +107,11 @@ private:
HistoryItem *_item = nullptr;
Fn<void(bool visible)> _toggleCallback;
std::unique_ptr<RoundPainter> _roundPainter;
float64 _opacity = 1.;
QPixmap _shadow;
QImage _roundingMask;
QImage _frame;
bool _down = false;
QPoint _downPoint;