1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
use egui::{Painter, Pos2, Rect, Style, Ui, emath::TSTransform};
use crate::{InPin, InPinId, NodeId, OutPin, OutPinId, Treeize};
use super::{
BackgroundPattern, NodeLayout, TreeizeStyle,
pin::{AnyPins, TreeizePin},
};
/// `TreeizeViewer` is a trait for viewing a Treeize.
///
/// It can extract necessary data from the nodes and controls their
/// response to certain events.
pub trait TreeizeViewer<T> {
/// Returns title of the node.
fn title(&mut self, node: &T) -> String;
/// Returns the node's frame.
/// All node's elements will be rendered inside this frame.
/// Except for pins if they are configured to be rendered outside of the frame.
///
/// Returns `default` by default.
/// `default` frame is taken from the [`TreeizeStyle::node_frame`] or constructed if it's `None`.
///
/// Override this method to customize the frame for specific nodes.
fn node_frame(
&mut self,
default: egui::Frame,
node: NodeId,
inputs: &[InPin],
outputs: &[OutPin],
treeize: &Treeize<T>,
) -> egui::Frame {
let _ = (node, inputs, outputs, treeize);
default
}
/// Returns the node's header frame.
///
/// This frame would be placed on top of the node's frame.
/// And header UI (see [`show_header`]) will be placed inside this frame.
///
/// Returns `default` by default.
/// `default` frame is taken from the [`TreeizeStyle::header_frame`],
/// or [`TreeizeStyle::node_frame`] with removed shadow if `None`,
/// or constructed if both are `None`.
fn header_frame(
&mut self,
default: egui::Frame,
node: NodeId,
inputs: &[InPin],
outputs: &[OutPin],
treeize: &Treeize<T>,
) -> egui::Frame {
let _ = (node, inputs, outputs, treeize);
default
}
/// Checks if node has a custom egui style.
#[inline]
fn has_node_style(
&mut self,
node: NodeId,
inputs: &[InPin],
outputs: &[OutPin],
treeize: &Treeize<T>,
) -> bool {
let _ = (node, inputs, outputs, treeize);
false
}
/// Modifies the node's egui style
fn apply_node_style(
&mut self,
style: &mut Style,
node: NodeId,
inputs: &[InPin],
outputs: &[OutPin],
treeize: &Treeize<T>,
) {
let _ = (style, node, inputs, outputs, treeize);
}
/// Returns elements layout for the node.
///
/// Node consists of 4 parts: header, body, input pins and output pins.
/// See [`NodeLayout`] for available placements.
///
/// Returns `default` by default.
/// `default` layout is taken from the [`TreeizeStyle::node_layout`] or constructed if it's `None`.
/// Override this method to customize the layout for specific nodes.
#[inline]
fn node_layout(
&mut self,
default: NodeLayout,
node: NodeId,
inputs: &[InPin],
outputs: &[OutPin],
treeize: &Treeize<T>,
) -> NodeLayout {
let _ = (node, inputs, outputs, treeize);
default
}
/// Renders elements inside the node's header frame.
///
/// This is the good place to show the node's title and controls related to the whole node.
///
/// By default it shows the node's title.
#[inline]
fn show_header(&mut self, node: NodeId, ui: &mut Ui, treeize: &mut Treeize<T>) {
let _ = node;
ui.label(self.title(&treeize[node]));
}
/// Returns true if node has an input pin.
fn has_input(&mut self, node: &T) -> bool;
/// Returns true if node has an output pin.
fn has_output(&mut self, node: &T) -> bool;
/// Renders one specified node's input element and returns drawer for the corresponding pin.
fn show_input(
&mut self,
pin: &InPin,
ui: &mut Ui,
treeize: &mut Treeize<T>,
) -> impl TreeizePin + 'static;
/// Renders the node's output.
fn show_output(
&mut self,
pin: &OutPin,
ui: &mut Ui,
treeize: &mut Treeize<T>,
) -> impl TreeizePin + 'static;
/// Checks if node has something to show in body - between input and output pins.
#[inline]
fn has_body(&mut self, node: &T) -> bool {
let _ = node;
false
}
/// Renders the node's body.
#[inline]
fn show_body(&mut self, node: NodeId, ui: &mut Ui, treeize: &mut Treeize<T>) {
let _ = (node, ui, treeize);
}
/// Reports the final node's rect after rendering.
///
/// It aimed to be used for custom positioning of nodes that requires node dimensions for calculations.
/// Node's position can be modified directly in this method.
#[inline]
fn final_node_rect(&mut self, node: NodeId, rect: Rect, ui: &mut Ui, treeize: &mut Treeize<T>) {
let _ = (node, rect, ui, treeize);
}
/// Checks if node has something to show in on-hover popup.
#[inline]
fn has_on_hover_popup(&mut self, node: &T) -> bool {
let _ = node;
false
}
/// Renders the node's on-hover popup.
#[inline]
fn show_on_hover_popup(
&mut self,
node: NodeId,
inputs: &[InPin],
outputs: &[OutPin],
ui: &mut Ui,
treeize: &mut Treeize<T>,
) {
let _ = (node, inputs, outputs, ui, treeize);
}
/// Checks if wire has something to show in widget.
/// This may not be called if wire is invisible.
#[inline]
fn has_wire_widget(&mut self, from: &OutPinId, to: &InPinId, treeize: &Treeize<T>) -> bool {
let _ = (from, to, treeize);
false
}
/// Renders the wire's widget.
/// This may not be called if wire is invisible.
#[inline]
fn show_wire_widget(&mut self, from: &OutPin, to: &InPin, ui: &mut Ui, treeize: &mut Treeize<T>) {
let _ = (from, to, ui, treeize);
}
/// Checks if the treeize has something to show in context menu if right-clicked or long-touched on empty space at `pos`.
#[inline]
fn has_graph_menu(&mut self, pos: Pos2, treeize: &mut Treeize<T>) -> bool {
let _ = (pos, treeize);
false
}
/// Show context menu for the treeize.
///
/// This can be used to implement menu for adding new nodes.
#[inline]
fn show_graph_menu(&mut self, pos: Pos2, ui: &mut Ui, treeize: &mut Treeize<T>) {
let _ = (pos, ui, treeize);
}
/// Checks if the treeize has something to show in context menu if wire drag is stopped at `pos`.
#[inline]
fn has_dropped_wire_menu(&mut self, src_pins: AnyPins, treeize: &mut Treeize<T>) -> bool {
let _ = (src_pins, treeize);
false
}
/// Show context menu for the treeize. This menu is opened when releasing a pin to empty
/// space. It can be used to implement menu for adding new node, and directly
/// connecting it to the released wire.
#[inline]
fn show_dropped_wire_menu(
&mut self,
pos: Pos2,
ui: &mut Ui,
src_pins: AnyPins,
treeize: &mut Treeize<T>,
) {
let _ = (pos, ui, src_pins, treeize);
}
/// Checks if the node has something to show in context menu if right-clicked or long-touched on the node.
#[inline]
fn has_node_menu(&mut self, node: &T) -> bool {
let _ = node;
false
}
/// Show context menu for the treeize.
///
/// This can be used to implement menu for adding new nodes.
#[inline]
fn show_node_menu(
&mut self,
node: NodeId,
inputs: &[InPin],
outputs: &[OutPin],
ui: &mut Ui,
treeize: &mut Treeize<T>,
) {
let _ = (node, inputs, outputs, ui, treeize);
}
/// Asks the viewer to connect two pins.
///
/// This is usually happens when user drags a wire from one node's output pin to another node's input pin or vice versa.
/// By default this method connects the pins and returns `Ok(())`.
#[inline]
fn connect(&mut self, from: &OutPin, to: &InPin, treeize: &mut Treeize<T>) {
treeize.connect(from.id, to.id);
}
/// Asks the viewer to disconnect two pins.
#[inline]
fn disconnect(&mut self, from: &OutPin, to: &InPin, treeize: &mut Treeize<T>) {
treeize.disconnect(from.id, to.id);
}
/// Asks the viewer to disconnect all wires from the output pin.
///
/// This is usually happens when right-clicking on an output pin.
/// By default this method disconnects the pins and returns `Ok(())`.
#[inline]
fn drop_outputs(&mut self, pin: &OutPin, treeize: &mut Treeize<T>) {
treeize.drop_outputs(pin.id);
}
/// Asks the viewer to disconnect all wires from the input pin.
///
/// This is usually happens when right-clicking on an input pin.
/// By default this method disconnects the pins and returns `Ok(())`.
#[inline]
fn drop_inputs(&mut self, pin: &InPin, treeize: &mut Treeize<T>) {
treeize.drop_inputs(pin.id);
}
/// Draws background of the treeize view.
///
/// By default it draws the background pattern using [`BackgroundPattern::draw`].
///
/// If you want to draw the background yourself, you can override this method.
#[inline]
fn draw_background(
&mut self,
background: Option<&BackgroundPattern>,
viewport: &Rect,
treeize_style: &TreeizeStyle,
style: &Style,
painter: &Painter,
treeize: &Treeize<T>,
) {
let _ = treeize;
if let Some(background) = background {
background.draw(viewport, treeize_style, style, painter);
}
}
/// Informs the viewer what is the current transform of the treeize view
/// and allows viewer to override it.
///
/// This method is called in the beginning of the graph rendering.
///
/// By default it does nothing.
#[inline]
fn current_transform(&mut self, to_global: &mut TSTransform, treeize: &mut Treeize<T>) {
let _ = (to_global, treeize);
}
}