use std::path::PathBuf;
use GORBIE::prelude::CardCtx;
use crate::widgets::{
BranchTimeline, CompassBoard, MessagesPanel, SharedPile, WikiViewer,
timeline::TimelineSource,
};
pub struct PileInspector {
pile_path: PathBuf,
pile_path_text: String,
shared_pile: Option<SharedPile>,
error: Option<String>,
timeline: BranchTimeline,
wiki: WikiViewer,
compass: CompassBoard,
messages: MessagesPanel,
}
impl PileInspector {
pub fn new(pile_path: impl Into<PathBuf>) -> Self {
let pile_path = pile_path.into();
let pile_path_text = pile_path.to_string_lossy().into_owned();
let sources = vec![
TimelineSource::Compass {
branch: "compass".to_string(),
},
TimelineSource::LocalMessages {
branch: "local-messages".to_string(),
},
TimelineSource::Wiki {
branch: "wiki".to_string(),
},
];
match SharedPile::open(&pile_path) {
Ok(pile) => {
let timeline =
BranchTimeline::multi_with_shared(pile.clone(), sources);
let wiki = WikiViewer::with_shared(pile.clone());
let compass = CompassBoard::with_shared(pile.clone(), "compass");
let messages = MessagesPanel::with_shared(pile.clone(), "local-messages");
Self {
pile_path,
pile_path_text,
shared_pile: Some(pile),
error: None,
timeline,
wiki,
compass,
messages,
}
}
Err(e) => {
let timeline = BranchTimeline::multi(pile_path.clone(), sources);
let wiki = WikiViewer::new(pile_path.clone());
let compass = CompassBoard::new(pile_path.clone(), "compass");
let messages = MessagesPanel::new(pile_path.clone(), "local-messages");
Self {
pile_path,
pile_path_text,
shared_pile: None,
error: Some(e),
timeline,
wiki,
compass,
messages,
}
}
}
}
pub fn set_pile_path(&mut self, path: impl Into<PathBuf>) {
let path = path.into();
if path == self.pile_path {
return;
}
self.pile_path = path.clone();
self.pile_path_text = self.pile_path.to_string_lossy().into_owned();
match SharedPile::open(&self.pile_path) {
Ok(pile) => {
self.timeline.set_shared_pile(pile.clone());
self.wiki.set_shared_pile(pile.clone());
self.compass.set_shared_pile(pile.clone());
self.messages.set_shared_pile(pile.clone());
self.shared_pile = Some(pile);
self.error = None;
}
Err(e) => {
self.timeline.set_pile_path(&self.pile_path);
self.wiki.set_pile_path(&self.pile_path);
self.compass.set_pile_path(&self.pile_path);
self.messages.set_pile_path(&self.pile_path);
self.shared_pile = None;
self.error = Some(e);
}
}
}
pub fn render(&mut self, ctx: &mut CardCtx<'_>) {
let mut reopen = false;
ctx.grid(|g| {
g.place(10, |ctx| {
ctx.text_field(&mut self.pile_path_text);
});
g.place(2, |ctx| {
if ctx.button("Open").clicked() {
reopen = true;
}
});
});
if reopen {
let trimmed = self.pile_path_text.trim().to_string();
self.set_pile_path(PathBuf::from(trimmed));
}
if let Some(err) = &self.error {
let color = ctx.ctx().global_style().visuals.error_fg_color;
ctx.label(
egui::RichText::new(format!("pile open error: {err}"))
.color(color)
.monospace()
.small(),
);
}
self.timeline.render(ctx);
self.wiki.render(ctx);
self.compass.render(ctx);
self.messages.render(ctx);
}
}