diff --git a/editor/src/messages/layout/utility_types/widgets/input_widgets.rs b/editor/src/messages/layout/utility_types/widgets/input_widgets.rs index 893b301cd8..983e7804fd 100644 --- a/editor/src/messages/layout/utility_types/widgets/input_widgets.rs +++ b/editor/src/messages/layout/utility_types/widgets/input_widgets.rs @@ -332,6 +332,9 @@ pub enum NumberInputMode { pub struct NodeCatalog { pub disabled: bool, + #[serde(rename = "initialSearchTerm")] + pub intial_search: String, + // Callbacks #[serde(skip)] #[derivative(Debug = "ignore", PartialEq = "ignore")] diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index 3157017d8b..422d5bb111 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -2709,7 +2709,22 @@ impl DocumentMessageHandler { .tooltip("Add an operation to the end of this layer's chain of nodes") .disabled(!has_selection || has_multiple_selection) .popover_layout({ - let node_chooser = NodeCatalog::new() + // Showing only compatible types + let compatible_type = selected_layer.and_then(|layer| { + let graph_layer = graph_modification_utils::NodeGraphLayer::new(layer, &self.network_interface); + let node_type = graph_layer.horizontal_layer_flow().nth(1); + if let Some(node_id) = node_type { + let (output_type, _) = self.network_interface.output_type(&node_id, 0, &self.selection_network_path); + Some(format!("type:{}", output_type.nested_type())) + } else { + None + } + }); + + let mut node_chooser = NodeCatalog::new(); + node_chooser.intial_search = compatible_type.unwrap_or("".to_string()); + + let node_chooser = node_chooser .on_update(move |node_type| { if let Some(layer) = selected_layer { NodeGraphMessage::CreateNodeInLayerWithTransaction { diff --git a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs index 23f7aaae50..40cfe18ca2 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs @@ -2017,26 +2017,57 @@ impl NodeGraphMessageHandler { let selection_all_locked = network_interface.selected_nodes().selected_unlocked_layers(network_interface).count() == 0; let selection_all_visible = selected_nodes.selected_nodes().all(|node_id| network_interface.is_visible(node_id, breadcrumb_network_path)); + let mut selected_layers = selected_nodes.selected_layers(network_interface.document_metadata()); + let selected_layer = selected_layers.next(); + let has_multiple_selection = selected_layers.next().is_some(); + let mut widgets = vec![ PopoverButton::new() .icon(Some("Node".to_string())) .tooltip("New Node (Right Click)") .popover_layout({ - let node_chooser = NodeCatalog::new() + // Showing only compatible types + let compatible_type = match (selection_includes_layers, has_multiple_selection, selected_layer) { + (true, false, Some(layer)) => { + let graph_layer = graph_modification_utils::NodeGraphLayer::new(layer, network_interface); + let node_type = graph_layer.horizontal_layer_flow().nth(1); + if let Some(node_id) = node_type { + let (output_type, _) = network_interface.output_type(&node_id, 0, &[]); + Some(format!("type:{}", output_type.nested_type())) + } else { + None + } + } + _ => None, + }; + + let single_layer_selected = selection_includes_layers && !has_multiple_selection; + + let mut node_chooser = NodeCatalog::new(); + node_chooser.intial_search = compatible_type.unwrap_or("".to_string()); + + let node_chooser = node_chooser .on_update(move |node_type| { - let node_id = NodeId::new(); - - Message::Batched { - messages: Box::new([ - NodeGraphMessage::CreateNodeFromContextMenu { - node_id: Some(node_id), - node_type: node_type.clone(), - xy: None, - add_transaction: true, - } - .into(), - NodeGraphMessage::SelectedNodesSet { nodes: vec![node_id] }.into(), - ]), + if let (true, Some(layer)) = (single_layer_selected, selected_layer) { + NodeGraphMessage::CreateNodeInLayerWithTransaction { + node_type: node_type.clone(), + layer: LayerNodeIdentifier::new_unchecked(layer.to_node()), + } + .into() + } else { + let node_id = NodeId::new(); + Message::Batched { + messages: Box::new([ + NodeGraphMessage::CreateNodeFromContextMenu { + node_id: Some(node_id), + node_type: node_type.clone(), + xy: None, + add_transaction: true, + } + .into(), + NodeGraphMessage::SelectedNodesSet { nodes: vec![node_id] }.into(), + ]), + } } }) .widget_holder(); @@ -2308,7 +2339,22 @@ impl NodeGraphMessageHandler { .icon(Some("Node".to_string())) .tooltip("Add an operation to the end of this layer's chain of nodes") .popover_layout({ - let node_chooser = NodeCatalog::new() + let layer_identifier = LayerNodeIdentifier::new(layer, &context.network_interface); + let compatible_type = { + let graph_layer = graph_modification_utils::NodeGraphLayer::new(layer_identifier, &context.network_interface); + let node_type = graph_layer.horizontal_layer_flow().nth(1); + if let Some(node_id) = node_type { + let (output_type, _) = context.network_interface.output_type(&node_id, 0, &[]); + Some(format!("type:{}", output_type.nested_type())) + } else { + None + } + }; + + let mut node_chooser = NodeCatalog::new(); + node_chooser.intial_search = compatible_type.unwrap_or("".to_string()); + + let node_chooser = node_chooser .on_update(move |node_type| { NodeGraphMessage::CreateNodeInLayerWithTransaction { node_type: node_type.clone(),