diff --git a/egui_node_graph/src/editor_ui.rs b/egui_node_graph/src/editor_ui.rs index 328c0b6..7ab452f 100644 --- a/egui_node_graph/src/editor_ui.rs +++ b/egui_node_graph/src/editor_ui.rs @@ -569,17 +569,26 @@ where for (param_name, param_id) in inputs { if self.graph[param_id].shown_inline { let height_before = ui.min_rect().bottom(); + // NOTE: We want to pass the `user_data` to + // `value_widget`, but we can't since that would require + // borrowing the graph twice. Here, we make the + // assumption that the value is cheaply replaced, and + // use `std::mem::take` to temporarily replace it with a + // dummy value. This requires `ValueType` to implement + // Default, but results in a totally safe alternative. + let mut value = std::mem::take(&mut self.graph[param_id].value); + if self.graph.connection(param_id).is_some() { - ui.label(param_name); + let node_responses = value.value_widget_connected( + ¶m_name, + self.node_id, + ui, + user_state, + &self.graph[self.node_id].user_data, + ); + + responses.extend(node_responses.into_iter().map(NodeResponse::User)); } else { - // NOTE: We want to pass the `user_data` to - // `value_widget`, but we can't since that would require - // borrowing the graph twice. Here, we make the - // assumption that the value is cheaply replaced, and - // use `std::mem::take` to temporarily replace it with a - // dummy value. This requires `ValueType` to implement - // Default, but results in a totally safe alternative. - let mut value = std::mem::take(&mut self.graph[param_id].value); let node_responses = value.value_widget( ¶m_name, self.node_id, @@ -587,9 +596,12 @@ where user_state, &self.graph[self.node_id].user_data, ); - self.graph[param_id].value = value; + responses.extend(node_responses.into_iter().map(NodeResponse::User)); } + + self.graph[param_id].value = value; + let height_after = ui.min_rect().bottom(); input_port_heights.push((height_before + height_after) / 2.0); } diff --git a/egui_node_graph/src/traits.rs b/egui_node_graph/src/traits.rs index 31a9a6d..c25dbb4 100644 --- a/egui_node_graph/src/traits.rs +++ b/egui_node_graph/src/traits.rs @@ -13,8 +13,10 @@ pub trait WidgetValueTrait: Default { type Response; type UserState; type NodeData; - /// This method will be called for each input parameter with a widget. The - /// return value is a vector of custom response objects which can be used + + /// This method will be called for each input parameter with a widget with an disconnected + /// input only. To display UI for connected inputs use [`WidgetValueTrait::value_widget_connected`]. + /// The return value is a vector of custom response objects which can be used /// to implement handling of side effects. If unsure, the response Vec can /// be empty. fn value_widget( @@ -25,6 +27,26 @@ pub trait WidgetValueTrait: Default { user_state: &mut Self::UserState, node_data: &Self::NodeData, ) -> Vec; + + /// This method will be called for each input parameter with a widget with a connected + /// input only. To display UI for diconnected inputs use [`WidgetValueTrait::value_widget`]. + /// The return value is a vector of custom response objects which can be used + /// to implement handling of side effects. If unsure, the response Vec can + /// be empty. + /// + /// Shows the input name label by default. + fn value_widget_connected( + &mut self, + param_name: &str, + _node_id: NodeId, + ui: &mut egui::Ui, + _user_state: &mut Self::UserState, + _node_data: &Self::NodeData, + ) -> Vec { + ui.label(param_name); + + Default::default() + } } /// This trait must be implemented by the `DataType` generic parameter of the