mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 14:17:12 +02:00
Added ability to open photo editor in SendFilesBox with left-click.
This commit is contained in:
parent
6975b04e6b
commit
18154e403a
9 changed files with 99 additions and 47 deletions
|
@ -13,6 +13,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_layers.h"
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
|
@ -25,15 +27,12 @@ AlbumPreview::AlbumPreview(
|
|||
gsl::span<Ui::PreparedFile> items,
|
||||
SendFilesWay way)
|
||||
: RpWidget(parent)
|
||||
, _sendWay(way) {
|
||||
, _sendWay(way)
|
||||
, _dragTimer([=] { switchToDrag(); }) {
|
||||
setMouseTracking(true);
|
||||
prepareThumbs(items);
|
||||
updateSize();
|
||||
updateFileRows();
|
||||
|
||||
AddPhotoEditorMenu(this, [=] {
|
||||
_thumbModified.fire(thumbIndex(thumbUnderCursor()));
|
||||
});
|
||||
}
|
||||
|
||||
AlbumPreview::~AlbumPreview() = default;
|
||||
|
@ -372,6 +371,13 @@ void AlbumPreview::changeThumbByIndex(int index) {
|
|||
_thumbChanged.fire(std::move(index));
|
||||
}
|
||||
|
||||
void AlbumPreview::modifyThumbByIndex(int index) {
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
_thumbModified.fire(std::move(index));
|
||||
}
|
||||
|
||||
void AlbumPreview::thumbButtonsCallback(
|
||||
not_null<AlbumThumbnail*> thumb,
|
||||
AttachButtonType type) {
|
||||
|
@ -381,6 +387,10 @@ void AlbumPreview::thumbButtonsCallback(
|
|||
case AttachButtonType::None: return;
|
||||
case AttachButtonType::Edit: changeThumbByIndex(index); break;
|
||||
case AttachButtonType::Delete: deleteThumbByIndex(index); break;
|
||||
case AttachButtonType::Modify:
|
||||
cancelDrag();
|
||||
modifyThumbByIndex(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -391,17 +401,21 @@ void AlbumPreview::mousePressEvent(QMouseEvent *e) {
|
|||
const auto position = e->pos();
|
||||
cancelDrag();
|
||||
if (const auto thumb = findThumb(position)) {
|
||||
if (thumb->buttonsContainPoint(e->pos())) {
|
||||
_pressedButtonType = thumb->buttonTypeFromPoint(e->pos());
|
||||
_draggedStartPosition = position;
|
||||
_pressedThumb = thumb;
|
||||
_pressedButtonType = thumb->buttonTypeFromPoint(position);
|
||||
|
||||
const auto isAlbum = _sendWay.sendImagesAsPhotos()
|
||||
&& _sendWay.groupFiles();
|
||||
if (!isAlbum) {
|
||||
return;
|
||||
}
|
||||
_paintedAbove = _suggestedThumb = _draggedThumb = thumb;
|
||||
_draggedStartPosition = position;
|
||||
_shrinkAnimation.start(
|
||||
[=] { update(); },
|
||||
0.,
|
||||
1.,
|
||||
AlbumThumbnail::kShrinkDuration);
|
||||
|
||||
if (_pressedButtonType == AttachButtonType::None) {
|
||||
switchToDrag();
|
||||
} else if (_pressedButtonType == AttachButtonType::Modify) {
|
||||
_dragTimer.callOnce(QApplication::startDragTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -410,6 +424,10 @@ void AlbumPreview::mouseMoveEvent(QMouseEvent *e) {
|
|||
applyCursor(style::cur_default);
|
||||
return;
|
||||
}
|
||||
if (_dragTimer.isActive()) {
|
||||
_dragTimer.cancel();
|
||||
switchToDrag();
|
||||
}
|
||||
const auto isAlbum = _sendWay.sendImagesAsPhotos()
|
||||
&& _sendWay.groupFiles();
|
||||
if (isAlbum && _draggedThumb) {
|
||||
|
@ -420,7 +438,7 @@ void AlbumPreview::mouseMoveEvent(QMouseEvent *e) {
|
|||
} else {
|
||||
const auto thumb = findThumb(e->pos());
|
||||
const auto regularCursor = isAlbum
|
||||
? style::cur_sizeall
|
||||
? style::cur_pointer
|
||||
: style::cur_default;
|
||||
const auto cursor = thumb
|
||||
? (thumb->buttonsContainPoint(e->pos())
|
||||
|
@ -492,18 +510,30 @@ void AlbumPreview::mouseReleaseEvent(QMouseEvent *e) {
|
|||
_draggedThumb = nullptr;
|
||||
_suggestedThumb = nullptr;
|
||||
update();
|
||||
} else if (const auto thumb = findThumb(e->pos())) {
|
||||
if (thumb->buttonsContainPoint(e->pos())) {
|
||||
const auto was = _pressedButtonType;
|
||||
const auto now = thumb->buttonTypeFromPoint(e->pos());
|
||||
if (was == now) {
|
||||
thumbButtonsCallback(thumb, now);
|
||||
}
|
||||
} else if (const auto thumb = base::take(_pressedThumb)) {
|
||||
const auto was = _pressedButtonType;
|
||||
const auto now = thumb->buttonTypeFromPoint(e->pos());
|
||||
if (was == now) {
|
||||
thumbButtonsCallback(thumb, now);
|
||||
}
|
||||
}
|
||||
_pressedButtonType = AttachButtonType::None;
|
||||
}
|
||||
|
||||
void AlbumPreview::switchToDrag() {
|
||||
_paintedAbove
|
||||
= _suggestedThumb
|
||||
= _draggedThumb
|
||||
= base::take(_pressedThumb);
|
||||
_shrinkAnimation.start(
|
||||
[=] { update(); },
|
||||
0.,
|
||||
1.,
|
||||
AlbumThumbnail::kShrinkDuration);
|
||||
applyCursor(style::cur_sizeall);
|
||||
update();
|
||||
}
|
||||
|
||||
rpl::producer<int> AlbumPreview::thumbModified() const {
|
||||
return _thumbModified.events();
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include "ui/rp_widget.h"
|
||||
#include "ui/chat/attach/attach_send_files_way.h"
|
||||
#include "base/timer.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
|
@ -57,10 +58,13 @@ private:
|
|||
AlbumThumbnail *thumbUnderCursor();
|
||||
void deleteThumbByIndex(int index);
|
||||
void changeThumbByIndex(int index);
|
||||
void modifyThumbByIndex(int index);
|
||||
void thumbButtonsCallback(
|
||||
not_null<AlbumThumbnail*> thumb,
|
||||
AttachButtonType type);
|
||||
|
||||
void switchToDrag();
|
||||
|
||||
void paintAlbum(Painter &p) const;
|
||||
void paintPhotos(Painter &p, QRect clip) const;
|
||||
void paintFiles(Painter &p, QRect clip) const;
|
||||
|
@ -87,8 +91,10 @@ private:
|
|||
AlbumThumbnail *_draggedThumb = nullptr;
|
||||
AlbumThumbnail *_suggestedThumb = nullptr;
|
||||
AlbumThumbnail *_paintedAbove = nullptr;
|
||||
AlbumThumbnail *_pressedThumb = nullptr;
|
||||
QPoint _draggedStartPosition;
|
||||
|
||||
base::Timer _dragTimer;
|
||||
AttachButtonType _pressedButtonType = AttachButtonType::None;
|
||||
|
||||
rpl::event_stream<int> _thumbDeleted;
|
||||
|
|
|
@ -29,6 +29,7 @@ AlbumThumbnail::AlbumThumbnail(
|
|||
: _layout(layout)
|
||||
, _fullPreview(file.preview)
|
||||
, _shrinkSize(int(std::ceil(st::historyMessageRadius / 1.4)))
|
||||
, _isPhoto(file.type == PreparedFile::Type::Photo)
|
||||
, _isVideo(file.type == PreparedFile::Type::Video)
|
||||
, _buttonsRect(st::sendBoxAlbumGroupRadius, st::roundedBg) {
|
||||
Expects(!_fullPreview.isNull());
|
||||
|
@ -229,6 +230,8 @@ void AlbumThumbnail::paintInAlbum(
|
|||
{ x, y },
|
||||
geometry.width(),
|
||||
shrinkProgress);
|
||||
|
||||
_lastRectOfModify = QRect(QPoint(x, y), geometry.size());
|
||||
}
|
||||
|
||||
void AlbumThumbnail::prepareCache(QSize size, int shrink) {
|
||||
|
@ -376,21 +379,29 @@ void AlbumThumbnail::drawSimpleFrame(Painter &p, QRect to, QSize size) const {
|
|||
}
|
||||
|
||||
void AlbumThumbnail::paintPhoto(Painter &p, int left, int top, int outerWidth) {
|
||||
const auto width = _photo.width() / style::DevicePixelRatio();
|
||||
const auto size = _photo.size() / style::DevicePixelRatio();
|
||||
p.drawPixmapLeft(
|
||||
left + (st::sendMediaPreviewSize - width) / 2,
|
||||
left + (st::sendMediaPreviewSize - size.width()) / 2,
|
||||
top,
|
||||
outerWidth,
|
||||
_photo);
|
||||
|
||||
const auto topLeft = QPoint{ left, top };
|
||||
|
||||
_lastRectOfButtons = paintButtons(
|
||||
p,
|
||||
{ left, top },
|
||||
topLeft,
|
||||
st::sendMediaPreviewSize,
|
||||
0);
|
||||
|
||||
_lastRectOfModify = QRect(topLeft, size);
|
||||
}
|
||||
|
||||
void AlbumThumbnail::paintFile(Painter &p, int left, int top, int outerWidth) {
|
||||
void AlbumThumbnail::paintFile(
|
||||
Painter &p,
|
||||
int left,
|
||||
int top,
|
||||
int outerWidth) {
|
||||
const auto &st = st::attachPreviewThumbLayout;
|
||||
const auto textLeft = left + st.thumbSize + st.padding.right();
|
||||
|
||||
|
@ -411,6 +422,10 @@ void AlbumThumbnail::paintFile(Painter &p, int left, int top, int outerWidth) {
|
|||
outerWidth,
|
||||
_status,
|
||||
_statusWidth);
|
||||
|
||||
_lastRectOfModify = QRect(
|
||||
QPoint(left, top),
|
||||
_fileThumb.size() / style::DevicePixelRatio());
|
||||
}
|
||||
|
||||
bool AlbumThumbnail::containsPoint(QPoint position) const {
|
||||
|
@ -418,14 +433,18 @@ bool AlbumThumbnail::containsPoint(QPoint position) const {
|
|||
}
|
||||
|
||||
bool AlbumThumbnail::buttonsContainPoint(QPoint position) const {
|
||||
return _lastRectOfButtons.contains(position);
|
||||
return (_isPhoto
|
||||
? _lastRectOfModify
|
||||
: _lastRectOfButtons).contains(position);
|
||||
}
|
||||
|
||||
AttachButtonType AlbumThumbnail::buttonTypeFromPoint(QPoint position) const {
|
||||
if (!buttonsContainPoint(position)) {
|
||||
return AttachButtonType::None;
|
||||
}
|
||||
return (position.x() < _lastRectOfButtons.center().x())
|
||||
return !_lastRectOfButtons.contains(position)
|
||||
? AttachButtonType::Modify
|
||||
: (position.x() < _lastRectOfButtons.center().x())
|
||||
? AttachButtonType::Edit
|
||||
: AttachButtonType::Delete;
|
||||
}
|
||||
|
|
|
@ -70,7 +70,9 @@ private:
|
|||
GroupMediaLayout _layout;
|
||||
std::optional<QRect> _animateFromGeometry;
|
||||
const QImage _fullPreview;
|
||||
const int _shrinkSize = 0;
|
||||
const int _shrinkSize;
|
||||
const bool _isPhoto;
|
||||
const bool _isVideo;
|
||||
QPixmap _albumImage;
|
||||
QImage _albumCache;
|
||||
QPoint _albumPosition;
|
||||
|
@ -81,12 +83,12 @@ private:
|
|||
QString _status;
|
||||
int _nameWidth = 0;
|
||||
int _statusWidth = 0;
|
||||
bool _isVideo = false;
|
||||
float64 _suggestedMove = 0.;
|
||||
Animations::Simple _suggestedMoveAnimation;
|
||||
int _lastShrinkValue = 0;
|
||||
RoundRect _buttonsRect;
|
||||
|
||||
QRect _lastRectOfModify;
|
||||
QRect _lastRectOfButtons;
|
||||
|
||||
object_ptr<IconButton> _editMedia = { nullptr };
|
||||
|
|
|
@ -276,16 +276,4 @@ QPixmap PrepareSongCoverForThumbnail(QImage image, int size) {
|
|||
&st::songCoverOverlayFg));
|
||||
}
|
||||
|
||||
void AddPhotoEditorMenu(not_null<Ui::RpWidget*> parent, Fn<void()> callback) {
|
||||
const auto menu = std::make_shared<base::unique_qptr<Ui::PopupMenu>>();
|
||||
parent->events(
|
||||
) | rpl::start_with_next([=](not_null<QEvent*> e) {
|
||||
if (e->type() == QEvent::ContextMenu) {
|
||||
*menu = base::make_unique_q<Ui::PopupMenu>(parent);
|
||||
(*menu)->addAction("Photo Editor", callback);
|
||||
(*menu)->popup(QCursor::pos());
|
||||
}
|
||||
}, parent->lifetime());
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
@ -138,6 +138,4 @@ struct PreparedGroup {
|
|||
|
||||
[[nodiscard]] QPixmap PrepareSongCoverForThumbnail(QImage image, int size);
|
||||
|
||||
void AddPhotoEditorMenu(not_null<Ui::RpWidget*> parent, Fn<void()> callback);
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace Ui {
|
|||
enum class AttachButtonType {
|
||||
Edit,
|
||||
Delete,
|
||||
Modify,
|
||||
None,
|
||||
};
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ SingleMediaPreview::SingleMediaPreview(
|
|||
, _gifPaused(std::move(gifPaused))
|
||||
, _animated(animated)
|
||||
, _sticker(sticker)
|
||||
, _photoEditorButton(base::make_unique_q<AbstractButton>(this))
|
||||
, _editMedia(this, st::sendBoxAlbumGroupButtonMedia)
|
||||
, _deleteMedia(this, st::sendBoxAlbumGroupButtonMedia)
|
||||
, _buttonsRect(st::sendBoxAlbumGroupRadius, st::roundedBg) {
|
||||
|
@ -76,8 +77,6 @@ SingleMediaPreview::SingleMediaPreview(
|
|||
_deleteMedia->setIconOverride(&st::sendBoxAlbumGroupButtonMediaDelete);
|
||||
|
||||
preparePreview(preview, animatedPreviewPath);
|
||||
|
||||
Ui::AddPhotoEditorMenu(this, [=] { _modifyRequests.fire({}); });
|
||||
}
|
||||
|
||||
SingleMediaPreview::~SingleMediaPreview() = default;
|
||||
|
@ -91,7 +90,7 @@ rpl::producer<> SingleMediaPreview::editRequests() const {
|
|||
}
|
||||
|
||||
rpl::producer<> SingleMediaPreview::modifyRequests() const {
|
||||
return _modifyRequests.events();
|
||||
return _photoEditorButton->clicks() | rpl::to_empty;
|
||||
}
|
||||
|
||||
void SingleMediaPreview::preparePreview(
|
||||
|
@ -159,6 +158,13 @@ void SingleMediaPreview::preparePreview(
|
|||
|
||||
prepareAnimatedPreview(animatedPreviewPath);
|
||||
|
||||
_photoEditorButton->resize(_previewWidth, _previewHeight);
|
||||
_photoEditorButton->moveToLeft(_previewLeft, 0);
|
||||
_photoEditorButton->setVisible(!_sticker
|
||||
&& !_gifPreview
|
||||
&& !_lottiePreview
|
||||
&& !_animated);
|
||||
|
||||
resize(width(), _previewHeight);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "ui/rp_widget.h"
|
||||
#include "ui/abstract_button.h"
|
||||
#include "ui/round_rect.h"
|
||||
#include "media/clip/media_clip_reader.h"
|
||||
#include "base/object_ptr.h"
|
||||
|
@ -62,6 +63,7 @@ private:
|
|||
Media::Clip::ReaderPointer _gifPreview;
|
||||
std::unique_ptr<Lottie::SinglePlayer> _lottiePreview;
|
||||
|
||||
base::unique_qptr<AbstractButton> _photoEditorButton;
|
||||
object_ptr<IconButton> _editMedia = { nullptr };
|
||||
object_ptr<IconButton> _deleteMedia = { nullptr };
|
||||
RoundRect _buttonsRect;
|
||||
|
|
Loading…
Add table
Reference in a new issue