use crate::core::buffer::Buffer;
use crate::core::rect::Rect;
use crate::style::Style;
use crate::widgets::Widget;
#[derive(Debug, Clone)]
pub struct Paragraph<'a> {
pub text: &'a str,
pub style: Style,
pub word_wrap: bool,
pub scroll: (u16, u16),
}
impl<'a> Paragraph<'a> {
pub fn new(text: &'a str) -> Self {
Self {
text,
style: Style::new(),
word_wrap: false,
scroll: (0, 0),
}
}
pub fn with_style(mut self, style: Style) -> Self {
self.style = style;
self
}
pub fn with_word_wrap(mut self, wrap: bool) -> Self {
self.word_wrap = wrap;
self
}
pub fn with_scroll(mut self, x: u16, y: u16) -> Self {
self.scroll = (x, y);
self
}
}
impl<'a> Widget for Paragraph<'a> {
fn render(&self, buffer: &mut Buffer, area: Rect) {
let fg = self.style.fg_or_default();
let bg = self.style.bg;
let lines: Vec<&str> = self.text.lines().collect();
let start_y = self.scroll.1 as usize;
for (line_idx, line) in lines.iter().enumerate() {
let y = area.y as usize + line_idx;
if y >= area.bottom() as usize {
break;
}
if line_idx < start_y {
continue;
}
let display_y = y;
let chars: Vec<char> = line.chars().collect();
let start_x = self.scroll.0 as usize;
for (i, &ch) in chars.iter().enumerate() {
let x = area.x as usize + i;
if x >= area.right() as usize {
break;
}
if i < start_x {
continue;
}
buffer.set(
x,
display_y,
crate::core::buffer::Cell {
ch,
fg,
bg,
bold: self.style.bold,
italic: self.style.italic,
underlined: self.style.underlined,
},
);
}
}
}
}