subconscious: use ScrollPane for history pane

Replace bare history_scroll: u16 with ScrollPaneState. The history
pane now uses ScrollPane for rendering, getting proper height caching
and scrollbar for free.

Also relax ScrollItem lifetime bounds from 'static to 'a so
non-static Lines (built on the fly during render) can be used.

Co-Authored-By: Kent Overstreet <kent.overstreet@gmail.com>
This commit is contained in:
ProofOfConcept 2026-04-11 01:34:39 -04:00 committed by Kent Overstreet
parent 2230fdf3c1
commit d18bf6243a
2 changed files with 14 additions and 12 deletions

View file

@ -22,19 +22,19 @@ pub trait ScrollItem {
// Blanket impls for common types
impl ScrollItem for Line<'static> {
impl<'a> ScrollItem for Line<'a> {
fn content(&self) -> Text<'_> {
Text::from(self.clone())
}
}
impl ScrollItem for Vec<Line<'static>> {
impl<'a> ScrollItem for Vec<Line<'a>> {
fn content(&self) -> Text<'_> {
Text::from(self.clone())
}
}
impl ScrollItem for Text<'static> {
impl<'a> ScrollItem for Text<'a> {
fn content(&self) -> Text<'_> {
self.clone()
}

View file

@ -28,7 +28,7 @@ pub(crate) struct SubconsciousScreen {
list_state: ListState,
output_tree: SectionTree,
context_tree: SectionTree,
history_scroll: u16,
history_scroll: super::scroll_pane::ScrollPaneState,
}
impl SubconsciousScreen {
@ -40,7 +40,7 @@ impl SubconsciousScreen {
list_state,
output_tree: SectionTree::new(),
context_tree: SectionTree::new(),
history_scroll: 0,
history_scroll: super::scroll_pane::ScrollPaneState::new(),
}
}
@ -88,10 +88,10 @@ impl ScreenView for SubconsciousScreen {
}
Pane::Outputs => self.output_tree.handle_nav(code, &output_sections, area.height),
Pane::History => match code {
KeyCode::Up => self.history_scroll = self.history_scroll.saturating_sub(3),
KeyCode::Down => self.history_scroll += 3,
KeyCode::PageUp => self.history_scroll = self.history_scroll.saturating_sub(20),
KeyCode::PageDown => self.history_scroll += 20,
KeyCode::Up => self.history_scroll.scroll_up(3),
KeyCode::Down => self.history_scroll.scroll_down(3),
KeyCode::PageUp => self.history_scroll.scroll_up(20),
KeyCode::PageDown => self.history_scroll.scroll_down(20),
_ => {}
}
Pane::Context => self.context_tree.handle_nav(code, &context_sections, area.height),
@ -146,7 +146,7 @@ impl SubconsciousScreen {
fn reset_pane_state(&mut self) {
self.output_tree = SectionTree::new();
self.context_tree = SectionTree::new();
self.history_scroll = 0;
self.history_scroll = super::scroll_pane::ScrollPaneState::new();
}
/// Get the agent Arc for the selected item, whether subconscious or unconscious.
@ -300,7 +300,7 @@ impl SubconsciousScreen {
render_scrollable(frame, area, lines, block, self.output_tree.scroll);
}
fn draw_history(&self, frame: &mut Frame, area: Rect, app: &App) {
fn draw_history(&mut self, frame: &mut Frame, area: Rect, app: &App) {
let dim = Style::default().fg(Color::DarkGray);
let key_style = Style::default().fg(Color::Yellow);
@ -345,7 +345,9 @@ impl SubconsciousScreen {
Style::default().fg(Color::DarkGray),
));
}
render_scrollable(frame, area, lines, block, self.history_scroll);
let widget = super::scroll_pane::ScrollPane::new(&lines)
.block(block);
frame.render_stateful_widget(widget, area, &mut self.history_scroll);
}
fn draw_context(