63 lines
1.3 KiB
Rust
63 lines
1.3 KiB
Rust
use crate::{box_constraints::BoxConstraints, Data, DataWrapper, Event, Point, Size, Widget};
|
|
|
|
pub struct Text<T: Data> {
|
|
text: Box<dyn Fn(&DataWrapper<T>) -> String>,
|
|
buf: String,
|
|
}
|
|
|
|
impl<T: Data> Text<T> {
|
|
pub fn new(text: Box<dyn Fn(&DataWrapper<T>) -> String>) -> Self {
|
|
Self {
|
|
text,
|
|
buf: String::new(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T: Data> Widget<T> for Text<T> {
|
|
fn update(&mut self, data: &DataWrapper<T>) {
|
|
self.buf = (*self.text)(data);
|
|
}
|
|
fn layout(&mut self, bc: &BoxConstraints) -> Size {
|
|
let mut width = 0;
|
|
let mut height = 1;
|
|
let mut x = 0;
|
|
for ch in self.buf.chars() {
|
|
if ch == '\n' {
|
|
height += 1;
|
|
x = 0;
|
|
}
|
|
x += 1;
|
|
if x > bc.max().width - 1 {
|
|
x = 0;
|
|
width = bc.max().width;
|
|
}
|
|
if x > width {
|
|
width = x;
|
|
}
|
|
}
|
|
Size::new(width, height).clamp(bc.min(), bc.max())
|
|
}
|
|
fn paint(&mut self, buf: &mut [char], origin: Point, size: &Size) {
|
|
let mut the_chars = self.buf.chars();
|
|
for y in 0..size.height {
|
|
for x in 0..size.width {
|
|
if let (Some(ch), Some(spot)) = (
|
|
the_chars.next(),
|
|
buf.get_mut(x + origin.x + (y + origin.y) * size.width),
|
|
) {
|
|
if ch == '\n' {
|
|
break;
|
|
} else if ch == '\t' {
|
|
// TODO: Figure out a way to handle this.
|
|
*spot = ch;
|
|
} else {
|
|
*spot = ch;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
fn event(&mut self, _: &mut DataWrapper<T>, _: &Event) {}
|
|
}
|