Fix popup menu with variable item height.

This commit is contained in:
John Preston 2022-07-26 18:31:20 +03:00
parent 14f5a828fc
commit 4ff70e7dff

View file

@ -148,29 +148,44 @@ not_null<QAction*> Menu::addAction(base::unique_qptr<ItemBase> widget) {
const auto raw = widget.get(); const auto raw = widget.get();
_actionWidgets.push_back(std::move(widget)); _actionWidgets.push_back(std::move(widget));
rpl::combine( const auto recountWidth = [=] {
raw->minWidthValue(), return _forceWidth
raw->heightValue()
) | rpl::start_with_next([=] {
const auto newWidth = _forceWidth
? _forceWidth ? _forceWidth
: std::clamp( : std::clamp(
_actionWidgets.empty() (_actionWidgets.empty()
? 0 ? 0
: (*ranges::max_element( : (*ranges::max_element(
_actionWidgets, _actionWidgets,
std::less<>(), std::less<>(),
&ItemBase::minWidth))->minWidth(), &ItemBase::minWidth))->minWidth()),
_st.widthMin, _st.widthMin,
_st.widthMax); _st.widthMax);
const auto newHeight = ranges::accumulate( };
_actionWidgets, const auto recountHeight = [=] {
0, auto result = 0;
ranges::plus(), for (const auto &widget : _actionWidgets) {
&ItemBase::height); if (widget->y() != result) {
resizeFromInner(newWidth, newHeight); widget->move(0, result);
}
result += widget->height();
}
return result;
};
raw->minWidthValue(
) | rpl::skip(1) | rpl::filter([=] {
return !_forceWidth;
}) | rpl::start_with_next([=] {
resizeFromInner(recountWidth(), height());
}, raw->lifetime()); }, raw->lifetime());
raw->heightValue(
) | rpl::skip(1) | rpl::start_with_next([=] {
resizeFromInner(width(), recountHeight());
}, raw->lifetime());
resizeFromInner(recountWidth(), recountHeight());
updateSelected(QCursor::pos()); updateSelected(QCursor::pos());
return action; return action;
@ -204,11 +219,10 @@ bool Menu::empty() const {
} }
void Menu::resizeFromInner(int w, int h) { void Menu::resizeFromInner(int w, int h) {
if ((w == width()) && (h == height())) { if (const auto s = QSize(w, h); s != size()) {
return; resize(s);
_resizesFromInner.fire({});
} }
resize(w, h);
_resizesFromInner.fire({});
} }
rpl::producer<> Menu::resizesFromInner() const { rpl::producer<> Menu::resizesFromInner() const {