egui_graph_edit/
traits.rs

1use super::*;
2
3/// This trait must be implemented by the `ValueType` generic parameter of the
4/// [`Graph`]. The trait allows drawing custom inline widgets for the different
5/// types of the node graph.
6///
7/// The [`Default`] trait bound is required to circumvent borrow checker issues
8/// using `std::mem::take` Otherwise, it would be impossible to pass the
9/// `node_data` parameter during `value_widget`. The default value is never
10/// used, so the implementation is not important, but it should be reasonably
11/// cheap to construct.
12pub trait WidgetValueTrait: Default {
13    type Response;
14    type UserState;
15    type NodeData;
16
17    /// This method will be called for each input parameter with a widget with an disconnected
18    /// input only. To display UI for connected inputs use [`WidgetValueTrait::value_widget_connected`].
19    /// The return value is a vector of custom response objects which can be used
20    /// to implement handling of side effects. If unsure, the response Vec can
21    /// be empty.
22    fn value_widget(
23        &mut self,
24        param_name: &str,
25        node_id: NodeId,
26        ui: &mut egui::Ui,
27        user_state: &mut Self::UserState,
28        node_data: &Self::NodeData,
29    ) -> Vec<Self::Response>;
30
31    /// This method will be called for each input parameter with a widget with a connected
32    /// input only. To display UI for diconnected inputs use [`WidgetValueTrait::value_widget`].
33    /// The return value is a vector of custom response objects which can be used
34    /// to implement handling of side effects. If unsure, the response Vec can
35    /// be empty.
36    ///
37    /// Shows the input name label by default.
38    fn value_widget_connected(
39        &mut self,
40        param_name: &str,
41        _node_id: NodeId,
42        ui: &mut egui::Ui,
43        _user_state: &mut Self::UserState,
44        _node_data: &Self::NodeData,
45    ) -> Vec<Self::Response> {
46        ui.label(param_name);
47
48        Default::default()
49    }
50}
51
52/// This trait must be implemented by the `DataType` generic parameter of the
53/// [`Graph`]. This trait tells the library how to visually expose data types
54/// to the user.
55pub trait DataTypeTrait<UserState>: PartialEq + Eq {
56    /// The associated port color of this datatype
57    fn data_type_color(&self, user_state: &mut UserState) -> egui::Color32;
58
59    /// The name of this datatype. Return type is specified as Cow<str> because
60    /// some implementations will need to allocate a new string to provide an
61    /// answer while others won't.
62    ///
63    /// ## Example (borrowed value)
64    /// Use this when you can get the name of the datatype from its fields or as
65    /// a &'static str. Prefer this method when possible.
66    /// ```ignore
67    /// pub struct DataType { name: String }
68    ///
69    /// impl DataTypeTrait<()> for DataType {
70    ///     fn name(&self) -> std::borrow::Cow<str> {
71    ///         Cow::Borrowed(&self.name)
72    ///     }
73    /// }
74    /// ```
75    ///
76    /// ## Example (owned value)
77    /// Use this when you can't derive the name of the datatype from its fields.
78    /// ```ignore
79    /// pub struct DataType { some_tag: i32 }
80    ///
81    /// impl DataTypeTrait<()> for DataType {
82    ///     fn name(&self) -> std::borrow::Cow<str> {
83    ///         Cow::Owned(format!("Super amazing type #{}", self.some_tag))
84    ///     }
85    /// }
86    /// ```
87    fn name(&self) -> std::borrow::Cow<str>;
88}
89
90/// This trait must be implemented for the `NodeData` generic parameter of the
91/// [`Graph`]. This trait allows customizing some aspects of the node drawing.
92pub trait NodeDataTrait
93where
94    Self: Sized,
95{
96    /// Must be set to the custom user `NodeResponse` type
97    type Response;
98    /// Must be set to the custom user `UserState` type
99    type UserState;
100    /// Must be set to the custom user `DataType` type
101    type DataType;
102    /// Must be set to the custom user `ValueType` type
103    type ValueType;
104
105    /// Additional UI elements to draw in the nodes, after the parameters.
106    fn bottom_ui(
107        &self,
108        ui: &mut egui::Ui,
109        node_id: NodeId,
110        graph: &Graph<Self, Self::DataType, Self::ValueType>,
111        user_state: &mut Self::UserState,
112    ) -> Vec<NodeResponse<Self::Response, Self>>
113    where
114        Self::Response: UserResponseTrait;
115
116    /// UI to draw on the top bar of the node.
117    fn top_bar_ui(
118        &self,
119        _ui: &mut egui::Ui,
120        _node_id: NodeId,
121        _graph: &Graph<Self, Self::DataType, Self::ValueType>,
122        _user_state: &mut Self::UserState,
123    ) -> Vec<NodeResponse<Self::Response, Self>>
124    where
125        Self::Response: UserResponseTrait,
126    {
127        Default::default()
128    }
129
130    /// UI to draw for each output
131    ///
132    /// Defaults to showing param_name as a simple label.
133    fn output_ui(
134        &self,
135        ui: &mut egui::Ui,
136        _node_id: NodeId,
137        _graph: &Graph<Self, Self::DataType, Self::ValueType>,
138        _user_state: &mut Self::UserState,
139        param_name: &str,
140    ) -> Vec<NodeResponse<Self::Response, Self>>
141    where
142        Self::Response: UserResponseTrait,
143    {
144        ui.label(param_name);
145
146        Default::default()
147    }
148
149    /// Set background color on titlebar
150    /// If the return value is None, the default color is set.
151    fn titlebar_color(
152        &self,
153        _ui: &egui::Ui,
154        _node_id: NodeId,
155        _graph: &Graph<Self, Self::DataType, Self::ValueType>,
156        _user_state: &mut Self::UserState,
157    ) -> Option<egui::Color32> {
158        None
159    }
160
161    /// Separator to put between elements in the node.
162    ///
163    /// Invoked between inputs, outputs and bottom UI. Useful for
164    /// complicated UIs that start to lose structure without explicit
165    /// separators. The `param_id` argument is the id of input or output
166    /// *preceeding* the separator.
167    ///
168    /// Default implementation does nothing.
169    fn separator(
170        &self,
171        _ui: &mut egui::Ui,
172        _node_id: NodeId,
173        _param_id: AnyParameterId,
174        _graph: &Graph<Self, Self::DataType, Self::ValueType>,
175        _user_state: &mut Self::UserState,
176    ) {
177    }
178
179    fn can_delete(
180        &self,
181        _node_id: NodeId,
182        _graph: &Graph<Self, Self::DataType, Self::ValueType>,
183        _user_state: &mut Self::UserState,
184    ) -> bool {
185        true
186    }
187
188    fn can_flip(
189        &self,
190        _node_id: NodeId,
191        _graph: &Graph<Self, Self::DataType, Self::ValueType>,
192        _user_state: &mut Self::UserState,
193    ) -> bool {
194        true
195    }
196}
197
198/// This trait can be implemented by any user type. The trait tells the library
199/// how to enumerate the node templates it will present to the user as part of
200/// the node finder.
201pub trait NodeTemplateIter {
202    type Item;
203    fn all_kinds(&self) -> Vec<Self::Item>;
204}
205
206/// Describes a category of nodes.
207///
208/// Used by [`NodeTemplateTrait::node_finder_categories`] to categorize nodes
209/// templates into groups.
210///
211/// If all nodes in a program are known beforehand, it's usefult to define
212/// an enum containing all categories and implement [`CategoryTrait`] for it. This will
213/// make it impossible to accidentally create a new category by mis-typing an existing
214/// one, like in the case of using string types.
215pub trait CategoryTrait {
216    /// Name of the category.
217    fn name(&self) -> String;
218}
219
220impl CategoryTrait for () {
221    fn name(&self) -> String {
222        String::new()
223    }
224}
225
226impl CategoryTrait for &str {
227    fn name(&self) -> String {
228        self.to_string()
229    }
230}
231
232impl CategoryTrait for String {
233    fn name(&self) -> String {
234        self.clone()
235    }
236}
237
238/// This trait must be implemented by the `NodeTemplate` generic parameter of
239/// the [`GraphEditorState`]. It allows the customization of node templates. A
240/// node template is what describes what kinds of nodes can be added to the
241/// graph, what is their name, and what are their input / output parameters.
242pub trait NodeTemplateTrait: Clone {
243    /// Must be set to the custom user `NodeData` type
244    type NodeData;
245    /// Must be set to the custom user `DataType` type
246    type DataType;
247    /// Must be set to the custom user `ValueType` type
248    type ValueType;
249    /// Must be set to the custom user `UserState` type
250    type UserState;
251    /// Must be a type that implements the [`CategoryTrait`] trait.
252    ///
253    /// `&'static str` is a good default if you intend to simply type out
254    /// the categories of your node. Use `()` if you don't need categories
255    /// at all.
256    type CategoryType;
257
258    /// Returns a descriptive name for the node kind, used in the node finder.
259    ///
260    /// The return type is Cow<str> to allow returning owned or borrowed values
261    /// more flexibly. Refer to the documentation for `DataTypeTrait::name` for
262    /// more information
263    fn node_finder_label(&self, user_state: &mut Self::UserState) -> std::borrow::Cow<str>;
264
265    /// Vec of categories to which the node belongs.
266    ///
267    /// It's often useful to organize similar nodes into categories, which will
268    /// then be used by the node finder to show a more manageable UI, especially
269    /// if the node template are numerous.
270    fn node_finder_categories(&self, _user_state: &mut Self::UserState) -> Vec<Self::CategoryType> {
271        Vec::default()
272    }
273
274    /// Returns a descriptive name for the node kind, used in the graph.
275    fn node_graph_label(&self, user_state: &mut Self::UserState) -> String;
276
277    /// Returns the user data for this node kind.
278    fn user_data(&self, user_state: &mut Self::UserState) -> Self::NodeData;
279
280    /// This function is run when this node kind gets added to the graph. The
281    /// node will be empty by default, and this function can be used to fill its
282    /// parameters.
283    fn build_node(
284        &self,
285        graph: &mut Graph<Self::NodeData, Self::DataType, Self::ValueType>,
286        user_state: &mut Self::UserState,
287        node_id: NodeId,
288    );
289}
290
291/// The custom user response types when drawing nodes in the graph must
292/// implement this trait.
293pub trait UserResponseTrait: Clone + std::fmt::Debug {}