refactor(console): phase 4b — extract ConsoleScrollController
Pull the auto-scroll concern out of ConsoleTab into a focused, ImGui-free
ConsoleScrollController (console_scroll_controller.{h,cpp}). It owns the three
coupled fields that were loose on the god-class — auto_scroll_, the wheel-up
cooldown, and the new-lines-while-scrolled-up backlog count — and the state
machine tying them together: wheel-up detaches + starts a cooldown, the cooldown
gates the at-bottom re-enable check, backlog counting happens only while
detached, and re-pinning (checkbox / jump pill / reaching the bottom) clears it.
The view keeps only what needs ImGui: it measures scroll position, hands the
controller a plain `atBottom` bool + frame delta, and issues the actual
SetScrollHereY. ConsoleTab loses three more members and all the scattered
auto-scroll bookkeeping collapses to scroll_.* calls.
Adds testConsoleScrollController: pinned start ignores backlog, wheel-up detach +
cooldown gating, re-enable only when at bottom, checkbox toggle semantics, and
the jump-to-bottom pill. Full-node + lite build clean; ctest green; source
hygiene clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include "ui/windows/console_input_model.h"
|
||||
#include "ui/windows/console_model.h"
|
||||
#include "ui/windows/console_output_model.h"
|
||||
#include "ui/windows/console_scroll_controller.h"
|
||||
#include "ui/windows/console_selection_controller.h"
|
||||
#include "ui/windows/console_tab_helpers.h"
|
||||
#include "ui/windows/console_text_layout.h"
|
||||
@@ -2338,6 +2339,64 @@ void testConsoleTextLayout()
|
||||
EXPECT_EQ(ExtractConsoleSelection(2, get2, std::vector<int>{0}, {0, 1}, {1, 3}), std::string("ello"));
|
||||
}
|
||||
|
||||
// ConsoleScrollController — auto-scroll state machine (pin, wheel-up cooldown, backlog).
|
||||
void testConsoleScrollController()
|
||||
{
|
||||
using dragonx::ui::ConsoleScrollController;
|
||||
|
||||
// Starts pinned to the bottom; new lines while pinned are not counted as a backlog.
|
||||
{
|
||||
ConsoleScrollController s;
|
||||
EXPECT_TRUE(s.autoScroll());
|
||||
s.onLinesAdded(5);
|
||||
EXPECT_EQ(s.newLines(), 0);
|
||||
}
|
||||
|
||||
// Wheel-up detaches, starts the cooldown, and begins counting backlog lines.
|
||||
{
|
||||
ConsoleScrollController s;
|
||||
s.onUserScrolledUp();
|
||||
EXPECT_FALSE(s.autoScroll());
|
||||
s.onLinesAdded(3);
|
||||
s.onLinesAdded(2);
|
||||
EXPECT_EQ(s.newLines(), 5);
|
||||
|
||||
// At-bottom is ignored until the cooldown elapses.
|
||||
s.considerReenable(true);
|
||||
EXPECT_FALSE(s.autoScroll());
|
||||
s.tickCooldown(ConsoleScrollController::kScrollUpCooldownSeconds + 0.01f);
|
||||
// Elapsed, but only re-pins when actually at the bottom.
|
||||
s.considerReenable(false);
|
||||
EXPECT_FALSE(s.autoScroll());
|
||||
s.considerReenable(true);
|
||||
EXPECT_TRUE(s.autoScroll());
|
||||
EXPECT_EQ(s.newLines(), 0); // re-pinning clears the backlog
|
||||
}
|
||||
|
||||
// Checkbox toggle: enabling clears the backlog, disabling preserves state.
|
||||
{
|
||||
ConsoleScrollController s;
|
||||
s.onUserScrolledUp();
|
||||
s.onLinesAdded(4);
|
||||
EXPECT_EQ(s.newLines(), 4);
|
||||
s.setAutoScroll(true);
|
||||
EXPECT_TRUE(s.autoScroll());
|
||||
EXPECT_EQ(s.newLines(), 0);
|
||||
s.setAutoScroll(false);
|
||||
EXPECT_FALSE(s.autoScroll());
|
||||
}
|
||||
|
||||
// Jump-to-bottom pill re-pins and clears the backlog.
|
||||
{
|
||||
ConsoleScrollController s;
|
||||
s.onUserScrolledUp();
|
||||
s.onLinesAdded(9);
|
||||
s.jumpToBottom();
|
||||
EXPECT_TRUE(s.autoScroll());
|
||||
EXPECT_EQ(s.newLines(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
// ConsoleSelectionController — anchor/caret state, ordering, select-all, eviction shift.
|
||||
void testConsoleSelectionController()
|
||||
{
|
||||
@@ -5192,6 +5251,7 @@ int main()
|
||||
testDaemonLifecycleAdapters();
|
||||
testConsoleTextLayout();
|
||||
testConsoleModel();
|
||||
testConsoleScrollController();
|
||||
testConsoleSelectionController();
|
||||
testRendererHelpers();
|
||||
testConsoleInputModel();
|
||||
|
||||
Reference in New Issue
Block a user