From 27dc91e51accb9c940b6415ed8765a9a081b2ea0 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sat, 30 Oct 2021 09:11:27 +0300 Subject: [PATCH] Moved management of selecting scroll to separated class in td_ui. --- .../chat_helpers/emoji_interactions.cpp | 2 +- .../history/history_inner_widget.cpp | 18 +++++-- .../history/history_inner_widget.h | 4 +- .../SourceFiles/history/history_widget.cpp | 28 ----------- Telegram/SourceFiles/history/history_widget.h | 7 --- .../ui/chat/select_scroll_manager.cpp | 50 +++++++++++++++++++ .../ui/chat/select_scroll_manager.h | 34 +++++++++++++ Telegram/cmake/td_ui.cmake | 2 + 8 files changed, 103 insertions(+), 42 deletions(-) create mode 100644 Telegram/SourceFiles/ui/chat/select_scroll_manager.cpp create mode 100644 Telegram/SourceFiles/ui/chat/select_scroll_manager.h diff --git a/Telegram/SourceFiles/chat_helpers/emoji_interactions.cpp b/Telegram/SourceFiles/chat_helpers/emoji_interactions.cpp index fa579ac6b..0f4e961e4 100644 --- a/Telegram/SourceFiles/chat_helpers/emoji_interactions.cpp +++ b/Telegram/SourceFiles/chat_helpers/emoji_interactions.cpp @@ -490,7 +490,7 @@ EmojiInteractionsBunch EmojiInteractions::Parse(const QByteArray &json) { return {}; } auto result = EmojiInteractionsBunch(); - for (const auto &interaction : actions) { + for (const auto interaction : actions) { const auto object = interaction.toObject(); const auto index = object.value("i").toInt(); if (index < 0 || index > 10) { diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 2ed3e5992..831fee325 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -252,6 +252,11 @@ HistoryInner::HistoryInner( ) | rpl::start_with_next([=](bool wide) { _isChatWide = wide; }, lifetime()); + + _selectScroll.scrolls( + ) | rpl::start_with_next([=](int d) { + _scroll->scrollToY(_scroll->scrollTop() + d); + }, _scroll->lifetime()); } Main::Session &HistoryInner::session() const { @@ -1226,7 +1231,7 @@ void HistoryInner::mouseActionCancel() { _dragStartPosition = QPoint(0, 0); _dragSelFrom = _dragSelTo = nullptr; _wasSelectedText = false; - _widget->noSelectingScroll(); + _selectScroll.cancel(); } std::unique_ptr HistoryInner::prepareDrag() { @@ -1281,7 +1286,7 @@ std::unique_ptr HistoryInner::prepareDrag() { }(); if (auto mimeData = TextUtilities::MimeDataFromText(selectedText)) { updateDragSelection(nullptr, nullptr, false); - _widget->noSelectingScroll(); + _selectScroll.cancel(); if (!urls.isEmpty()) mimeData->setUrls(urls); if (uponSelected && !_controller->adaptive().isOneColumn()) { @@ -1474,7 +1479,7 @@ void HistoryInner::mouseActionFinish( _mouseAction = MouseAction::None; _mouseActionItem = nullptr; _mouseSelectType = TextSelectType::Letters; - _widget->noSelectingScroll(); + _selectScroll.cancel(); _widget->updateTopBarSelection(); if (QGuiApplication::clipboard()->supportsSelection() @@ -3064,10 +3069,13 @@ void HistoryInner::mouseActionUpdate() { } if (_mouseAction == MouseAction::Selecting) { - _widget->checkSelectingScroll(mousePos); + _selectScroll.checkDeltaScroll( + mousePos, + _scroll->scrollTop(), + _scroll->scrollTop() + _scroll->height()); } else { updateDragSelection(nullptr, nullptr, false); - _widget->noSelectingScroll(); + _selectScroll.cancel(); } if (_mouseAction == MouseAction::None && (lnkChanged || cur != _cursor)) { diff --git a/Telegram/SourceFiles/history/history_inner_widget.h b/Telegram/SourceFiles/history/history_inner_widget.h index 579ff7c1a..d55f5308e 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.h +++ b/Telegram/SourceFiles/history/history_inner_widget.h @@ -7,9 +7,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once -#include "base/timer.h" #include "ui/rp_widget.h" #include "ui/effects/animations.h" +#include "ui/chat/select_scroll_manager.h" // Has base/timer.h. #include "ui/widgets/tooltip.h" #include "ui/widgets/scroll_area.h" #include "history/view/history_view_top_bar_widget.h" @@ -413,6 +413,8 @@ private: QPoint _touchStart, _touchPrevPos, _touchPos; base::Timer _touchSelectTimer; + Ui::SelectScrollManager _selectScroll; + Ui::TouchScrollState _touchScrollState = Ui::TouchScrollState::Manual; bool _touchPrevPosValid = false; bool _touchWaitingAcceleration = false; diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 048270f81..acac67acf 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -247,7 +247,6 @@ HistoryWidget::HistoryWidget( controller, this))) , _membersDropdownShowTimer([=] { showMembersDropdown(); }) -, _scrollTimer([=] { scrollByTimer(); }) , _saveDraftTimer([=] { saveDraft(); }) , _saveCloudDraftTimer([=] { saveCloudDraft(); }) , _topShadow(this) { @@ -2079,7 +2078,6 @@ void HistoryWidget::showHistory( } } - noSelectingScroll(); _nonEmptySelection = false; _itemRevealPending.clear(); _itemRevealAnimations.clear(); @@ -7313,32 +7311,6 @@ QPoint HistoryWidget::clampMousePosition(QPoint point) { return point; } -void HistoryWidget::scrollByTimer() { - const auto d = (_scrollDelta > 0) - ? qMin(_scrollDelta * 3 / 20 + 1, int32(Ui::kMaxScrollSpeed)) - : qMax(_scrollDelta * 3 / 20 - 1, -int32(Ui::kMaxScrollSpeed)); - _scroll->scrollToY(_scroll->scrollTop() + d); -} - -void HistoryWidget::checkSelectingScroll(QPoint point) { - if (point.y() < _scroll->scrollTop()) { - _scrollDelta = point.y() - _scroll->scrollTop(); - } else if (point.y() >= _scroll->scrollTop() + _scroll->height()) { - _scrollDelta = point.y() - _scroll->scrollTop() - _scroll->height() + 1; - } else { - _scrollDelta = 0; - } - if (_scrollDelta) { - _scrollTimer.callEach(15); - } else { - _scrollTimer.cancel(); - } -} - -void HistoryWidget::noSelectingScroll() { - _scrollTimer.cancel(); -} - bool HistoryWidget::touchScroll(const QPoint &delta) { int32 scTop = _scroll->scrollTop(), scMax = _scroll->scrollTopMax(); const auto scNew = std::clamp(scTop - delta.y(), 0, scMax); diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 39d0a9217..7592d8ca8 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -183,9 +183,6 @@ public: QPoint clampMousePosition(QPoint point); - void checkSelectingScroll(QPoint point); - void noSelectingScroll(); - bool touchScroll(const QPoint &delta); void enqueueMessageHighlight(not_null view); @@ -365,7 +362,6 @@ private: void preloadHistoryIfNeeded(); void handleScroll(); - void scrollByTimer(); void updateHistoryItemsByTimer(); [[nodiscard]] Dialogs::EntryState computeDialogsEntryState() const; @@ -762,9 +758,6 @@ private: Window::SlideDirection _showDirection; QPixmap _cacheUnder, _cacheOver; - base::Timer _scrollTimer; - int32 _scrollDelta = 0; - MsgId _highlightedMessageId = 0; std::deque _highlightQueue; base::Timer _highlightTimer; diff --git a/Telegram/SourceFiles/ui/chat/select_scroll_manager.cpp b/Telegram/SourceFiles/ui/chat/select_scroll_manager.cpp new file mode 100644 index 000000000..69f4be21b --- /dev/null +++ b/Telegram/SourceFiles/ui/chat/select_scroll_manager.cpp @@ -0,0 +1,50 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "ui/chat/select_scroll_manager.h" + +#include "ui/widgets/scroll_area.h" + +namespace Ui { + +SelectScrollManager::SelectScrollManager() +: _timer([=] { scrollByTimer(); }) { +} + +void SelectScrollManager::scrollByTimer() { + const auto d = (_delta > 0) + ? std::min(_delta * 3 / 20 + 1, kMaxScrollSpeed) + : std::max(_delta * 3 / 20 - 1, -kMaxScrollSpeed); + _scrolls.fire_copy(d); +} + +void SelectScrollManager::checkDeltaScroll( + const QPoint &point, + int top, + int bottom) { + const auto diff = point.y() - top; + _delta = (diff < 0) + ? diff + : (point.y() >= bottom) + ? (point.y() - bottom + 1) + : 0; + if (_delta) { + _timer.callEach(15); + } else { + _timer.cancel(); + } +} + +void SelectScrollManager::cancel() { + _timer.cancel(); +} + +rpl::producer SelectScrollManager::scrolls() { + return _scrolls.events(); +} + +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/chat/select_scroll_manager.h b/Telegram/SourceFiles/ui/chat/select_scroll_manager.h new file mode 100644 index 000000000..2ef63d2ae --- /dev/null +++ b/Telegram/SourceFiles/ui/chat/select_scroll_manager.h @@ -0,0 +1,34 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +#include "base/timer.h" + +namespace Ui { + +class ScrollArea; + +class SelectScrollManager final { +public: + SelectScrollManager(); + + void checkDeltaScroll(const QPoint &point, int top, int bottom); + void cancel(); + + rpl::producer scrolls(); + +private: + void scrollByTimer(); + + base::Timer _timer; + int _delta = 0; + rpl::event_stream _scrolls; + +}; + +} // namespace Ui diff --git a/Telegram/cmake/td_ui.cmake b/Telegram/cmake/td_ui.cmake index b9d71f459..038f8673a 100644 --- a/Telegram/cmake/td_ui.cmake +++ b/Telegram/cmake/td_ui.cmake @@ -164,6 +164,8 @@ PRIVATE ui/chat/pinned_bar.h ui/chat/requests_bar.cpp ui/chat/requests_bar.h + ui/chat/select_scroll_manager.cpp + ui/chat/select_scroll_manager.h ui/controls/call_mute_button.cpp ui/controls/call_mute_button.h ui/controls/delete_message_context_action.cpp