use eframe::egui;
use nord_format::fields::{ControlKind, Field, Library};
use super::controls::{self, Sets};
pub const PIANO_MODEL: &str = "piano_panel.piano_model";
pub struct PianoLookup {
pub id: Option<u32>,
pub name: Option<String>,
pub can_ask: bool,
pub asked: bool,
pub models: Vec<(u32, String)>,
pub scan_disagrees: Option<String>,
}
impl PianoLookup {
pub(super) fn names(&self, field: &Field) -> Option<&str> {
if field.spec.control != ControlKind::Reference(Library::Piano) {
return None;
}
if super::library_id(&field.value) != self.id {
return None;
}
self.name.as_deref()
}
pub(super) fn model_cell(&self, ui: &mut egui::Ui, field: &Field, sets: &mut Sets) -> bool {
if self.models.is_empty() {
return false;
}
let current: Option<u32> = field.value.trim().parse().ok();
let shown = current
.and_then(|n| self.models.iter().find(|(position, _)| *position == n))
.map(|(position, name)| format!("{position} — {name}"))
.unwrap_or_else(|| field.value.clone());
controls::named_cell(ui, &field.path, 230.0, |ui| {
egui::ComboBox::from_id_salt("piano-model-names")
.selected_text(shown)
.width(214.0)
.show_ui(ui, |ui| {
for (position, name) in &self.models {
let row = format!("{position} — {name}");
if ui
.selectable_label(current == Some(*position), row)
.clicked()
{
sets.push((field.path.clone(), position.to_string()));
}
}
});
});
true
}
pub(super) fn ui(&mut self, ui: &mut egui::Ui) {
if let Some(scanned) = &self.scan_disagrees {
ui.colored_label(
crate::app::warn(ui.visuals()),
format!(
"the model list calls this position {scanned:?}, but the instrument's \
dependency reply names the piano below — trust the instrument",
),
);
}
let Some(id) = self.id else {
return;
};
ui.horizontal_wrapped(|ui| {
ui.label(egui::RichText::new("currently").small().weak());
match &self.name {
Some(name) => {
ui.label(egui::RichText::new(name).strong());
ui.label(
egui::RichText::new("— named by the instrument")
.small()
.weak(),
);
if self.can_ask {
self.asked |= ui
.small_button("Ask again")
.on_hover_text("read this program's dependencies again")
.clicked();
}
}
None => {
ui.label(egui::RichText::new(format!("piano {id:#010x}")).monospace());
match self.can_ask {
true => {
self.asked |= ui
.small_button("Ask the instrument")
.on_hover_text("read this program's dependencies for the name")
.clicked();
}
false => {
ui.label(
egui::RichText::new(
"— the file stores the id; only the instrument knows the name",
)
.small()
.weak(),
);
}
}
}
}
});
}
}