use std::sync::Once;
use duat_core::{
context::Handle,
data::Pass,
hook::{self, OnMouseEvent, WidgetOpened},
mode::MouseEventKind,
opts::PrintOpts,
text::{Text, TextMut},
ui::Widget,
};
pub fn add_info_hooks() {
use MouseEventKind::{ScrollDown, ScrollUp};
hook::add::<OnMouseEvent<Info>>(|pa, event| match event.kind {
ScrollDown | ScrollUp => {
let (info, area) = event.handle.write_with_area(pa);
let scroll = if let ScrollDown = event.kind { 3 } else { -3 };
area.scroll_ver(&info.text, scroll, info.print_opts());
}
_ => {}
});
hook::add::<WidgetOpened<Info>>(|pa, info| {
let (info, area) = info.write_with_area(pa);
let size = area.size_of_text(info.print_opts(), &info.text).unwrap();
_ = area.set_width(size.x);
_ = area.set_height(size.y);
});
}
pub struct Info {
text: Text,
}
impl Info {
pub fn new(text: Text) -> Self {
static ONCE: Once = Once::new();
ONCE.call_once(|| {});
Self { text }
}
pub fn set_text(pa: &mut Pass, info: &Handle<Self>, func: impl FnOnce(&mut Text)) {
let (info, area) = info.write_with_area(pa);
func(&mut info.text);
let size = area.size_of_text(info.print_opts(), &info.text).unwrap();
_ = area.set_width(size.x);
_ = area.set_height(size.y);
}
}
impl Widget for Info {
fn text(&self) -> &Text {
&self.text
}
fn text_mut(&mut self) -> TextMut<'_> {
self.text.as_mut()
}
fn print_opts(&self) -> PrintOpts {
let mut opts = PrintOpts::new();
opts.wrap_lines = true;
opts.tabstop = 2;
opts
}
}