Allow animated scroll-to in BoxContent.

This commit is contained in:
John Preston 2024-04-23 19:11:31 +04:00
parent ae5a61f7ae
commit 27b7534734
4 changed files with 46 additions and 10 deletions

View file

@ -263,8 +263,21 @@ RectParts BoxContent::customCornersFilling() {
} }
void BoxContent::scrollToY(int top, int bottom) { void BoxContent::scrollToY(int top, int bottom) {
scrollTo({ top, bottom });
}
void BoxContent::scrollTo(ScrollToRequest request, anim::type animated) {
if (_scroll) { if (_scroll) {
_scroll->scrollToY(top, bottom); const auto v = _scroll->computeScrollTo(request.ymin, request.ymax);
const auto now = _scroll->scrollTop();
if (animated == anim::type::instant || v == now) {
_scrollAnimation.stop();
_scroll->scrollToY(v);
} else {
_scrollAnimation.start([=] {
_scroll->scrollToY(_scrollAnimation.value(v));
}, now, v, st::slideWrapDuration, anim::sineInOut);
}
} }
} }

View file

@ -13,6 +13,7 @@
#include "ui/widgets/labels.h" #include "ui/widgets/labels.h"
#include "ui/layers/layer_widget.h" #include "ui/layers/layer_widget.h"
#include "ui/layers/show.h" #include "ui/layers/show.h"
#include "ui/effects/animations.h"
#include "ui/effects/animation_value.h" #include "ui/effects/animation_value.h"
#include "ui/text/text_entity.h" #include "ui/text/text_entity.h"
#include "ui/rp_widget.h" #include "ui/rp_widget.h"
@ -59,6 +60,7 @@ class ScrollArea;
class FlatLabel; class FlatLabel;
class FadeShadow; class FadeShadow;
class BoxContent; class BoxContent;
struct ScrollToRequest;
class BoxContentDelegate { class BoxContentDelegate {
public: public:
@ -213,6 +215,9 @@ public:
void scrollByDraggingDelta(int delta); void scrollByDraggingDelta(int delta);
void scrollToY(int top, int bottom = -1); void scrollToY(int top, int bottom = -1);
void scrollTo(
ScrollToRequest request,
anim::type animated = anim::type::instant);
void sendScrollViewportEvent(not_null<QEvent*> event); void sendScrollViewportEvent(not_null<QEvent*> event);
[[nodiscard]] rpl::producer<> scrolls() const; [[nodiscard]] rpl::producer<> scrolls() const;
[[nodiscard]] int scrollTop() const; [[nodiscard]] int scrollTop() const;
@ -309,6 +314,7 @@ private:
object_ptr<FadeShadow> _bottomShadow = { nullptr }; object_ptr<FadeShadow> _bottomShadow = { nullptr };
Ui::DraggingScrollManager _draggingScroll; Ui::DraggingScrollManager _draggingScroll;
Ui::Animations::Simple _scrollAnimation;
rpl::event_stream<> _boxClosingStream; rpl::event_stream<> _boxClosingStream;

View file

@ -706,32 +706,48 @@ void ScrollArea::scrollToWidget(not_null<QWidget*> widget) {
} }
} }
void ScrollArea::scrollToY(int toTop, int toBottom) { int ScrollArea::computeScrollTo(int toTop, int toBottom) {
if (const auto inner = widget()) { if (const auto inner = widget()) {
SendPendingMoveResizeEvents(inner); SendPendingMoveResizeEvents(inner);
} }
SendPendingMoveResizeEvents(this); SendPendingMoveResizeEvents(this);
int toMin = 0, toMax = scrollTopMax(); const auto toMin = 0;
const auto toMax = scrollTopMax();
if (toTop < toMin) { if (toTop < toMin) {
toTop = toMin; toTop = toMin;
} else if (toTop > toMax) { } else if (toTop > toMax) {
toTop = toMax; toTop = toMax;
} }
bool exact = (toBottom < 0); const auto exact = (toBottom < 0);
int curTop = scrollTop(), curHeight = height(), curBottom = curTop + curHeight, scToTop = toTop; const auto curTop = scrollTop();
const auto curHeight = height();
const auto curBottom = curTop + curHeight;
auto scToTop = toTop;
if (!exact && toTop >= curTop) { if (!exact && toTop >= curTop) {
if (toBottom < toTop) toBottom = toTop; if (toBottom < toTop) {
if (toBottom <= curBottom) return; toBottom = toTop;
}
if (toBottom <= curBottom) {
return curTop;
}
scToTop = toBottom - curHeight; scToTop = toBottom - curHeight;
if (scToTop > toTop) scToTop = toTop; if (scToTop > toTop) {
if (scToTop == curTop) return; scToTop = toTop;
}
if (scToTop == curTop) {
return curTop;
}
} else { } else {
scToTop = toTop; scToTop = toTop;
} }
verticalScrollBar()->setValue(scToTop); return scToTop;
}
void ScrollArea::scrollToY(int toTop, int toBottom) {
verticalScrollBar()->setValue(computeScrollTo(toTop, toBottom));
} }
void ScrollArea::doSetOwnedWidget(object_ptr<QWidget> w) { void ScrollArea::doSetOwnedWidget(object_ptr<QWidget> w) {

View file

@ -166,6 +166,7 @@ public:
void scrollTo(ScrollToRequest request); void scrollTo(ScrollToRequest request);
void scrollToWidget(not_null<QWidget*> widget); void scrollToWidget(not_null<QWidget*> widget);
[[nodiscard]] int computeScrollTo(int toTop, int toBottom);
void scrollToY(int toTop, int toBottom = -1); void scrollToY(int toTop, int toBottom = -1);
void disableScroll(bool dis); void disableScroll(bool dis);