Skip to content

Commit 6c3c2e8

Browse files
0SlowPoke0Keavon
andauthored
Add selection removal to the Select tool's box select (Ctrl+Shift modifier) (#2162)
* select parent-node,remove deselect all layers message * Comment nits * implement negative selection box * moved comment and formatting * Apply suggestions from code review --------- Co-authored-by: Keavon Chambers <[email protected]>
1 parent 6d737f1 commit 6c3c2e8

File tree

2 files changed

+34
-16
lines changed

2 files changed

+34
-16
lines changed

editor/src/messages/input_mapper/input_mappings.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ pub fn input_mappings() -> Mapping {
9898
// SelectToolMessage
9999
entry!(PointerMove; refresh_keys=[Control, Alt, Shift], action_dispatch=SelectToolMessage::PointerMove(SelectToolPointerKeys { axis_align: Shift, snap_angle: Control, center: Alt, duplicate: Alt })),
100100
entry!(KeyDown(MouseLeft); action_dispatch=SelectToolMessage::DragStart { extend_selection: Shift, select_deepest: Accel }),
101-
entry!(KeyUp(MouseLeft); action_dispatch=SelectToolMessage::DragStop { remove_from_selection: Shift }),
101+
entry!(KeyUp(MouseLeft); action_dispatch=SelectToolMessage::DragStop { remove_from_selection: Shift, negative_box_selection: Control }),
102102
entry!(KeyDown(Enter); action_dispatch=SelectToolMessage::Enter),
103103
entry!(DoubleClick(MouseButton::Left); action_dispatch=SelectToolMessage::EditLayer),
104104
entry!(KeyDown(MouseRight); action_dispatch=SelectToolMessage::Abort),

editor/src/messages/tool/tool_messages/select_tool.rs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub enum SelectToolMessage {
7272

7373
// Tool-specific messages
7474
DragStart { extend_selection: Key, select_deepest: Key },
75-
DragStop { remove_from_selection: Key },
75+
DragStop { remove_from_selection: Key, negative_box_selection: Key },
7676
EditLayer,
7777
Enter,
7878
PointerMove(SelectToolPointerKeys),
@@ -902,7 +902,7 @@ impl Fsm for SelectToolFsmState {
902902
let selection = tool_data.nested_selection_behavior;
903903
SelectToolFsmState::Ready { selection }
904904
}
905-
(SelectToolFsmState::Dragging, SelectToolMessage::DragStop { remove_from_selection }) => {
905+
(SelectToolFsmState::Dragging, SelectToolMessage::DragStop { remove_from_selection, .. }) => {
906906
// Deselect layer if not snap dragging
907907
responses.add(DocumentMessage::EndTransaction);
908908

@@ -1001,20 +1001,34 @@ impl Fsm for SelectToolFsmState {
10011001
let selection = tool_data.nested_selection_behavior;
10021002
SelectToolFsmState::Ready { selection }
10031003
}
1004-
(SelectToolFsmState::DrawingBox { .. }, SelectToolMessage::DragStop { .. } | SelectToolMessage::Enter) => {
1004+
(
1005+
SelectToolFsmState::DrawingBox { .. },
1006+
SelectToolMessage::DragStop {
1007+
remove_from_selection,
1008+
negative_box_selection,
1009+
},
1010+
) => {
10051011
let quad = tool_data.selection_quad();
10061012
let new_selected: HashSet<_> = document.intersect_quad_no_artboards(quad, input).collect();
10071013
let current_selected: HashSet<_> = document.network_interface.selected_nodes(&[]).unwrap().selected_layers(document.metadata()).collect();
10081014
if new_selected != current_selected {
1009-
let parent_selected: HashSet<_> = new_selected
1010-
.into_iter()
1011-
.map(|layer| {
1012-
// Find the parent node
1013-
layer.ancestors(document.metadata()).filter(not_artboard(document)).last().unwrap_or(layer)
1014-
})
1015-
.collect();
1016-
1017-
tool_data.layers_dragging.extend(parent_selected.iter().copied());
1015+
// Negative selection when both Shift and Ctrl are pressed
1016+
if input.keyboard.key(remove_from_selection) && input.keyboard.key(negative_box_selection) {
1017+
let updated_selection = current_selected
1018+
.into_iter()
1019+
.filter(|layer| !new_selected.iter().any(|selected| layer.starts_with(*selected, document.metadata())))
1020+
.collect();
1021+
tool_data.layers_dragging = updated_selection;
1022+
} else {
1023+
let parent_selected: HashSet<_> = new_selected
1024+
.into_iter()
1025+
.map(|layer| {
1026+
// Find the parent node
1027+
layer.ancestors(document.metadata()).filter(not_artboard(document)).last().unwrap_or(layer)
1028+
})
1029+
.collect();
1030+
tool_data.layers_dragging.extend(parent_selected.iter().copied());
1031+
}
10181032
responses.add(NodeGraphMessage::SelectedNodesSet {
10191033
nodes: tool_data
10201034
.layers_dragging
@@ -1143,9 +1157,13 @@ impl Fsm for SelectToolFsmState {
11431157
responses.add(FrontendMessage::UpdateInputHints { hint_data });
11441158
}
11451159
SelectToolFsmState::DrawingBox { .. } => {
1146-
// TODO: Add hint and implement functionality for holding Shift to extend the selection, thus preventing the prior selection from being cleared
1147-
// TODO: Also fix the current functionality so canceling the box select doesn't clear the prior selection
1148-
let hint_data = HintData(vec![HintGroup(vec![HintInfo::mouse(MouseMotion::Rmb, ""), HintInfo::keys([Key::Escape], "Cancel").prepend_slash()])]);
1160+
let hint_data = HintData(vec![
1161+
HintGroup(vec![HintInfo::mouse(MouseMotion::Rmb, ""), HintInfo::keys([Key::Escape], "Cancel").prepend_slash()]),
1162+
HintGroup(vec![HintInfo::keys([Key::Control, Key::Shift], "Remove from Selection").add_mac_keys([Key::Command, Key::Shift])]),
1163+
// TODO: Re-select deselected layers during drag when Shift is pressed, and re-deselect if Shift is released before drag ends.
1164+
// TODO: (See https://discord.com/channels/731730685944922173/1216976541947531264/1321360311298818048)
1165+
// HintGroup(vec![HintInfo::keys([Key::Shift], "Extend Selection")])
1166+
]);
11491167
responses.add(FrontendMessage::UpdateInputHints { hint_data });
11501168
}
11511169
_ => {}

0 commit comments

Comments
 (0)