Window menu: a panel's item hides it while it shows and shows it again where it was (part of #2361)

This commit is contained in:
Marco Arnulfo
2026-10-16 14:57:23 +07:00
committed by bflatastic
parent 80b7aee756
commit c91405dbea
3 changed files with 58 additions and 3 deletions
@@ -136,7 +136,7 @@ fn the_menus_reach_asset_export() {
assert_eq!(find("assets.add", "As Single Asset"), Some(vec!["Object".to_string(), "Collect for Export".to_string()]));
assert_eq!(find("assets.add", "As Multiple Assets"), Some(vec!["Object".to_string(), "Collect for Export".to_string()]));
let window = entries.iter().find(|e| e.label == "Asset Export").unwrap();
assert_eq!(window.params, json!({"panel": crate::panels::asset_export::ID}));
assert_eq!(window.params, json!({"panel": crate::panels::asset_export::ID, "toggle": true}));
app.run("window.panel", window.params.clone()).unwrap();
assert_eq!(app.ui.open_panel.as_deref(), Some(crate::panels::asset_export::ID));
app.run("assets.add", json!({"multiple": false})).unwrap();
+17 -2
View File
@@ -325,7 +325,12 @@ pub const UI_COMMANDS: &[(&str, &str, &str, &str)] = &[
"Shift+Tab",
"{} show/hide the dock and the floating panels (hiding them closes a panel popped out of the icon column), leaving the toolbar and the Control bar as they are; returns whether the panels show",
),
("window.panel", "Show Panel", "", "{panel: id} e.g. layers, swatches, stroke (case-insensitive; display labels like \"Layers\" work too)"),
(
"window.panel",
"Show Panel",
"",
"{panel: id, toggle?: bool} e.g. layers, swatches, stroke (case-insensitive; display labels like \"Layers\" work too); toggle (the Window menu) hides a panel that shows, and shows it again where it was",
),
(
"window.panel.layout",
"Change Panel Layout",
@@ -979,6 +984,16 @@ pub fn check_params(session: &vectorcraft_engine::Session, id: &str, params: &Va
}
pub fn run_ui_command(app: &mut VectorcraftApp, id: &str, p: &Value) -> Option<Result<Value, String>> {
// The Window menu's panel items toggle like its other checked items (#2361); the panel's
// other ways in (shortcuts, Show Properties Panel, a tool's double-click) only show it.
if id == "window.panel" && p.get("toggle").and_then(Value::as_bool) == Some(true) && checked(app, id, p) == Some(true) {
let panel = p.get("panel").and_then(Value::as_str).and_then(normalize_panel).unwrap_or_default();
if app.ui.open_panel.as_deref() == Some(panel) {
app.ui.open_panel = None;
return Some(Ok(json!({"open": null})));
}
return Some(app.run("window.panel.close", json!({"panel": panel})));
}
if let Some(result) = crate::panel_docking::command(app, id, p) {
return Some(result);
}
@@ -2157,7 +2172,7 @@ pub fn menu_tree() -> Vec<(&'static str, Vec<Item>)> {
}
pub fn menu_tree_named(english_names: bool) -> Vec<(&'static str, Vec<Item>)> {
let panel = |label: &'static str, id: &'static str| cp(label, "window.panel", json!({ "panel": id }));
let panel = |label: &'static str, id: &'static str| cp(label, "window.panel", json!({ "panel": id, "toggle": true }));
vec![
(
// The application menu: About and Discord only. The in-window bar never shows it (File
+40
View File
@@ -574,3 +574,43 @@ fn native_set_drop_targets_respect_the_visible_layer_above_an_ordinary_float() {
"visible native group owns the drop: {target:?}"
);
}
/// Window › Properties hides the panel while it shows, and the next click shows it again where it
/// was (#2361): in the dock as the app starts, floating, and once the layout has been changed.
/// The panel's other ways in (a tool's double-click, Show Properties Panel) only show it.
#[test]
fn the_window_menu_item_hides_a_shown_panel_and_shows_it_again() {
let item = crate::menus::menu_entries(&app())
.into_iter()
.find(|e| e.path == ["Window"] && e.command.as_deref() == Some("window.panel") && e.params["panel"] == "properties")
.expect("Window › Properties");
let params = item.params;
let shown = |app: &VectorcraftApp| crate::menus::checked(app, "window.panel", &params) == Some(true);
let in_layout = |app: &VectorcraftApp| app.ui.docking.as_ref().is_some_and(|layout| layout.contains(&"properties".into()));
let mut app = app();
assert!(app.ui.docking.is_none() && shown(&app), "the default dock shows Properties");
let start = legacy(&app);
app.run("window.panel", params.clone()).unwrap();
assert!(!shown(&app) && !in_layout(&app), "the first click hides it");
app.run("window.panel", params.clone()).unwrap();
assert!(shown(&app));
assert_eq!(app.ui.docking.as_ref(), Some(&start), "the second shows it where it was");
app.run("window.panel.move", json!({"panel":"properties", "anchor":"layers", "zone":"top"})).unwrap();
let moved = app.ui.docking.clone();
app.run("window.panel", params.clone()).unwrap();
assert!(!shown(&app) && !in_layout(&app));
app.run("window.panel", params.clone()).unwrap();
assert!(shown(&app) && app.ui.docking == moved);
app.run("window.panel.float", json!({"panel":"properties", "x":50, "y":70, "width":330, "height":410})).unwrap();
let floating = app.ui.docking.clone();
app.run("window.panel", params.clone()).unwrap();
assert!(!shown(&app) && !in_layout(&app), "a floating Properties hides too");
app.run("window.panel", params.clone()).unwrap();
assert!(shown(&app) && app.ui.docking == floating);
app.run("window.panel", json!({"panel":"properties"})).unwrap();
assert!(shown(&app), "without the menu's toggle the command only shows the panel");
}