mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-23 20:22:57 -05:00
Preserve legacy selection repair, modifier routing, viewer lifecycle and workspace persistence through the shared docking integration. Qualify the complete workspace gate by refreshing the 18 stale Audio Spectrum hashes for the existing linear renderer, with an independent synthetic-tone regression.
51 lines
1.7 KiB
Rust
51 lines
1.7 KiB
Rust
//! Automation registry: every interactive element registers a stable id and its screen rect each
|
|
//! frame, so agents can click/drag by id (`ui.click {id:"timeline.track.V1.lock"}`) and
|
|
//! `ui.inspect` can report the full on-screen widget tree.
|
|
|
|
use egui::Rect;
|
|
use serde::Serialize;
|
|
|
|
#[derive(Clone, Debug, Serialize)]
|
|
pub struct Element {
|
|
pub id: String,
|
|
pub label: String,
|
|
pub rect: [f32; 4],
|
|
#[serde(skip)]
|
|
pub(crate) response_id: Option<egui::Id>,
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub struct Registry {
|
|
pub elements: Vec<Element>,
|
|
/// Last frame's elements (for lookups from control handlers between frames).
|
|
pub previous: Vec<Element>,
|
|
}
|
|
|
|
impl Registry {
|
|
pub fn add(&mut self, id: &str, rect: Rect, label: &str) {
|
|
self.elements.push(Element {
|
|
id: id.to_string(),
|
|
label: label.to_string(),
|
|
rect: [rect.min.x, rect.min.y, rect.width(), rect.height()],
|
|
response_id: None,
|
|
});
|
|
}
|
|
/// Bind an automation name to the widget that actually receives keyboard input.
|
|
pub fn add_response(&mut self, id: &str, response: &egui::Response, label: &str) {
|
|
self.add(id, response.rect, label);
|
|
if let Some(element) = self.elements.last_mut() {
|
|
element.response_id = Some(response.id);
|
|
}
|
|
}
|
|
pub fn begin_frame(&mut self) {
|
|
self.previous = std::mem::take(&mut self.elements);
|
|
}
|
|
pub fn find(&self, id: &str) -> Option<&Element> {
|
|
self.previous.iter().chain(self.elements.iter()).find(|e| e.id == id)
|
|
}
|
|
/// Elements whose id starts with a prefix.
|
|
pub fn query(&self, prefix: &str) -> Vec<&Element> {
|
|
self.previous.iter().filter(|e| e.id.starts_with(prefix)).collect()
|
|
}
|
|
}
|