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 /// Set an outer border color for the node.
162 /// If the return value is None, no custom border is drawn.
163 fn border_color(
164 &self,
165 _ui: &egui::Ui,
166 _node_id: NodeId,
167 _graph: &Graph<Self, Self::DataType, Self::ValueType>,
168 _user_state: &mut Self::UserState,
169 ) -> Option<egui::Color32> {
170 None
171 }
172
173 /// Set the width of a custom outer border.
174 /// This is only used when `border_color` returns `Some`.
175 fn border_width(
176 &self,
177 _ui: &egui::Ui,
178 _node_id: NodeId,
179 _graph: &Graph<Self, Self::DataType, Self::ValueType>,
180 _user_state: &mut Self::UserState,
181 ) -> f32 {
182 2.0
183 }
184
185 /// Separator to put between elements in the node.
186 ///
187 /// Invoked between inputs, outputs and bottom UI. Useful for
188 /// complicated UIs that start to lose structure without explicit
189 /// separators. The `param_id` argument is the id of input or output
190 /// *preceeding* the separator.
191 ///
192 /// Default implementation does nothing.
193 fn separator(
194 &self,
195 _ui: &mut egui::Ui,
196 _node_id: NodeId,
197 _param_id: AnyParameterId,
198 _graph: &Graph<Self, Self::DataType, Self::ValueType>,
199 _user_state: &mut Self::UserState,
200 ) {
201 }
202
203 fn can_delete(
204 &self,
205 _node_id: NodeId,
206 _graph: &Graph<Self, Self::DataType, Self::ValueType>,
207 _user_state: &mut Self::UserState,
208 ) -> bool {
209 true
210 }
211
212 fn can_flip(
213 &self,
214 _node_id: NodeId,
215 _graph: &Graph<Self, Self::DataType, Self::ValueType>,
216 _user_state: &mut Self::UserState,
217 ) -> bool {
218 true
219 }
220}
221
222/// This trait can be implemented by any user type. The trait tells the library
223/// how to enumerate the node templates it will present to the user as part of
224/// the node finder.
225pub trait NodeTemplateIter {
226 type Item;
227 fn all_kinds(&self) -> Vec<Self::Item>;
228}
229
230/// Describes a category of nodes.
231///
232/// Used by [`NodeTemplateTrait::node_finder_categories`] to categorize nodes
233/// templates into groups.
234///
235/// If all nodes in a program are known beforehand, it's usefult to define
236/// an enum containing all categories and implement [`CategoryTrait`] for it. This will
237/// make it impossible to accidentally create a new category by mis-typing an existing
238/// one, like in the case of using string types.
239pub trait CategoryTrait {
240 /// Name of the category.
241 fn name(&self) -> String;
242}
243
244impl CategoryTrait for () {
245 fn name(&self) -> String {
246 String::new()
247 }
248}
249
250impl CategoryTrait for &str {
251 fn name(&self) -> String {
252 self.to_string()
253 }
254}
255
256impl CategoryTrait for String {
257 fn name(&self) -> String {
258 self.clone()
259 }
260}
261
262/// This trait must be implemented by the `NodeTemplate` generic parameter of
263/// the [`GraphEditorState`]. It allows the customization of node templates. A
264/// node template is what describes what kinds of nodes can be added to the
265/// graph, what is their name, and what are their input / output parameters.
266pub trait NodeTemplateTrait: Clone {
267 /// Must be set to the custom user `NodeData` type
268 type NodeData;
269 /// Must be set to the custom user `DataType` type
270 type DataType;
271 /// Must be set to the custom user `ValueType` type
272 type ValueType;
273 /// Must be set to the custom user `UserState` type
274 type UserState;
275 /// Must be a type that implements the [`CategoryTrait`] trait.
276 ///
277 /// `&'static str` is a good default if you intend to simply type out
278 /// the categories of your node. Use `()` if you don't need categories
279 /// at all.
280 type CategoryType;
281
282 /// Returns a descriptive name for the node kind, used in the node finder.
283 ///
284 /// The return type is Cow<str> to allow returning owned or borrowed values
285 /// more flexibly. Refer to the documentation for `DataTypeTrait::name` for
286 /// more information
287 fn node_finder_label(&self, user_state: &mut Self::UserState) -> std::borrow::Cow<'_, str>;
288
289 /// Vec of categories to which the node belongs.
290 ///
291 /// It's often useful to organize similar nodes into categories, which will
292 /// then be used by the node finder to show a more manageable UI, especially
293 /// if the node template are numerous.
294 fn node_finder_categories(&self, _user_state: &mut Self::UserState) -> Vec<Self::CategoryType> {
295 Vec::default()
296 }
297
298 /// Returns a descriptive name for the node kind, used in the graph.
299 fn node_graph_label(&self, user_state: &mut Self::UserState) -> String;
300
301 /// Returns the user data for this node kind.
302 fn user_data(&self, user_state: &mut Self::UserState) -> Self::NodeData;
303
304 /// This function is run when this node kind gets added to the graph. The
305 /// node will be empty by default, and this function can be used to fill its
306 /// parameters.
307 fn build_node(
308 &self,
309 graph: &mut Graph<Self::NodeData, Self::DataType, Self::ValueType>,
310 user_state: &mut Self::UserState,
311 node_id: NodeId,
312 );
313}
314
315/// The custom user response types when drawing nodes in the graph must
316/// implement this trait.
317pub trait UserResponseTrait: Clone + std::fmt::Debug {}