From de1182fbe36c0f3021a03def01761568e5ea2490 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Wed, 21 Oct 2026 17:59:47 -0700 Subject: [PATCH] =?UTF-8?q?Library=20panels:=20Locate=20Library=E2=80=A6?= =?UTF-8?q?=20reads=20a=20missing=20library=20whose=20panel=20isn't=20pers?= =?UTF-8?q?istent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ui.libraryPanel.locate decided whether a panel's library was missing through missing_file, which answers only for a persistent panel. A command that turns Persistent off leaves the panel open on its missing library until the next drawn frame closes it, and while the window is hidden the app draws no frame between control requests. Locate Library… on that panel answered "isn't missing its library" and read no file. The check now asks whether the panel's library can be found, the lookup the tab label and the per-frame tidy use. A panel whose library is there is still refused, persistent or not. window.swatchLibrary and window.graphicStyleLibrary had the same check: given the library id of such a panel, they answered "no library". They now bring the open panel forward and answer its file's name with count 0; the panel still closes at the next tidy. Docs: docs/mcp.md (ui.libraryPanel.locate, window.swatchLibrary). --- crates/ui-egui/src/panels/library_panel.rs | 77 +++++++++++++++++++--- docs/mcp.md | 9 +-- 2 files changed, 74 insertions(+), 12 deletions(-) diff --git a/crates/ui-egui/src/panels/library_panel.rs b/crates/ui-egui/src/panels/library_panel.rs index 6ef14648e..2c167e35a 100644 --- a/crates/ui-egui/src/panels/library_panel.rs +++ b/crates/ui-egui/src/panels/library_panel.rs @@ -244,9 +244,17 @@ fn missing_file(app: &VectorcraftApp, k: Kind, id: &str) -> Option { (k.name)(app, id).is_none().then(|| s.path.clone().unwrap_or_else(|| id.to_string())) } -/// The name of missing library `id` of `k` ([`missing_file`]): its file's name without the extension. +/// The file of library `id` of `k` when its panel is open and the library can't be found, +/// Persistent or not (a panel whose Persistent a command turned off stays open until [`tidy`]). +fn open_missing_file(app: &VectorcraftApp, k: Kind, id: &str) -> Option { + let s = settings(&app.ui, k.kind, id).filter(|_| is_open(&app.ui, &panel_id(k.kind, id)))?; + (k.name)(app, id).is_none().then(|| s.path.clone().unwrap_or_else(|| id.to_string())) +} + +/// The name of missing library `id` of `k` ([`missing_file`], or [`open_missing_file`]): its file's +/// name without the extension. fn missing_name(app: &VectorcraftApp, k: Kind, id: &str) -> Option { - let file = missing_file(app, k, id)?; + let file = missing_file(app, k, id).or_else(|| open_missing_file(app, k, id))?; Some(std::path::Path::new(&file).file_stem().map_or_else(|| file.clone(), |s| s.to_string_lossy().into_owned())) } @@ -393,9 +401,10 @@ pub(crate) fn library_name<'a>(id: &str, name: &'a str) -> &'a str { } /// The opener of library `K`'s libraries (`window.swatchLibrary {library}`): open library `library` -/// (an id or a name, or the id of a missing library's persistent panel, [`missing_file`]) in its -/// own panel, floating, or bring its panel forward when it is open; `null` closes every panel of -/// `K`'s libraries. → {open, panel, name, count} (a missing library: its [`missing_name`], count 0) +/// (an id or a name, or the id of a missing library's persistent or open panel, [`missing_name`]) +/// in its own panel, floating, or bring its panel forward when it is open; `null` closes every +/// panel of `K`'s libraries. → {open, panel, name, count} (a missing library: its +/// [`missing_name`], count 0) pub(crate) fn open_command(app: &mut VectorcraftApp, p: &Value) -> Result { let Some(key) = p.get("library").filter(|v| !v.is_null()) else { for panel in open_panels(&app.ui).into_iter().filter(|p| parse(p).is_some_and(|(k, _)| k.kind == K::KIND)) { @@ -488,8 +497,8 @@ pub(crate) fn command(app: &mut VectorcraftApp, p: &Value) -> Result Result