mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added AbstractSingleMediaPreview.
This commit is contained in:
parent
19139a9a5f
commit
86db29cec7
5 changed files with 317 additions and 219 deletions
|
@ -0,0 +1,201 @@
|
||||||
|
/*
|
||||||
|
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 "ui/chat/attach/attach_abstract_single_media_preview.h"
|
||||||
|
|
||||||
|
#include "editor/photo_editor_common.h"
|
||||||
|
#include "ui/chat/attach/attach_controls.h"
|
||||||
|
#include "ui/image/image_prepare.h"
|
||||||
|
#include "ui/widgets/buttons.h"
|
||||||
|
#include "styles/style_boxes.h"
|
||||||
|
#include "styles/style_chat.h"
|
||||||
|
#include "styles/style_layers.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr auto kMinPreviewWidth = 20;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
AbstractSingleMediaPreview::AbstractSingleMediaPreview(QWidget *parent)
|
||||||
|
: RpWidget(parent)
|
||||||
|
, _minThumbH(st::sendBoxAlbumGroupSize.height()
|
||||||
|
+ st::sendBoxAlbumGroupSkipTop * 2)
|
||||||
|
, _photoEditorButton(base::make_unique_q<AbstractButton>(this))
|
||||||
|
, _controls(base::make_unique_q<AttachControlsWidget>(this)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractSingleMediaPreview::~AbstractSingleMediaPreview() = default;
|
||||||
|
|
||||||
|
rpl::producer<> AbstractSingleMediaPreview::deleteRequests() const {
|
||||||
|
return _controls->deleteRequests();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> AbstractSingleMediaPreview::editRequests() const {
|
||||||
|
return _controls->editRequests();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> AbstractSingleMediaPreview::modifyRequests() const {
|
||||||
|
return _photoEditorButton->clicks() | rpl::to_empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractSingleMediaPreview::preparePreview(QImage preview) {
|
||||||
|
auto maxW = 0;
|
||||||
|
auto maxH = 0;
|
||||||
|
if (_animated && drawBackground()) {
|
||||||
|
auto limitW = st::sendMediaPreviewSize;
|
||||||
|
auto limitH = st::confirmMaxHeight;
|
||||||
|
maxW = qMax(preview.width(), 1);
|
||||||
|
maxH = qMax(preview.height(), 1);
|
||||||
|
if (maxW * limitH > maxH * limitW) {
|
||||||
|
if (maxW < limitW) {
|
||||||
|
maxH = maxH * limitW / maxW;
|
||||||
|
maxW = limitW;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (maxH < limitH) {
|
||||||
|
maxW = maxW * limitH / maxH;
|
||||||
|
maxH = limitH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
preview = Images::prepare(
|
||||||
|
preview,
|
||||||
|
maxW * style::DevicePixelRatio(),
|
||||||
|
maxH * style::DevicePixelRatio(),
|
||||||
|
Images::Option::Smooth | Images::Option::Blurred,
|
||||||
|
maxW,
|
||||||
|
maxH);
|
||||||
|
}
|
||||||
|
auto originalWidth = preview.width();
|
||||||
|
auto originalHeight = preview.height();
|
||||||
|
if (!originalWidth || !originalHeight) {
|
||||||
|
originalWidth = originalHeight = 1;
|
||||||
|
}
|
||||||
|
_previewWidth = st::sendMediaPreviewSize;
|
||||||
|
if (preview.width() < _previewWidth) {
|
||||||
|
_previewWidth = qMax(preview.width(), kMinPreviewWidth);
|
||||||
|
}
|
||||||
|
auto maxthumbh = qMin(qRound(1.5 * _previewWidth), st::confirmMaxHeight);
|
||||||
|
_previewHeight = qRound(originalHeight
|
||||||
|
* float64(_previewWidth)
|
||||||
|
/ originalWidth);
|
||||||
|
if (_previewHeight > maxthumbh) {
|
||||||
|
_previewWidth = qRound(_previewWidth
|
||||||
|
* float64(maxthumbh)
|
||||||
|
/ _previewHeight);
|
||||||
|
accumulate_max(_previewWidth, kMinPreviewWidth);
|
||||||
|
_previewHeight = maxthumbh;
|
||||||
|
}
|
||||||
|
_previewLeft = (st::boxWideWidth - _previewWidth) / 2;
|
||||||
|
if (_previewHeight < _minThumbH) {
|
||||||
|
_previewTop = (_minThumbH - _previewHeight) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
preview = std::move(preview).scaled(
|
||||||
|
_previewWidth * style::DevicePixelRatio(),
|
||||||
|
_previewHeight * style::DevicePixelRatio(),
|
||||||
|
Qt::IgnoreAspectRatio,
|
||||||
|
Qt::SmoothTransformation);
|
||||||
|
preview = Images::prepareOpaque(std::move(preview));
|
||||||
|
_preview = PixmapFromImage(std::move(preview));
|
||||||
|
_preview.setDevicePixelRatio(style::DevicePixelRatio());
|
||||||
|
|
||||||
|
_photoEditorButton->resize(_previewWidth, _previewHeight);
|
||||||
|
_photoEditorButton->moveToLeft(_previewLeft, _previewTop);
|
||||||
|
_photoEditorButton->setVisible(isPhoto());
|
||||||
|
|
||||||
|
resize(width(), std::max(_previewHeight, _minThumbH));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractSingleMediaPreview::resizeEvent(QResizeEvent *e) {
|
||||||
|
_controls->moveToRight(
|
||||||
|
st::boxPhotoPadding.right() + st::sendBoxAlbumGroupSkipRight,
|
||||||
|
st::sendBoxAlbumGroupSkipTop,
|
||||||
|
width());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractSingleMediaPreview::paintEvent(QPaintEvent *e) {
|
||||||
|
Painter p(this);
|
||||||
|
|
||||||
|
if (drawBackground()) {
|
||||||
|
const auto &padding = st::boxPhotoPadding;
|
||||||
|
if (_previewLeft > padding.left()) {
|
||||||
|
p.fillRect(
|
||||||
|
padding.left(),
|
||||||
|
_previewTop,
|
||||||
|
_previewLeft - padding.left(),
|
||||||
|
_previewHeight,
|
||||||
|
st::confirmBg);
|
||||||
|
}
|
||||||
|
if ((_previewLeft + _previewWidth) < (width() - padding.right())) {
|
||||||
|
p.fillRect(
|
||||||
|
_previewLeft + _previewWidth,
|
||||||
|
_previewTop,
|
||||||
|
width() - padding.right() - _previewLeft - _previewWidth,
|
||||||
|
_previewHeight,
|
||||||
|
st::confirmBg);
|
||||||
|
}
|
||||||
|
if (_previewTop > 0) {
|
||||||
|
p.fillRect(
|
||||||
|
padding.left(),
|
||||||
|
0,
|
||||||
|
width() - padding.right() - padding.left(),
|
||||||
|
height(),
|
||||||
|
st::confirmBg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!tryPaintAnimation(p)) {
|
||||||
|
p.drawPixmap(_previewLeft, _previewTop, _preview);
|
||||||
|
}
|
||||||
|
if (_animated && !isAnimatedPreviewReady()) {
|
||||||
|
const auto innerSize = st::msgFileLayout.thumbSize;
|
||||||
|
auto inner = QRect(
|
||||||
|
_previewLeft + (_previewWidth - innerSize) / 2,
|
||||||
|
_previewTop + (_previewHeight - innerSize) / 2,
|
||||||
|
innerSize,
|
||||||
|
innerSize);
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setBrush(st::msgDateImgBg);
|
||||||
|
|
||||||
|
{
|
||||||
|
PainterHighQualityEnabler hq(p);
|
||||||
|
p.drawEllipse(inner);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto icon = &st::historyFileInPlay;
|
||||||
|
icon->paintInCenter(p, inner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int AbstractSingleMediaPreview::previewLeft() const {
|
||||||
|
return _previewLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AbstractSingleMediaPreview::previewTop() const {
|
||||||
|
return _previewTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AbstractSingleMediaPreview::previewWidth() const {
|
||||||
|
return _previewWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AbstractSingleMediaPreview::previewHeight() const {
|
||||||
|
return _previewHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractSingleMediaPreview::setAnimated(bool animated) {
|
||||||
|
_animated = animated;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AbstractSingleMediaPreview::isPhoto() const {
|
||||||
|
return drawBackground()
|
||||||
|
&& !isAnimatedPreviewReady()
|
||||||
|
&& !_animated;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Ui
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
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 "ui/rp_widget.h"
|
||||||
|
#include "ui/abstract_button.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
|
||||||
|
class AttachControlsWidget;
|
||||||
|
|
||||||
|
class AbstractSingleMediaPreview : public RpWidget {
|
||||||
|
public:
|
||||||
|
AbstractSingleMediaPreview(QWidget *parent);
|
||||||
|
~AbstractSingleMediaPreview();
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<> deleteRequests() const;
|
||||||
|
[[nodiscard]] rpl::producer<> editRequests() const;
|
||||||
|
[[nodiscard]] rpl::producer<> modifyRequests() const;
|
||||||
|
|
||||||
|
[[nodiscard]] bool isPhoto() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool drawBackground() const = 0;
|
||||||
|
virtual bool tryPaintAnimation(Painter &p) = 0;
|
||||||
|
virtual bool isAnimatedPreviewReady() const = 0;
|
||||||
|
|
||||||
|
void preparePreview(QImage preview);
|
||||||
|
|
||||||
|
int previewLeft() const;
|
||||||
|
int previewTop() const;
|
||||||
|
int previewWidth() const;
|
||||||
|
int previewHeight() const;
|
||||||
|
|
||||||
|
void setAnimated(bool animated);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
|
||||||
|
bool _animated = false;
|
||||||
|
QPixmap _preview;
|
||||||
|
int _previewLeft = 0;
|
||||||
|
int _previewTop = 0;
|
||||||
|
int _previewWidth = 0;
|
||||||
|
int _previewHeight = 0;
|
||||||
|
|
||||||
|
const int _minThumbH;
|
||||||
|
const base::unique_qptr<AbstractButton> _photoEditorButton;
|
||||||
|
const base::unique_qptr<AttachControlsWidget> _controls;
|
||||||
|
|
||||||
|
rpl::event_stream<> _modifyRequests;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Ui
|
|
@ -8,22 +8,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/chat/attach/attach_single_media_preview.h"
|
#include "ui/chat/attach/attach_single_media_preview.h"
|
||||||
|
|
||||||
#include "editor/photo_editor_common.h"
|
#include "editor/photo_editor_common.h"
|
||||||
#include "ui/chat/attach/attach_controls.h"
|
|
||||||
#include "ui/chat/attach/attach_prepare.h"
|
#include "ui/chat/attach/attach_prepare.h"
|
||||||
#include "ui/widgets/buttons.h"
|
|
||||||
#include "core/mime_type.h"
|
#include "core/mime_type.h"
|
||||||
#include "lottie/lottie_single_player.h"
|
#include "lottie/lottie_single_player.h"
|
||||||
#include "styles/style_boxes.h"
|
|
||||||
#include "styles/style_chat.h"
|
|
||||||
#include "styles/style_layers.h"
|
|
||||||
#include "styles/palette.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
namespace {
|
|
||||||
|
|
||||||
constexpr auto kMinPreviewWidth = 20;
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
SingleMediaPreview *SingleMediaPreview::Create(
|
SingleMediaPreview *SingleMediaPreview::Create(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
|
@ -65,119 +54,59 @@ SingleMediaPreview::SingleMediaPreview(
|
||||||
bool animated,
|
bool animated,
|
||||||
bool sticker,
|
bool sticker,
|
||||||
const QString &animatedPreviewPath)
|
const QString &animatedPreviewPath)
|
||||||
: RpWidget(parent)
|
: AbstractSingleMediaPreview(parent)
|
||||||
, _gifPaused(std::move(gifPaused))
|
, _gifPaused(std::move(gifPaused))
|
||||||
, _animated(animated)
|
, _sticker(sticker) {
|
||||||
, _sticker(sticker)
|
|
||||||
, _minThumbH(st::sendBoxAlbumGroupSize.height()
|
|
||||||
+ st::sendBoxAlbumGroupSkipTop * 2)
|
|
||||||
, _photoEditorButton(base::make_unique_q<AbstractButton>(this))
|
|
||||||
, _controls(base::make_unique_q<AttachControlsWidget>(this)) {
|
|
||||||
Expects(!preview.isNull());
|
Expects(!preview.isNull());
|
||||||
|
setAnimated(animated);
|
||||||
|
|
||||||
preparePreview(preview, animatedPreviewPath);
|
prepareAnimatedPreview(animatedPreviewPath, animated);
|
||||||
|
preparePreview(preview);
|
||||||
}
|
}
|
||||||
|
|
||||||
SingleMediaPreview::~SingleMediaPreview() = default;
|
bool SingleMediaPreview::drawBackground() const {
|
||||||
|
return !_sticker;
|
||||||
rpl::producer<> SingleMediaPreview::deleteRequests() const {
|
|
||||||
return _controls->deleteRequests();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<> SingleMediaPreview::editRequests() const {
|
bool SingleMediaPreview::tryPaintAnimation(Painter &p) {
|
||||||
return _controls->editRequests();
|
if (_gifPreview && _gifPreview->started()) {
|
||||||
|
auto s = QSize(previewWidth(), previewHeight());
|
||||||
|
auto paused = _gifPaused();
|
||||||
|
auto frame = _gifPreview->current(
|
||||||
|
s.width(),
|
||||||
|
s.height(),
|
||||||
|
s.width(),
|
||||||
|
s.height(),
|
||||||
|
ImageRoundRadius::None,
|
||||||
|
RectPart::None,
|
||||||
|
paused ? 0 : crl::now());
|
||||||
|
p.drawPixmap(previewLeft(), previewTop(), frame);
|
||||||
|
return true;
|
||||||
|
} else if (_lottiePreview && _lottiePreview->ready()) {
|
||||||
|
const auto frame = _lottiePreview->frame();
|
||||||
|
const auto size = frame.size() / style::DevicePixelRatio();
|
||||||
|
p.drawImage(
|
||||||
|
QRect(
|
||||||
|
previewLeft() + (previewWidth() - size.width()) / 2,
|
||||||
|
(previewHeight() - size.height()) / 2,
|
||||||
|
size.width(),
|
||||||
|
size.height()),
|
||||||
|
frame);
|
||||||
|
_lottiePreview->markFrameShown();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<> SingleMediaPreview::modifyRequests() const {
|
bool SingleMediaPreview::isAnimatedPreviewReady() const {
|
||||||
return _photoEditorButton->clicks() | rpl::to_empty;
|
return _gifPreview || _lottiePreview;
|
||||||
}
|
|
||||||
|
|
||||||
void SingleMediaPreview::preparePreview(
|
|
||||||
QImage preview,
|
|
||||||
const QString &animatedPreviewPath) {
|
|
||||||
auto maxW = 0;
|
|
||||||
auto maxH = 0;
|
|
||||||
if (_animated && !_sticker) {
|
|
||||||
auto limitW = st::sendMediaPreviewSize;
|
|
||||||
auto limitH = st::confirmMaxHeight;
|
|
||||||
maxW = qMax(preview.width(), 1);
|
|
||||||
maxH = qMax(preview.height(), 1);
|
|
||||||
if (maxW * limitH > maxH * limitW) {
|
|
||||||
if (maxW < limitW) {
|
|
||||||
maxH = maxH * limitW / maxW;
|
|
||||||
maxW = limitW;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (maxH < limitH) {
|
|
||||||
maxW = maxW * limitH / maxH;
|
|
||||||
maxH = limitH;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
preview = Images::prepare(
|
|
||||||
preview,
|
|
||||||
maxW * style::DevicePixelRatio(),
|
|
||||||
maxH * style::DevicePixelRatio(),
|
|
||||||
Images::Option::Smooth | Images::Option::Blurred,
|
|
||||||
maxW,
|
|
||||||
maxH);
|
|
||||||
}
|
|
||||||
auto originalWidth = preview.width();
|
|
||||||
auto originalHeight = preview.height();
|
|
||||||
if (!originalWidth || !originalHeight) {
|
|
||||||
originalWidth = originalHeight = 1;
|
|
||||||
}
|
|
||||||
_previewWidth = st::sendMediaPreviewSize;
|
|
||||||
if (preview.width() < _previewWidth) {
|
|
||||||
_previewWidth = qMax(preview.width(), kMinPreviewWidth);
|
|
||||||
}
|
|
||||||
auto maxthumbh = qMin(qRound(1.5 * _previewWidth), st::confirmMaxHeight);
|
|
||||||
_previewHeight = qRound(originalHeight
|
|
||||||
* float64(_previewWidth)
|
|
||||||
/ originalWidth);
|
|
||||||
if (_previewHeight > maxthumbh) {
|
|
||||||
_previewWidth = qRound(_previewWidth
|
|
||||||
* float64(maxthumbh)
|
|
||||||
/ _previewHeight);
|
|
||||||
accumulate_max(_previewWidth, kMinPreviewWidth);
|
|
||||||
_previewHeight = maxthumbh;
|
|
||||||
}
|
|
||||||
_previewLeft = (st::boxWideWidth - _previewWidth) / 2;
|
|
||||||
if (_previewHeight < _minThumbH) {
|
|
||||||
_previewTop = (_minThumbH - _previewHeight) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
preview = std::move(preview).scaled(
|
|
||||||
_previewWidth * style::DevicePixelRatio(),
|
|
||||||
_previewHeight * style::DevicePixelRatio(),
|
|
||||||
Qt::IgnoreAspectRatio,
|
|
||||||
Qt::SmoothTransformation);
|
|
||||||
preview = Images::prepareOpaque(std::move(preview));
|
|
||||||
_preview = PixmapFromImage(std::move(preview));
|
|
||||||
_preview.setDevicePixelRatio(style::DevicePixelRatio());
|
|
||||||
|
|
||||||
prepareAnimatedPreview(animatedPreviewPath);
|
|
||||||
|
|
||||||
_photoEditorButton->resize(_previewWidth, _previewHeight);
|
|
||||||
_photoEditorButton->moveToLeft(_previewLeft, _previewTop);
|
|
||||||
_photoEditorButton->setVisible(!_sticker
|
|
||||||
&& !_gifPreview
|
|
||||||
&& !_lottiePreview
|
|
||||||
&& !_animated);
|
|
||||||
|
|
||||||
resize(width(), std::max(_previewHeight, _minThumbH));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SingleMediaPreview::resizeEvent(QResizeEvent *e) {
|
|
||||||
_controls->moveToRight(
|
|
||||||
st::boxPhotoPadding.right() + st::sendBoxAlbumGroupSkipRight,
|
|
||||||
st::sendBoxAlbumGroupSkipTop,
|
|
||||||
width());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SingleMediaPreview::prepareAnimatedPreview(
|
void SingleMediaPreview::prepareAnimatedPreview(
|
||||||
const QString &animatedPreviewPath) {
|
const QString &animatedPreviewPath,
|
||||||
if (_sticker && _animated) {
|
bool animated) {
|
||||||
const auto box = QSize(_previewWidth, _previewHeight)
|
if (_sticker && animated) {
|
||||||
|
const auto box = QSize(previewWidth(), previewHeight())
|
||||||
* style::DevicePixelRatio();
|
* style::DevicePixelRatio();
|
||||||
_lottiePreview = std::make_unique<Lottie::SinglePlayer>(
|
_lottiePreview = std::make_unique<Lottie::SinglePlayer>(
|
||||||
Lottie::ReadContent(QByteArray(), animatedPreviewPath),
|
Lottie::ReadContent(QByteArray(), animatedPreviewPath),
|
||||||
|
@ -206,7 +135,7 @@ void SingleMediaPreview::clipCallback(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_gifPreview && _gifPreview->ready() && !_gifPreview->started()) {
|
if (_gifPreview && _gifPreview->ready() && !_gifPreview->started()) {
|
||||||
auto s = QSize(_previewWidth, _previewHeight);
|
const auto s = QSize(previewWidth(), previewHeight());
|
||||||
_gifPreview->start(
|
_gifPreview->start(
|
||||||
s.width(),
|
s.width(),
|
||||||
s.height(),
|
s.height(),
|
||||||
|
@ -227,80 +156,4 @@ void SingleMediaPreview::clipCallback(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SingleMediaPreview::paintEvent(QPaintEvent *e) {
|
|
||||||
Painter p(this);
|
|
||||||
|
|
||||||
if (!_sticker) {
|
|
||||||
const auto &padding = st::boxPhotoPadding;
|
|
||||||
if (_previewLeft > padding.left()) {
|
|
||||||
p.fillRect(
|
|
||||||
padding.left(),
|
|
||||||
_previewTop,
|
|
||||||
_previewLeft - padding.left(),
|
|
||||||
_previewHeight,
|
|
||||||
st::confirmBg);
|
|
||||||
}
|
|
||||||
if ((_previewLeft + _previewWidth) < (width() - padding.right())) {
|
|
||||||
p.fillRect(
|
|
||||||
_previewLeft + _previewWidth,
|
|
||||||
_previewTop,
|
|
||||||
width() - padding.right() - _previewLeft - _previewWidth,
|
|
||||||
_previewHeight,
|
|
||||||
st::confirmBg);
|
|
||||||
}
|
|
||||||
if (_previewTop > 0) {
|
|
||||||
p.fillRect(
|
|
||||||
padding.left(),
|
|
||||||
0,
|
|
||||||
width() - padding.right() - padding.left(),
|
|
||||||
height(),
|
|
||||||
st::confirmBg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_gifPreview && _gifPreview->started()) {
|
|
||||||
auto s = QSize(_previewWidth, _previewHeight);
|
|
||||||
auto paused = _gifPaused();
|
|
||||||
auto frame = _gifPreview->current(
|
|
||||||
s.width(),
|
|
||||||
s.height(),
|
|
||||||
s.width(),
|
|
||||||
s.height(),
|
|
||||||
ImageRoundRadius::None,
|
|
||||||
RectPart::None,
|
|
||||||
paused ? 0 : crl::now());
|
|
||||||
p.drawPixmap(_previewLeft, _previewTop, frame);
|
|
||||||
} else if (_lottiePreview && _lottiePreview->ready()) {
|
|
||||||
const auto frame = _lottiePreview->frame();
|
|
||||||
const auto size = frame.size() / style::DevicePixelRatio();
|
|
||||||
p.drawImage(
|
|
||||||
QRect(
|
|
||||||
_previewLeft + (_previewWidth - size.width()) / 2,
|
|
||||||
(_previewHeight - size.height()) / 2,
|
|
||||||
size.width(),
|
|
||||||
size.height()),
|
|
||||||
frame);
|
|
||||||
_lottiePreview->markFrameShown();
|
|
||||||
} else {
|
|
||||||
p.drawPixmap(_previewLeft, _previewTop, _preview);
|
|
||||||
}
|
|
||||||
if (_animated && !_gifPreview && !_lottiePreview) {
|
|
||||||
const auto innerSize = st::msgFileLayout.thumbSize;
|
|
||||||
auto inner = QRect(
|
|
||||||
_previewLeft + (_previewWidth - innerSize) / 2,
|
|
||||||
_previewTop + (_previewHeight - innerSize) / 2,
|
|
||||||
innerSize,
|
|
||||||
innerSize);
|
|
||||||
p.setPen(Qt::NoPen);
|
|
||||||
p.setBrush(st::msgDateImgBg);
|
|
||||||
|
|
||||||
{
|
|
||||||
PainterHighQualityEnabler hq(p);
|
|
||||||
p.drawEllipse(inner);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto icon = &st::historyFileInPlay;
|
|
||||||
icon->paintInCenter(p, inner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
|
@ -7,8 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/chat/attach/attach_abstract_single_media_preview.h"
|
||||||
#include "ui/abstract_button.h"
|
|
||||||
#include "media/clip/media_clip_reader.h"
|
#include "media/clip/media_clip_reader.h"
|
||||||
|
|
||||||
namespace Lottie {
|
namespace Lottie {
|
||||||
|
@ -17,11 +16,9 @@ class SinglePlayer;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
class AttachControlsWidget;
|
|
||||||
struct PreparedFile;
|
struct PreparedFile;
|
||||||
class IconButton;
|
|
||||||
|
|
||||||
class SingleMediaPreview final : public RpWidget {
|
class SingleMediaPreview final : public AbstractSingleMediaPreview {
|
||||||
public:
|
public:
|
||||||
static SingleMediaPreview *Create(
|
static SingleMediaPreview *Create(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
|
@ -35,39 +32,23 @@ public:
|
||||||
bool animated,
|
bool animated,
|
||||||
bool sticker,
|
bool sticker,
|
||||||
const QString &animatedPreviewPath);
|
const QString &animatedPreviewPath);
|
||||||
~SingleMediaPreview();
|
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<> deleteRequests() const;
|
protected:
|
||||||
[[nodiscard]] rpl::producer<> editRequests() const;
|
bool drawBackground() const override;
|
||||||
[[nodiscard]] rpl::producer<> modifyRequests() const;
|
bool tryPaintAnimation(Painter &p) override;
|
||||||
|
bool isAnimatedPreviewReady() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void prepareAnimatedPreview(
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
const QString &animatedPreviewPath,
|
||||||
|
bool animated);
|
||||||
void preparePreview(
|
|
||||||
QImage preview,
|
|
||||||
const QString &animatedPreviewPath);
|
|
||||||
void prepareAnimatedPreview(const QString &animatedPreviewPath);
|
|
||||||
void clipCallback(Media::Clip::Notification notification);
|
void clipCallback(Media::Clip::Notification notification);
|
||||||
|
|
||||||
Fn<bool()> _gifPaused;
|
const Fn<bool()> _gifPaused;
|
||||||
bool _animated = false;
|
const bool _sticker = false;
|
||||||
bool _sticker = false;
|
|
||||||
QPixmap _preview;
|
|
||||||
int _previewLeft = 0;
|
|
||||||
int _previewTop = 0;
|
|
||||||
int _previewWidth = 0;
|
|
||||||
int _previewHeight = 0;
|
|
||||||
Media::Clip::ReaderPointer _gifPreview;
|
Media::Clip::ReaderPointer _gifPreview;
|
||||||
std::unique_ptr<Lottie::SinglePlayer> _lottiePreview;
|
std::unique_ptr<Lottie::SinglePlayer> _lottiePreview;
|
||||||
|
|
||||||
const int _minThumbH;
|
|
||||||
const base::unique_qptr<AbstractButton> _photoEditorButton;
|
|
||||||
const base::unique_qptr<AttachControlsWidget> _controls;
|
|
||||||
|
|
||||||
rpl::event_stream<> _modifyRequests;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
|
@ -108,6 +108,8 @@ PRIVATE
|
||||||
ui/boxes/single_choice_box.h
|
ui/boxes/single_choice_box.h
|
||||||
ui/chat/attach/attach_abstract_single_file_preview.cpp
|
ui/chat/attach/attach_abstract_single_file_preview.cpp
|
||||||
ui/chat/attach/attach_abstract_single_file_preview.h
|
ui/chat/attach/attach_abstract_single_file_preview.h
|
||||||
|
ui/chat/attach/attach_abstract_single_media_preview.cpp
|
||||||
|
ui/chat/attach/attach_abstract_single_media_preview.h
|
||||||
ui/chat/attach/attach_album_preview.cpp
|
ui/chat/attach/attach_album_preview.cpp
|
||||||
ui/chat/attach/attach_album_preview.h
|
ui/chat/attach/attach_album_preview.h
|
||||||
ui/chat/attach/attach_album_thumbnail.cpp
|
ui/chat/attach/attach_album_thumbnail.cpp
|
||||||
|
|
Loading…
Add table
Reference in a new issue