use crate::{
AnnatomicApp,
app::{MainView, OPEN_LABEL},
};
use anyhow::Result;
use egui::{Button, Id, Key, Modifiers, RichText, ScrollArea, TextEdit, Ui, Widget};
use egui_notify::Toast;
#[cfg(test)]
mod tests;
pub(crate) fn show(ui: &mut Ui, app: &mut AnnatomicApp) -> Result<()> {
let mut corpora: Vec<_> = app.project.corpus_locations.keys().cloned().collect();
corpora.sort();
ui.heading("Corpus Selection");
ui.columns_const(|[c1, c2]| {
if let Err(e) = corpus_selection(c1, app, &corpora) {
app.notifier.report_error(e);
}
if c2.link(RichText::new("Import corpus").heading()).clicked() {
app.main_view = MainView::Import;
}
let export_link = egui::Link::new(RichText::new("Export corpus").heading());
if c2
.add_enabled(app.project.selected_corpus.is_some(), export_link)
.clicked()
{
app.main_view = MainView::Export;
}
create_new_corpus(c2, app);
});
Ok(())
}
fn corpus_selection(ui: &mut Ui, app: &mut AnnatomicApp, corpora: &[String]) -> Result<()> {
if corpora.is_empty() {
ui.label("No corpus available.");
} else {
ui.group(|ui| {
ui.vertical(|ui| {
ScrollArea::vertical().show(ui, |ui| {
for (idx, corpus_name) in corpora.iter().enumerate() {
ui.horizontal(|ui| {
let is_selected = app.project.selected_corpus.as_ref().is_some_and(
|selected_corpus| selected_corpus.name == *corpus_name,
);
let label = ui.selectable_label(is_selected, corpus_name);
if ui.ctx().memory(|m| m.focused().is_none())
&& (is_selected
|| (app.project.selected_corpus.is_none() && idx == 0))
{
label.request_focus();
}
let delete_button = Button::new(egui_phosphor::regular::TRASH)
.ui(ui)
.on_hover_text(format!("Delete corpus {corpus_name}"));
if label.clicked() && !ui.ctx().input(|i| i.modifiers.command) {
let result = app.apply_pending_updates();
if app.notifier.ok_or_report(result).is_some() {
if is_selected {
app.select_corpus(None);
} else {
app.select_corpus(Some(corpus_name.clone()));
}
}
}
if delete_button.clicked() {
let result = app.apply_pending_updates();
if app.notifier.ok_or_report(result).is_some() {
app.project.scheduled_for_deletion = Some(corpus_name.clone());
}
}
if is_selected
&& (ui.link(OPEN_LABEL.as_str()).clicked()
|| label.ctx.input_mut(|i| {
i.consume_key(Modifiers::COMMAND, Key::Enter)
}))
{
app.change_view(MainView::CorpusStructure);
}
});
}
});
});
});
}
Ok(())
}
fn create_new_corpus(ui: &mut Ui, app: &mut AnnatomicApp) {
ui.vertical(|ui| {
ui.heading("Create new");
let edit_id = Id::from("new-corpus-name");
let text_edit = TextEdit::singleline(&mut app.new_corpus_name)
.hint_text("Corpus name")
.id(edit_id)
.desired_width(ui.available_width())
.ui(ui);
if ui.button("Add").clicked()
|| (!app.new_corpus_name.is_empty()
&& text_edit
.ctx
.input_mut(|i| i.consume_key(Modifiers::NONE, Key::Enter)))
{
let result = app.apply_pending_updates();
if app.notifier.ok_or_report(result).is_some() && app.new_corpus_name.is_empty() {
app.notifier
.add_toast(Toast::warning("Empty corpus name not allowed"));
} else if let Err(e) = app.project.new_empty_corpus(&app.new_corpus_name) {
app.notifier.report_error(e);
} else {
app.notifier.add_toast(Toast::info(format!(
"Corpus \"{}\" added",
&app.new_corpus_name
)));
app.select_corpus(Some(app.new_corpus_name.clone()));
app.new_corpus_name = String::new();
ui.memory_mut(|mem| mem.surrender_focus(edit_id));
}
}
});
}