Fit the chain/params split to the chain's rows until it is dragged

The split between the chain list and the params sat at a fixed 300 px,
wrong for a short chain and for a long one alike. It now rests under the
chain's rows, growing with the chain up to eight stages before the list
scrolls. Once the user drags it, it stays put; a double-click on the
handle fits it to the rows again.

GtkPaned sizes the fixed pane from its minimum height, which is only the
drag floor here, so the fit is done by hand from the natural height.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Si
2026-09-23 22:21:51 +02:00
co-authored by Claude Opus 5.5
parent d0b5669f46
commit a01ada5372
3 changed files with 162 additions and 16 deletions
+36 -11
View File
@@ -185,16 +185,16 @@ void runTests(Gtk::Window& window) {
add->popdown();
pump();
// With the split dragged all the way down, the button must still work.
if (split != nullptr) split->set_position(10000);
pump();
add->popup();
pump();
check(menu->get_mapped(), "the menu opens with the split dragged to the bottom");
add->popdown();
pump();
if (split != nullptr) split->set_position(300);
pump();
std::vector<Gtk::ScrolledWindow*> listScrollers;
collect<Gtk::ScrolledWindow>(window, [&](Gtk::ScrolledWindow& s) {
return s.get_child() != nullptr && isAncestor(*s.get_child(), *chainList);
}, listScrollers);
auto* listScroller = listScrollers.empty() ? nullptr : listScrollers.back();
check(listScroller != nullptr && listScroller->get_propagate_natural_height() &&
listScroller->get_max_content_height() > 0,
"the chain list asks for the height of its rows, up to a cap");
const int emptySplit = split != nullptr ? split->get_position() : -1;
check(rowCount(*chainList) == 0, "the chain starts empty");
check(addFromMenu(*add, "Blur"), "picking Blur from the menu");
@@ -240,10 +240,35 @@ void runTests(Gtk::Window& window) {
check(!sources->get_visible(), "and the sources hide again");
std::cout << "many stages\n";
for (int i = 0; i < 12; ++i) addFromMenu(*add, effects[static_cast<std::size_t>(i) % effects.size()]->title());
for (int i = 0; i < 4; ++i) addFromMenu(*add, effects[static_cast<std::size_t>(i) % effects.size()]->title());
pump();
const int fewSplit = split != nullptr ? split->get_position() : -1;
check(split != nullptr && fewSplit > emptySplit,
"the split moves down as the chain grows");
for (int i = 4; i < 12; ++i) addFromMenu(*add, effects[static_cast<std::size_t>(i) % effects.size()]->title());
check(rowCount(*chainList) == 13, "the menu still works with a long chain");
check(addFromMenu(*add, effects.back()->title()) && rowCount(*chainList) == 14,
"including for the last effect in the menu");
pump();
const int longSplit = split != nullptr ? split->get_position() : -1;
check(longSplit > fewSplit && listScroller != nullptr &&
listScroller->get_height() <= listScroller->get_max_content_height() + 2,
"up to the cap, past which the list scrolls");
if (split != nullptr) split->set_position(emptySplit + 20);
pump();
addFromMenu(*add, effects.front()->title());
pump();
check(split != nullptr && split->get_position() == emptySplit + 20,
"once dragged, the split stays put as the chain grows");
// With the split dragged all the way down, the button must still work.
if (split != nullptr) split->set_position(10000);
pump();
add->popup();
pump();
check(menu->get_mapped(), "the menu opens with the split dragged to the bottom");
add->popdown();
pump();
}
} // namespace