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.
21 lines
1.0 KiB
Rust
21 lines
1.0 KiB
Rust
use ratatui::prelude::*;
|
||
|
||
/// Trait implemented by every type that can live inside the conversation
|
||
/// history list. It provides two primitives that the parent scroll-view
|
||
/// needs: how *tall* the widget is at a given width and how to render an
|
||
/// arbitrary contiguous *window* of that widget.
|
||
///
|
||
/// The `first_visible_line` argument to [`render_window`] allows partial
|
||
/// rendering when the top of the widget is scrolled off-screen. The caller
|
||
/// guarantees that `first_visible_line + area.height as usize` never exceeds
|
||
/// the total height previously returned by [`height`].
|
||
pub(crate) trait CellWidget {
|
||
/// Total height measured in wrapped terminal lines when drawn with the
|
||
/// given *content* width (no scrollbar column included).
|
||
fn height(&self, width: u16) -> usize;
|
||
|
||
/// Render a *window* that starts `first_visible_line` lines below the top
|
||
/// of the widget. The window’s size is given by `area`.
|
||
fn render_window(&self, first_visible_line: usize, area: Rect, buf: &mut Buffer);
|
||
}
|