1
0
зеркало из https://github.com/glebtv/tui-textarea.git synced 2026-09-03 22:35:50 +03:00

directly implement Widget for &TextArea (fix #78)

Этот коммит содержится в:
rhysd
2024-08-02 15:53:48 +09:00
родитель dea5b03335
Коммит c99108bf45
20 изменённых файлов: 134 добавлений и 116 удалений

Просмотреть файл

@@ -211,10 +211,8 @@ loop {
term.draw(|f| {
// Get `ratatui::layout::Rect` where the editor should be rendered
let rect = ...;
// `TextArea::widget` builds a widget to render the editor with tui
let widget = textarea.widget();
// Render the widget in terminal screen
f.render_widget(widget, rect);
// Render the textarea in terminal screen
f.render_widget(&textarea, rect);
})?;
if let Event::Key(key) = read()? {
@@ -234,8 +232,7 @@ println!("Lines: {:?}", textarea.lines());
`TextArea` is an instance to manage the editor state. By default, it disables line numbers and highlights cursor line
with underline.
`TextArea::widget()` builds a widget to render the current state of the editor. Create the widget and render it on each
tick of event loop.
`&TextArea` reference implements ratatui's `Widget` trait. Render it on every tick of event loop.
`TextArea::input()` receives inputs from tui backends. The method can take key events from backends such as
`crossterm::event::KeyEvent` or `termion::event::Key` directly if the features are enabled. The method handles default
@@ -440,7 +437,7 @@ tui-textarea = { version = "*", features = ["search"] }
### Single-line input like `<input>` in HTML
To use `TextArea` for single-line input widget like `<input>` in HTML, ignore all key mappings which inserts newline.
To use `TextArea` for a single-line input widget like `<input>` in HTML, ignore all key mappings which inserts newline.
```rust,ignore
use crossterm::event::{Event, read};
@@ -628,9 +625,8 @@ loop {
term.draw(|f| {
let rects = ...;
for (editor, rect) in editors.iter_mut().zip(rects.into_iter()) {
let widget = editor.widget();
f.render_widget(widget, rect);
for (editor, rect) in editors.iter().zip(rects.into_iter()) {
f.render_widget(editor, rect);
}
})?;

Просмотреть файл

@@ -116,7 +116,6 @@ pub trait TerminalExt {
impl TerminalExt for Terminal<DummyBackend> {
#[inline]
fn draw_textarea(&mut self, textarea: &TextArea<'_>) {
self.draw(|f| f.render_widget(textarea.widget(), f.size()))
.unwrap();
self.draw(|f| f.render_widget(textarea, f.size())).unwrap();
}
}

Просмотреть файл

@@ -188,13 +188,12 @@ impl<'a> Editor<'a> {
let chunks = layout.split(f.size());
if search_height > 0 {
f.render_widget(self.search.textarea.widget(), chunks[0]);
f.render_widget(&self.search.textarea, chunks[0]);
}
let buffer = &self.buffers[self.current];
let textarea = &buffer.textarea;
let widget = textarea.widget();
f.render_widget(widget, chunks[1]);
f.render_widget(&textarea, chunks[1]);
// Render status line
let modified = if buffer.modified { " [modified]" } else { "" };

Просмотреть файл

@@ -26,7 +26,7 @@ fn main() -> io::Result<()> {
loop {
term.draw(|f| {
f.render_widget(textarea.widget(), f.size());
f.render_widget(&textarea, f.size());
})?;
match crossterm::event::read()?.into() {
Input { key: Key::Esc, .. } => break,

Просмотреть файл

@@ -31,8 +31,7 @@ fn main() -> io::Result<()> {
loop {
term.draw(|f| {
let chunks = layout.split(f.size());
let widget = textarea.widget();
f.render_widget(widget, chunks[0]);
f.render_widget(&textarea, chunks[0]);
})?;
match crossterm::event::read()?.into() {

Просмотреть файл

@@ -38,7 +38,7 @@ fn main() -> io::Result<()> {
textarea.set_placeholder_text("prompt message");
loop {
term.draw(|f| {
f.render_widget(textarea.widget(), area);
f.render_widget(&textarea, area);
})?;
match crossterm::event::read()?.into() {
Input { key: Key::Esc, .. } => break,

Просмотреть файл

@@ -50,8 +50,7 @@ fn main() -> io::Result<()> {
loop {
term.draw(|f| {
let chunks = layout.split(f.size());
let widget = textarea.widget();
f.render_widget(widget, chunks[0]);
f.render_widget(&textarea, chunks[0]);
})?;
match crossterm::event::read()?.into() {

Просмотреть файл

@@ -54,8 +54,7 @@ fn main() -> io::Result<()> {
term.draw(|f| {
let chunks = layout.split(f.size());
for (textarea, chunk) in textarea.iter().zip(chunks.iter()) {
let widget = textarea.widget();
f.render_widget(widget, *chunk);
f.render_widget(textarea, *chunk);
}
})?;
match crossterm::event::read()?.into() {

Просмотреть файл

@@ -57,8 +57,7 @@ fn main() -> Result<(), Box<dyn Error>> {
Event::Tick => {}
}
term.draw(|f| {
let widget = textarea.widget();
f.render_widget(widget, f.size());
f.render_widget(&textarea, f.size());
})?;
}

Просмотреть файл

@@ -22,8 +22,7 @@ fn main() -> Result<(), Box<dyn Error>> {
// The event loop
loop {
term.draw(|f| {
let widget = textarea.widget();
f.render_widget(widget, f.size());
f.render_widget(&textarea, f.size());
})?;
if let Some(input) = term

Просмотреть файл

@@ -190,13 +190,12 @@ impl<'a> Editor<'a> {
let chunks = layout.split(f.size());
if search_height > 0 {
f.render_widget(self.search.textarea.widget(), chunks[0]);
f.render_widget(&self.search.textarea, chunks[0]);
}
let buffer = &self.buffers[self.current];
let textarea = &buffer.textarea;
let widget = textarea.widget();
f.render_widget(widget, chunks[1]);
f.render_widget(&textarea, chunks[1]);
// Render status line
let modified = if buffer.modified { " [modified]" } else { "" };

Просмотреть файл

@@ -28,7 +28,7 @@ fn main() -> io::Result<()> {
loop {
term.draw(|f| {
f.render_widget(textarea.widget(), f.size());
f.render_widget(&textarea, f.size());
})?;
match crossterm::event::read()?.into() {
Input { key: Key::Esc, .. } => break,

Просмотреть файл

@@ -57,8 +57,7 @@ fn main() -> Result<(), Box<dyn Error>> {
Event::Tick => {}
}
term.draw(|f| {
let widget = textarea.widget();
f.render_widget(widget, f.size());
f.render_widget(&textarea, f.size());
})?;
}

Просмотреть файл

@@ -34,7 +34,7 @@ fn main() -> io::Result<()> {
.direction(Direction::Vertical)
.constraints([Constraint::Length(height), Constraint::Min(0)])
.split(f.size());
f.render_widget(textarea.widget(), chunks[0]);
f.render_widget(&textarea, chunks[0]);
})?;
match crossterm::event::read()?.into() {
Input { key: Key::Esc, .. } => break,

Просмотреть файл

@@ -419,7 +419,7 @@ fn main() -> io::Result<()> {
let mut vim = Vim::new(Mode::Normal);
loop {
term.draw(|f| f.render_widget(textarea.widget(), f.size()))?;
term.draw(|f| f.render_widget(&textarea, f.size()))?;
vim = match vim.transition(crossterm::event::read()?.into(), &mut textarea) {
Transition::Mode(mode) if vim.mode != mode => {

2
fuzz/Cargo.lock сгенерированный
Просмотреть файл

@@ -453,7 +453,7 @@ dependencies = [
[[package]]
name = "tui-textarea"
version = "0.5.1"
version = "0.5.2"
dependencies = [
"arbitrary",
"crossterm",

Просмотреть файл

@@ -233,7 +233,7 @@ pub enum CursorMove {
/// ```
/// # use ratatui::buffer::Buffer;
/// # use ratatui::layout::Rect;
/// # use ratatui::widgets::Widget;
/// # use ratatui::widgets::Widget as _;
/// use tui_textarea::{TextArea, CursorMove};
///
/// // Let's say terminal height is 8.
@@ -244,7 +244,7 @@ pub enum CursorMove {
/// # // Call `render` at least once to populate terminal size
/// # let r = Rect { x: 0, y: 0, width: 24, height: 8 };
/// # let mut b = Buffer::empty(r.clone());
/// # textarea.widget().render(r, &mut b);
/// # textarea.render(r, &mut b);
///
/// // Move cursor to the end of lines (line 20). It is outside the viewport (line 1 to line 8)
/// textarea.move_cursor(CursorMove::Bottom);
@@ -378,7 +378,7 @@ mod tests {
fn in_viewport() {
use crate::ratatui::buffer::Buffer;
use crate::ratatui::layout::Rect;
use crate::ratatui::widgets::Widget;
use crate::ratatui::widgets::Widget as _;
use crate::{CursorMove, TextArea};
let mut textarea: TextArea = (0..20).map(|i| i.to_string()).collect();
@@ -389,7 +389,7 @@ mod tests {
height: 8,
};
let mut b = Buffer::empty(r);
textarea.widget().render(r, &mut b);
textarea.render(r, &mut b);
textarea.move_cursor(CursorMove::Bottom);
assert_eq!(textarea.cursor(), (19, 0));

Просмотреть файл

@@ -18,7 +18,7 @@ pub enum Scrolling {
/// ```
/// # use ratatui::buffer::Buffer;
/// # use ratatui::layout::Rect;
/// # use ratatui::widgets::Widget;
/// # use ratatui::widgets::Widget as _;
/// use tui_textarea::{TextArea, Scrolling};
///
/// // Let's say terminal height is 8.
@@ -28,7 +28,7 @@ pub enum Scrolling {
/// # // Call `render` at least once to populate terminal size
/// # let r = Rect { x: 0, y: 0, width: 24, height: 8 };
/// # let mut b = Buffer::empty(r.clone());
/// # textarea.widget().render(r, &mut b);
/// # textarea.render(r, &mut b);
///
/// // Scroll down by 2 lines.
/// textarea.scroll(Scrolling::Delta{rows: 2, cols: 0});
@@ -44,7 +44,7 @@ pub enum Scrolling {
/// ```
/// # use ratatui::buffer::Buffer;
/// # use ratatui::layout::Rect;
/// # use ratatui::widgets::Widget;
/// # use ratatui::widgets::Widget as _;
/// use tui_textarea::{TextArea, Scrolling};
///
/// // Let's say terminal height is 8.
@@ -54,7 +54,7 @@ pub enum Scrolling {
/// # // Call `render` at least once to populate terminal size
/// # let r = Rect { x: 0, y: 0, width: 24, height: 8 };
/// # let mut b = Buffer::empty(r.clone());
/// # textarea.widget().render(r, &mut b);
/// # textarea.render(r, &mut b);
///
/// // Scroll down by one page (8 lines)
/// textarea.scroll(Scrolling::PageDown);
@@ -70,7 +70,7 @@ pub enum Scrolling {
/// ```
/// # use ratatui::buffer::Buffer;
/// # use ratatui::layout::Rect;
/// # use ratatui::widgets::Widget;
/// # use ratatui::widgets::Widget as _;
/// use tui_textarea::{TextArea, Scrolling, CursorMove};
///
/// // Let's say terminal height is 8.
@@ -80,13 +80,13 @@ pub enum Scrolling {
/// # // Call `render` at least once to populate terminal size
/// # let r = Rect { x: 0, y: 0, width: 24, height: 8 };
/// # let mut b = Buffer::empty(r.clone());
/// # textarea.widget().render(r.clone(), &mut b);
/// # textarea.render(r.clone(), &mut b);
///
/// // Go to the last line at first
/// textarea.move_cursor(CursorMove::Bottom);
/// assert_eq!(textarea.cursor(), (19, 0));
/// # // Call `render` to populate terminal size
/// # textarea.widget().render(r.clone(), &mut b);
/// # textarea.render(r.clone(), &mut b);
///
/// // Scroll up by one page (8 lines)
/// textarea.scroll(Scrolling::PageUp);
@@ -100,7 +100,7 @@ pub enum Scrolling {
/// ```
/// # use ratatui::buffer::Buffer;
/// # use ratatui::layout::Rect;
/// # use ratatui::widgets::Widget;
/// # use ratatui::widgets::Widget as _;
/// use tui_textarea::{TextArea, Scrolling};
///
/// // Let's say terminal height is 8.
@@ -110,7 +110,7 @@ pub enum Scrolling {
/// # // Call `render` at least once to populate terminal size
/// # let r = Rect { x: 0, y: 0, width: 24, height: 8 };
/// # let mut b = Buffer::empty(r.clone());
/// # textarea.widget().render(r, &mut b);
/// # textarea.render(r, &mut b);
///
/// // Scroll down by half-page (4 lines)
/// textarea.scroll(Scrolling::HalfPageDown);
@@ -126,7 +126,7 @@ pub enum Scrolling {
/// ```
/// # use ratatui::buffer::Buffer;
/// # use ratatui::layout::Rect;
/// # use ratatui::widgets::Widget;
/// # use ratatui::widgets::Widget as _;
/// use tui_textarea::{TextArea, Scrolling, CursorMove};
///
/// // Let's say terminal height is 8.
@@ -136,13 +136,13 @@ pub enum Scrolling {
/// # // Call `render` at least once to populate terminal size
/// # let r = Rect { x: 0, y: 0, width: 24, height: 8 };
/// # let mut b = Buffer::empty(r.clone());
/// # textarea.widget().render(r.clone(), &mut b);
/// # textarea.render(r.clone(), &mut b);
///
/// // Go to the last line at first
/// textarea.move_cursor(CursorMove::Bottom);
/// assert_eq!(textarea.cursor(), (19, 0));
/// # // Call `render` to populate terminal size
/// # textarea.widget().render(r.clone(), &mut b);
/// # textarea.render(r.clone(), &mut b);
///
/// // Scroll up by half-page (4 lines)
/// textarea.scroll(Scrolling::HalfPageUp);
@@ -193,7 +193,7 @@ mod tests {
fn delta() {
use crate::ratatui::buffer::Buffer;
use crate::ratatui::layout::Rect;
use crate::ratatui::widgets::Widget;
use crate::ratatui::widgets::Widget as _;
use crate::TextArea;
let mut textarea: TextArea = (0..20).map(|i| i.to_string()).collect();
@@ -204,7 +204,7 @@ mod tests {
height: 8,
};
let mut b = Buffer::empty(r);
textarea.widget().render(r, &mut b);
textarea.render(r, &mut b);
textarea.scroll(Scrolling::Delta { rows: 2, cols: 0 });
assert_eq!(textarea.cursor(), (2, 0));

Просмотреть файл

@@ -9,7 +9,7 @@ use crate::scroll::Scrolling;
#[cfg(feature = "search")]
use crate::search::Search;
use crate::util::{spaces, Pos};
use crate::widget::{Renderer, Viewport};
use crate::widget::Viewport;
use crate::word::{find_word_exclusive_end_forward, find_word_start_backward};
#[cfg(feature = "ratatui")]
use ratatui::text::Line;
@@ -55,13 +55,18 @@ impl fmt::Display for YankText {
}
}
/// A type to manage state of textarea.
/// A type to manage state of textarea. These are some important methods:
///
/// [`TextArea::default`] creates an empty textarea. [`TextArea::new`] creates a textarea with given text lines.
/// [`TextArea::from`] creates a textarea from an iterator of lines. [`TextArea::input`] handles key input.
/// [`TextArea::widget`] builds a widget to render. And [`TextArea::lines`] returns line texts.
/// - [`TextArea::default`] creates an empty textarea.
/// - [`TextArea::new`] creates a textarea with given text lines.
/// - [`TextArea::from`] creates a textarea from an iterator of lines.
/// - [`TextArea::input`] handles key input.
/// - [`TextArea::lines`] returns line texts.
/// ```
/// use tui_textarea::{TextArea, Input, Key};
/// use ratatui::backend::CrosstermBackend;
/// use ratatui::layout::{Constraint, Direction, Layout};
/// use ratatui::Terminal;
///
/// let mut textarea = TextArea::default();
///
@@ -69,12 +74,35 @@ impl fmt::Display for YankText {
/// let input = Input { key: Key::Char('a'), ctrl: false, alt: false, shift: false };
/// textarea.input(input);
///
/// // Get widget to render.
/// let widget = textarea.widget();
///
/// // Get lines as String.
/// println!("Lines: {:?}", textarea.lines());
/// ```
///
/// It implements [`ratatui::widgets::Widget`] trait so it can be rendered to a
/// terminal screen via [`ratatui::terminal::Frame::render_widget`] method.
/// ```no_run
/// use ratatui::backend::CrosstermBackend;
/// use ratatui::layout::{Constraint, Direction, Layout};
/// use ratatui::Terminal;
/// use tui_textarea::TextArea;
///
/// let mut textarea = TextArea::default();
///
/// let layout = Layout::default()
/// .direction(Direction::Vertical)
/// .constraints([Constraint::Min(1)].as_ref());
/// let backend = CrosstermBackend::new(std::io::stdout());
/// let mut term = Terminal::new(backend).unwrap();
///
/// loop {
/// term.draw(|f| {
/// let chunks = layout.split(f.size());
/// f.render_widget(&textarea, chunks[0]);
/// }).unwrap();
///
/// // ...
/// }
/// ```
#[derive(Clone, Debug)]
pub struct TextArea<'a> {
lines: Vec<String>,
@@ -1589,32 +1617,41 @@ impl<'a> TextArea<'a> {
/// Build a ratatui (or tui-rs) widget to render the current state of the textarea. The widget instance returned
/// from this method can be rendered with [`ratatui::terminal::Frame::render_widget`].
///
/// This method was deprecated at v0.5.3 and is no longer necessary. Instead you can directly pass `&TextArea`
/// reference to the `Frame::render_widget` method call.
/// ```no_run
/// use ratatui::backend::CrosstermBackend;
/// use ratatui::layout::{Constraint, Direction, Layout};
/// use ratatui::Terminal;
/// use tui_textarea::TextArea;
/// # use ratatui::layout::Rect;
/// # use ratatui::Terminal;
/// # use ratatui::widgets::Widget as _;
/// # use ratatui::backend::CrosstermBackend;
/// # use tui_textarea::TextArea;
/// #
/// # let backend = CrosstermBackend::new(std::io::stdout());
/// # let mut term = Terminal::new(backend).unwrap();
/// # let textarea = TextArea::default();
/// #
/// # #[allow(deprecated)]
/// # term.draw(|f| {
/// # let rect = Rect {
/// # x: 0,
/// # y: 0,
/// # width: 24,
/// # height: 8,
/// # };
/// // v0.5.2 or earlier
/// f.render_widget(textarea.widget(), rect);
///
/// let mut textarea = TextArea::default();
///
/// let layout = Layout::default()
/// .direction(Direction::Vertical)
/// .constraints([Constraint::Min(1)].as_ref());
/// let backend = CrosstermBackend::new(std::io::stdout());
/// let mut term = Terminal::new(backend).unwrap();
///
/// loop {
/// term.draw(|f| {
/// let chunks = layout.split(f.size());
/// let widget = textarea.widget();
/// f.render_widget(widget, chunks[0]);
/// }).unwrap();
///
/// // ...
/// }
/// // v0.5.3 or later
/// f.render_widget(&textarea, rect);
/// # }).unwrap();
/// ```
#[deprecated(
since = "0.5.3",
note = "calling this method is no longer neccessary on rendering a textarea. pass &TextArea reference to `Frame::render_widget` method call directly"
)]
pub fn widget(&'a self) -> impl Widget + 'a {
Renderer::new(self)
self
}
/// Set the style of textarea. By default, textarea is not styled.
@@ -2277,7 +2314,7 @@ impl<'a> TextArea<'a> {
/// ```
/// # use ratatui::buffer::Buffer;
/// # use ratatui::layout::Rect;
/// # use ratatui::widgets::Widget;
/// # use ratatui::widgets::Widget as _;
/// use tui_textarea::TextArea;
///
/// // Let's say terminal height is 8.
@@ -2287,7 +2324,7 @@ impl<'a> TextArea<'a> {
/// # // Call `render` at least once to populate terminal size
/// # let r = Rect { x: 0, y: 0, width: 24, height: 8 };
/// # let mut b = Buffer::empty(r.clone());
/// # textarea.widget().render(r, &mut b);
/// # textarea.render(r, &mut b);
///
/// // Scroll down by 15 lines. Since terminal height is 8, cursor will go out
/// // the viewport.
@@ -2330,7 +2367,7 @@ mod tests {
fn scroll() {
use crate::ratatui::buffer::Buffer;
use crate::ratatui::layout::Rect;
use crate::ratatui::widgets::Widget;
use crate::ratatui::widgets::Widget as _;
let mut textarea: TextArea = (0..20).map(|i| i.to_string()).collect();
let r = Rect {
@@ -2340,7 +2377,7 @@ mod tests {
height: 8,
};
let mut b = Buffer::empty(r);
textarea.widget().render(r, &mut b);
textarea.render(r, &mut b);
textarea.scroll((15, 0));
assert_eq!(textarea.cursor(), (15, 0));

Просмотреть файл

@@ -11,14 +11,14 @@ use std::sync::atomic::{AtomicU64, Ordering};
#[cfg(feature = "tuirs")]
use tui::text::Spans as Line;
// &mut 'a (u16, u16, u16, u16) is not available since Renderer instance totally takes over the ownership of TextArea
// &mut 'a (u16, u16, u16, u16) is not available since `render` method takes immutable reference of TextArea
// instance. In the case, the TextArea instance cannot be accessed from any other objects since it is mutablly
// borrowed.
//
// `tui::terminal::Frame::render_stateful_widget` would be an assumed way to render a stateful widget. But at this
// point we stick with using `tui::terminal::Frame::render_widget` because it is simpler API. Users don't need to
// `ratatui::terminal::Frame::render_stateful_widget` would be an assumed way to render a stateful widget. But at this
// point we stick with using `ratatui::terminal::Frame::render_widget` because it is simpler API. Users don't need to
// manage states of textarea instances separately.
// https://docs.rs/tui/latest/tui/terminal/struct.Frame.html#method.render_stateful_widget
// https://docs.rs/ratatui/latest/ratatui/terminal/struct.Frame.html#method.render_stateful_widget
#[derive(Default, Debug)]
pub struct Viewport(AtomicU64);
@@ -80,36 +80,30 @@ impl Viewport {
}
}
pub struct Renderer<'a>(&'a TextArea<'a>);
impl<'a> Renderer<'a> {
pub fn new(textarea: &'a TextArea<'a>) -> Self {
Self(textarea)
}
impl<'a> TextArea<'a> {
#[inline]
fn text(&self, top_row: usize, height: usize) -> Text<'a> {
let lines_len = self.0.lines().len();
fn text_widget(&'a self, top_row: usize, height: usize) -> Text<'a> {
let lines_len = self.lines().len();
let lnum_len = num_digits(lines_len);
let bottom_row = cmp::min(top_row + height, lines_len);
let mut lines = Vec::with_capacity(bottom_row - top_row);
for (i, line) in self.0.lines()[top_row..bottom_row].iter().enumerate() {
lines.push(self.0.line_spans(line.as_str(), top_row + i, lnum_len));
for (i, line) in self.lines()[top_row..bottom_row].iter().enumerate() {
lines.push(self.line_spans(line.as_str(), top_row + i, lnum_len));
}
Text::from(lines)
}
#[inline]
fn placeholder_text(&self) -> Text<'a> {
let cursor = Span::styled(" ", self.0.cursor_style);
let text = Span::raw(self.0.placeholder.as_str());
fn placeholder_widget(&'a self) -> Text<'a> {
let cursor = Span::styled(" ", self.cursor_style);
let text = Span::raw(self.placeholder.as_str());
Text::from(Line::from(vec![cursor, text]))
}
}
impl<'a> Widget for Renderer<'a> {
impl Widget for &TextArea<'_> {
fn render(self, area: Rect, buf: &mut Buffer) {
let Rect { width, height, .. } = if let Some(b) = self.0.block() {
let Rect { width, height, .. } = if let Some(b) = self.block() {
b.inner(area)
} else {
area
@@ -125,15 +119,15 @@ impl<'a> Widget for Renderer<'a> {
}
}
let cursor = self.0.cursor();
let (top_row, top_col) = self.0.viewport.scroll_top();
let cursor = self.cursor();
let (top_row, top_col) = self.viewport.scroll_top();
let top_row = next_scroll_top(top_row, cursor.0 as u16, height);
let top_col = next_scroll_top(top_col, cursor.1 as u16, width);
let (text, style) = if !self.0.placeholder.is_empty() && self.0.is_empty() {
(self.placeholder_text(), self.0.placeholder_style)
let (text, style) = if !self.placeholder.is_empty() && self.is_empty() {
(self.placeholder_widget(), self.placeholder_style)
} else {
(self.text(top_row as usize, height as usize), self.0.style())
(self.text_widget(top_row as _, height as _), self.style())
};
// To get fine control over the text color and the surrrounding block they have to be rendered separately
@@ -141,8 +135,8 @@ impl<'a> Widget for Renderer<'a> {
let mut text_area = area;
let mut inner = Paragraph::new(text)
.style(style)
.alignment(self.0.alignment());
if let Some(b) = self.0.block() {
.alignment(self.alignment());
if let Some(b) = self.block() {
text_area = b.inner(area);
b.clone().render(area, buf)
}
@@ -151,7 +145,7 @@ impl<'a> Widget for Renderer<'a> {
}
// Store scroll top position for rendering on the next tick
self.0.viewport.store(top_row, top_col, width, height);
self.viewport.store(top_row, top_col, width, height);
inner.render(text_area, buf);
}