From 188edce25864ee63e475576a6e303a40de4eb57c Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 14 Mar 2025 15:02:53 +0400 Subject: [PATCH] Support swipe-back from main menu. --- .../SourceFiles/window/window_main_menu.cpp | 74 +++++++++++++++++++ .../SourceFiles/window/window_main_menu.h | 14 ++-- 2 files changed, 83 insertions(+), 5 deletions(-) diff --git a/Telegram/SourceFiles/window/window_main_menu.cpp b/Telegram/SourceFiles/window/window_main_menu.cpp index 61157fe228..d035668295 100644 --- a/Telegram/SourceFiles/window/window_main_menu.cpp +++ b/Telegram/SourceFiles/window/window_main_menu.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_main_menu.h" #include "apiwrap.h" +#include "base/event_filter.h" #include "base/qt_signal_producer.h" #include "boxes/about_box.h" #include "boxes/peer_list_controllers.h" @@ -39,12 +40,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "support/support_templates.h" #include "ui/boxes/confirm_box.h" #include "ui/chat/chat_theme.h" +#include "ui/controls/swipe_handler.h" #include "ui/controls/userpic_button.h" #include "ui/effects/snowflakes.h" #include "ui/effects/toggle_arrow.h" #include "ui/painter.h" #include "ui/text/text_options.h" #include "ui/text/text_utilities.h" +#include "ui/ui_utility.h" #include "ui/unread_badge_paint.h" #include "ui/vertical_list.h" #include "ui/widgets/menu/menu_add_action_callback_factory.h" @@ -532,6 +535,8 @@ MainMenu::MainMenu( } }, lifetime()); } + + setupSwipe(); } MainMenu::~MainMenu() = default; @@ -896,6 +901,19 @@ void MainMenu::chooseEmojiStatus() { } } +bool MainMenu::eventHook(QEvent *event) { + const auto type = event->type(); + if (type == QEvent::TouchBegin + || type == QEvent::TouchUpdate + || type == QEvent::TouchEnd + || type == QEvent::TouchCancel) { + QTouchEvent ev = *static_cast(event); + ev.setTimestamp(crl::now()); + QGuiApplication::sendEvent(_inner, &ev); + } + return RpWidget::eventHook(event); +} + void MainMenu::paintEvent(QPaintEvent *e) { auto p = Painter(this); const auto clip = e->rect(); @@ -996,4 +1014,60 @@ rpl::producer OtherAccountsUnreadState( }); } +void MainMenu::setupSwipe() { + const auto outer = _controller->widget()->body(); + base::install_event_filter(this, outer, [=](not_null e) { + const auto type = e->type(); + if (type == QEvent::TouchBegin + || type == QEvent::TouchUpdate + || type == QEvent::TouchEnd + || type == QEvent::TouchCancel) { + QGuiApplication::sendEvent(_inner, e); + return base::EventFilterResult::Cancel; + } else if (type == QEvent::Wheel) { + const auto w = static_cast(e.get()); + const auto d = Ui::ScrollDeltaF(w); + if (std::abs(d.x()) > std::abs(d.y())) { + QGuiApplication::sendEvent(_inner, e); + return base::EventFilterResult::Cancel; + } + } + return base::EventFilterResult::Continue; + }); + const auto handles = outer->testAttribute(Qt::WA_AcceptTouchEvents); + if (!handles) { + outer->setAttribute(Qt::WA_AcceptTouchEvents); + lifetime().add([=] { + outer->setAttribute(Qt::WA_AcceptTouchEvents, false); + }); + } + + Ui::Controls::SetupSwipeHandler(_inner, _scroll.data(), [=]( + Ui::Controls::SwipeContextData data) { + if (data.translation < 0) { + if (!_swipeBackData.callback) { + _swipeBackData = Ui::Controls::SetupSwipeBack( + this, + [=]() -> std::pair { + return { + st::historyForwardChooseBg->c, + st::historyForwardChooseFg->c, + }; + }); + } + _swipeBackData.callback(data); + return; + } else if (_swipeBackData.lifetime) { + _swipeBackData = {}; + } + }, [=](int, Qt::LayoutDirection direction) { + if (direction != Qt::LeftToRight) { + return Ui::Controls::SwipeHandlerFinishData(); + } + return Ui::Controls::DefaultSwipeBackHandlerFinishData([=] { + closeLayer(); + }); + }); +} + } // namespace Window diff --git a/Telegram/SourceFiles/window/window_main_menu.h b/Telegram/SourceFiles/window/window_main_menu.h index 3089151e4f..764803fd0d 100644 --- a/Telegram/SourceFiles/window/window_main_menu.h +++ b/Telegram/SourceFiles/window/window_main_menu.h @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/binary_guard.h" #include "ui/rp_widget.h" #include "ui/unread_badge.h" +#include "ui/controls/swipe_handler_data.h" #include "ui/layers/layer_widget.h" namespace Ui { @@ -49,7 +50,11 @@ public: void parentResized() override; void showFinished() override; -protected: +private: + class ToggleAccountsButton; + class ResetScaleButton; + + bool eventHook(QEvent *event) override; void paintEvent(QPaintEvent *e) override; void resizeEvent(QResizeEvent *e) override; @@ -57,10 +62,6 @@ protected: setFocus(); } -private: - class ToggleAccountsButton; - class ResetScaleButton; - void moveBadge(); void setupUserpicButton(); void setupAccounts(); @@ -73,6 +74,7 @@ private: void initResetScaleButton(); void toggleAccounts(); void chooseEmojiStatus(); + void setupSwipe(); void drawName(Painter &p); @@ -99,6 +101,8 @@ private: base::Timer _nightThemeSwitch; base::unique_qptr _contextMenu; + Ui::Controls::SwipeBackResult _swipeBackData; + rpl::variable _showFinished = false; };