use crate::ui::{align::RightAlign, Component};
use arcdps::imgui::{ChildWindow, Ui};
use chrono::Local;
use super::Windowable;
const FORMAT: &str = "%b %d %H:%M:%S.%3f";
#[derive(Debug, Clone)]
pub struct Log {
pub contents: String,
pub active: bool,
last_scroll_max: f32,
activity_toggle_width: f32,
clear_button_width: f32,
copy_button_width: f32,
}
impl Log {
pub fn new() -> Self {
Self {
contents: String::new(),
active: true,
last_scroll_max: 0.0,
activity_toggle_width: 60.0,
clear_button_width: 60.0,
copy_button_width: 60.0,
}
}
pub fn log<S>(&mut self, output: S)
where
S: AsRef<str>,
{
if self.active {
let now = Local::now();
let line = format!("{}: {}\n", now.format(FORMAT), output.as_ref());
self.contents.push_str(&line);
}
}
pub fn clear(&mut self) {
self.contents.clear();
}
}
impl Default for Log {
fn default() -> Self {
Self::new()
}
}
impl Component<()> for Log {
fn render(&mut self, ui: &Ui, _props: ()) {
ui.align_text_to_frame_padding();
ui.text(format!("Time: {}", Local::now().format(FORMAT)));
let mut align = RightAlign::build();
let contents = &mut self.contents;
align.item(ui, &mut self.clear_button_width, || {
if ui.button("Clear") {
contents.clear();
}
});
align.item(ui, &mut self.copy_button_width, || {
if ui.button("Copy") {
ui.set_clipboard_text(contents);
}
});
let active = &mut self.active;
align.item_with_spacing(ui, 10.0, &mut self.activity_toggle_width, || {
ui.checkbox("Active", active);
});
ui.separator();
ChildWindow::new("##log-scroller")
.scrollable(true)
.horizontal_scrollbar(true)
.build(ui, || {
ui.text(&self.contents);
#[allow(clippy::float_cmp)]
if ui.scroll_y() == self.last_scroll_max {
ui.set_scroll_here_y_with_ratio(1.0);
}
self.last_scroll_max = ui.scroll_max_y();
});
}
}
impl Windowable<()> for Log {
const CONTEXT_MENU: bool = true;
}