use crate::reply::agent::Offer;
use crate::ui::{Aim, Model, theme};
use super::{INTERRUPT, NUDGE, acts};
pub const STOP: &str = "stop";
pub const MORE: &str = "…";
const OPEN_ID: &str = "the composer's strip";
fn offered(model: &Model, act: Offer) -> bool {
model
.records
.agent
.as_ref()
.is_none_or(|row| row.offers.contains(&act))
}
fn control(ui: &mut egui::Ui, glyph: &str, word: &str, op: &str) -> bool {
let seat = ui.button(theme::worded(glyph, word));
crate::ui::act::tag(&seat, &[op]);
seat.clicked()
}
pub fn render(ui: &mut egui::Ui, model: &mut Model, aim: &Aim, agent: &str) {
let running = offered(model, Offer::Stop);
let quiet = offered(model, Offer::Nudge);
let wanted = model.filling();
let id = egui::Id::new(OPEN_ID);
let mut open = ui.data(|d| d.get_temp::<bool>(id)).unwrap_or(false) || wanted.is_some();
let (mut cut, mut nudged, mut halted) = (false, false, false);
ui.horizontal_wrapped(|ui| {
if running {
cut = control(
ui,
theme::glyph::INTERRUPT,
INTERRUPT,
crate::verbs::INTERRUPT.word,
);
}
if quiet {
nudged = control(ui, theme::glyph::NUDGE, NUDGE, crate::verbs::NUDGE.word);
}
if running {
halted = control(ui, theme::glyph::STOP, STOP, crate::verbs::STOP.word);
}
let records = ui.button(crate::ui::records::OPEN);
crate::ui::act::tag(
&records,
&[
crate::verbs::STEPS.word,
crate::verbs::FILES.word,
crate::verbs::RAIL.word,
crate::verbs::GOVERNING.word,
crate::verbs::AGENT.word,
crate::verbs::INBOX.word,
],
);
if records.clicked() {
model.begin_records();
}
if ui.button(MORE).clicked() {
open = !open;
}
});
ui.data_mut(|d| d.insert_temp(id, open));
if cut {
super::fire(model, crate::verbs::interrupt, &aim.address, agent);
}
if nudged {
model
.outbox
.push(crate::ui::Posted::act(crate::verbs::nudge(
aim.address.clone(),
agent.to_owned(),
)));
}
if halted {
model.outbox.push(crate::ui::Posted::act(crate::verbs::stop(
aim.address.clone(),
agent.to_owned(),
false,
)));
}
if open {
acts::render(ui, model, aim, agent, wanted);
}
}
#[cfg(test)]
mod tests;