fix(select): box/lasso adds to the selection (#83)
Box selection is a two-click window (corner, corner): the first empty click armed the box AND cleared the selection, and the box completion cleared again before applying its hits — so a second box dropped everything the first one picked. Stop clearing on the arming click and make the completion accumulate like individual picks (#47): a plain box or lasso adds, Shift+box/lasso removes the enclosed entities, an empty box/lasso (or Esc) clears. Fixes #83 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
610f7f140d
commit
2519d64907
1 changed files with 47 additions and 14 deletions
|
|
@ -3320,11 +3320,20 @@ impl OpenCADStudio {
|
||||||
vp_mat,
|
vp_mat,
|
||||||
bounds,
|
bounds,
|
||||||
));
|
));
|
||||||
self.tabs[i].scene.deselect_all();
|
// Box/lasso accumulates like individual picks
|
||||||
for h in &handles {
|
// (issue #83): a plain box adds to the current
|
||||||
self.tabs[i].scene.select_entity(*h, false);
|
// selection, Shift+box removes the boxed
|
||||||
|
// entities. Esc / empty-space click still clears.
|
||||||
|
if self.shift_down {
|
||||||
|
for h in &handles {
|
||||||
|
self.tabs[i].scene.deselect_entity(*h);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for h in &handles {
|
||||||
|
self.tabs[i].scene.select_entity(*h, false);
|
||||||
|
}
|
||||||
|
self.tabs[i].scene.expand_selection_for_groups(&handles);
|
||||||
}
|
}
|
||||||
self.tabs[i].scene.expand_selection_for_groups(&handles);
|
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
selection_just_completed = true;
|
selection_just_completed = true;
|
||||||
}
|
}
|
||||||
|
|
@ -3364,11 +3373,21 @@ impl OpenCADStudio {
|
||||||
));
|
));
|
||||||
// Selection filter: keep only allowed types.
|
// Selection filter: keep only allowed types.
|
||||||
handles.retain(|&h| self.tabs[i].scene.passes_selection_filter(h));
|
handles.retain(|&h| self.tabs[i].scene.passes_selection_filter(h));
|
||||||
self.tabs[i].scene.deselect_all();
|
// Accumulate like the box path (issue #83): plain
|
||||||
for h in &handles {
|
// lasso adds, Shift+lasso removes, an empty lasso
|
||||||
self.tabs[i].scene.select_entity(*h, false);
|
// clears.
|
||||||
|
if self.shift_down {
|
||||||
|
for h in &handles {
|
||||||
|
self.tabs[i].scene.deselect_entity(*h);
|
||||||
|
}
|
||||||
|
} else if handles.is_empty() {
|
||||||
|
self.tabs[i].scene.deselect_all();
|
||||||
|
} else {
|
||||||
|
for h in &handles {
|
||||||
|
self.tabs[i].scene.select_entity(*h, false);
|
||||||
|
}
|
||||||
|
self.tabs[i].scene.expand_selection_for_groups(&handles);
|
||||||
}
|
}
|
||||||
self.tabs[i].scene.expand_selection_for_groups(&handles);
|
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
selection_just_completed = true;
|
selection_just_completed = true;
|
||||||
}
|
}
|
||||||
|
|
@ -3451,8 +3470,11 @@ impl OpenCADStudio {
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
selection_just_completed = true;
|
selection_just_completed = true;
|
||||||
} else {
|
} else {
|
||||||
self.tabs[i].scene.deselect_all();
|
// Empty-space click only ARMS a box here; it
|
||||||
self.refresh_properties();
|
// no longer clears the selection, so a box can
|
||||||
|
// add to it (issue #83). The box completion
|
||||||
|
// (or Esc) decides what happens to the
|
||||||
|
// selection.
|
||||||
let mut sel = self.tabs[i].scene.selection.borrow_mut();
|
let mut sel = self.tabs[i].scene.selection.borrow_mut();
|
||||||
// Full-canvas space: ViewportMove updates
|
// Full-canvas space: ViewportMove updates
|
||||||
// box_current in canvas coords and the overlay
|
// box_current in canvas coords and the overlay
|
||||||
|
|
@ -3488,11 +3510,22 @@ impl OpenCADStudio {
|
||||||
));
|
));
|
||||||
// Selection filter: keep only allowed types.
|
// Selection filter: keep only allowed types.
|
||||||
handles.retain(|&h| self.tabs[i].scene.passes_selection_filter(h));
|
handles.retain(|&h| self.tabs[i].scene.passes_selection_filter(h));
|
||||||
self.tabs[i].scene.deselect_all();
|
// Accumulate (issue #83): a plain box adds to the
|
||||||
for h in &handles {
|
// current selection, Shift+box removes the boxed
|
||||||
self.tabs[i].scene.select_entity(*h, false);
|
// entities, and an empty box clears (the two-click
|
||||||
|
// analogue of clicking empty space).
|
||||||
|
if self.shift_down {
|
||||||
|
for h in &handles {
|
||||||
|
self.tabs[i].scene.deselect_entity(*h);
|
||||||
|
}
|
||||||
|
} else if handles.is_empty() {
|
||||||
|
self.tabs[i].scene.deselect_all();
|
||||||
|
} else {
|
||||||
|
for h in &handles {
|
||||||
|
self.tabs[i].scene.select_entity(*h, false);
|
||||||
|
}
|
||||||
|
self.tabs[i].scene.expand_selection_for_groups(&handles);
|
||||||
}
|
}
|
||||||
self.tabs[i].scene.expand_selection_for_groups(&handles);
|
|
||||||
self.refresh_properties();
|
self.refresh_properties();
|
||||||
let mut sel = self.tabs[i].scene.selection.borrow_mut();
|
let mut sel = self.tabs[i].scene.selection.borrow_mut();
|
||||||
sel.box_last = Some((a, p));
|
sel.box_last = Some((a, p));
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue