diff --git a/Telegram/SourceFiles/ui/chat/continuous_scroll.cpp b/Telegram/SourceFiles/ui/chat/continuous_scroll.cpp new file mode 100644 index 000000000..dbaf5514d --- /dev/null +++ b/Telegram/SourceFiles/ui/chat/continuous_scroll.cpp @@ -0,0 +1,74 @@ +/* +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/continuous_scroll.h" + +#include +#include + +namespace Ui { + +void ContinuousScroll::wheelEvent(QWheelEvent *e) { + if (_tracking + && !e->angleDelta().isNull() + && (e->angleDelta().y() < 0) + && (scrollTopMax() == scrollTop())) { + _addContentRequests.fire({}); + if (base::take(_contentAdded)) { + viewportEvent(e); + } + return; + } + ScrollArea::wheelEvent(e); +} + +void ContinuousScroll::setTrackingContent(bool value) { + if (_tracking == value) { + return; + } + _tracking = value; + reconnect(); +} + +void ContinuousScroll::reconnect() { + if (!_tracking) { + _connection.release(); + return; + } + const auto handleAction = [=](int action) { + const auto scroll = verticalScrollBar(); + const auto step = (action == QAbstractSlider::SliderSingleStepAdd) + ? scroll->singleStep() + : (action == QAbstractSlider::SliderPageStepAdd) + ? scroll->pageStep() + : 0; + if (!action) { + return; + } + const auto newTop = scrollTop() + step; + if (newTop > scrollTopMax()) { + _addContentRequests.fire({}); + if (base::take(_contentAdded)) { + scroll->setSliderPosition(newTop); + } + } + }; + _connection = QObject::connect( + verticalScrollBar(), + &QAbstractSlider::actionTriggered, + handleAction); +} + +void ContinuousScroll::contentAdded() { + _contentAdded = true; +} + +rpl::producer<> ContinuousScroll::addContentRequests() const { + return _addContentRequests.events(); +} + +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/chat/continuous_scroll.h b/Telegram/SourceFiles/ui/chat/continuous_scroll.h new file mode 100644 index 000000000..d325332b1 --- /dev/null +++ b/Telegram/SourceFiles/ui/chat/continuous_scroll.h @@ -0,0 +1,41 @@ +/* +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 "ui/widgets/scroll_area.h" +#include "base/qt_connection.h" + +namespace Ui { + +// This class is designed for seamless scrolling of +// on-demand augmented content. +class ContinuousScroll final : public ScrollArea { +public: + using ScrollArea::ScrollArea; + + [[nodiscard]] rpl::producer<> addContentRequests() const; + void contentAdded(); + + void setTrackingContent(bool value); + +protected: + void wheelEvent(QWheelEvent *e) override; + +private: + void reconnect(); + + base::qt_connection _connection; + + bool _contentAdded = false; + bool _tracking = false; + + rpl::event_stream<> _addContentRequests; + +}; + +} // namespace Ui diff --git a/Telegram/cmake/td_ui.cmake b/Telegram/cmake/td_ui.cmake index b6efcc979..9113d5531 100644 --- a/Telegram/cmake/td_ui.cmake +++ b/Telegram/cmake/td_ui.cmake @@ -141,6 +141,8 @@ PRIVATE ui/chat/chat_style.h ui/chat/chat_theme.cpp ui/chat/chat_theme.h + ui/chat/continuous_scroll.cpp + ui/chat/continuous_scroll.h ui/chat/forward_options_box.cpp ui/chat/forward_options_box.h ui/chat/group_call_bar.cpp