Layers: art moved into a hidden or locked layer, or hidden by a data set, is deselected

These commands moved selected objects into a hidden or locked layer,
or hid them, and left them selected, with the key object still set
when it was one of them:

- a row dragged into a hidden layer or group (layer.move);
- node.move into a hidden or locked layer or group;
- Merge Selected into a hidden or locked layer;
- Flatten Artwork into a locked layer;
- Collect in New Layer, when the topmost row it collects is in a
  hidden or locked layer;
- applying a data set that hides bound objects (dataset.select,
  dataset.next, dataset.prev).

They now call Selection::deselect_uneditable after the change, as
layer.setProps, layer.hideOthers and layer.lockOthers do. Every
selected object left hidden or locked is deselected, and the key
object is cleared when it is one of them. Undo restores the objects
and selects them again with the key object. A row drag into a hidden
layer and node.move into a hidden or locked layer still succeed. The
params text of layer.move, node.move, layer.merge, layer.flatten,
layer.collectInNew and dataset.select describes the deselection.

The Layers panel section of docs/mcp.md said that node.move has the
same rules as layer.move; it now says that node.move also moves a row
into a locked layer or group, which layer.move refuses.

Docs: docs/mcp.md, docs/target-app-parity.md.
This commit is contained in:
dotCooCoo
2026-10-12 14:50:00 +07:00
committed by bflatastic
parent 1e76e389d2
commit 307a5a6298
7 changed files with 164 additions and 9 deletions
+4 -2
View File
@@ -379,7 +379,7 @@ fn dataset_list(s: &mut Session, _p: &Value) -> Result<Value> {
fn apply_dataset(s: &mut Session, name: &str) -> Result<Value> {
const C: &str = "dataset.select";
let (applied, skipped) = s.edit("Apply Data Set", |d, _| {
let (applied, skipped) = s.edit("Apply Data Set", |d, sel| {
let ds = d.variables.dataset(name).cloned().ok_or_else(|| bad(C, format!("no dataset named `{name}`")))?;
// One object may be driven by several variables; walk them in definition order, so two
// text variables on the same object land the later one's value and both are counted.
@@ -424,6 +424,8 @@ fn apply_dataset(s: &mut Session, name: &str) -> Result<Value> {
}
}
d.variables.active_dataset = Some(name.to_string());
// Every selected object left hidden or locked, such as one the row hid, is deselected.
sel.deselect_uneditable(d);
Ok((applied, skipped))
})?;
Ok(json!({"name": name, "applied": applied, "skipped": skipped}))
@@ -569,7 +571,7 @@ pub fn specs() -> Vec<CommandSpec> {
"Select Data Set",
["Window", "Variables"],
None,
"{name} apply a dataset in one undo step → {applied, skipped}",
"{name} apply a dataset in one undo step, deselecting every selected object left hidden or locked (the key object too) → {applied, skipped}",
has_doc,
dataset_select
),