diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp index 5737d3cd2..abd383c4c 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp @@ -13,6 +13,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_boxes.h" #include "styles/style_layers.h" +#include + namespace Ui { namespace { @@ -25,15 +27,12 @@ AlbumPreview::AlbumPreview( gsl::span 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 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 AlbumPreview::thumbModified() const { return _thumbModified.events(); } diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.h b/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.h index e9fc6006e..767212bcd 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.h @@ -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 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 _thumbDeleted; diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp index 90a5289ce..1f8d47243 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp @@ -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; } diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.h b/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.h index 8341f4e8c..ced90f7f7 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.h @@ -70,7 +70,9 @@ private: GroupMediaLayout _layout; std::optional _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 _editMedia = { nullptr }; diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp index 1db8ed1a3..b3a738999 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp @@ -276,16 +276,4 @@ QPixmap PrepareSongCoverForThumbnail(QImage image, int size) { &st::songCoverOverlayFg)); } -void AddPhotoEditorMenu(not_null parent, Fn callback) { - const auto menu = std::make_shared>(); - parent->events( - ) | rpl::start_with_next([=](not_null e) { - if (e->type() == QEvent::ContextMenu) { - *menu = base::make_unique_q(parent); - (*menu)->addAction("Photo Editor", callback); - (*menu)->popup(QCursor::pos()); - } - }, parent->lifetime()); -} - } // namespace Ui diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h index 11254b0e2..87b8c769f 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h @@ -138,6 +138,4 @@ struct PreparedGroup { [[nodiscard]] QPixmap PrepareSongCoverForThumbnail(QImage image, int size); -void AddPhotoEditorMenu(not_null parent, Fn callback); - } // namespace Ui diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_send_files_way.h b/Telegram/SourceFiles/ui/chat/attach/attach_send_files_way.h index d155b14bf..2dce94383 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_send_files_way.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_send_files_way.h @@ -14,6 +14,7 @@ namespace Ui { enum class AttachButtonType { Edit, Delete, + Modify, None, }; diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.cpp index efbd11f56..ce52599a3 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.cpp @@ -68,6 +68,7 @@ SingleMediaPreview::SingleMediaPreview( , _gifPaused(std::move(gifPaused)) , _animated(animated) , _sticker(sticker) +, _photoEditorButton(base::make_unique_q(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); } diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.h b/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.h index 169435dd5..ded3cede4 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.h @@ -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 _lottiePreview; + base::unique_qptr _photoEditorButton; object_ptr _editMedia = { nullptr }; object_ptr _deleteMedia = { nullptr }; RoundRect _buttonsRect;