diff --git a/editor/src/messages/input_mapper/input_mappings.rs b/editor/src/messages/input_mapper/input_mappings.rs index 211d4cf9..8e33f194 100644 --- a/editor/src/messages/input_mapper/input_mappings.rs +++ b/editor/src/messages/input_mapper/input_mappings.rs @@ -336,6 +336,7 @@ pub fn input_mappings() -> Mapping { entry!(KeyDown(KeyG); modifiers=[Accel], action_dispatch=DocumentMessage::GroupSelectedLayers { group_folder_type: GroupFolderType::Layer }), entry!(KeyDown(KeyG); modifiers=[Accel, Shift], action_dispatch=DocumentMessage::UngroupSelectedLayers), entry!(KeyDown(KeyN); modifiers=[Accel, Shift], action_dispatch=DocumentMessage::CreateEmptyFolder), + entry!(KeyDown(Backslash); modifiers=[Alt], action_dispatch=DocumentMessage::SelectParentLayer), entry!(KeyDown(BracketLeft); modifiers=[Alt], action_dispatch=DocumentMessage::SelectionStepBack), entry!(KeyDown(BracketRight); modifiers=[Alt], action_dispatch=DocumentMessage::SelectionStepForward), entry!(KeyDown(MouseBack); action_dispatch=DocumentMessage::SelectionStepBack), diff --git a/editor/src/messages/portfolio/document/document_message.rs b/editor/src/messages/portfolio/document/document_message.rs index 8ae84271..db2919da 100644 --- a/editor/src/messages/portfolio/document/document_message.rs +++ b/editor/src/messages/portfolio/document/document_message.rs @@ -109,6 +109,7 @@ pub enum DocumentMessage { RenderRulers, RenderScrollbars, SaveDocument, + SelectParentLayer, SelectAllLayers, SelectedLayersLower, SelectedLayersLowerToBack, diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index fcda8ddb..10b11790 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -931,6 +931,31 @@ impl MessageHandler> for DocumentMessag name, }) } + DocumentMessage::SelectParentLayer => { + let selected_nodes = self.network_interface.selected_nodes(&[]).unwrap(); + let selected_layers = selected_nodes.selected_layers(self.metadata()); + + let mut parent_layers = HashSet::new(); + + // Find the parent of each selected layer + for layer in selected_layers { + // Get this layer's parent + let Some(parent) = layer.parent(self.metadata()) else { continue }; + + // Either use the parent, or keep the same layer if it's already at the top level + let to_insert = if parent == LayerNodeIdentifier::ROOT_PARENT { layer } else { parent }; + + // Add the layer to the set of those which will become selected + parent_layers.insert(to_insert.to_node()); + } + + // Select each parent layer + if !parent_layers.is_empty() { + let nodes = parent_layers.into_iter().collect(); + responses.add(NodeGraphMessage::SelectedNodesSet { nodes }); + responses.add(BroadcastEvent::SelectionChanged); + } + } DocumentMessage::SelectAllLayers => { let metadata = self.metadata(); let all_layers_except_artboards_invisible_and_locked = metadata.all_layers().filter(|&layer| !self.network_interface.is_artboard(&layer.to_node(), &[])).filter(|&layer| { @@ -1358,6 +1383,7 @@ impl MessageHandler> for DocumentMessag ToggleOverlaysVisibility, ToggleSnapping, Undo, + SelectParentLayer, SelectionStepForward, SelectionStepBack, ZoomCanvasTo100Percent, diff --git a/editor/src/messages/portfolio/menu_bar/menu_bar_message_handler.rs b/editor/src/messages/portfolio/menu_bar/menu_bar_message_handler.rs index 9ae11ee3..f18d3ca9 100644 --- a/editor/src/messages/portfolio/menu_bar/menu_bar_message_handler.rs +++ b/editor/src/messages/portfolio/menu_bar/menu_bar_message_handler.rs @@ -260,6 +260,13 @@ impl LayoutHolder for MenuBarMessageHandler { disabled: no_active_document || !has_selected_nodes, ..MenuBarEntry::default() }, + MenuBarEntry { + label: "Select Parent".into(), + shortcut: action_keys!(DocumentMessageDiscriminant::SelectParentLayer), + action: MenuBarEntry::create_action(|_| DocumentMessage::SelectParentLayer.into()), + disabled: no_active_document || !has_selected_nodes, + ..MenuBarEntry::default() + }, MenuBarEntry { label: "Previous Selection".into(), icon: Some("HistoryUndo".into()),