mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-07 23:53:58 +02:00
Add edit/remove buttons to Single[File|Media]Preview.
This commit is contained in:
parent
5589f51369
commit
d7fe2948ac
9 changed files with 162 additions and 65 deletions
|
@ -508,29 +508,33 @@ editMediaButton: IconButton {
|
||||||
|
|
||||||
// SendFilesBox
|
// SendFilesBox
|
||||||
|
|
||||||
sendBoxAlbumGroupEditInternalSkip: 9px;
|
sendBoxAlbumGroupEditInternalSkip: 8px;
|
||||||
sendBoxAlbumGroupSkipRight: 6px;
|
sendBoxAlbumGroupSkipRight: 6px;
|
||||||
sendBoxAlbumGroupSkipTop: 6px;
|
sendBoxAlbumGroupSkipTop: 6px;
|
||||||
sendBoxAlbumGroupRadius: 12px;
|
sendBoxAlbumGroupRadius: 13px;
|
||||||
sendBoxAlbumGroupHeight: 25px;
|
sendBoxAlbumGroupHeight: 26px;
|
||||||
|
|
||||||
sendBoxFileGroupSkipTop: 2px;
|
sendBoxFileGroupSkipTop: 2px;
|
||||||
sendBoxFileGroupSkipRight: 0px;
|
sendBoxFileGroupSkipRight: 0px;
|
||||||
sendBoxFileGroupEditInternalSkip: 4px;
|
sendBoxFileGroupEditInternalSkip: 4px;
|
||||||
|
|
||||||
sendBoxAlbumGroupEditButtonIcon: editMediaButtonIconPhoto;
|
|
||||||
sendBoxAlbumGroupEditButtonIconPosition: point(4px, -1px);
|
|
||||||
|
|
||||||
sendBoxAlbumGroupButtonFile: IconButton(editMediaButton) {
|
sendBoxAlbumGroupButtonFile: IconButton(editMediaButton) {
|
||||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||||
color: windowBgRipple;
|
color: windowBgRipple;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sendBoxAlbumGroupEditButtonIconFile: editMediaButtonIconFile;
|
||||||
sendBoxAlbumGroupDeleteButtonIconPosition: point(-3px, 0px);
|
|
||||||
sendBoxAlbumGroupDeleteButtonIcon: icon {{ "history_file_cancel", msgServiceFg}};
|
|
||||||
sendBoxAlbumGroupDeleteButtonIconFile: icon {{ "history_file_cancel", menuIconFg, point(6px, 6px) }};
|
sendBoxAlbumGroupDeleteButtonIconFile: icon {{ "history_file_cancel", menuIconFg, point(6px, 6px) }};
|
||||||
|
|
||||||
|
sendBoxAlbumGroupButtonMediaEdit: icon {{ "settings_edit", msgServiceFg, point(3px, -2px) }};
|
||||||
|
sendBoxAlbumGroupButtonMediaDelete: icon {{ "history_file_cancel", msgServiceFg, point(2px, 5px) }};
|
||||||
|
sendBoxAlbumGroupButtonMedia: IconButton {
|
||||||
|
width: sendBoxAlbumGroupHeight;
|
||||||
|
height: sendBoxAlbumGroupHeight;
|
||||||
|
|
||||||
|
icon: sendBoxAlbumGroupButtonMediaEdit;
|
||||||
|
}
|
||||||
|
|
||||||
// End of SendFilesBox
|
// End of SendFilesBox
|
||||||
|
|
||||||
calendarTitleHeight: boxTitleHeight;
|
calendarTitleHeight: boxTitleHeight;
|
||||||
|
|
|
@ -132,6 +132,7 @@ SendFilesBox::Block::Block(
|
||||||
gifPaused,
|
gifPaused,
|
||||||
first);
|
first);
|
||||||
if (media) {
|
if (media) {
|
||||||
|
_isSingleMedia = true;
|
||||||
_preview.reset(media);
|
_preview.reset(media);
|
||||||
} else {
|
} else {
|
||||||
_preview.reset(
|
_preview.reset(
|
||||||
|
@ -154,19 +155,35 @@ object_ptr<Ui::RpWidget> SendFilesBox::Block::takeWidget() {
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<int> SendFilesBox::Block::itemDeleteRequest() const {
|
rpl::producer<int> SendFilesBox::Block::itemDeleteRequest() const {
|
||||||
if (!_isAlbum) {
|
using namespace rpl::mappers;
|
||||||
return rpl::never<int>();
|
|
||||||
|
const auto preview = _preview.get();
|
||||||
|
if (_isAlbum) {
|
||||||
|
const auto album = static_cast<Ui::AlbumPreview*>(_preview.get());
|
||||||
|
return album->thumbDeleted() | rpl::map(_1 + _from);
|
||||||
|
} else if (_isSingleMedia) {
|
||||||
|
const auto media = static_cast<Ui::SingleMediaPreview*>(preview);
|
||||||
|
return media->deleteRequests() | rpl::map([=] { return _from; });
|
||||||
|
} else {
|
||||||
|
const auto single = static_cast<Ui::SingleFilePreview*>(preview);
|
||||||
|
return single->deleteRequests() | rpl::map([=] { return _from; });
|
||||||
}
|
}
|
||||||
const auto album = static_cast<Ui::AlbumPreview*>(_preview.get());
|
|
||||||
return album->thumbDeleted();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<int> SendFilesBox::Block::itemReplaceRequest() const {
|
rpl::producer<int> SendFilesBox::Block::itemReplaceRequest() const {
|
||||||
if (!_isAlbum) {
|
using namespace rpl::mappers;
|
||||||
return rpl::never<int>();
|
|
||||||
|
const auto preview = _preview.get();
|
||||||
|
if (_isAlbum) {
|
||||||
|
const auto album = static_cast<Ui::AlbumPreview*>(preview);
|
||||||
|
return album->thumbChanged() | rpl::map(_1 + _from);
|
||||||
|
} else if (_isSingleMedia) {
|
||||||
|
const auto media = static_cast<Ui::SingleMediaPreview*>(preview);
|
||||||
|
return media->editRequests() | rpl::map([=] { return _from; });
|
||||||
|
} else {
|
||||||
|
const auto single = static_cast<Ui::SingleFilePreview*>(preview);
|
||||||
|
return single->editRequests() | rpl::map([=] { return _from; });
|
||||||
}
|
}
|
||||||
const auto album = static_cast<Ui::AlbumPreview*>(_preview.get());
|
|
||||||
return album->thumbChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendFilesBox::Block::setSendWay(Ui::SendFilesWay way) {
|
void SendFilesBox::Block::setSendWay(Ui::SendFilesWay way) {
|
||||||
|
@ -512,7 +529,7 @@ void SendFilesBox::pushBlock(int from, int till) {
|
||||||
) | rpl::filter([=] {
|
) | rpl::filter([=] {
|
||||||
return !_removingIndex;
|
return !_removingIndex;
|
||||||
}) | rpl::start_with_next([=](int index) {
|
}) | rpl::start_with_next([=](int index) {
|
||||||
_removingIndex = from + index;
|
_removingIndex = index;
|
||||||
crl::on_main(this, [=] {
|
crl::on_main(this, [=] {
|
||||||
const auto index = base::take(_removingIndex).value_or(-1);
|
const auto index = base::take(_removingIndex).value_or(-1);
|
||||||
if (index < 0 || index >= _list.files.size()) {
|
if (index < 0 || index >= _list.files.size()) {
|
||||||
|
@ -529,19 +546,19 @@ void SendFilesBox::pushBlock(int from, int till) {
|
||||||
if (list.files.empty()) {
|
if (list.files.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_list.files[from + index] = std::move(list.files.front());
|
_list.files[index] = std::move(list.files.front());
|
||||||
refreshAllAfterChanges(from);
|
refreshAllAfterChanges(from);
|
||||||
};
|
};
|
||||||
const auto checkResult = [=](const Ui::PreparedList &list) {
|
const auto checkResult = [=](const Ui::PreparedList &list) {
|
||||||
if (_sendLimit != SendLimit::One) {
|
if (_sendLimit != SendLimit::One) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
auto removing = std::move(_list.files[from + index]);
|
auto removing = std::move(_list.files[index]);
|
||||||
std::swap(_list.files[from + index], _list.files.back());
|
std::swap(_list.files[index], _list.files.back());
|
||||||
_list.files.pop_back();
|
_list.files.pop_back();
|
||||||
const auto result = _list.canBeSentInSlowmodeWith(list);
|
const auto result = _list.canBeSentInSlowmodeWith(list);
|
||||||
_list.files.push_back(std::move(removing));
|
_list.files.push_back(std::move(removing));
|
||||||
std::swap(_list.files[from + index], _list.files.back());
|
std::swap(_list.files[index], _list.files.back());
|
||||||
if (!result) {
|
if (!result) {
|
||||||
Ui::Toast::Show(tr::lng_slowmode_no_many(tr::now));
|
Ui::Toast::Show(tr::lng_slowmode_no_many(tr::now));
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -112,6 +112,7 @@ private:
|
||||||
int _from = 0;
|
int _from = 0;
|
||||||
int _till = 0;
|
int _till = 0;
|
||||||
bool _isAlbum = false;
|
bool _isAlbum = false;
|
||||||
|
bool _isSingleMedia = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
void initSendWay();
|
void initSendWay();
|
||||||
|
|
|
@ -109,7 +109,7 @@ AlbumThumbnail::AlbumThumbnail(
|
||||||
});
|
});
|
||||||
_deleteMedia->setClickedCallback(deleteCallback);
|
_deleteMedia->setClickedCallback(deleteCallback);
|
||||||
|
|
||||||
_editMedia->setIconOverride(&st::editMediaButtonIconFile);
|
_editMedia->setIconOverride(&st::sendBoxAlbumGroupEditButtonIconFile);
|
||||||
_deleteMedia->setIconOverride(&st::sendBoxAlbumGroupDeleteButtonIconFile);
|
_deleteMedia->setIconOverride(&st::sendBoxAlbumGroupDeleteButtonIconFile);
|
||||||
|
|
||||||
updateFileRow(-1);
|
updateFileRow(-1);
|
||||||
|
@ -520,19 +520,16 @@ QRect AlbumThumbnail::paintButtons(
|
||||||
QRect groupRect(groupX, groupY, groupWidth, size);
|
QRect groupRect(groupX, groupY, groupWidth, size);
|
||||||
_buttonsRect.paint(p, groupRect);
|
_buttonsRect.paint(p, groupRect);
|
||||||
|
|
||||||
const auto editP = st::sendBoxAlbumGroupEditButtonIconPosition;
|
st::sendBoxAlbumGroupButtonMediaEdit.paint(
|
||||||
const auto deleteP = st::sendBoxAlbumGroupDeleteButtonIconPosition;
|
|
||||||
|
|
||||||
st::sendBoxAlbumGroupEditButtonIcon.paintInCenter(
|
|
||||||
p,
|
p,
|
||||||
QRect(groupX + editP.x(), groupY + editP.y(), size, size));
|
groupX,
|
||||||
st::sendBoxAlbumGroupDeleteButtonIcon.paintInCenter(
|
groupY,
|
||||||
|
outerWidth);
|
||||||
|
st::sendBoxAlbumGroupButtonMediaDelete.paint(
|
||||||
p,
|
p,
|
||||||
QRect(
|
groupX + size + skipInternal,
|
||||||
groupX + deleteLeft + deleteP.x(),
|
groupY,
|
||||||
groupY + deleteP.y(),
|
outerWidth);
|
||||||
size,
|
|
||||||
size));
|
|
||||||
p.setOpacity(1);
|
p.setOpacity(1);
|
||||||
|
|
||||||
return groupRect;
|
return groupRect;
|
||||||
|
|
|
@ -89,8 +89,8 @@ private:
|
||||||
|
|
||||||
QRect _lastRectOfButtons;
|
QRect _lastRectOfButtons;
|
||||||
|
|
||||||
object_ptr<IconButton> _editMedia = nullptr;
|
object_ptr<IconButton> _editMedia = { nullptr };
|
||||||
object_ptr<IconButton> _deleteMedia = nullptr;
|
object_ptr<IconButton> _deleteMedia = { nullptr };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/chat/attach/attach_prepare.h"
|
#include "ui/chat/attach/attach_prepare.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
#include "ui/text/text_options.h"
|
#include "ui/text/text_options.h"
|
||||||
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/image/image_prepare.h"
|
#include "ui/image/image_prepare.h"
|
||||||
#include "ui/cached_round_corners.h"
|
#include "base/timer_rpl.h"
|
||||||
#include "core/mime_type.h"
|
#include "core/mime_type.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
|
@ -23,13 +24,30 @@ namespace Ui {
|
||||||
SingleFilePreview::SingleFilePreview(
|
SingleFilePreview::SingleFilePreview(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
const PreparedFile &file)
|
const PreparedFile &file)
|
||||||
: RpWidget(parent) {
|
: RpWidget(parent)
|
||||||
|
, _editMedia(this, st::sendBoxAlbumGroupButtonFile)
|
||||||
|
, _deleteMedia(this, st::sendBoxAlbumGroupButtonFile) {
|
||||||
preparePreview(file);
|
preparePreview(file);
|
||||||
|
|
||||||
|
_editMedia->setIconOverride(&st::sendBoxAlbumGroupEditButtonIconFile);
|
||||||
|
_deleteMedia->setIconOverride(&st::sendBoxAlbumGroupDeleteButtonIconFile);
|
||||||
|
|
||||||
auto h = _fileThumb.isNull()
|
auto h = _fileThumb.isNull()
|
||||||
? (st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom())
|
? (st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom())
|
||||||
: (st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom());
|
: (st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom());
|
||||||
resize(width(), st::boxPhotoPadding.top() + h + st::msgShadow);
|
resize(width(), h);
|
||||||
|
}
|
||||||
|
|
||||||
|
SingleFilePreview::~SingleFilePreview() = default;
|
||||||
|
|
||||||
|
rpl::producer<> SingleFilePreview::editRequests() const {
|
||||||
|
return _editMedia->clicks() | rpl::map([] {
|
||||||
|
return base::timer_once(st::historyAttach.ripple.hideDuration);
|
||||||
|
}) | rpl::flatten_latest();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> SingleFilePreview::deleteRequests() const {
|
||||||
|
return _deleteMedia->clicks() | rpl::to_empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SingleFilePreview::prepareThumb(const QImage &preview) {
|
void SingleFilePreview::prepareThumb(const QImage &preview) {
|
||||||
|
@ -134,9 +152,7 @@ void SingleFilePreview::paintEvent(QPaintEvent *e) {
|
||||||
linktop = st::msgFileThumbLinkTop;
|
linktop = st::msgFileThumbLinkTop;
|
||||||
}
|
}
|
||||||
auto namewidth = w - nameleft - (_fileThumb.isNull() ? st::msgFilePadding.left() : st::msgFileThumbPadding.left());
|
auto namewidth = w - nameleft - (_fileThumb.isNull() ? st::msgFilePadding.left() : st::msgFileThumbPadding.left());
|
||||||
int32 x = (width() - w) / 2, y = st::boxPhotoPadding.top();
|
int32 x = (width() - w) / 2, y = 0;
|
||||||
|
|
||||||
FillRoundRect(p, x, y, w, h, st::msgOutBg, MessageOutCorners, &st::msgOutShadow);
|
|
||||||
|
|
||||||
if (_fileThumb.isNull()) {
|
if (_fileThumb.isNull()) {
|
||||||
QRect inner(style::rtlrect(x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, width()));
|
QRect inner(style::rtlrect(x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, width()));
|
||||||
|
@ -168,4 +184,14 @@ void SingleFilePreview::paintEvent(QPaintEvent *e) {
|
||||||
p.drawTextLeft(x + nameleft, y + statustop, width(), _statusText);
|
p.drawTextLeft(x + nameleft, y + statustop, width(), _statusText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SingleFilePreview::resizeEvent(QResizeEvent *e) {
|
||||||
|
const auto w = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
|
||||||
|
const auto x = (width() - w) / 2;
|
||||||
|
const auto top = st::sendBoxFileGroupSkipTop;
|
||||||
|
auto right = st::sendBoxFileGroupSkipRight + x;
|
||||||
|
_deleteMedia->moveToRight(right, top);
|
||||||
|
right += st::sendBoxFileGroupEditInternalSkip + _deleteMedia->width();
|
||||||
|
_editMedia->moveToRight(right, top);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
|
@ -8,21 +8,27 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
|
#include "base/object_ptr.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
struct PreparedFile;
|
struct PreparedFile;
|
||||||
|
class IconButton;
|
||||||
|
|
||||||
class SingleFilePreview final : public RpWidget {
|
class SingleFilePreview final : public RpWidget {
|
||||||
public:
|
public:
|
||||||
SingleFilePreview(
|
SingleFilePreview(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
const PreparedFile &file);
|
const PreparedFile &file);
|
||||||
|
~SingleFilePreview();
|
||||||
|
|
||||||
protected:
|
[[nodiscard]] rpl::producer<> deleteRequests() const;
|
||||||
void paintEvent(QPaintEvent *e) override;
|
[[nodiscard]] rpl::producer<> editRequests() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
|
||||||
void preparePreview(const PreparedFile &file);
|
void preparePreview(const PreparedFile &file);
|
||||||
void prepareThumb(const QImage &preview);
|
void prepareThumb(const QImage &preview);
|
||||||
|
|
||||||
|
@ -33,6 +39,9 @@ private:
|
||||||
QString _statusText;
|
QString _statusText;
|
||||||
int _statusWidth = 0;
|
int _statusWidth = 0;
|
||||||
|
|
||||||
|
object_ptr<IconButton> _editMedia = { nullptr };
|
||||||
|
object_ptr<IconButton> _deleteMedia = { nullptr };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
|
@ -8,11 +8,13 @@ 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 "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_boxes.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
|
#include "styles/palette.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -64,20 +66,27 @@ SingleMediaPreview::SingleMediaPreview(
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
, _gifPaused(std::move(gifPaused))
|
, _gifPaused(std::move(gifPaused))
|
||||||
, _animated(animated)
|
, _animated(animated)
|
||||||
, _sticker(sticker) {
|
, _sticker(sticker)
|
||||||
|
, _editMedia(this, st::sendBoxAlbumGroupButtonMedia)
|
||||||
|
, _deleteMedia(this, st::sendBoxAlbumGroupButtonMedia)
|
||||||
|
, _buttonsRect(st::sendBoxAlbumGroupRadius, st::callFingerprintBg) {
|
||||||
Expects(!preview.isNull());
|
Expects(!preview.isNull());
|
||||||
|
|
||||||
_canSendAsPhoto = !_animated
|
_deleteMedia->setIconOverride(&st::sendBoxAlbumGroupButtonMediaDelete);
|
||||||
&& !_sticker
|
|
||||||
&& ValidateThumbDimensions(
|
|
||||||
preview.width(),
|
|
||||||
preview.height());
|
|
||||||
|
|
||||||
preparePreview(preview, animatedPreviewPath);
|
preparePreview(preview, animatedPreviewPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
SingleMediaPreview::~SingleMediaPreview() = default;
|
SingleMediaPreview::~SingleMediaPreview() = default;
|
||||||
|
|
||||||
|
rpl::producer<> SingleMediaPreview::deleteRequests() const {
|
||||||
|
return _deleteMedia->clicks() | rpl::to_empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> SingleMediaPreview::editRequests() const {
|
||||||
|
return _editMedia->clicks() | rpl::to_empty;
|
||||||
|
}
|
||||||
|
|
||||||
void SingleMediaPreview::preparePreview(
|
void SingleMediaPreview::preparePreview(
|
||||||
QImage preview,
|
QImage preview,
|
||||||
const QString &animatedPreviewPath) {
|
const QString &animatedPreviewPath) {
|
||||||
|
@ -136,7 +145,20 @@ void SingleMediaPreview::preparePreview(
|
||||||
|
|
||||||
prepareAnimatedPreview(animatedPreviewPath);
|
prepareAnimatedPreview(animatedPreviewPath);
|
||||||
|
|
||||||
resize(width(), st::boxPhotoPadding.top() + _previewHeight);
|
resize(width(), _previewHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleMediaPreview::resizeEvent(QResizeEvent *e) {
|
||||||
|
const auto skipInternal = st::sendBoxAlbumGroupEditInternalSkip;
|
||||||
|
const auto size = st::sendBoxAlbumGroupHeight;
|
||||||
|
const auto skipRight = st::sendBoxAlbumGroupSkipRight;
|
||||||
|
const auto skipTop = st::sendBoxAlbumGroupSkipTop;
|
||||||
|
const auto groupWidth = size * 2 + skipInternal;
|
||||||
|
|
||||||
|
const auto left = _previewLeft + _previewWidth - groupWidth - skipRight;
|
||||||
|
const auto top = skipTop;
|
||||||
|
_editMedia->move(left, top);
|
||||||
|
_deleteMedia->move(left + size + skipInternal, top);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SingleMediaPreview::prepareAnimatedPreview(
|
void SingleMediaPreview::prepareAnimatedPreview(
|
||||||
|
@ -190,33 +212,33 @@ void SingleMediaPreview::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
if (!_sticker) {
|
if (!_sticker) {
|
||||||
if (_previewLeft > st::boxPhotoPadding.left()) {
|
if (_previewLeft > st::boxPhotoPadding.left()) {
|
||||||
p.fillRect(st::boxPhotoPadding.left(), st::boxPhotoPadding.top(), _previewLeft - st::boxPhotoPadding.left(), _previewHeight, st::confirmBg);
|
p.fillRect(st::boxPhotoPadding.left(), 0, _previewLeft - st::boxPhotoPadding.left(), _previewHeight, st::confirmBg);
|
||||||
}
|
}
|
||||||
if (_previewLeft + _previewWidth < width() - st::boxPhotoPadding.right()) {
|
if (_previewLeft + _previewWidth < width() - st::boxPhotoPadding.right()) {
|
||||||
p.fillRect(_previewLeft + _previewWidth, st::boxPhotoPadding.top(), width() - st::boxPhotoPadding.right() - _previewLeft - _previewWidth, _previewHeight, st::confirmBg);
|
p.fillRect(_previewLeft + _previewWidth, 0, width() - st::boxPhotoPadding.right() - _previewLeft - _previewWidth, _previewHeight, st::confirmBg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_gifPreview && _gifPreview->started()) {
|
if (_gifPreview && _gifPreview->started()) {
|
||||||
auto s = QSize(_previewWidth, _previewHeight);
|
auto s = QSize(_previewWidth, _previewHeight);
|
||||||
auto paused = _gifPaused();
|
auto paused = _gifPaused();
|
||||||
auto frame = _gifPreview->current(s.width(), s.height(), s.width(), s.height(), ImageRoundRadius::None, RectPart::None, paused ? 0 : crl::now());
|
auto frame = _gifPreview->current(s.width(), s.height(), s.width(), s.height(), ImageRoundRadius::None, RectPart::None, paused ? 0 : crl::now());
|
||||||
p.drawPixmap(_previewLeft, st::boxPhotoPadding.top(), frame);
|
p.drawPixmap(_previewLeft, 0, frame);
|
||||||
} else if (_lottiePreview && _lottiePreview->ready()) {
|
} else if (_lottiePreview && _lottiePreview->ready()) {
|
||||||
const auto frame = _lottiePreview->frame();
|
const auto frame = _lottiePreview->frame();
|
||||||
const auto size = frame.size() / style::DevicePixelRatio();
|
const auto size = frame.size() / style::DevicePixelRatio();
|
||||||
p.drawImage(
|
p.drawImage(
|
||||||
QRect(
|
QRect(
|
||||||
_previewLeft + (_previewWidth - size.width()) / 2,
|
_previewLeft + (_previewWidth - size.width()) / 2,
|
||||||
st::boxPhotoPadding.top() + (_previewHeight - size.height()) / 2,
|
(_previewHeight - size.height()) / 2,
|
||||||
size.width(),
|
size.width(),
|
||||||
size.height()),
|
size.height()),
|
||||||
frame);
|
frame);
|
||||||
_lottiePreview->markFrameShown();
|
_lottiePreview->markFrameShown();
|
||||||
} else {
|
} else {
|
||||||
p.drawPixmap(_previewLeft, st::boxPhotoPadding.top(), _preview);
|
p.drawPixmap(_previewLeft, 0, _preview);
|
||||||
}
|
}
|
||||||
if (_animated && !_gifPreview && !_lottiePreview) {
|
if (_animated && !_gifPreview && !_lottiePreview) {
|
||||||
auto inner = QRect(_previewLeft + (_previewWidth - st::msgFileSize) / 2, st::boxPhotoPadding.top() + (_previewHeight - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
|
auto inner = QRect(_previewLeft + (_previewWidth - st::msgFileSize) / 2, (_previewHeight - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
p.setBrush(st::msgDateImgBg);
|
p.setBrush(st::msgDateImgBg);
|
||||||
|
|
||||||
|
@ -228,6 +250,21 @@ void SingleMediaPreview::paintEvent(QPaintEvent *e) {
|
||||||
auto icon = &st::historyFileInPlay;
|
auto icon = &st::historyFileInPlay;
|
||||||
icon->paintInCenter(p, inner);
|
icon->paintInCenter(p, inner);
|
||||||
}
|
}
|
||||||
|
paintButtonsBackground(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleMediaPreview::paintButtonsBackground(QPainter &p) {
|
||||||
|
const auto skipInternal = st::sendBoxAlbumGroupEditInternalSkip;
|
||||||
|
const auto size = st::sendBoxAlbumGroupHeight;
|
||||||
|
const auto skipRight = st::sendBoxAlbumGroupSkipRight;
|
||||||
|
const auto skipTop = st::sendBoxAlbumGroupSkipTop;
|
||||||
|
const auto groupWidth = size * 2 + skipInternal;
|
||||||
|
|
||||||
|
const auto left = _previewLeft + _previewWidth - groupWidth - skipRight;
|
||||||
|
const auto top = skipTop;
|
||||||
|
|
||||||
|
QRect groupRect(left, top, groupWidth, size);
|
||||||
|
_buttonsRect.paint(p, groupRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
|
@ -8,7 +8,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
|
#include "ui/round_rect.h"
|
||||||
#include "media/clip/media_clip_reader.h"
|
#include "media/clip/media_clip_reader.h"
|
||||||
|
#include "base/object_ptr.h"
|
||||||
|
|
||||||
namespace Lottie {
|
namespace Lottie {
|
||||||
class SinglePlayer;
|
class SinglePlayer;
|
||||||
|
@ -17,8 +19,9 @@ class SinglePlayer;
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
struct PreparedFile;
|
struct PreparedFile;
|
||||||
|
class IconButton;
|
||||||
|
|
||||||
class SingleMediaPreview : public RpWidget {
|
class SingleMediaPreview final : public RpWidget {
|
||||||
public:
|
public:
|
||||||
static SingleMediaPreview *Create(
|
static SingleMediaPreview *Create(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
|
@ -34,24 +37,23 @@ public:
|
||||||
const QString &animatedPreviewPath);
|
const QString &animatedPreviewPath);
|
||||||
~SingleMediaPreview();
|
~SingleMediaPreview();
|
||||||
|
|
||||||
bool canSendAsPhoto() const {
|
[[nodiscard]] rpl::producer<> deleteRequests() const;
|
||||||
return _canSendAsPhoto;
|
[[nodiscard]] rpl::producer<> editRequests() const;
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void paintEvent(QPaintEvent *e) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
|
||||||
void preparePreview(
|
void preparePreview(
|
||||||
QImage preview,
|
QImage preview,
|
||||||
const QString &animatedPreviewPath);
|
const QString &animatedPreviewPath);
|
||||||
void prepareAnimatedPreview(const QString &animatedPreviewPath);
|
void prepareAnimatedPreview(const QString &animatedPreviewPath);
|
||||||
|
void paintButtonsBackground(QPainter &p);
|
||||||
void clipCallback(Media::Clip::Notification notification);
|
void clipCallback(Media::Clip::Notification notification);
|
||||||
|
|
||||||
Fn<bool()> _gifPaused;
|
Fn<bool()> _gifPaused;
|
||||||
bool _animated = false;
|
bool _animated = false;
|
||||||
bool _sticker = false;
|
bool _sticker = false;
|
||||||
bool _canSendAsPhoto = false;
|
|
||||||
QPixmap _preview;
|
QPixmap _preview;
|
||||||
int _previewLeft = 0;
|
int _previewLeft = 0;
|
||||||
int _previewWidth = 0;
|
int _previewWidth = 0;
|
||||||
|
@ -59,6 +61,10 @@ private:
|
||||||
Media::Clip::ReaderPointer _gifPreview;
|
Media::Clip::ReaderPointer _gifPreview;
|
||||||
std::unique_ptr<Lottie::SinglePlayer> _lottiePreview;
|
std::unique_ptr<Lottie::SinglePlayer> _lottiePreview;
|
||||||
|
|
||||||
|
object_ptr<IconButton> _editMedia = { nullptr };
|
||||||
|
object_ptr<IconButton> _deleteMedia = { nullptr };
|
||||||
|
RoundRect _buttonsRect;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
Loading…
Add table
Reference in a new issue