Allow animated scroll-to in BoxContent.
This commit is contained in:
parent
ae5a61f7ae
commit
27b7534734
4 changed files with 46 additions and 10 deletions
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue