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.
This commit is contained in:
32
codex-rs/tui/src/text_block.rs
Normal file
32
codex-rs/tui/src/text_block.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user