diff --git a/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion_test.cpp b/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion_test.cpp index 7fcdf75612..eb0e84dc66 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion_test.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion_test.cpp @@ -39,39 +39,17 @@ void Widget::setupTopBarSuggestionTestHotkeys() { _topBarSuggestionHeightChanged.fire(0); return; } - _topBarSuggestionPlaceholder.reset(_innerList->insert( - 0, - object_ptr(_innerList))); - _topBarSuggestionPlaceholder->paintOn([ - ph = _topBarSuggestionPlaceholder.get() - ](QPainter &p) { - p.fillRect(ph->rect(), st::dialogsBg); - }); _topBarSuggestion.reset(wrap); - _topBarSuggestion->setParent(_scroll); - _topBarSuggestion->raise(); _topBarSuggestion->toggle(false, anim::type::instant); - _topBarSuggestion->heightValue( - ) | rpl::on_next([=, this](int h) { - if (_topBarSuggestionPlaceholder) { - _topBarSuggestionPlaceholder->resize( - _topBarSuggestionPlaceholder->width(), - h); - } - _scroll->setBarTopInset(h); - _topBarSuggestionHeightChanged.fire_copy(h); - }, _topBarSuggestion->entity()->lifetime()); - const auto pinToScroll = [this] { - if (_topBarSuggestion) { - _topBarSuggestion->resizeToWidth(_scroll->width()); - _topBarSuggestion->moveToLeft(0, 0); - } - }; - _scroll->sizeValue( - ) | rpl::to_empty | rpl::on_next( - pinToScroll, - _topBarSuggestion->entity()->lifetime()); - pinToScroll(); + MountTopBarSuggestion({ + .scroll = _scroll, + .innerList = _innerList, + .wrap = _topBarSuggestion.get(), + .placeholder = &_topBarSuggestionPlaceholder, + .heightChanged = [this](int h) { + _topBarSuggestionHeightChanged.fire_copy(h); + }, + }); _topBarSuggestion->toggle(true, anim::type::normal); }; diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index 64babfe07e..27eaa8c5f6 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "dialogs/ui/dialogs_stories_content.h" #include "dialogs/ui/dialogs_stories_list.h" #include "dialogs/ui/dialogs_suggestions.h" +#include "dialogs/ui/dialogs_top_bar_suggestion_content.h" #include "dialogs/dialogs_inner_widget.h" #include "dialogs/dialogs_search_from_controllers.h" #include "dialogs/dialogs_top_bar_suggestion.h" @@ -1132,38 +1133,16 @@ void Widget::setupTopBarSuggestions() { }) | rpl::flatten_latest() | rpl::on_next([=]( Ui::SlideWrap *raw) { if (raw) { - _topBarSuggestionPlaceholder.reset(_innerList->insert( - 0, - object_ptr(_innerList))); - _topBarSuggestionPlaceholder->paintOn([ - ph = _topBarSuggestionPlaceholder.get() - ](QPainter &p) { - p.fillRect(ph->rect(), st::dialogsBg); - }); _topBarSuggestion.reset(raw); - _topBarSuggestion->setParent(_scroll); - _topBarSuggestion->raise(); - _topBarSuggestion->heightValue( - ) | rpl::on_next([=](int h) { - if (_topBarSuggestionPlaceholder) { - _topBarSuggestionPlaceholder->resize( - _topBarSuggestionPlaceholder->width(), - h); - } - _scroll->setBarTopInset(h); - _topBarSuggestionHeightChanged.fire_copy(h); - }, _topBarSuggestion->entity()->lifetime()); - const auto pinToScroll = [=] { - if (_topBarSuggestion) { - _topBarSuggestion->resizeToWidth(_scroll->width()); - _topBarSuggestion->moveToLeft(0, 0); - } - }; - _scroll->sizeValue( - ) | rpl::to_empty | rpl::on_next( - pinToScroll, - _topBarSuggestion->entity()->lifetime()); - pinToScroll(); + MountTopBarSuggestion({ + .scroll = _scroll, + .innerList = _innerList, + .wrap = _topBarSuggestion.get(), + .placeholder = &_topBarSuggestionPlaceholder, + .heightChanged = [=](int h) { + _topBarSuggestionHeightChanged.fire_copy(h); + }, + }); } else { _topBarSuggestionPlaceholder = nullptr; _topBarSuggestion = nullptr; diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.cpp index d44432197b..6870d38097 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.cpp @@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/vertical_list.h" #include "ui/vertical_list.h" #include "ui/widgets/buttons.h" +#include "ui/widgets/elastic_scroll.h" #include "ui/widgets/labels.h" #include "ui/widgets/shadow.h" #include "ui/wrap/fade_wrap.h" @@ -42,14 +43,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Dialogs { namespace { -[[nodiscard]] int PillRadius() { - const auto padding = st::msgReplyPadding.top(); - return (padding - + st::semiboldTextStyle.font->height - + st::dialogsTopBarSuggestionAboutStyle.font->height - + padding) / 2; -} - [[nodiscard]] QString FormatUnconfirmedAuthMessage( const std::vector &list) { if (list.empty()) { @@ -86,6 +79,42 @@ namespace { } // namespace +int PillRadius() { + const auto padding = st::msgReplyPadding.top(); + return (padding + + st::semiboldTextStyle.font->height + + st::dialogsTopBarSuggestionAboutStyle.font->height + + padding) / 2; +} + +int PaintSuggestionBubbleBackground( + QPainter &p, + QRect outer, + const Ui::BoxShadow &shadow) { + const auto &margins = st::dialogsTopBarSuggestionMargins; + const auto pill = outer - margins; + PaintTopFade( + p, + outer.width(), + margins.top() + pill.height() / 2, + st::dialogsBg->c); + if (pill.isEmpty()) { + return 0; + } + const auto radius = std::min({ + PillRadius(), + pill.width() / 2, + pill.height() / 2, + }); + shadow.paint(p, pill, radius); + auto hq = PainterHighQualityEnabler(p); + p.setBrush(st::dialogsBg); + p.setPen(Qt::NoPen); + p.drawRoundedRect(pill, radius, radius); + PaintPillOutline(p, pill, radius); + return radius; +} + UnconfirmedAuthWrap::UnconfirmedAuthWrap( not_null parent, object_ptr &&child) @@ -161,27 +190,7 @@ not_null CreateUnconfirmedAuthContent( const auto content = wrap->entity(); const auto &margins = st::dialogsTopBarSuggestionMargins; content->paintOn([=](QPainter &p) { - const auto outer = content->rect(); - const auto pill = outer - margins; - PaintTopFade( - p, - outer.width(), - margins.top() + pill.height() / 2, - st::dialogsBg->c); - if (pill.isEmpty()) { - return; - } - const auto radius = std::min({ - PillRadius(), - pill.width() / 2, - pill.height() / 2, - }); - wrap->shadow().paint(p, pill, radius); - auto hq = PainterHighQualityEnabler(p); - p.setBrush(st::dialogsBg); - p.setPen(Qt::NoPen); - p.drawRoundedRect(pill, radius, radius); - PaintPillOutline(p, pill, radius); + PaintSuggestionBubbleBackground(p, content->rect(), wrap->shadow()); }); const auto &basePadding = st::dialogsUnconfirmedAuthPadding; @@ -356,28 +365,10 @@ void TopBarSuggestionContent::draw(QPainter &p) { const auto &margins = st::dialogsTopBarSuggestionMargins; const auto pill = outer - margins; - PaintTopFade( - p, - outer.width(), - margins.top() + pill.height() / 2, - st::dialogsBg->c); - + const auto radius = PaintSuggestionBubbleBackground(p, outer, _shadow); if (pill.isEmpty()) { return; } - const auto radius = std::min({ - PillRadius(), - pill.width() / 2, - pill.height() / 2, - }); - - _shadow.paint(p, pill, radius); - - auto hq = PainterHighQualityEnabler(p); - p.setBrush(st::dialogsBg); - p.setPen(Qt::NoPen); - p.drawRoundedRect(pill, radius, radius); - PaintPillOutline(p, pill, radius); auto clipPath = QPainterPath(); clipPath.addRoundedRect(pill, radius, radius); @@ -621,4 +612,43 @@ const style::TextStyle & TopBarSuggestionContent::contentTitleSt() const { return _contentTitleSt; } +void MountTopBarSuggestion(MountTopBarSuggestionArgs args) { + const auto scroll = args.scroll; + const auto innerList = args.innerList; + const auto wrap = args.wrap; + const auto placeholder = args.placeholder; + const auto heightChanged = std::move(args.heightChanged); + if (placeholder) { + placeholder->reset(innerList->insert( + 0, + object_ptr(innerList))); + const auto raw = placeholder->get(); + raw->paintOn([raw](QPainter &p) { + p.fillRect(raw->rect(), st::dialogsBg); + }); + } + wrap->setParent(scroll); + wrap->raise(); + wrap->heightValue() | rpl::on_next([=](int h) { + if (placeholder) { + if (const auto raw = placeholder->get()) { + raw->resize(raw->width(), h); + } + } + scroll->setBarTopInset(h); + if (heightChanged) { + heightChanged(h); + } + }, wrap->entity()->lifetime()); + const auto pinToScroll = [=] { + wrap->resizeToWidth(scroll->width()); + wrap->moveToLeft(0, 0); + }; + scroll->sizeValue( + ) | rpl::to_empty | rpl::on_next( + pinToScroll, + wrap->entity()->lifetime()); + pinToScroll(); +} + } // namespace Dialogs diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.h b/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.h index a68b798272..b8dd9f47db 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.h @@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Ui { class DynamicImage; +class ElasticScroll; class IconButton; } // namespace Ui @@ -27,6 +28,13 @@ struct UnreviewedAuth; namespace Dialogs { +[[nodiscard]] int PillRadius(); + +int PaintSuggestionBubbleBackground( + QPainter &p, + QRect outer, + const Ui::BoxShadow &shadow); + class UnconfirmedAuthWrap : public Ui::SlideWrap { public: UnconfirmedAuthWrap( @@ -126,4 +134,14 @@ private: }; +struct MountTopBarSuggestionArgs { + not_null scroll; + not_null innerList; + not_null*> wrap; + base::unique_qptr *placeholder = nullptr; + Fn heightChanged; +}; + +void MountTopBarSuggestion(MountTopBarSuggestionArgs args); + } // namespace Dialogs