mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-09-06 20:13:12 +02:00
feat: smooth scroll
This commit is contained in:
parent
1642734548
commit
e6b0c61d78
22 changed files with 262 additions and 0 deletions
|
@ -6886,6 +6886,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"ayu_DisableAds" = "Disable Ads";
|
||||
"ayu_DisableStories" = "Disable Stories";
|
||||
"ayu_DisableCustomBackgrounds" = "Disable Custom Backgrounds";
|
||||
"ayu_SmoothScroll" = "Smooth Scroll";
|
||||
"ayu_DisableNotificationsDelay" = "Disable Notify Delay";
|
||||
"ayu_LocalPremium" = "Local Telegram Premium";
|
||||
"ayu_DisplayGhostStatus" = "Display Ghost Mode Status";
|
||||
|
|
|
@ -32,6 +32,7 @@ void initUiSettings() {
|
|||
|
||||
AyuUiSettings::setMonoFont(settings.monoFont);
|
||||
AyuUiSettings::setWideMultiplier(settings.wideMultiplier);
|
||||
AyuUiSettings::setSmoothScroll(settings.smoothScroll);
|
||||
}
|
||||
|
||||
void initDatabase() {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <fstream>
|
||||
|
||||
#include "ayu_worker.h"
|
||||
#include "ayu/ayu_ui_settings.h"
|
||||
#include "window/window_controller.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
@ -229,6 +230,7 @@ AyuGramSettings::AyuGramSettings() {
|
|||
increaseWebviewHeight = false;
|
||||
increaseWebviewWidth = false;
|
||||
|
||||
smoothScroll = true;
|
||||
disableNotificationsDelay = false;
|
||||
localPremium = false;
|
||||
showChannelReactions = true;
|
||||
|
@ -410,6 +412,10 @@ void set_increaseWebviewHeight(bool val) {
|
|||
void set_increaseWebviewWidth(bool val) {
|
||||
settings->increaseWebviewWidth = val;
|
||||
}
|
||||
void set_smoothScroll(bool val) {
|
||||
settings->smoothScroll = val;
|
||||
AyuUiSettings::setSmoothScroll(val);
|
||||
}
|
||||
|
||||
void set_disableNotificationsDelay(bool val) {
|
||||
settings->disableNotificationsDelay = val;
|
||||
|
|
|
@ -74,6 +74,7 @@ public:
|
|||
bool increaseWebviewHeight;
|
||||
bool increaseWebviewWidth;
|
||||
|
||||
bool smoothScroll;
|
||||
bool disableNotificationsDelay;
|
||||
bool localPremium;
|
||||
bool showChannelReactions;
|
||||
|
@ -158,6 +159,7 @@ void set_spoofWebviewAsAndroid(bool val);
|
|||
void set_increaseWebviewHeight(bool val);
|
||||
void set_increaseWebviewWidth(bool val);
|
||||
|
||||
void set_smoothScroll(bool val);
|
||||
void set_disableNotificationsDelay(bool val);
|
||||
void set_localPremium(bool val);
|
||||
void set_hideChannelReactions(bool val);
|
||||
|
@ -232,6 +234,7 @@ inline void to_json(nlohmann::json &nlohmann_json_j, const AyuGramSettings &nloh
|
|||
NLOHMANN_JSON_TO(spoofWebviewAsAndroid)
|
||||
NLOHMANN_JSON_TO(increaseWebviewHeight)
|
||||
NLOHMANN_JSON_TO(increaseWebviewWidth)
|
||||
NLOHMANN_JSON_TO(smoothScroll)
|
||||
NLOHMANN_JSON_TO(disableNotificationsDelay)
|
||||
NLOHMANN_JSON_TO(localPremium)
|
||||
NLOHMANN_JSON_TO(appIcon)
|
||||
|
@ -297,6 +300,7 @@ inline void from_json(const nlohmann::json &nlohmann_json_j, AyuGramSettings &nl
|
|||
NLOHMANN_JSON_FROM_WITH_DEFAULT(spoofWebviewAsAndroid)
|
||||
NLOHMANN_JSON_FROM_WITH_DEFAULT(increaseWebviewHeight)
|
||||
NLOHMANN_JSON_FROM_WITH_DEFAULT(increaseWebviewWidth)
|
||||
NLOHMANN_JSON_FROM_WITH_DEFAULT(smoothScroll)
|
||||
NLOHMANN_JSON_FROM_WITH_DEFAULT(disableNotificationsDelay)
|
||||
NLOHMANN_JSON_FROM_WITH_DEFAULT(localPremium)
|
||||
NLOHMANN_JSON_FROM_WITH_DEFAULT(appIcon)
|
||||
|
|
|
@ -167,6 +167,11 @@ Widget::Widget(
|
|||
_inner->scrollToSignal(
|
||||
) | rpl::start_with_next([=](int top)
|
||||
{
|
||||
|
||||
// AyuGram smooth scroll
|
||||
_scroll->stopSmoothScroll();
|
||||
// AyuGram smooth scroll
|
||||
|
||||
_scroll->scrollToY(top);
|
||||
},
|
||||
lifetime());
|
||||
|
|
|
@ -789,6 +789,27 @@ void SetupQoLToggles(not_null<Ui::VerticalLayout*> container) {
|
|||
AddDivider(container);
|
||||
AddSkip(container);
|
||||
|
||||
|
||||
AddButtonWithIcon(
|
||||
container,
|
||||
tr::ayu_SmoothScroll(),
|
||||
st::settingsButtonNoIcon
|
||||
)->toggleOn(
|
||||
rpl::single(settings->smoothScroll)
|
||||
)->toggledValue(
|
||||
) | rpl::filter(
|
||||
[=](bool enabled)
|
||||
{
|
||||
return (enabled != settings->smoothScroll);
|
||||
}) | start_with_next(
|
||||
[=](bool enabled)
|
||||
{
|
||||
AyuSettings::set_smoothScroll(enabled);
|
||||
AyuSettings::save();
|
||||
},
|
||||
container->lifetime());
|
||||
|
||||
|
||||
AddButtonWithIcon(
|
||||
container,
|
||||
tr::ayu_DisableNotificationsDelay(),
|
||||
|
|
|
@ -33,6 +33,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include <QtWidgets/QApplication>
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/smooth_scroll/smooth_scroll.h"
|
||||
#include "ui/ui_utility.h"
|
||||
|
||||
|
||||
namespace ChatHelpers {
|
||||
namespace {
|
||||
|
||||
|
@ -948,6 +953,36 @@ void StickersListFooter::scrollByWheelEvent(
|
|||
? e->pixelDelta().y()
|
||||
: e->angleDelta().y());
|
||||
const auto use = [&](ScrollState &state) {
|
||||
|
||||
// AyuGram smooth scroll
|
||||
if (state.dragging) {
|
||||
SmoothScroll::Scroller::stop(state.scrollAnimation, state.scrollTo);
|
||||
return;
|
||||
}
|
||||
const auto scrollDelta = Ui::ScrollDelta(e);
|
||||
const auto scroll = (std::abs(scrollDelta.y()) >= std::abs(scrollDelta.x()))
|
||||
? scrollDelta.y()
|
||||
: scrollDelta.x();
|
||||
|
||||
if (SmoothScroll::Scroller::handleScroll(
|
||||
-scroll,
|
||||
state.scrollAnimation,
|
||||
state.scrollTo,
|
||||
{
|
||||
.getScroll = [&]{return qRound(state.x.current());},
|
||||
.setScroll = [&](int v){
|
||||
state.x = anim::value(v);
|
||||
update();
|
||||
},
|
||||
.getNewTarget = [&](int t){return std::clamp(t, 0, state.max);}
|
||||
},
|
||||
anim::easeOutCubic,
|
||||
st::slideWrapDuration
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
// AyuGram smooth scroll
|
||||
|
||||
const auto now = qRound(state.x.current());
|
||||
const auto used = now - delta;
|
||||
const auto next = std::clamp(used, 0, state.max);
|
||||
|
|
|
@ -199,6 +199,11 @@ private:
|
|||
anim::value selectionWidth;
|
||||
crl::time animationStart = 0;
|
||||
Ui::Animations::Basic animation;
|
||||
|
||||
|
||||
// AyuGram smooth scroll
|
||||
Ui::Animations::Simple scrollAnimation;
|
||||
float64 scrollTo = -1.;
|
||||
};
|
||||
struct ExpandingContext {
|
||||
QRect clip;
|
||||
|
|
|
@ -63,6 +63,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "styles/style_menu_icons.h"
|
||||
#include "styles/style_window.h"
|
||||
|
||||
|
||||
// AyuGram includes
|
||||
#include <QScrollBar>
|
||||
|
||||
|
||||
namespace Dialogs {
|
||||
namespace {
|
||||
|
||||
|
@ -1349,6 +1354,31 @@ void Suggestions::setupTabs() {
|
|||
if (std::abs(pixelDelta.x()) + std::abs(angleDelta.x())) {
|
||||
return false;
|
||||
}
|
||||
// AyuGram smooth scroll
|
||||
const auto delta = Ui::ScrollDelta(e);
|
||||
const auto bar = _tabsScroll->horizontalScrollBar();
|
||||
if (SmoothScroll::Scroller::handleScroll(
|
||||
-delta.y(),
|
||||
_tabsWheelAnimation,
|
||||
_tabsWheelScrollTo,
|
||||
{
|
||||
.getScroll = [bar]
|
||||
{
|
||||
return bar->value();
|
||||
},
|
||||
.setScroll = [bar](int v)
|
||||
{
|
||||
bar->setValue(v);
|
||||
},
|
||||
.getNewTarget = [bar](int t)
|
||||
{
|
||||
return std::clamp(t, bar->minimum(), bar->maximum());
|
||||
}
|
||||
})) {
|
||||
return true;
|
||||
}
|
||||
// AyuGram smooth scroll
|
||||
|
||||
const auto y = pixelDelta.y() ? pixelDelta.y() : angleDelta.y();
|
||||
_tabsScroll->scrollToX(_tabsScroll->scrollLeft() - y);
|
||||
return true;
|
||||
|
|
|
@ -112,6 +112,10 @@ public:
|
|||
|
||||
class ObjectListController;
|
||||
|
||||
|
||||
// AyuGram smooth scroll
|
||||
Ui::Animations::Simple _tabsWheelAnimation;
|
||||
float64 _tabsWheelScrollTo = -1.;
|
||||
private:
|
||||
using MediaType = Storage::SharedMediaType;
|
||||
enum class Tab : uchar {
|
||||
|
|
|
@ -326,6 +326,11 @@ Widget::Widget(
|
|||
}, lifetime());
|
||||
_inner->scrollToSignal(
|
||||
) | rpl::start_with_next([=](int top) {
|
||||
|
||||
// AyuGram smooth scroll
|
||||
_scroll->stopSmoothScroll();
|
||||
// AyuGram smooth scroll
|
||||
|
||||
_scroll->scrollToY(top);
|
||||
}, lifetime());
|
||||
|
||||
|
|
|
@ -7142,6 +7142,18 @@ void HistoryWidget::updateHistoryGeometry(
|
|||
updateListSize();
|
||||
_updateHistoryGeometryRequired = false;
|
||||
|
||||
// AyuGram smooth scroll
|
||||
|
||||
// workaround:
|
||||
// stop smooth scroll to prevent the view from
|
||||
// jumping to the top when older messages are loaded
|
||||
|
||||
// scroll position isn't correctly calculated on resize
|
||||
_scroll->stopSmoothScroll();
|
||||
|
||||
// AyuGram smooth scroll
|
||||
|
||||
|
||||
auto newScrollTop = 0;
|
||||
if (initial) {
|
||||
newScrollTop = countInitialScrollTop();
|
||||
|
|
|
@ -571,6 +571,7 @@ bool Item::listScrollTo(int top, bool syntetic) {
|
|||
updateInnerVisibleArea();
|
||||
return false;
|
||||
}
|
||||
_scroll->stopSmoothScroll();
|
||||
_scroll->scrollToY(top);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2912,6 +2912,11 @@ bool ChatWidget::listScrollTo(int top, bool syntetic) {
|
|||
const auto scrolled = (_scroll->scrollTop() != top);
|
||||
_synteticScrollEvent = syntetic;
|
||||
if (scrolled) {
|
||||
|
||||
// AyuGram smooth scroll
|
||||
_scroll->stopSmoothScroll();
|
||||
// AyuGram smooth scroll
|
||||
|
||||
_scroll->scrollToY(top);
|
||||
} else if (syntetic) {
|
||||
updateInnerVisibleArea();
|
||||
|
|
|
@ -26,6 +26,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "styles/style_chat_helpers.h"
|
||||
#include "styles/style_menu_icons.h"
|
||||
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/smooth_scroll/smooth_scroll.h"
|
||||
|
||||
namespace HistoryView::Reactions {
|
||||
namespace {
|
||||
|
||||
|
@ -124,6 +128,35 @@ bool Button::consumeWheelEvent(not_null<QWheelEvent*> e) {
|
|||
if (horizontal) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// AyuGram smooth scroll
|
||||
const auto scrollDelta = Ui::ScrollDelta(e) * (expandUp() ? -1. : 1.);
|
||||
if (SmoothScroll::Scroller::handleScroll(
|
||||
-scrollDelta.y(),
|
||||
_scrollAnimation,
|
||||
_scrollTarget,
|
||||
{
|
||||
.getScroll = [this]
|
||||
{
|
||||
return int(base::SafeRound(_scroll));
|
||||
},
|
||||
.setScroll = [this](int value)
|
||||
{
|
||||
_scroll = value;
|
||||
_update(_geometry);
|
||||
},
|
||||
.getNewTarget = [=](int target)
|
||||
{
|
||||
return std::clamp(target, 0, scrollMax);
|
||||
}
|
||||
},
|
||||
anim::easeOutCubic,
|
||||
kCollapseDuration)) {
|
||||
e->accept();
|
||||
return true;
|
||||
}
|
||||
// AyuGram smooth scroll
|
||||
|
||||
const auto between = st::reactionCornerSkip;
|
||||
const auto oneHeight = (st::reactionCornerSize.height() + between);
|
||||
const auto max = oneHeight * kMaxReactionsScrollAtOnce;
|
||||
|
@ -209,6 +242,14 @@ void Button::updateGeometry(Fn<void(QRect)> update) {
|
|||
)) - _collapsed.height();
|
||||
if (!added && _state != State::Inside) {
|
||||
_scroll = 0;
|
||||
|
||||
// AyuGram smooth scroll
|
||||
if (_scrollAnimation.animating()) {
|
||||
_scrollAnimation.stop();
|
||||
}
|
||||
_scrollTarget = -1.;
|
||||
// AyuGram smooth scroll
|
||||
|
||||
}
|
||||
const auto geometry = _collapsed.marginsAdded({
|
||||
0,
|
||||
|
|
|
@ -131,6 +131,11 @@ private:
|
|||
base::Timer _hideTimer;
|
||||
std::optional<QPoint> _lastGlobalPosition;
|
||||
|
||||
|
||||
// AyuGram smooth scroll
|
||||
|
||||
Ui::Animations::Simple _scrollAnimation;
|
||||
float64 _scrollTarget = -1.;
|
||||
};
|
||||
|
||||
class Manager final : public base::has_weak_ptr {
|
||||
|
|
|
@ -295,6 +295,10 @@ void ContentWidget::scrollTopRestore(int scrollTop) {
|
|||
void ContentWidget::scrollTo(const Ui::ScrollToRequest &request) {
|
||||
_scroll->scrollTo(request);
|
||||
}
|
||||
// AyuGram smooth scroll
|
||||
void ContentWidget::stopSmoothScroll() {
|
||||
_scroll->stopSmoothScroll();
|
||||
}
|
||||
|
||||
bool ContentWidget::floatPlayerHandleWheelEvent(QEvent *e) {
|
||||
return _scroll->viewportEvent(e);
|
||||
|
|
|
@ -169,6 +169,8 @@ protected:
|
|||
|
||||
void setViewport(rpl::producer<not_null<QEvent*>> &&events) const;
|
||||
|
||||
// AyuGram smooth scroll
|
||||
void stopSmoothScroll();
|
||||
private:
|
||||
RpWidget *doSetInnerWidget(object_ptr<RpWidget> inner);
|
||||
void updateControlsGeometry();
|
||||
|
|
|
@ -136,6 +136,10 @@ Widget::Widget(QWidget *parent, not_null<Controller*> controller)
|
|||
_inner->setScrollHeightValue(scrollHeightValue());
|
||||
_inner->scrollToRequests(
|
||||
) | rpl::start_with_next([this](Ui::ScrollToRequest request) {
|
||||
// AyuGram smooth scroll
|
||||
stopSmoothScroll();
|
||||
// AyuGram smooth scroll
|
||||
|
||||
scrollTo(request);
|
||||
}, _inner->lifetime());
|
||||
}
|
||||
|
|
|
@ -19,6 +19,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include <QtWidgets/QApplication>
|
||||
|
||||
// AyuGram includes
|
||||
#include "ayu/smooth_scroll/smooth_scroll.h"
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
|
@ -45,6 +48,11 @@ public:
|
|||
|
||||
[[nodiscard]] rpl::producer<int> moveRequests() const;
|
||||
|
||||
|
||||
// AyuGram smooth scroll
|
||||
bool isDragging() const {
|
||||
return _dragging;
|
||||
}
|
||||
private:
|
||||
struct Button {
|
||||
EmojiGroup group;
|
||||
|
@ -375,6 +383,38 @@ void SearchWithGroups::initGroups() {
|
|||
|
||||
widget->moveRequests(
|
||||
) | rpl::start_with_next([=](int delta) {
|
||||
|
||||
// AyuGram smooth scroll
|
||||
|
||||
if (widget->isDragging()) {
|
||||
SmoothScroll::Scroller::stop(
|
||||
_groupsScrollAnimation,
|
||||
_groupsScrollTo);
|
||||
moveGroupsBy(width(), delta);
|
||||
return;
|
||||
}
|
||||
if (SmoothScroll::Scroller::handleScroll(
|
||||
delta,
|
||||
_groupsScrollAnimation,
|
||||
_groupsScrollTo,
|
||||
{
|
||||
.getScroll = [=] {
|
||||
return _groups->x();
|
||||
},
|
||||
.setScroll = [=](int value) {
|
||||
moveGroupsTo(width(), value);
|
||||
},
|
||||
.getNewTarget = [=](int target) {
|
||||
return clampGroupsLeft(width(), target);
|
||||
}
|
||||
},
|
||||
anim::easeOutCubic,
|
||||
st::slideWrapDuration
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
// AyuGram smooth scroll
|
||||
|
||||
moveGroupsBy(width(), delta);
|
||||
}, lifetime());
|
||||
|
||||
|
|
|
@ -114,6 +114,10 @@ private:
|
|||
base::Timer _debounceTimer;
|
||||
bool _inited = false;
|
||||
|
||||
|
||||
// AyuGram smooth scroll
|
||||
Animations::Simple _groupsScrollAnimation;
|
||||
float64 _groupsScrollTo = -1.;
|
||||
};
|
||||
|
||||
class TabbedSearch final {
|
||||
|
|
|
@ -53,6 +53,11 @@ struct State final {
|
|||
|
||||
std::unique_ptr<Ui::ChatsFiltersTabsReorder> reorder;
|
||||
bool ignoreRefresh = false;
|
||||
|
||||
// AyuGram smooth scroll
|
||||
Animations::Simple scrollAnimation;
|
||||
float64 scrollTo = -1.;
|
||||
|
||||
};
|
||||
|
||||
void ShowMenu(
|
||||
|
@ -303,6 +308,28 @@ not_null<Ui::RpWidget*> AddChatFiltersTabsStrip(
|
|||
if (std::abs(pixelDelta.x()) + std::abs(angleDelta.x())) {
|
||||
return false;
|
||||
}
|
||||
// AyuGram smooth scroll
|
||||
const auto delta = ScrollDelta(e);
|
||||
|
||||
if (SmoothScroll::Scroller::handleScroll(
|
||||
-delta.y(),
|
||||
state->scrollAnimation,
|
||||
state->scrollTo,
|
||||
{
|
||||
.getScroll = [=] { return scroll->horizontalScrollBar()->value(); },
|
||||
.setScroll = [=](int v) { scroll->horizontalScrollBar()->setValue(v); },
|
||||
.getNewTarget = [bar = scroll->horizontalScrollBar()](int t)
|
||||
{
|
||||
return std::clamp(t, bar->minimum(), bar->maximum());
|
||||
}
|
||||
})
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
// AyuGram smooth scroll
|
||||
|
||||
|
||||
|
||||
const auto bar = scroll->horizontalScrollBar();
|
||||
const auto y = pixelDelta.y() ? pixelDelta.y() : angleDelta.y();
|
||||
bar->setValue(bar->value() - y);
|
||||
|
|
Loading…
Add table
Reference in a new issue