diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index 1c6d5a601..083144ebb 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -10,7 +10,7 @@ use crate::messages::portfolio::document::node_graph::NodeGraphHandlerData; use crate::messages::portfolio::document::overlays::grid_overlays::{grid_overlay, overlay_options}; use crate::messages::portfolio::document::properties_panel::utility_types::PropertiesPanelMessageHandlerData; use crate::messages::portfolio::document::utility_types::clipboards::Clipboard; -use crate::messages::portfolio::document::utility_types::document_metadata::{is_artboard, DocumentMetadata, LayerNodeIdentifier}; +use crate::messages::portfolio::document::utility_types::document_metadata::{is_artboard, is_folder, DocumentMetadata, LayerNodeIdentifier}; use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, DocumentMode, FlipAxis, PTZ}; use crate::messages::portfolio::document::utility_types::nodes::RawBuffer; use crate::messages::portfolio::utility_types::PersistentData; @@ -900,9 +900,26 @@ impl DocumentMessageHandler { .map(|(layer, _)| layer) } - /// Find the layer that has been clicked on from a viewport space location + /// Find the deepest layer given in the sorted array (by returning the one which is not a folder from the list of layers under the click location). + pub fn find_deepest(&self, node_list: &[LayerNodeIdentifier], network: &NodeNetwork) -> Option { + node_list.iter().find(|&&layer| !is_folder(layer, network)).copied() + } + + /// Find any layers sorted by index that are under the given location in viewport space. + pub fn click_list_any(&self, viewport_location: DVec2, network: &NodeNetwork) -> Vec { + self.click_xray(viewport_location).filter(|&layer| !is_artboard(layer, network)).collect::>() + } + + /// Find layers under the location in viewport space that was clicked, listed by their depth in the layer tree hierarchy. + pub fn click_list(&self, viewport_location: DVec2, network: &NodeNetwork) -> Vec { + let mut node_list = self.click_list_any(viewport_location, network); + node_list.truncate(node_list.iter().position(|&layer| !is_folder(layer, network)).unwrap_or(0) + 1); + node_list + } + + /// Find the deepest layer that has been clicked on from a location in viewport space. pub fn click(&self, viewport_location: DVec2, network: &NodeNetwork) -> Option { - self.click_xray(viewport_location).find(|&layer| !is_artboard(layer, network)) + self.click_list(viewport_location, network).last().copied() } /// Get the combined bounding box of the click targets of the selected visible layers in viewport space diff --git a/editor/src/messages/tool/tool_messages/select_tool.rs b/editor/src/messages/tool/tool_messages/select_tool.rs index 000214a72..b1a31830e 100644 --- a/editor/src/messages/tool/tool_messages/select_tool.rs +++ b/editor/src/messages/tool/tool_messages/select_tool.rs @@ -494,7 +494,8 @@ impl Fsm for SelectToolFsmState { .unwrap_or_default(); let mut selected: Vec<_> = document.selected_nodes.selected_visible_and_unlocked_layers(document.metadata()).collect(); - let intersection = document.click(input.mouse.position, &document.network); + let intersection_list = document.click_list(input.mouse.position, &document.network); + let intersection = document.find_deepest(&intersection_list, &document.network); // If the user is dragging the bounding box bounds, go into ResizingBounds mode. // If the user is dragging the rotate trigger, go into RotatingBounds mode. @@ -591,11 +592,11 @@ impl Fsm for SelectToolFsmState { responses.add(DocumentMessage::StartTransaction); tool_data.layer_selected_on_start = Some(intersection); - selected = vec![intersection]; + selected = intersection_list; match tool_data.nested_selection_behavior { NestedSelectionBehavior::Shallowest if !input.keyboard.key(select_deepest) => drag_shallowest_manipulation(responses, selected, tool_data, document), - _ => drag_deepest_manipulation(responses, selected, tool_data), + _ => drag_deepest_manipulation(responses, selected, tool_data, document), } tool_data.get_snap_candidates(document, input); SelectToolFsmState::Dragging @@ -1115,8 +1116,8 @@ fn drag_shallowest_manipulation(responses: &mut VecDeque, selected: Vec }); } -fn drag_deepest_manipulation(responses: &mut VecDeque, mut selected: Vec, tool_data: &mut SelectToolData) { - tool_data.layers_dragging.append(&mut selected); +fn drag_deepest_manipulation(responses: &mut VecDeque, selected: Vec, tool_data: &mut SelectToolData, document: &DocumentMessageHandler) { + tool_data.layers_dragging.append(&mut vec![document.find_deepest(&selected, &document.network).unwrap_or_default()]); responses.add(NodeGraphMessage::SelectedNodesSet { nodes: tool_data.layers_dragging.iter().map(|layer| layer.to_node()).collect(), });