Object: Cmd/Ctrl+Alt+Shift+2 locks every unselected object

The reference app locks all deselected artwork on Cmd/Ctrl+Alt+Shift+2.
VectorCraft had no command for it: Object > Lock held Selection, All
Artwork Above and Other Layers.

The new command, object.lock.unselected (Object > Lock > Unselected
Artwork), locks in one undo step the objects that Hide > Unselected
Artwork hides: every object that Select All takes and that is neither
selected nor holds a selected object. It returns the count. Hidden
objects stay unlocked. The selection stays as it is, Unlock All unlocks
the objects again and selects them, and with nothing to lock the
command records no undo step. Both commands now share one function,
which locks or hides the objects that the existing unselected helper
returns.

In isolation mode the menu item is disabled, and the command returns
the error "not available in isolation mode" that Hide > Unselected
Artwork returns there, and changes nothing.

Docs: docs/mcp.md, docs/target-app-parity.md.
This commit is contained in:
dotCooCoo
2026-10-31 03:34:47 +07:00
committed by bflatastic
parent 7591e35345
commit a372d39a31
6 changed files with 156 additions and 7 deletions
+6 -1
View File
@@ -165,7 +165,12 @@ pub fn menu_tree_named(english_names: bool) -> Vec<(&'static str, Vec<Item>)> {
c("Ungroup", "object.ungroup"),
sub(
"Lock",
vec![c("Selection", "object.lock"), c("All Artwork Above", "object.lock.above"), c("Other Layers", "object.lock.otherLayers")],
vec![
c("Selection", "object.lock"),
c("All Artwork Above", "object.lock.above"),
c("Other Layers", "object.lock.otherLayers"),
c("Unselected Artwork", "object.lock.unselected"),
],
),
c("Unlock All", "object.unlockAll"),
sub(
+34
View File
@@ -336,6 +336,40 @@ fn cmd_alt_shift_j_opens_average_and_join() {
assert_eq!(app.ui.dialog.as_ref().map(|d| d.str("to")).as_deref(), Some("smooth"), "the choice confirmed last");
}
/// Cmd+Alt+Shift+2 is Object › Lock › Unselected Artwork: it locks the object that is not
/// selected. Cmd+Alt+2 still unlocks all, and Cmd+2 still locks the selection. In isolation mode
/// the item is disabled.
#[test]
fn cmd_alt_shift_2_locks_unselected_artwork() {
let mut app = VectorcraftApp::new(vectorcraft_engine::Session::new(), Default::default());
app.session.execute("file.new", &json!({"width": 200, "height": 200})).unwrap();
assert_eq!(crate::menus::shortcut_of("object.lock.unselected"), Some("Cmd+Alt+Shift+2"));
let rect = |app: &mut VectorcraftApp, x: f64| {
let r = app.session.execute("shape.rectangle", &json!({"x": x, "y": 10, "width": 20, "height": 20})).unwrap();
vectorcraft_doc::NodeId(r["id"].as_u64().unwrap())
};
let (a, b) = (rect(&mut app, 10.0), rect(&mut app, 50.0));
let locked = |app: &VectorcraftApp| [a, b].map(|id| app.session.doc().unwrap().doc.node(id).unwrap().locked);
let two = |modifiers| egui::Event::Key { key: Key::Num2, physical_key: None, pressed: true, repeat: false, modifiers };
app.session.execute("select.set", &json!({"ids": [a.0]})).unwrap();
frame(&mut app, vec![two(Modifiers::COMMAND | Modifiers::ALT | Modifiers::SHIFT)]);
assert_eq!(locked(&app), [false, true]);
frame(&mut app, vec![two(Modifiers::COMMAND | Modifiers::ALT)]);
assert_eq!(locked(&app), [false, false], "Cmd+Alt+2 unlocks all");
app.session.execute("select.set", &json!({"ids": [a.0]})).unwrap();
frame(&mut app, vec![two(Modifiers::COMMAND)]);
assert_eq!(locked(&app), [true, false], "Cmd+2 locks the selection");
// In isolation mode the menu item is off, and the shortcut locks nothing.
app.session.execute("object.unlockAll", &json!({})).unwrap();
app.session.execute("select.set", &json!({"ids": [a.0, b.0]})).unwrap();
let g = app.session.execute("object.group", &json!({})).unwrap()["id"].as_u64().unwrap();
app.session.execute("object.isolate", &json!({"id": g})).unwrap();
app.session.execute("select.set", &json!({"ids": [a.0]})).unwrap();
assert!(!crate::menus::enabled(&app, "object.lock.unselected"));
frame(&mut app, vec![two(Modifiers::COMMAND | Modifiers::ALT | Modifiers::SHIFT)]);
assert_eq!(locked(&app), [false, false], "nothing is locked in isolation mode");
}
/// Cmd+Shift+B while the Type tool edits text is Type › Bold, not Hide Bounding Box (#724).
#[test]
fn cmd_shift_b_while_typing_is_bold_not_the_bounding_box() {