Fix #901: Shift-click a target circle in the Layers panel to add or remove it
Clicking an object's target circle in the Layers panel always replaced the selection, so several objects couldn't be picked there. Shift-click now adds the object (a layer: its art) to the selection, or takes it out when it is selected already, as in Illustrator; nothing stays targeted then. layer.target takes add: true for it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
6917984329
commit
980cc4fe44
|
|
@ -128,6 +128,20 @@ impl Selection {
|
|||
}
|
||||
self.target = Some(id);
|
||||
}
|
||||
/// Shift-clicking `id`'s target circle: it (a layer: its art) joins the selection, or leaves it
|
||||
/// when it is all selected already. Several objects are then selected, none targeted.
|
||||
pub fn toggle_target(&mut self, doc: &Document, id: NodeId) {
|
||||
let ids = match doc.node(id) {
|
||||
Some(n) if n.is_layer() => n.layer_art(true),
|
||||
_ => vec![id],
|
||||
};
|
||||
if ids.iter().all(|i| self.contains(*i)) {
|
||||
ids.iter().for_each(|i| self.remove(*i));
|
||||
} else {
|
||||
ids.into_iter().for_each(|i| self.add(i));
|
||||
}
|
||||
self.target = None;
|
||||
}
|
||||
/// What appearance and transparency edits act on: the targeted object, group or layer, else
|
||||
/// the selected objects.
|
||||
pub fn subjects(&self) -> &[NodeId] {
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
|||
"Target",
|
||||
[],
|
||||
None,
|
||||
"{id} target a layer, group or object as clicking its target circle in the Layers panel does: a layer gets its visible, unlocked art (its sublayers' too) selected and becomes the current layer, and appearance.*, effect.*, transparency.* and the opacity-mask commands without `ids` then act on the layer itself; anything else is selected. Any other selection change ends the targeting (`document.inspect` → target) → {id, selected: [..]}",
|
||||
"{id, add?: bool (Shift-click: the item joins the selection, or leaves it when all selected; nothing is targeted)} target a layer, group or object as clicking its target circle in the Layers panel does: a layer gets its visible, unlocked art (its sublayers' too) selected and becomes the current layer, and appearance.*, effect.*, transparency.* and the opacity-mask commands without `ids` then act on the layer itself; anything else is selected. Any other selection change ends the targeting (`document.inspect` → target) → {id, selected: [..]}",
|
||||
has_doc,
|
||||
target
|
||||
),
|
||||
|
|
@ -362,7 +362,11 @@ fn target(s: &mut Session, p: &Value) -> Result<Value> {
|
|||
}
|
||||
let layer = n.is_layer();
|
||||
let rows = st.layer_rows.clone();
|
||||
s.select(|d, sel| sel.set_target(d, id))?;
|
||||
if p.get("add").and_then(Value::as_bool).unwrap_or(false) {
|
||||
s.select(|d, sel| sel.toggle_target(d, id))?;
|
||||
} else {
|
||||
s.select(|d, sel| sel.set_target(d, id))?;
|
||||
}
|
||||
let st = s.doc_mut()?;
|
||||
// Targeting doesn't change which rows are highlighted.
|
||||
st.layer_rows = rows;
|
||||
|
|
|
|||
|
|
@ -664,7 +664,7 @@ fn row(ui: &mut Ui, view: &View, item: &Row, out: &mut Out) {
|
|||
}
|
||||
let m = ui.input(|i| i.modifiers);
|
||||
if tresp.clicked() {
|
||||
out.actions.push(("layer.target".into(), json!({"id": n.id.0})));
|
||||
out.actions.push(("layer.target".into(), json!({"id": n.id.0, "add": m.shift})));
|
||||
} else if sq_resp.clicked() {
|
||||
out.actions.push(("layer.selectAll".into(), json!({"id": n.id.0, "add": m.shift})));
|
||||
} else if resp.clicked() {
|
||||
|
|
@ -1239,6 +1239,13 @@ mod tests {
|
|||
}
|
||||
let st = app.session.active().unwrap();
|
||||
assert_eq!((st.selection.target, st.selection.objects.clone()), (Some(a), vec![a]));
|
||||
// Shift-clicking another object's circle adds it to the selection (#901), and again takes
|
||||
// it out; nothing is targeted meanwhile.
|
||||
click_with(&mut app, &ctx, c[1], egui::Modifiers::SHIFT);
|
||||
let st = app.session.active().unwrap();
|
||||
assert_eq!((st.selection.target, st.selection.objects.clone()), (None, vec![a, b]));
|
||||
click_with(&mut app, &ctx, c[1], egui::Modifiers::SHIFT);
|
||||
assert_eq!(app.session.active().unwrap().selection.objects, vec![a]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Reference in New Issue