use egui::Ui;
use egui::containers::menu::{MenuButton, SubMenuButton};
use gled_model::patching::Patch;
use gled_model::patching::layout::LayoutSelection;
pub(crate) fn selection_label(patch: &Patch, selection: LayoutSelection) -> String {
let Some(layout) = patch.layout(selection.layout) else {
return "missing layout".to_string();
};
if selection.mode == 0 {
layout.name.clone()
} else {
format!(
"{} \u{203a} {}",
layout.name,
layout.mode(selection.mode).name
)
}
}
fn layout_entries(ui: &mut Ui, patch: &Patch, picked: &mut Option<LayoutSelection>) {
for layout_ref in patch.layout_refs() {
let Some(layout) = patch.layout(layout_ref) else {
continue;
};
let name = layout.name.clone();
if layout.modes.len() > 1 {
let modes: Vec<String> = layout.modes.iter().map(|mode| mode.name.clone()).collect();
let (response, _) = SubMenuButton::new(name).ui(ui, |ui| {
for (index, mode) in modes.iter().enumerate() {
if ui.button(mode).clicked() {
*picked = Some(LayoutSelection::new(layout_ref, index));
ui.close();
}
}
});
if response.clicked() {
*picked = Some(LayoutSelection::new(layout_ref, 0));
ui.close();
}
} else if ui.button(name).clicked() {
*picked = Some(LayoutSelection::new(layout_ref, 0));
ui.close();
}
}
}
pub(crate) fn selection_button(ui: &mut Ui, patch: &Patch, current: &mut LayoutSelection) -> bool {
let mut picked = None;
MenuButton::new(selection_label(patch, *current)).ui(ui, |ui| {
layout_entries(ui, patch, &mut picked);
});
match picked {
Some(picked) if picked != *current => {
*current = picked;
true
}
_ => false,
}
}
pub(crate) fn inherited_selection_button(
ui: &mut Ui,
patch: &Patch,
current: &mut Option<LayoutSelection>,
) -> bool {
let label = match current {
None => "inherit".to_string(),
Some(selection) => selection_label(patch, *selection),
};
let mut picked = None;
let mut inherit = false;
MenuButton::new(label).ui(ui, |ui| {
if ui.button("inherit").clicked() {
inherit = true;
ui.close();
}
ui.separator();
layout_entries(ui, patch, &mut picked);
});
if inherit {
let changed = current.is_some();
*current = None;
return changed;
}
match picked {
Some(picked) if *current != Some(picked) => {
*current = Some(picked);
true
}
_ => false,
}
}