From d18bf6243a54fa5402e7847203042c5199ddc2bc Mon Sep 17 00:00:00 2001 From: ProofOfConcept Date: Sat, 11 Apr 2026 01:34:39 -0400 Subject: [PATCH] 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 --- src/user/scroll_pane.rs | 6 +++--- src/user/subconscious.rs | 20 +++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/user/scroll_pane.rs b/src/user/scroll_pane.rs index 53106da..37042d6 100644 --- a/src/user/scroll_pane.rs +++ b/src/user/scroll_pane.rs @@ -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> { +impl<'a> ScrollItem for Vec> { 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() } diff --git a/src/user/subconscious.rs b/src/user/subconscious.rs index 8c76b1d..3fade9a 100644 --- a/src/user/subconscious.rs +++ b/src/user/subconscious.rs @@ -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(