From 4ba2581df83703ba44def47da1d37f73ce522bd2 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sun, 15 Mar 2026 16:43:26 +0300 Subject: [PATCH] Removed Replace button from attach previews and added More button. --- .../icons/send_media/send_media_cross.svg | 7 + .../icons/send_media/send_media_more.svg | 9 + .../icons/send_media/send_media_replace.png | Bin 407 -> 0 bytes .../send_media/send_media_replace@2x.png | Bin 772 -> 0 bytes .../send_media/send_media_replace@3x.png | Bin 1018 -> 0 bytes Telegram/Resources/langs/lang.strings | 1 + .../SourceFiles/boxes/edit_caption_box.cpp | 68 +++- Telegram/SourceFiles/boxes/send_files_box.cpp | 304 +++++++++++------- .../chat_helpers/chat_helpers.style | 14 +- .../ui/chat/attach/attach_controls.cpp | 56 ++-- .../ui/chat/attach/attach_controls.h | 4 - .../attach/attach_single_file_preview.cpp | 2 +- Telegram/SourceFiles/ui/menu_icons.style | 1 + 13 files changed, 314 insertions(+), 152 deletions(-) create mode 100644 Telegram/Resources/icons/send_media/send_media_cross.svg create mode 100644 Telegram/Resources/icons/send_media/send_media_more.svg delete mode 100644 Telegram/Resources/icons/send_media/send_media_replace.png delete mode 100644 Telegram/Resources/icons/send_media/send_media_replace@2x.png delete mode 100644 Telegram/Resources/icons/send_media/send_media_replace@3x.png diff --git a/Telegram/Resources/icons/send_media/send_media_cross.svg b/Telegram/Resources/icons/send_media/send_media_cross.svg new file mode 100644 index 0000000000..50abac8af8 --- /dev/null +++ b/Telegram/Resources/icons/send_media/send_media_cross.svg @@ -0,0 +1,7 @@ + + + Icon / SendMedia / cross + + + + diff --git a/Telegram/Resources/icons/send_media/send_media_more.svg b/Telegram/Resources/icons/send_media/send_media_more.svg new file mode 100644 index 0000000000..b7ddcad3ec --- /dev/null +++ b/Telegram/Resources/icons/send_media/send_media_more.svg @@ -0,0 +1,9 @@ + + + Icon / SendMedia / more_vertical + + + + + + diff --git a/Telegram/Resources/icons/send_media/send_media_replace.png b/Telegram/Resources/icons/send_media/send_media_replace.png deleted file mode 100644 index 262550ad4e1a19cbffdbf0d75e6129529242ecf1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 407 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1SIoCSFHz9jKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-uv49!D1}S`GTDlgfjM3A@F~maf zZSY1u7YBi@)4iwUtp2X7qSeVCu;9WERnx%Fj5Q7V3-kk!Q&L~<%Deylu)&^%@hyoG zeUE3TbSCgVkGWpTnAr5m=KU@|ho&RRW}RWiw`WdRwdz1&iiAu{x=-r0Ouob^>ovMu zQ-3PC6gh9pooys`f0K^auNGrd?|rvdX<2-AS@?bZ>!^bIPJu0PvKLKq@BVwxzirV@ zb_QS1bQa|{uB1CJw0_*4m4DEpulD|OOB<=nCaYI{vf(ch*>%z3)%ILz*NbtkyFMuW b*}~*s?6YRu@`rPFg963V)z4*}Q$iB}>g$uv diff --git a/Telegram/Resources/icons/send_media/send_media_replace@2x.png b/Telegram/Resources/icons/send_media/send_media_replace@2x.png deleted file mode 100644 index 6bbcd0b6c12bdbc479d0ded848ecc5e4f5c40b9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 772 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1SD@Ho{PKr6OLS_6DVLH|t3aolV@OAF zeBQZZXV0DE$?o<}<9@dH`(F8d-_z1-YF4-#E|3V|(O?r{{y&@Xc<|F|n|UQxvRtiq z^30DHZj30gntS{0v4at&KWp}dtuD2jKhf=(=JeC+m;RYj*zLA>Z=AjaC8q$9e_ z=8r!{tWUF=+vm3UZP{thocz-lG%qba{P07Ovc*;V^g|-Ai<37>yX3kz>C&2OLcP-B&WjUoO2DVyXxAwAD?v2}gNXvISa9NhAw$Q?f6_bR)=!=h@n`D=A>U&!OHMs4 z+I+Kz?Oy5(28K85Dn6UX3LJWT=2Y6|*=LW<;PRTmU@+_6(nOJ#3o3@s9vJevY<7}Q z6ubVWNnpyBXGJ?Futa=_KDqwz`|rXH6Jd+S74)zieaH22Kyh9j`ebcdy@YMu4w8GD27;O0JnzhC^Q-ryT@n}QRfjG8(jJYaTRkMR5fGLlG!PC{xWt~$(699j@MGOD{ diff --git a/Telegram/Resources/icons/send_media/send_media_replace@3x.png b/Telegram/Resources/icons/send_media/send_media_replace@3x.png deleted file mode 100644 index 31b27a7302af7a046b1497506968e80d60b6c946..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1018 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1SD_us|Wxo#^NA%Cx&(BWL^R}E~ycoX}-P; zT0k}j17mw80}DtA5K93u0|WB{Mh0de%?J`(zyz1|Sip>6gA`6MbbAj}p5p1^7?Q#I zHgb2CmZL=2YzKo|u6snx$|i}dROwyX)T%H`@BM=OiO2N(6Bhe=ES}b>Vb^f$=Bk9p ztuBF%=YO6PED5`N^JZ*$?8Ez6diU#p?wdLH=FF`(UnsJAFa|YjtZz;U7`7aK z_@TnaZvOjs@BGd@l3#WIefjR#!aXZbMCgQRh`24jDDQjz_wU^+Uv{xn*VL@JnlJ%%^3$T7 z_x{=EZI3oIjAeLp=uKVd`s<}TA4}c8bEl@hKHt@aF;p)me);v+sqNac&%XMso}Ih> zw)avYY3@*yQ&KP9R8&5OQ%#WHdE)h1G@j~A}G{#f&OjNWm# z#M3XVQWx$%%aWw8uRmw4d@RF@XN6A=WF&pqAE9$Y(Mpe5!6;b9{bc+aMH#;Ox;m|O zbqow_2KIrg1-Mz5u4aW6>}TRhm{G7JvT26LB6gV&PQ{H!-M?pTwVLqYZDJQ z{;AnswD)OIzBqegtj)5^nKp9ozg8I)`kOHG2usX+ zVZ7IKnuO6!HLICEE}NKq)(R-)nI=~pd9da3OO?qdpBA0uXJANR_?$THb?BeE(=e64lPOjkA{p0ZQ_uoUAH|F@M`vk4L^7*rI zw(0!y$`d_SUrmzM4?E^=ZavXtdZE_A{JGs1EjV}{ni?nae*ApaX^q1tog*LOY;A00 zJj#BqdbYCTFPHZ3$ZHO(b>!^r?VArKSjaruyX()10JbFznhsnOn2;%n^#|g;wKPsi S%S3(wFRfhw diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 5e9de2d5f9..cb2ea149d3 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -4949,6 +4949,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_context_quote_and_reply" = "Quote & Reply"; "lng_context_reply_to_task" = "Reply to Task"; "lng_context_edit_msg" = "Edit"; +"lng_context_draw" = "Draw"; "lng_context_add_factcheck" = "Add Fact Check"; "lng_context_edit_factcheck" = "Edit Fact Check"; "lng_context_add_offer" = "Add Offer"; diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.cpp b/Telegram/SourceFiles/boxes/edit_caption_box.cpp index c1985e2dcc..bb803d6aba 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_caption_box.cpp @@ -57,6 +57,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/ui_utility.h" #include "ui/widgets/checkbox.h" #include "ui/widgets/fields/input_field.h" +#include "ui/widgets/popup_menu.h" #include "ui/widgets/scroll_area.h" #include "ui/wrap/slide_wrap.h" #include "ui/wrap/vertical_layout.h" @@ -65,6 +66,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_chat.h" #include "styles/style_chat_helpers.h" #include "styles/style_layers.h" +#include "styles/style_menu_icons.h" #include @@ -711,12 +713,70 @@ void EditCaptionBox::setupControls() { } void EditCaptionBox::setupEditEventHandler() { + const auto menu + = lifetime().make_state>(); _editMediaClicks.events( ) | rpl::on_next([=] { - ChooseReplacement(_controller, _albumType, crl::guard(this, [=]( - Ui::PreparedList &&list) { - setPreparedList(std::move(list)); - })); + *menu = base::make_unique_q( + this, + st::popupMenuWithIcons); + (*menu)->setForcedOrigin(Ui::PanelAnimation::Origin::TopRight); + if (_isAllowedEditMedia) { + (*menu)->addAction(tr::lng_attach_replace(tr::now), [=] { + ChooseReplacement( + _controller, + _albumType, + crl::guard(this, [=](Ui::PreparedList &&list) { + setPreparedList(std::move(list)); + })); + }, &st::menuIconReplace); + } + using Type = Ui::PreparedFile::Type; + const auto canDraw = !_preparedList.files.empty() + ? (_preparedList.files.front().type == Type::Photo) + : (_isPhoto && !_asFile); + if (canDraw) { + (*menu)->addAction(tr::lng_context_draw(tr::now), [=] { + _photoEditorOpens.fire({}); + }, &st::menuIconDraw); + } + if (!_asFile && (_isPhoto || _isVideo)) { + if (_preparedList.hasSpoilerMenu(!_asFile)) { + const auto spoilered = hasSpoiler(); + auto text = spoilered + ? tr::lng_context_disable_spoiler(tr::now) + : tr::lng_context_spoiler_effect(tr::now); + auto callback = [=] { + _mediaEditManager.apply({ .type = spoilered + ? SendMenu::ActionType::SpoilerOff + : SendMenu::ActionType::SpoilerOn + }); + rebuildPreview(); + }; + (*menu)->addAction( + std::move(text), + std::move(callback), + spoilered + ? &st::menuIconSpoilerOff + : &st::menuIconSpoiler); + } + if (_isVideo && !_preparedList.files.empty()) { + (*menu)->addAction(tr::lng_context_edit_cover(tr::now), [=] { + setupEditCoverHandler(); + }, &st::menuIconEdit); + if (_preparedList.files.front().videoCover != nullptr) { + (*menu)->addAction( + tr::lng_context_clear_cover(tr::now), + [=] { setupClearCoverHandler(); }, + &st::menuIconCancel); + } + } + } + if ((*menu)->empty()) { + *menu = nullptr; + } else { + (*menu)->popup(QCursor::pos()); + } }, lifetime()); } diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index d4987651ac..55a84efcc2 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -1084,6 +1084,7 @@ void SendFilesBox::addMenuButton() { top->setClickedCallback([=] { const auto &tabbed = _st.tabbed; _menu = base::make_unique_q(top, tabbed.menu); + _menu->setForcedOrigin(Ui::PanelAnimation::Origin::TopRight); const auto position = QCursor::pos(); SendMenu::FillSendMenu( _menu.get(), @@ -1226,41 +1227,31 @@ void SendFilesBox::pushBlock(int from, int till) { const auto widget = _inner->add( block.takeWidget(), QMargins(0, _inner->count() ? st::sendMediaRowSkip : 0, 0, 0)); - - block.itemDeleteRequest( - ) | rpl::filter([=] { - return !_removingIndex; - }) | rpl::on_next([=](int index) { + struct State { + base::unique_qptr menu; + }; + const auto state = widget->lifetime().make_state(); + const auto openedOnce = widget->lifetime().make_state(false); + const auto openInPhotoEditor = [=, show = _show](int index) { applyBlockChanges(); - _removingIndex = index; - crl::on_main(this, [=] { - const auto index = base::take(_removingIndex).value_or(-1); - if (index < 0 || index >= _list.files.size()) { - return; - } - // Just close the box if it is the only one. - if (_list.files.size() == 1) { - requestToTakeTextWithTags(); - closeBox(); - return; - } - refreshAllAfterChanges(index, [&] { - _list.files.erase(_list.files.begin() + index); - if (index == _list.files.size()) { - auto &last = _list.files.back(); - const auto was = base::take(last.caption); - if (fieldText().empty() && !last.isSticker()) { - _caption->setTextWithTags(was); - } + if (!(*openedOnce)) { + show->session().settings().incrementPhotoEditorHintShown(); + show->session().saveSettings(); + } + *openedOnce = true; + Editor::OpenWithPreparedFile( + this, + show, + &_list.files[index], + st::sendMediaPreviewSize, + [=](bool ok) { + if (ok) { + refreshAllAfterChanges(from); } }); - }); - }, widget->lifetime()); - - const auto show = uiShow(); - block.itemReplaceRequest( - ) | rpl::on_next([=](int index) { + }; + const auto replaceAttachment = [=, show = _show](int index) { applyBlockChanges(); const auto replace = [=](Ui::PreparedList list) { @@ -1333,28 +1324,8 @@ void SendFilesBox::pushBlock(int from, int till) { tr::lng_choose_file(tr::now), FileDialog::AllOrImagesFilter(), crl::guard(this, callback)); - }, widget->lifetime()); - - const auto openedOnce = widget->lifetime().make_state(false); - block.itemModifyRequest( - ) | rpl::on_next([=, show = _show](int index) { - applyBlockChanges(); - - if (!(*openedOnce)) { - show->session().settings().incrementPhotoEditorHintShown(); - show->session().saveSettings(); - } - *openedOnce = true; - Editor::OpenWithPreparedFile( - this, - show, - &_list.files[index], - st::sendMediaPreviewSize, - [=](bool ok) { if (ok) refreshAllAfterChanges(from); }); - }, widget->lifetime()); - - block.itemEditCoverRequest( - ) | rpl::on_next([=, show = _show](int index) { + }; + const auto editCover = [=, show = _show](int index) { applyBlockChanges(); const auto replace = [=](Ui::PreparedList list) { @@ -1414,15 +1385,170 @@ void SendFilesBox::pushBlock(int from, int till) { tr::lng_choose_cover(tr::now), FileDialog::ImagesFilter(), crl::guard(this, callback)); - }, widget->lifetime()); - - block.itemClearCoverRequest( - ) | rpl::on_next([=](int index) { + }; + const auto clearCover = [=](int index) { applyBlockChanges(); refreshAllAfterChanges(from, [&] { auto &entry = _list.files[index]; entry.videoCover = nullptr; }); + }; + const auto showContextMenu = [=](int fileIndex, QPoint globalPosition) { + if (from >= till + || fileIndex < from + || fileIndex >= till + || fileIndex >= _list.files.size()) { + return false; + } + state->menu = base::make_unique_q( + widget, + _st.tabbed.menu); + state->menu->setForcedOrigin(Ui::PanelAnimation::Origin::TopRight); + const auto &file = _list.files[fileIndex]; + state->menu->addAction(tr::lng_attach_replace(tr::now), [=] { + replaceAttachment(fileIndex); + }, &st::menuIconReplace); + const auto canOpenPhotoEditor = true + && _sendWay.current().sendImagesAsPhotos() + && (file.type == Ui::PreparedFile::Type::Photo); + if (canOpenPhotoEditor) { + state->menu->addAction(tr::lng_context_draw(tr::now), [=] { + openInPhotoEditor(fileIndex); + }, &st::menuIconDraw); + } + const auto canEditFileData = !SkipCaption( + file, + _sendWay.current()); + if (canEditFileData) { + state->menu->addAction(tr::lng_rename_file(tr::now), [=] { + auto &file = _list.files[fileIndex]; + _show->show(Box(RenameFileBox, file.displayName, [=]( + QString newName) { + const auto displayName = std::move(newName); + _list.files[fileIndex].displayName = displayName; + if (!setDisplayNameInSingleFilePreview( + fileIndex, + displayName)) { + refreshAllAfterChanges(from); + } + })); + }, &st::menuIconEdit); + state->menu->addAction( + tr::lng_context_upload_edit_caption(tr::now), + [=] { + auto &file = _list.files[fileIndex]; + const auto count = int(_list.files.size()); + const auto sync = (fileIndex + 1 == count); + _show->show(Box( + EditFileCaptionBox, + _st, + _toPeer, + sync ? fieldText() : file.caption, + [=](TextWithTags text) { + if (!validateLength(text.text)) { + return false; + } + if (sync) { + _caption->setTextWithTags( + base::take(text)); + } + _list.files[fileIndex].caption = text; + if (!setCaptionInSingleFilePreview( + fileIndex, + text)) { + refreshAllAfterChanges(from); + } + return true; + })); + }, + &st::menuIconCaptionShow); + } + const auto canToggleSpoiler = !hasPrice() + && _sendWay.current().sendImagesAsPhotos(); + if (canToggleSpoiler) { + const auto spoilered = file.spoiler; + const auto &icons = _st.tabbed.icons; + state->menu->addAction(spoilered + ? tr::lng_context_disable_spoiler(tr::now) + : tr::lng_context_spoiler_effect(tr::now), [=] { + applyBlockChanges(); + refreshAllAfterChanges(from, [&] { + auto &entry = _list.files[fileIndex]; + entry.spoiler = !spoilered; + }); + }, spoilered ? &icons.menuSpoilerOff : &icons.menuSpoiler); + } + const auto canEditCover = file.isVideoFile() + && (_toPeer->isBroadcast() || _toPeer->isSelf()); + if (canEditCover) { + state->menu->addAction(tr::lng_context_edit_cover(tr::now), [=] { + editCover(fileIndex); + }, &st::menuIconEdit); + + if (file.videoCover != nullptr) { + state->menu->addAction( + tr::lng_context_clear_cover(tr::now), + [=] { clearCover(fileIndex); }, + &st::menuIconCancel); + } + } + if (state->menu->empty()) { + state->menu = nullptr; + return false; + } + state->menu->popup(globalPosition); + return true; + }; + + block.itemDeleteRequest( + ) | rpl::filter([=] { + return !_removingIndex; + }) | rpl::on_next([=](int index) { + applyBlockChanges(); + + _removingIndex = index; + crl::on_main(this, [=] { + const auto index = base::take(_removingIndex).value_or(-1); + if (index < 0 || index >= _list.files.size()) { + return; + } + // Just close the box if it is the only one. + if (_list.files.size() == 1) { + requestToTakeTextWithTags(); + closeBox(); + return; + } + refreshAllAfterChanges(index, [&] { + _list.files.erase(_list.files.begin() + index); + if (index == _list.files.size()) { + auto &last = _list.files.back(); + const auto was = base::take(last.caption); + if (fieldText().empty() && !last.isSticker()) { + _caption->setTextWithTags(was); + } + } + }); + }); + }, widget->lifetime()); + + block.itemReplaceRequest( + ) | rpl::on_next([=](int index) { + showContextMenu(index, QCursor::pos()); + }, widget->lifetime()); + + block.itemModifyRequest( + ) | rpl::on_next([=](int index) { + openInPhotoEditor(index); + }, widget->lifetime()); + + block.itemEditCoverRequest( + ) | rpl::on_next([=](int index) { + editCover(index); + }, widget->lifetime()); + + block.itemClearCoverRequest( + ) | rpl::on_next([=](int index) { + clearCover(index); }, widget->lifetime()); block.orderUpdated() | rpl::on_next([=]{ @@ -1432,11 +1558,7 @@ void SendFilesBox::pushBlock(int from, int till) { } }, widget->lifetime()); - struct State { - base::unique_qptr menu; - }; - const auto state = widget->lifetime().make_state(); - base::install_event_filter(widget, [=, from = from, till = till]( + base::install_event_filter(widget, [=]( not_null e) { if (e->type() == QEvent::ContextMenu) { const auto mouse = static_cast(e.get()); @@ -1454,63 +1576,9 @@ void SendFilesBox::pushBlock(int from, int till) { if (fileIndex >= till || fileIndex >= _list.files.size()) { return base::EventFilterResult::Continue; } - state->menu = base::make_unique_q( - widget, - _st.tabbed.menu); - const auto &file = _list.files[fileIndex]; - const auto canEditFileData = !SkipCaption( - file, - _sendWay.current()); - if (canEditFileData) { - state->menu->addAction(tr::lng_rename_file(tr::now), [=] { - auto &file = _list.files[fileIndex]; - _show->show(Box(RenameFileBox, file.displayName, [=]( - QString newName) { - const auto displayName = std::move(newName); - _list.files[fileIndex].displayName = displayName; - if (!setDisplayNameInSingleFilePreview( - fileIndex, - displayName)) { - refreshAllAfterChanges(from); - } - })); - }, &st::menuIconEdit); - state->menu->addAction( - tr::lng_context_upload_edit_caption(tr::now), - [=] { - auto &file = _list.files[fileIndex]; - const auto count = int(_list.files.size()); - const auto sync = (fileIndex + 1 == count); - _show->show(Box( - EditFileCaptionBox, - _st, - _toPeer, - sync ? fieldText() : file.caption, - [=](TextWithTags text) { - if (!validateLength(text.text)) { - return false; - } - if (sync) { - _caption->setTextWithTags( - base::take(text)); - } - _list.files[fileIndex].caption = text; - if (!setCaptionInSingleFilePreview( - fileIndex, - text)) { - refreshAllAfterChanges(from); - } - return true; - })); - }, - &st::menuIconCaptionShow); + if (showContextMenu(fileIndex, mouse->globalPos())) { + return base::EventFilterResult::Cancel; } - if (state->menu->empty()) { - state->menu = nullptr; - return base::EventFilterResult::Continue; - } - state->menu->popup(mouse->globalPos()); - return base::EventFilterResult::Cancel; } return base::EventFilterResult::Continue; }, widget->lifetime()); diff --git a/Telegram/SourceFiles/chat_helpers/chat_helpers.style b/Telegram/SourceFiles/chat_helpers/chat_helpers.style index 42f1fd14ed..597a82ed3d 100644 --- a/Telegram/SourceFiles/chat_helpers/chat_helpers.style +++ b/Telegram/SourceFiles/chat_helpers/chat_helpers.style @@ -588,7 +588,7 @@ emojiEmpty: icon {{ "emoji_empty", windowSubTextFg }}; editMediaButtonSize: 32px; -editMediaButtonIconFile: icon {{ "send_media/send_media_replace", menuIconFg }}; +editMediaButtonIconFile: icon {{ "send_media/send_media_more", menuIconFg }}; editMediaButton: IconButton(defaultIconButton) { width: editMediaButtonSize; height: editMediaButtonSize; @@ -602,10 +602,10 @@ editMediaButton: IconButton(defaultIconButton) { sendBoxAlbumGroupEditInternalSkip: 8px; sendBoxAlbumGroupSkipRight: 5px; sendBoxAlbumGroupSkipTop: 5px; -sendBoxAlbumGroupRadius: 4px; -sendBoxAlbumGroupSize: size(62px, 25px); +sendBoxAlbumGroupSize: size(48px, 26px); sendBoxAlbumGroupSizeVertical: size(30px, 50px); sendBoxAlbumSmallGroupSize: size(30px, 25px); +sendBoxAlbumSmallGroupCircleSize: 27px; sendBoxFileGroupSkipTop: 2px; sendBoxFileGroupSkipRight: 5px; @@ -617,11 +617,11 @@ sendBoxAlbumGroupButtonFile: IconButton(editMediaButton) { } } sendBoxAlbumGroupEditButtonIconFile: editMediaButtonIconFile; -sendBoxAlbumGroupDeleteButtonIconFile: icon {{ "send_media/send_media_delete", menuIconFg }}; +sendBoxAlbumGroupDeleteButtonIconFile: icon {{ "send_media/send_media_cross", menuIconFg }}; -sendBoxAlbumButtonMediaEdit: icon {{ "send_media/send_media_replace", roundedFg }}; -sendBoxAlbumGroupButtonMediaEdit: icon {{ "send_media/send_media_replace", roundedFg, point(4px, 1px) }}; -sendBoxAlbumGroupButtonMediaDelete: icon {{ "send_media/send_media_delete", roundedFg }}; +sendBoxAlbumButtonMediaMore: icon {{ "send_media/send_media_more", roundedFg }}; +sendBoxAlbumGroupButtonMediaMore: icon {{ "send_media/send_media_more", roundedFg, point(4px, 1px) }}; +sendBoxAlbumGroupButtonMediaDelete: icon {{ "send_media/send_media_cross", roundedFg, point(-2px, 1px) }}; defaultComposeIcons: ComposeIcons { settings: icon {{ "emoji/emoji_settings", emojiIconFg }}; diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_controls.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_controls.cpp index ee3ae3c095..bf29895e9a 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_controls.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_controls.cpp @@ -7,21 +7,36 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "ui/chat/attach/attach_controls.h" +#include "ui/painter.h" #include "styles/style_chat_helpers.h" namespace Ui { -AttachControls::AttachControls() -: _rect(st::sendBoxAlbumGroupRadius, st::roundedBg) { -} - void AttachControls::paint(QPainter &p, int x, int y) { const auto groupWidth = width(); const auto groupHeight = height(); const auto full = (_type == Type::Full); - QRect groupRect(x, y, groupWidth, groupHeight); - _rect.paint(p, groupRect); + const auto groupRect = QRect(x, y, groupWidth, groupHeight); + { + auto hq = PainterHighQualityEnabler(p); + p.setPen(Qt::NoPen); + p.setBrush(st::roundedBg); + if (_type == Type::EditOnly) { + const auto desired = st::sendBoxAlbumSmallGroupCircleSize; + const auto available = std::min(groupWidth, groupHeight); + const auto side = std::min(desired, available); + const auto circleRect = QRect( + x + ((groupWidth - side) / 2), + y + ((groupHeight - side) / 2), + side, + side); + p.drawEllipse(circleRect); + } else { + const auto radius = std::min(groupWidth, groupHeight) / 2.; + p.drawRoundedRect(groupRect, radius, radius); + } + } if (full) { const auto groupHalfWidth = groupWidth / 2; @@ -29,13 +44,13 @@ void AttachControls::paint(QPainter &p, int x, int y) { const auto editRect = _vertical ? QRect(x, y, groupWidth, groupHalfHeight) : QRect(x, y, groupHalfWidth, groupHeight); - st::sendBoxAlbumGroupButtonMediaEdit.paintInCenter(p, editRect); + st::sendBoxAlbumGroupButtonMediaMore.paintInCenter(p, editRect); const auto deleteRect = _vertical ? QRect(x, y + groupHalfHeight, groupWidth, groupHalfHeight) : QRect(x + groupHalfWidth, y, groupHalfWidth, groupHeight); st::sendBoxAlbumGroupButtonMediaDelete.paintInCenter(p, deleteRect); } else if (_type == Type::EditOnly) { - st::sendBoxAlbumButtonMediaEdit.paintInCenter(p, groupRect); + st::sendBoxAlbumButtonMediaMore.paintInCenter(p, groupRect); } } @@ -45,7 +60,10 @@ int AttachControls::width() const { ? st::sendBoxAlbumGroupSizeVertical.width() : st::sendBoxAlbumGroupSize.width()) : (_type == Type::EditOnly) - ? st::sendBoxAlbumSmallGroupSize.width() + ? ((st::sendBoxAlbumSmallGroupSize.width() + > st::sendBoxAlbumSmallGroupCircleSize) + ? st::sendBoxAlbumSmallGroupSize.width() + : st::sendBoxAlbumSmallGroupCircleSize) : 0; } @@ -55,7 +73,10 @@ int AttachControls::height() const { ? st::sendBoxAlbumGroupSizeVertical.height() : st::sendBoxAlbumGroupSize.height()) : (_type == Type::EditOnly) - ? st::sendBoxAlbumSmallGroupSize.height() + ? ((st::sendBoxAlbumSmallGroupSize.height() + > st::sendBoxAlbumSmallGroupCircleSize) + ? st::sendBoxAlbumSmallGroupSize.height() + : st::sendBoxAlbumSmallGroupCircleSize) : 0; } @@ -86,17 +107,16 @@ AttachControlsWidget::AttachControlsWidget( _controls.setType(type); const auto w = _controls.width(); - resize(w, _controls.height()); + const auto h = _controls.height(); + resize(w, h); if (type == AttachControls::Type::Full) { - _edit->resize(w / 2, _controls.height()); - _delete->resize(w / 2, _controls.height()); - - _edit->moveToLeft(0, 0, w); - _delete->moveToRight(0, 0, w); + const auto leftWidth = w / 2; + const auto rightWidth = w - leftWidth; + _edit->setGeometryToLeft(0, 0, leftWidth, h, w); + _delete->setGeometryToLeft(leftWidth, 0, rightWidth, h, w); } else if (type == AttachControls::Type::EditOnly) { - _edit->resize(w, _controls.height()); - _edit->moveToLeft(0, 0, w); + _edit->setGeometryToLeft(0, 0, w, h, w); } paintRequest( diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_controls.h b/Telegram/SourceFiles/ui/chat/attach/attach_controls.h index bf69927745..3f3d2c3108 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_controls.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_controls.h @@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once #include "ui/abstract_button.h" -#include "ui/round_rect.h" #include "ui/rp_widget.h" namespace Ui { @@ -21,8 +20,6 @@ public: None, }; - AttachControls(); - void paint(QPainter &p, int x, int y); void setType(Type type); void setVertical(bool vertical); @@ -33,7 +30,6 @@ public: [[nodiscard]] bool vertical() const; private: - RoundRect _rect; Type _type = Type::Full; bool _vertical = false; diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_single_file_preview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_single_file_preview.cpp index 0eef6b959a..75db8c0915 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_single_file_preview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_single_file_preview.cpp @@ -51,7 +51,7 @@ void SingleFilePreview::preparePreview(const PreparedFile &file) { auto preview = QImage(); if (const auto image = std::get_if( &file.information->media)) { - preview = image->data; + preview = file.preview.isNull() ? image->data : file.preview; } else if (const auto video = std::get_if( &file.information->media)) { preview = video->thumbnail; diff --git a/Telegram/SourceFiles/ui/menu_icons.style b/Telegram/SourceFiles/ui/menu_icons.style index bb23ec9e19..92f863dfb9 100644 --- a/Telegram/SourceFiles/ui/menu_icons.style +++ b/Telegram/SourceFiles/ui/menu_icons.style @@ -12,6 +12,7 @@ menuIconReactions: icon {{ "menu/read_reactions", menuIconColor }}; menuIconReply: icon {{ "menu/reply", menuIconColor }}; menuIconViewReplies: icon {{ "menu/view_replies", menuIconColor }}; menuIconEdit: icon {{ "menu/edit", menuIconColor }}; +menuIconDraw: icon {{ "mediaview/draw", menuIconColor, point(2px, 3px) }}; menuIconPin: icon {{ "menu/pin", menuIconColor }}; menuIconUnpin: icon {{ "menu/unpin", menuIconColor }}; menuIconCopy: icon {{ "menu/copy", menuIconColor }};