mirror of
https://github.com/ratatui-org/ratatui
synced 2024-11-10 07:04:17 +00:00
feat(widgets): Rename StatefulWidget::render
to render_stateful
This change renames the `StatefulWidget::render` method to `render_stateful` to avoid conflicts with the `Widget::render` method. Often both the `Widget` and `StatefulWidget` traits are in scope, and when calling the `render` method on a `StatefulWidget` the compiler cannot determine which trait to use. This change resolves that issue by renaming the `StatefulWidget::render` method to `render_stateful`. The `StatefulWidget::render` method is still available, but it is deprecated. A default implementation of `render_stateful` is provided that calls the deprecated `render` method. Callers should update their code to use `render_stateful` instead of `render`. implementors of the `StatefulWidget` trait should update their implementations to implement `render_stateful` instead of `render`, and provide an implementation of `render` that calls `render_stateful`. This change is non-breaking. The deprecated `render` method will be removed in a future release of Ratatui (likely 0.29.0). Addresses part of a problem raised in <https://github.com/ratatui-org/ratatui/issues/996>
This commit is contained in:
parent
4bfdc15b80
commit
fa8001f21d
12 changed files with 132 additions and 64 deletions
|
@ -63,7 +63,7 @@ fn render_stateful(bencher: &mut Bencher, list: &List, mut state: ListState) {
|
|||
bencher.iter_batched(
|
||||
|| list.to_owned(),
|
||||
|bench_list| {
|
||||
StatefulWidget::render(bench_list, buffer.area, &mut buffer, &mut state);
|
||||
bench_list.render_stateful(buffer.area, &mut buffer, &mut state);
|
||||
},
|
||||
BatchSize::LargeInput,
|
||||
);
|
||||
|
|
|
@ -256,7 +256,8 @@ impl App {
|
|||
if scrollbar_needed {
|
||||
let mut state = ScrollbarState::new(self.max_scroll_offset as usize)
|
||||
.position(self.scroll_offset as usize);
|
||||
Scrollbar::new(ScrollbarOrientation::VerticalRight).render(area, buf, &mut state);
|
||||
Scrollbar::new(ScrollbarOrientation::VerticalRight)
|
||||
.render_stateful(area, buf, &mut state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,15 +104,12 @@ fn render_inbox(selected_index: usize, area: Rect, buf: &mut Buffer) {
|
|||
})
|
||||
.collect_vec();
|
||||
let mut state = ListState::default().with_selected(Some(selected_index));
|
||||
StatefulWidget::render(
|
||||
List::new(items)
|
||||
.style(theme.inbox)
|
||||
.highlight_style(theme.selected_item)
|
||||
.highlight_symbol(highlight_symbol),
|
||||
inbox,
|
||||
buf,
|
||||
&mut state,
|
||||
);
|
||||
|
||||
List::new(items)
|
||||
.style(theme.inbox)
|
||||
.highlight_style(theme.selected_item)
|
||||
.highlight_symbol(highlight_symbol)
|
||||
.render_stateful(inbox, buf, &mut state);
|
||||
let mut scrollbar_state = ScrollbarState::default()
|
||||
.content_length(EMAILS.len())
|
||||
.position(selected_index);
|
||||
|
@ -121,7 +118,7 @@ fn render_inbox(selected_index: usize, area: Rect, buf: &mut Buffer) {
|
|||
.end_symbol(None)
|
||||
.track_symbol(None)
|
||||
.thumb_symbol("▐")
|
||||
.render(inbox, buf, &mut scrollbar_state);
|
||||
.render_stateful(inbox, buf, &mut scrollbar_state);
|
||||
}
|
||||
|
||||
fn render_email(selected_index: usize, area: Rect, buf: &mut Buffer) {
|
||||
|
|
|
@ -160,15 +160,12 @@ fn render_ingredients(selected_row: usize, area: Rect, buf: &mut Buffer) {
|
|||
let mut state = TableState::default().with_selected(Some(selected_row));
|
||||
let rows = INGREDIENTS.iter().copied();
|
||||
let theme = THEME.recipe;
|
||||
StatefulWidget::render(
|
||||
Table::new(rows, [Constraint::Length(7), Constraint::Length(30)])
|
||||
.block(Block::new().style(theme.ingredients))
|
||||
.header(Row::new(vec!["Qty", "Ingredient"]).style(theme.ingredients_header))
|
||||
.highlight_style(Style::new().light_yellow()),
|
||||
area,
|
||||
buf,
|
||||
&mut state,
|
||||
);
|
||||
|
||||
Table::new(rows, [Constraint::Length(7), Constraint::Length(30)])
|
||||
.block(Block::new().style(theme.ingredients))
|
||||
.header(Row::new(vec!["Qty", "Ingredient"]).style(theme.ingredients_header))
|
||||
.highlight_style(Style::new().light_yellow())
|
||||
.render_stateful(area, buf, &mut state);
|
||||
}
|
||||
|
||||
fn render_scrollbar(position: usize, area: Rect, buf: &mut Buffer) {
|
||||
|
@ -181,5 +178,5 @@ fn render_scrollbar(position: usize, area: Rect, buf: &mut Buffer) {
|
|||
.end_symbol(None)
|
||||
.track_symbol(None)
|
||||
.thumb_symbol("▐")
|
||||
.render(area, buf, &mut state);
|
||||
.render_stateful(area, buf, &mut state);
|
||||
}
|
||||
|
|
|
@ -60,15 +60,12 @@ fn render_hops(selected_row: usize, area: Rect, buf: &mut Buffer) {
|
|||
.padding(Padding::new(1, 1, 1, 1))
|
||||
.title_alignment(Alignment::Center)
|
||||
.title("Traceroute bad.horse".bold().white());
|
||||
StatefulWidget::render(
|
||||
Table::new(rows, [Constraint::Max(100), Constraint::Length(15)])
|
||||
.header(Row::new(vec!["Host", "Address"]).set_style(THEME.traceroute.header))
|
||||
.highlight_style(THEME.traceroute.selected)
|
||||
.block(block),
|
||||
area,
|
||||
buf,
|
||||
&mut state,
|
||||
);
|
||||
|
||||
Table::new(rows, [Constraint::Max(100), Constraint::Length(15)])
|
||||
.header(Row::new(vec!["Host", "Address"]).set_style(THEME.traceroute.header))
|
||||
.highlight_style(THEME.traceroute.selected)
|
||||
.block(block)
|
||||
.render_stateful(area, buf, &mut state);
|
||||
let mut scrollbar_state = ScrollbarState::default()
|
||||
.content_length(HOPS.len())
|
||||
.position(selected_row);
|
||||
|
@ -84,7 +81,7 @@ fn render_hops(selected_row: usize, area: Rect, buf: &mut Buffer) {
|
|||
.end_symbol(None)
|
||||
.track_symbol(None)
|
||||
.thumb_symbol("▌")
|
||||
.render(area, buf, &mut scrollbar_state);
|
||||
.render_stateful(area, buf, &mut scrollbar_state);
|
||||
}
|
||||
|
||||
pub fn render_ping(progress: usize, area: Rect, buf: &mut Buffer) {
|
||||
|
|
|
@ -331,7 +331,7 @@ impl App {
|
|||
|
||||
let mut spacing = self.spacing;
|
||||
self.selected_tab
|
||||
.render(content_area, &mut demo_buf, &mut spacing);
|
||||
.render_stateful(content_area, &mut demo_buf, &mut spacing);
|
||||
|
||||
let visible_content = demo_buf
|
||||
.content
|
||||
|
@ -348,7 +348,8 @@ impl App {
|
|||
let area = area.intersection(buf.area);
|
||||
let mut state = ScrollbarState::new(max_scroll_offset() as usize)
|
||||
.position(self.scroll_offset as usize);
|
||||
Scrollbar::new(ScrollbarOrientation::VerticalRight).render(area, buf, &mut state);
|
||||
Scrollbar::new(ScrollbarOrientation::VerticalRight)
|
||||
.render_stateful(area, buf, &mut state);
|
||||
}
|
||||
scrollbar_needed
|
||||
}
|
||||
|
@ -387,8 +388,15 @@ impl SelectedTab {
|
|||
|
||||
impl StatefulWidget for SelectedTab {
|
||||
type State = u16;
|
||||
fn render(self, area: Rect, buf: &mut Buffer, spacing: &mut Self::State) {
|
||||
let spacing = *spacing;
|
||||
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
|
||||
self.render_stateful(area, buf, state);
|
||||
}
|
||||
|
||||
fn render_stateful(self, area: Rect, buf: &mut Buffer, state: &mut Self::State)
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let spacing = *state;
|
||||
match self {
|
||||
Self::Legacy => Self::render_examples(area, buf, Flex::Legacy, spacing),
|
||||
Self::Start => Self::render_examples(area, buf, Flex::Start, spacing),
|
||||
|
|
|
@ -249,9 +249,7 @@ impl App {
|
|||
.highlight_spacing(HighlightSpacing::Always);
|
||||
|
||||
// We can now render the item list
|
||||
// (look careful we are using StatefulWidget's render.)
|
||||
// ratatui::widgets::StatefulWidget::render as stateful_render
|
||||
StatefulWidget::render(items, inner_area, buf, &mut self.items.state);
|
||||
items.render_stateful(inner_area, buf, &mut self.items.state);
|
||||
}
|
||||
|
||||
fn render_info(&self, area: Rect, buf: &mut Buffer) {
|
||||
|
|
|
@ -99,7 +99,7 @@ impl Frame<'_> {
|
|||
widget.render_ref(area, self.buffer);
|
||||
}
|
||||
|
||||
/// Render a [`StatefulWidget`] to the current buffer using [`StatefulWidget::render`].
|
||||
/// Render a [`StatefulWidget`] to the current buffer using [`StatefulWidget::render_stateful`].
|
||||
///
|
||||
/// Usually the area argument is the size of the current frame or a sub-area of the current
|
||||
/// frame (which can be obtained using [`Layout`] to split the total area).
|
||||
|
@ -125,7 +125,7 @@ impl Frame<'_> {
|
|||
where
|
||||
W: StatefulWidget,
|
||||
{
|
||||
widget.render(area, self.buffer, state);
|
||||
widget.render_stateful(area, self.buffer, state);
|
||||
}
|
||||
|
||||
/// Render a [`StatefulWidgetRef`] to the current buffer using
|
||||
|
|
|
@ -221,9 +221,43 @@ pub trait StatefulWidget {
|
|||
///
|
||||
/// If you don't need this then you probably want to implement [`Widget`] instead.
|
||||
type State;
|
||||
|
||||
/// Renders the the widget into the buffer using the provided state.
|
||||
///
|
||||
/// Draws the current state of the widget in the given buffer. That is the only method required
|
||||
/// to implement a custom stateful widget.
|
||||
///
|
||||
/// When both `Widget` and `StatefulWidget` are in scope, this method conflicts with the
|
||||
/// `render` method from the `Widget` trait. Prior to Ratatui 0.27.0, this conflict caused
|
||||
/// apps to have to qualify the method call when using the `StatefulWidget` trait. To avoid
|
||||
/// this, the `render` method is deprecated and replaced with a new method called
|
||||
/// `render_stateful`. This new method does not conflict with the `render` method from the
|
||||
/// `Widget` trait.
|
||||
///
|
||||
/// This method will be removed in a future release (likely Ratatui 0.29.0). Callers should
|
||||
/// update their code to use the `render_stateful` method instead. Widget implementors may
|
||||
/// either:
|
||||
/// - Implement the `render` method, and change the name of the method to `render_stateful` when
|
||||
/// the `render` method is removed. A default implementation of `render_stateful` is provided
|
||||
/// that calls `render`.
|
||||
/// - Implement the `render_stateful` method directly and add a temporary implementation of
|
||||
/// `render` that calls `render_stateful` until the `render` method is removed.
|
||||
#[deprecated(note = "Use `render_stateful` instead")]
|
||||
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State);
|
||||
|
||||
/// Renders the the widget into the buffer using the provided state.
|
||||
///
|
||||
/// This method replaces the `render` method with a name that does not conflict with the
|
||||
/// `render` method from the `Widget` trait. (This conflict causes apps to have to specifially
|
||||
/// disambiguate the method call when using the `StatefulWidget` trait in situations where both
|
||||
/// traits are in scope.)
|
||||
fn render_stateful(self, area: Rect, buf: &mut Buffer, state: &mut Self::State)
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
#[allow(deprecated)]
|
||||
self.render(area, buf, state);
|
||||
}
|
||||
}
|
||||
|
||||
/// A `WidgetRef` is a trait that allows rendering a widget by reference.
|
||||
|
@ -387,6 +421,13 @@ impl<W: WidgetRef> WidgetRef for Option<W> {
|
|||
/// impl StatefulWidget for PersonalGreeting {
|
||||
/// type State = String;
|
||||
/// fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
|
||||
/// self.render_stateful(area, buf, state);
|
||||
/// }
|
||||
///
|
||||
/// fn render_stateful(self, area: Rect, buf: &mut Buffer, state: &mut Self::State)
|
||||
/// where
|
||||
/// Self: Sized,
|
||||
/// {
|
||||
/// (&self).render_ref(area, buf, state);
|
||||
/// }
|
||||
/// }
|
||||
|
@ -571,7 +612,7 @@ mod tests {
|
|||
#[rstest]
|
||||
fn render(mut buf: Buffer, mut state: String) {
|
||||
let widget = PersonalGreeting;
|
||||
widget.render(buf.area, &mut buf, &mut state);
|
||||
widget.render_stateful(buf.area, &mut buf, &mut state);
|
||||
assert_eq!(buf, Buffer::with_lines(["Hello world "]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -862,6 +862,13 @@ impl StatefulWidget for List<'_> {
|
|||
type State = ListState;
|
||||
|
||||
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
|
||||
self.render_stateful(area, buf, state);
|
||||
}
|
||||
|
||||
fn render_stateful(self, area: Rect, buf: &mut Buffer, state: &mut Self::State)
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
StatefulWidgetRef::render_ref(&self, area, buf, state);
|
||||
}
|
||||
}
|
||||
|
@ -869,7 +876,15 @@ impl StatefulWidget for List<'_> {
|
|||
// Note: remove this when StatefulWidgetRef is stabilized and replace with the blanket impl
|
||||
impl StatefulWidget for &List<'_> {
|
||||
type State = ListState;
|
||||
|
||||
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
|
||||
self.render_stateful(area, buf, state);
|
||||
}
|
||||
|
||||
fn render_stateful(self, area: Rect, buf: &mut Buffer, state: &mut Self::State)
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
StatefulWidgetRef::render_ref(self, area, buf, state);
|
||||
}
|
||||
}
|
||||
|
@ -1162,7 +1177,7 @@ mod tests {
|
|||
height: u16,
|
||||
) -> Buffer {
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, width, height));
|
||||
StatefulWidget::render(widget, buffer.area, &mut buffer, state);
|
||||
widget.render_stateful(buffer.area, &mut buffer, state);
|
||||
buffer
|
||||
}
|
||||
|
||||
|
@ -1222,7 +1237,7 @@ mod tests {
|
|||
let list = List::new(items.to_owned()).highlight_symbol(">>");
|
||||
let mut state = ListState::default().with_selected(selected);
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 5));
|
||||
StatefulWidget::render(list, buffer.area, &mut buffer, &mut state);
|
||||
list.render_stateful(buffer.area, &mut buffer, &mut state);
|
||||
assert_eq!(buffer, Buffer::with_lines(expected));
|
||||
}
|
||||
|
||||
|
@ -2121,7 +2136,7 @@ mod tests {
|
|||
let list = List::new([item]).highlight_symbol(highlight_symbol);
|
||||
let mut state = ListState::default();
|
||||
state.select(Some(0));
|
||||
StatefulWidget::render(list, single_line_buf.area, &mut single_line_buf, &mut state);
|
||||
list.render_stateful(single_line_buf.area, &mut single_line_buf, &mut state);
|
||||
assert_eq!(single_line_buf, Buffer::with_lines([expected]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -680,7 +680,7 @@ mod tests {
|
|||
) {
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, expected.width() as u16, 1));
|
||||
let mut state = ScrollbarState::new(content_length).position(position);
|
||||
scrollbar_no_arrows.render(buffer.area, &mut buffer, &mut state);
|
||||
scrollbar_no_arrows.render_stateful(buffer.area, &mut buffer, &mut state);
|
||||
assert_eq!(buffer, Buffer::with_lines([expected]));
|
||||
}
|
||||
|
||||
|
@ -703,7 +703,7 @@ mod tests {
|
|||
) {
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, expected.width() as u16, 1));
|
||||
let mut state = ScrollbarState::new(content_length).position(position);
|
||||
scrollbar_no_arrows.render(buffer.area, &mut buffer, &mut state);
|
||||
scrollbar_no_arrows.render_stateful(buffer.area, &mut buffer, &mut state);
|
||||
assert_eq!(buffer, Buffer::with_lines([expected]));
|
||||
}
|
||||
|
||||
|
@ -718,7 +718,7 @@ mod tests {
|
|||
let size = expected.width();
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, size as u16, 1));
|
||||
let mut state = ScrollbarState::new(content_length).position(position);
|
||||
scrollbar_no_arrows.render(buffer.area, &mut buffer, &mut state);
|
||||
scrollbar_no_arrows.render_stateful(buffer.area, &mut buffer, &mut state);
|
||||
assert_eq!(buffer, Buffer::with_lines([expected]));
|
||||
}
|
||||
|
||||
|
@ -735,7 +735,7 @@ mod tests {
|
|||
let size = expected.width();
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, size as u16, 1));
|
||||
let mut state = ScrollbarState::new(content_length).position(position);
|
||||
scrollbar_no_arrows.render(buffer.area, &mut buffer, &mut state);
|
||||
scrollbar_no_arrows.render_stateful(buffer.area, &mut buffer, &mut state);
|
||||
assert_eq!(buffer, Buffer::with_lines([expected]));
|
||||
}
|
||||
|
||||
|
@ -751,7 +751,7 @@ mod tests {
|
|||
let size = expected.width();
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, size as u16, 1));
|
||||
let mut state = ScrollbarState::new(content_length).position(position);
|
||||
scrollbar_no_arrows.render(buffer.area, &mut buffer, &mut state);
|
||||
scrollbar_no_arrows.render_stateful(buffer.area, &mut buffer, &mut state);
|
||||
assert_eq!(buffer, Buffer::with_lines([expected]));
|
||||
}
|
||||
|
||||
|
@ -778,7 +778,7 @@ mod tests {
|
|||
Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
|
||||
.begin_symbol(None)
|
||||
.end_symbol(None)
|
||||
.render(buffer.area, &mut buffer, &mut state);
|
||||
.render_stateful(buffer.area, &mut buffer, &mut state);
|
||||
assert_eq!(buffer, Buffer::with_lines([expected]));
|
||||
}
|
||||
|
||||
|
@ -806,7 +806,7 @@ mod tests {
|
|||
.track_symbol(None)
|
||||
.begin_symbol(None)
|
||||
.end_symbol(None)
|
||||
.render(buffer.area, &mut buffer, &mut state);
|
||||
.render_stateful(buffer.area, &mut buffer, &mut state);
|
||||
assert_eq!(buffer, Buffer::with_lines([expected]));
|
||||
}
|
||||
|
||||
|
@ -837,7 +837,7 @@ mod tests {
|
|||
.track_symbol(None)
|
||||
.begin_symbol(None)
|
||||
.end_symbol(None)
|
||||
.render(buffer.area, &mut buffer, &mut state);
|
||||
.render_stateful(buffer.area, &mut buffer, &mut state);
|
||||
assert_eq!(buffer, Buffer::with_lines([expected]));
|
||||
}
|
||||
|
||||
|
@ -868,7 +868,7 @@ mod tests {
|
|||
.end_symbol(Some(">"))
|
||||
.track_symbol(Some("-"))
|
||||
.thumb_symbol("#")
|
||||
.render(buffer.area, &mut buffer, &mut state);
|
||||
.render_stateful(buffer.area, &mut buffer, &mut state);
|
||||
assert_eq!(buffer, Buffer::with_lines([expected]));
|
||||
}
|
||||
|
||||
|
@ -895,7 +895,7 @@ mod tests {
|
|||
Scrollbar::new(ScrollbarOrientation::HorizontalBottom)
|
||||
.begin_symbol(None)
|
||||
.end_symbol(None)
|
||||
.render(buffer.area, &mut buffer, &mut state);
|
||||
.render_stateful(buffer.area, &mut buffer, &mut state);
|
||||
let empty_string = " ".repeat(size as usize);
|
||||
assert_eq!(buffer, Buffer::with_lines([&empty_string, expected]));
|
||||
}
|
||||
|
@ -923,7 +923,7 @@ mod tests {
|
|||
Scrollbar::new(ScrollbarOrientation::HorizontalTop)
|
||||
.begin_symbol(None)
|
||||
.end_symbol(None)
|
||||
.render(buffer.area, &mut buffer, &mut state);
|
||||
.render_stateful(buffer.area, &mut buffer, &mut state);
|
||||
let empty_string = " ".repeat(size as usize);
|
||||
assert_eq!(buffer, Buffer::with_lines([expected, &empty_string]));
|
||||
}
|
||||
|
@ -953,7 +953,7 @@ mod tests {
|
|||
.end_symbol(Some(">"))
|
||||
.track_symbol(Some("-"))
|
||||
.thumb_symbol("#")
|
||||
.render(buffer.area, &mut buffer, &mut state);
|
||||
.render_stateful(buffer.area, &mut buffer, &mut state);
|
||||
let bar = expected.chars().map(|c| format!("{c} "));
|
||||
assert_eq!(buffer, Buffer::with_lines(bar));
|
||||
}
|
||||
|
@ -983,7 +983,7 @@ mod tests {
|
|||
.end_symbol(Some(">"))
|
||||
.track_symbol(Some("-"))
|
||||
.thumb_symbol("#")
|
||||
.render(buffer.area, &mut buffer, &mut state);
|
||||
.render_stateful(buffer.area, &mut buffer, &mut state);
|
||||
let bar = expected.chars().map(|c| format!(" {c}"));
|
||||
assert_eq!(buffer, Buffer::with_lines(bar));
|
||||
}
|
||||
|
@ -1011,7 +1011,7 @@ mod tests {
|
|||
let mut state = ScrollbarState::new(content_length)
|
||||
.position(position)
|
||||
.viewport_content_length(2);
|
||||
scrollbar_no_arrows.render(buffer.area, &mut buffer, &mut state);
|
||||
scrollbar_no_arrows.render_stateful(buffer.area, &mut buffer, &mut state);
|
||||
assert_eq!(buffer, Buffer::with_lines([expected]));
|
||||
}
|
||||
|
||||
|
@ -1040,7 +1040,7 @@ mod tests {
|
|||
let mut state = ScrollbarState::new(content_length)
|
||||
.position(position)
|
||||
.viewport_content_length(2);
|
||||
scrollbar_no_arrows.render(buffer.area, &mut buffer, &mut state);
|
||||
scrollbar_no_arrows.render_stateful(buffer.area, &mut buffer, &mut state);
|
||||
assert_eq!(buffer, Buffer::with_lines([expected]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -580,7 +580,7 @@ impl Widget for Table<'_> {
|
|||
impl WidgetRef for Table<'_> {
|
||||
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
|
||||
let mut state = TableState::default();
|
||||
StatefulWidget::render(self, area, buf, &mut state);
|
||||
self.render_stateful(area, buf, &mut state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -588,7 +588,14 @@ impl StatefulWidget for Table<'_> {
|
|||
type State = TableState;
|
||||
|
||||
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
|
||||
StatefulWidget::render(&self, area, buf, state);
|
||||
self.render_stateful(area, buf, state);
|
||||
}
|
||||
|
||||
fn render_stateful(self, area: Rect, buf: &mut Buffer, state: &mut Self::State)
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
(&self).render_stateful(area, buf, state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -596,6 +603,13 @@ impl StatefulWidget for Table<'_> {
|
|||
impl StatefulWidget for &Table<'_> {
|
||||
type State = TableState;
|
||||
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
|
||||
self.render_stateful(area, buf, state);
|
||||
}
|
||||
|
||||
fn render_stateful(self, area: Rect, buf: &mut Buffer, state: &mut Self::State)
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
StatefulWidgetRef::render_ref(self, area, buf, state);
|
||||
}
|
||||
}
|
||||
|
@ -1189,7 +1203,7 @@ mod tests {
|
|||
.highlight_style(Style::new().red())
|
||||
.highlight_symbol(">>");
|
||||
let mut state = TableState::new().with_selected(0);
|
||||
StatefulWidget::render(table, Rect::new(0, 0, 15, 3), &mut buf, &mut state);
|
||||
table.render_stateful(Rect::new(0, 0, 15, 3), &mut buf, &mut state);
|
||||
let expected = Buffer::with_lines([
|
||||
">>Cell1 Cell2 ".red(),
|
||||
" Cell3 Cell4 ".into(),
|
||||
|
@ -1414,7 +1428,7 @@ mod tests {
|
|||
let area = Rect::new(0, 0, columns, 3);
|
||||
let mut buf = Buffer::empty(area);
|
||||
let mut state = TableState::default().with_selected(selection);
|
||||
StatefulWidget::render(table, area, &mut buf, &mut state);
|
||||
table.render_stateful(area, &mut buf, &mut state);
|
||||
assert_eq!(buf, Buffer::with_lines(expected));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue