diff --git a/ui/layers/generic_box.cpp b/ui/layers/generic_box.cpp index d96a17a..8ce8c16 100644 --- a/ui/layers/generic_box.cpp +++ b/ui/layers/generic_box.cpp @@ -17,22 +17,28 @@ void GenericBox::prepare() { _init(this); const auto currentWidth = width(); - const auto pinned = _pinnedToTopContent.data(); - if (pinned) { - pinned->resizeToWidth(currentWidth); + const auto pinnedToTop = _pinnedToTopContent.data(); + const auto pinnedToBottom = _pinnedToBottomContent.data(); + if (pinnedToTop) { + pinnedToTop->resizeToWidth(currentWidth); + } + if (pinnedToBottom) { + pinnedToBottom->resizeToWidth(currentWidth); } auto wrap = object_ptr(this, std::move(_owned)); wrap->resizeToWidth(currentWidth); rpl::combine( - pinned ? pinned->heightValue() : rpl::single(0), - wrap->heightValue() - ) | rpl::start_with_next([=](int top, int height) { + pinnedToTop ? pinnedToTop->heightValue() : rpl::single(0), + wrap->heightValue(), + pinnedToBottom ? pinnedToBottom->heightValue() : rpl::single(0) + ) | rpl::start_with_next([=](int top, int height, int bottom) { Expects(_minHeight >= 0); Expects(!_maxHeight || _minHeight <= _maxHeight); setInnerTopSkip(top); - const auto desired = top + height; + setInnerBottomSkip(bottom); + const auto desired = top + height + bottom; setDimensions( currentWidth, std::clamp( @@ -45,7 +51,17 @@ void GenericBox::prepare() { setInnerWidget( std::move(wrap), _scrollSt ? *_scrollSt : st::boxScroll, - pinned ? pinned->height() : 0); + pinnedToTop ? pinnedToTop->height() : 0, + pinnedToBottom ? pinnedToBottom->height() : 0); + + if (pinnedToBottom) { + rpl::combine( + heightValue(), + pinnedToBottom->heightValue() + ) | rpl::start_with_next([=](int outer, int height) { + pinnedToBottom->move(0, outer - height); + }, pinnedToBottom->lifetime()); + } } void GenericBox::addSkip(int height) { @@ -58,6 +74,12 @@ not_null GenericBox::doSetPinnedToTopContent( return _pinnedToTopContent.data(); } +not_null GenericBox::doSetPinnedToBottomContent( + object_ptr content) { + _pinnedToBottomContent = std::move(content); + return _pinnedToBottomContent.data(); +} + int GenericBox::rowsCount() const { return _content->count(); } diff --git a/ui/layers/generic_box.h b/ui/layers/generic_box.h index dd54c70..3bfd724 100644 --- a/ui/layers/generic_box.h +++ b/ui/layers/generic_box.h @@ -100,6 +100,12 @@ public: doSetPinnedToTopContent(std::move(content)).get()); } + template + not_null setPinnedToBottomContent(object_ptr content) { + return static_cast( + doSetPinnedToBottomContent(std::move(content)).get()); + } + [[nodiscard]] not_null verticalLayout(); using BoxContent::setNoContentMargin; @@ -132,6 +138,8 @@ private: void prepare() override; not_null doSetPinnedToTopContent( object_ptr content); + not_null doSetPinnedToBottomContent( + object_ptr content); FnMut)> _init; Fn _focus; @@ -144,6 +152,7 @@ private: int _maxHeight = 0; object_ptr _pinnedToTopContent = { nullptr }; + object_ptr _pinnedToBottomContent = { nullptr }; };