Files
llmx/codex-rs/tui/src/text_block.rs
Michael Bolin ae1a83f095 feat: introduce CellWidget trait (#1148)
The motivation behind this PR is to make it so a `HistoryCell` is more
like a `WidgetRef` that knows how to render itself into a `Rect` so that
it can be backed by something other than a `Vec<Line>`. Because a
`HistoryCell` is intended to appear in a scrollable list, we want to
ensure the stack of cells can be scrolled one `Line` at a time even if
the `HistoryCell` is not backed by a `Vec<Line>` itself.

To this end, we introduce the `CellWidget` trait whose key method is:

```
fn render_window(&self, first_visible_line: usize, area: Rect, buf: &mut Buffer);
```

The `first_visible_line` param is what differs from
`WidgetRef::render_ref()`, as a `CellWidget` needs to know the offset
into its "full view" at which it should start rendering.

The bookkeeping in `ConversationHistoryWidget` has been updated
accordingly to ensure each `CellWidget` in the history is rendered
appropriately.
2025-05-28 14:03:19 -07:00

33 lines
1.1 KiB
Rust

use crate::cell_widget::CellWidget;
use ratatui::prelude::*;
/// A simple widget that just displays a list of `Line`s via a `Paragraph`.
/// This is the default rendering backend for most `HistoryCell` variants.
#[derive(Clone)]
pub(crate) struct TextBlock {
pub(crate) lines: Vec<Line<'static>>,
}
impl TextBlock {
pub(crate) fn new(lines: Vec<Line<'static>>) -> Self {
Self { lines }
}
}
impl CellWidget for TextBlock {
fn height(&self, width: u16) -> usize {
// Use the same wrapping configuration as ConversationHistoryWidget so
// measurement stays in sync with rendering.
ratatui::widgets::Paragraph::new(self.lines.clone())
.wrap(crate::conversation_history_widget::wrap_cfg())
.line_count(width)
}
fn render_window(&self, first_visible_line: usize, area: Rect, buf: &mut Buffer) {
ratatui::widgets::Paragraph::new(self.lines.clone())
.wrap(crate::conversation_history_widget::wrap_cfg())
.scroll((first_visible_line as u16, 0))
.render(area, buf);
}
}