use core::fmt;
use crate::{
buffer::Buffer,
enums::Wrap,
geometry::{Padding, Rect, Vec2},
prelude::TextAlign,
text::Line,
widgets::Widget,
};
pub trait Text: Widget {
fn append_lines<'a>(
&'a self,
lines: &mut Vec<Line<'a>>,
size: &Vec2,
wrap: Option<Wrap>,
) -> bool;
fn get_align(&self) -> TextAlign;
}
pub fn text_render(
text: &dyn Text,
buffer: &mut Buffer,
mut rect: Rect,
ellipsis: &str,
align: TextAlign,
) {
let mut lines = vec![];
let fit = text.append_lines(&mut lines, rect.size(), None);
if !fit && let Some(l) = lines.last_mut() {
l.add_ellipsis(rect.width(), ellipsis);
}
for line in lines {
line.render(buffer, rect, align);
rect = rect.inner(Padding::top(1));
}
}
impl fmt::Debug for dyn Text {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Converted text")
}
}
macro_rules! impl_display_for_text {
($($type:ty),* $(,)?) => {
$(impl std::fmt::Display for $type {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
{
let mut lines = vec![];
let size = Vec2::new(usize::MAX, usize::MAX);
self.append_lines(&mut lines, &size, None);
for (i, line) in lines.iter().enumerate() {
if i > 0 {
writeln!(f)?;
}
write!(f, "{}", line)?;
}
Ok(())
}
})*
};
}
impl_display_for_text!(
crate::widgets::Span,
crate::widgets::Grad,
crate::widgets::Paragraph,
);