mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-01 12:00:48 +00:00
Change layer widget height with animation.
This commit is contained in:
parent
9933d1ff3a
commit
f6f39d1560
@ -86,15 +86,50 @@ void LayerWidget::setupHeightConsumers() {
|
||||
}) | rpl::start_with_next([this] {
|
||||
resizeToWidth(width());
|
||||
}, lifetime());
|
||||
|
||||
_content->grabbingForExpanding(
|
||||
) | rpl::start_with_next([=](bool grabbing) {
|
||||
if (grabbing) {
|
||||
_savedHeight = _contentHeight;
|
||||
_savedHeightAnimation = base::take(_heightAnimation);
|
||||
setContentHeight(_desiredHeight);
|
||||
} else {
|
||||
_heightAnimation = base::take(_savedHeightAnimation);
|
||||
setContentHeight(_savedHeight);
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
_content->desiredHeightValue(
|
||||
) | rpl::start_with_next([this](int height) {
|
||||
accumulate_max(_desiredHeight, height);
|
||||
if (_content && !_inResize) {
|
||||
if (!height) {
|
||||
// New content arrived.
|
||||
_heightAnimated = _heightAnimation.animating();
|
||||
return;
|
||||
}
|
||||
std::swap(_desiredHeight, height);
|
||||
if (!height
|
||||
|| (_heightAnimated && !_heightAnimation.animating())) {
|
||||
setContentHeight(_desiredHeight);
|
||||
} else {
|
||||
_heightAnimated = true;
|
||||
_heightAnimation.start([=] {
|
||||
setContentHeight(_heightAnimation.value(_desiredHeight));
|
||||
}, _contentHeight, _desiredHeight, st::slideDuration);
|
||||
resizeToWidth(width());
|
||||
}
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void LayerWidget::setContentHeight(int height) {
|
||||
if (_contentHeight == height) {
|
||||
return;
|
||||
}
|
||||
_contentHeight = height;
|
||||
if (_content && !_inResize) {
|
||||
resizeToWidth(width());
|
||||
}
|
||||
}
|
||||
|
||||
void LayerWidget::showFinished() {
|
||||
floatPlayerShowVisible();
|
||||
}
|
||||
@ -217,8 +252,8 @@ int LayerWidget::resizeGetHeight(int newWidth) {
|
||||
st::infoLayerTopMaximal);
|
||||
auto newBottom = newTop;
|
||||
|
||||
// Top rounding is included in _desiredHeight.
|
||||
auto desiredHeight = _desiredHeight + st::boxRadius;
|
||||
// Top rounding is included in _contentHeight.
|
||||
auto desiredHeight = _contentHeight + st::boxRadius;
|
||||
accumulate_min(desiredHeight, windowHeight - newTop - newBottom);
|
||||
|
||||
// First resize content to new width and get the new desired height.
|
||||
@ -230,6 +265,8 @@ int LayerWidget::resizeGetHeight(int newWidth) {
|
||||
auto scrollTillBottom = _content->scrollTillBottom(contentHeight);
|
||||
auto additionalScroll = std::min(scrollTillBottom, newBottom);
|
||||
|
||||
const auto expanding = (_desiredHeight > _contentHeight);
|
||||
|
||||
desiredHeight += additionalScroll;
|
||||
contentHeight += additionalScroll;
|
||||
_tillBottom = (newTop + desiredHeight >= windowHeight);
|
||||
@ -241,7 +278,8 @@ int LayerWidget::resizeGetHeight(int newWidth) {
|
||||
contentLeft,
|
||||
contentTop,
|
||||
contentWidth,
|
||||
contentHeight }, additionalScroll);
|
||||
contentHeight,
|
||||
}, expanding, additionalScroll);
|
||||
|
||||
auto newGeometry = QRect(newLeft, newTop, newWidth, desiredHeight);
|
||||
if (newGeometry != geometry()) {
|
||||
|
@ -68,11 +68,17 @@ private:
|
||||
not_null<const HistoryItem*> item) override;
|
||||
|
||||
void setupHeightConsumers();
|
||||
void setContentHeight(int height);
|
||||
|
||||
not_null<Window::SessionController*> _controller;
|
||||
object_ptr<WrapWidget> _content;
|
||||
|
||||
int _desiredHeight = 0;
|
||||
int _contentHeight = 0;
|
||||
int _savedHeight = 0;
|
||||
Ui::Animations::Simple _heightAnimation;
|
||||
Ui::Animations::Simple _savedHeightAnimation;
|
||||
bool _heightAnimated = false;
|
||||
bool _inResize = false;
|
||||
bool _tillBottom = false;
|
||||
|
||||
|
@ -44,9 +44,10 @@ void SectionWidget::init() {
|
||||
|
||||
sizeValue(
|
||||
) | rpl::start_with_next([wrap = _content.data()](QSize size) {
|
||||
const auto expanding = false;
|
||||
auto wrapGeometry = QRect{ { 0, 0 }, size };
|
||||
auto additionalScroll = 0;
|
||||
wrap->updateGeometry(wrapGeometry, additionalScroll);
|
||||
wrap->updateGeometry(wrapGeometry, expanding, additionalScroll);
|
||||
}, _content->lifetime());
|
||||
|
||||
_connecting = std::make_unique<Window::ConnectionState>(
|
||||
|
@ -645,10 +645,10 @@ rpl::producer<bool> WrapWidget::topShadowToggledValue() const {
|
||||
|
||||
rpl::producer<int> WrapWidget::desiredHeightForContent() const {
|
||||
using namespace rpl::mappers;
|
||||
return rpl::combine(
|
||||
return rpl::single(0) | rpl::then(rpl::combine(
|
||||
_content->desiredHeightValue(),
|
||||
topWidget()->heightValue(),
|
||||
_1 + _2);
|
||||
_1 + _2));
|
||||
}
|
||||
|
||||
rpl::producer<SelectedItems> WrapWidget::selectedListValue() const {
|
||||
@ -738,7 +738,14 @@ QPixmap WrapWidget::grabForShowAnimation(
|
||||
//if (params.withTabs && _topTabs) {
|
||||
// _topTabs->hide();
|
||||
//}
|
||||
const auto expanding = _expanding;
|
||||
if (expanding) {
|
||||
_grabbingForExpanding = true;
|
||||
}
|
||||
auto result = Ui::GrabWidget(this);
|
||||
if (expanding) {
|
||||
_grabbingForExpanding = false;
|
||||
}
|
||||
if (params.withTopBarShadow) {
|
||||
_topShadow->setVisible(true);
|
||||
}
|
||||
@ -1007,11 +1014,15 @@ object_ptr<Ui::RpWidget> WrapWidget::createTopBarSurrogate(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void WrapWidget::updateGeometry(QRect newGeometry, int additionalScroll) {
|
||||
void WrapWidget::updateGeometry(
|
||||
QRect newGeometry,
|
||||
bool expanding,
|
||||
int additionalScroll) {
|
||||
auto scrollChanged = (_additionalScroll != additionalScroll);
|
||||
auto geometryChanged = (geometry() != newGeometry);
|
||||
auto shrinkingContent = (additionalScroll < _additionalScroll);
|
||||
_additionalScroll = additionalScroll;
|
||||
_expanding = expanding;
|
||||
|
||||
if (geometryChanged) {
|
||||
if (shrinkingContent) {
|
||||
@ -1038,6 +1049,10 @@ rpl::producer<int> WrapWidget::scrollTillBottomChanges() const {
|
||||
) | rpl::flatten_latest();
|
||||
}
|
||||
|
||||
rpl::producer<bool> WrapWidget::grabbingForExpanding() const {
|
||||
return _grabbingForExpanding.value();
|
||||
}
|
||||
|
||||
WrapWidget::~WrapWidget() = default;
|
||||
|
||||
} // namespace Info
|
||||
|
@ -118,11 +118,15 @@ public:
|
||||
|
||||
object_ptr<Ui::RpWidget> createTopBarSurrogate(QWidget *parent);
|
||||
|
||||
bool closeByOutsideClick() const;
|
||||
[[nodiscard]] bool closeByOutsideClick() const;
|
||||
|
||||
void updateGeometry(QRect newGeometry, int additionalScroll);
|
||||
int scrollTillBottom(int forHeight) const;
|
||||
rpl::producer<int> scrollTillBottomChanges() const;
|
||||
void updateGeometry(
|
||||
QRect newGeometry,
|
||||
bool expanding,
|
||||
int additionalScroll);
|
||||
[[nodiscard]] int scrollTillBottom(int forHeight) const;
|
||||
[[nodiscard]] rpl::producer<int> scrollTillBottomChanges() const;
|
||||
[[nodiscard]] rpl::producer<bool> grabbingForExpanding() const;
|
||||
|
||||
~WrapWidget();
|
||||
|
||||
@ -203,6 +207,8 @@ private:
|
||||
std::unique_ptr<Controller> _controller;
|
||||
object_ptr<ContentWidget> _content = { nullptr };
|
||||
int _additionalScroll = 0;
|
||||
bool _expanding = false;
|
||||
rpl::variable<bool> _grabbingForExpanding = false;
|
||||
//object_ptr<Ui::PlainShadow> _topTabsBackground = { nullptr };
|
||||
//object_ptr<Ui::SettingsSlider> _topTabs = { nullptr };
|
||||
object_ptr<TopBar> _topBar = { nullptr };
|
||||
|
Loading…
Reference in New Issue
Block a user