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
use egui::{Pos2, Rect, Ui};
use crate::{InPin, InPinId, NodeId, OutPin, OutPinId, Snarl};
use super::pin::{AnyPins, PinInfo};
/// SnarlViewer is a trait for viewing a Snarl.
///
/// It can extract necessary data from the nodes and controls their
/// response to certain events.
pub trait SnarlViewer<T> {
/// Returns title of the node.
fn title(&mut self, node: &T) -> String;
/// Renders the node's header.
#[inline]
fn show_header(
&mut self,
node: NodeId,
inputs: &[InPin],
outputs: &[OutPin],
ui: &mut Ui,
scale: f32,
snarl: &mut Snarl<T>,
) {
let _ = (inputs, outputs, scale);
ui.label(self.title(&snarl[node]));
}
/// Returns number of output pins of the node.
fn outputs(&mut self, node: &T) -> usize;
/// Returns number of input pins of the node.
fn inputs(&mut self, node: &T) -> usize;
/// Renders the node's input pin.
fn show_input(&mut self, pin: &InPin, ui: &mut Ui, scale: f32, snarl: &mut Snarl<T>)
-> PinInfo;
/// Renders the node's output pin.
fn show_output(
&mut self,
pin: &OutPin,
ui: &mut Ui,
scale: f32,
snarl: &mut Snarl<T>,
) -> PinInfo;
/// 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,
inputs: &[InPin],
outputs: &[OutPin],
ui: &mut Ui,
scale: f32,
snarl: &mut Snarl<T>,
) {
let _ = (node, inputs, outputs, ui, scale, snarl);
}
/// Checks if node has something to show in footer - below pins and body.
#[inline]
fn has_footer(&mut self, node: &T) -> bool {
let _ = node;
false
}
/// Renders the node's footer.
#[inline]
fn show_footer(
&mut self,
node: NodeId,
inputs: &[InPin],
outputs: &[OutPin],
ui: &mut Ui,
scale: f32,
snarl: &mut Snarl<T>,
) {
let _ = (node, inputs, outputs, ui, scale, snarl);
}
/// 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 modfied directly in this method.
#[inline]
fn final_node_rect(
&mut self,
node: NodeId,
ui_rect: Rect,
graph_rect: Rect,
ui: &mut Ui,
scale: f32,
snarl: &mut Snarl<T>,
) {
let _ = (node, ui_rect, graph_rect, ui, scale, snarl);
}
/// 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,
scale: f32,
snarl: &mut Snarl<T>,
) {
let _ = (node, inputs, outputs, ui, scale, snarl);
}
/// 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, snarl: &Snarl<T>) -> bool {
let _ = (from, to, snarl);
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,
scale: f32,
snarl: &mut Snarl<T>,
) {
let _ = (from, to, ui, scale, snarl);
}
/// Checks if the snarl 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, snarl: &mut Snarl<T>) -> bool {
let _ = (pos, snarl);
false
}
/// Show context menu for the snarl.
///
/// This can be used to implement menu for adding new nodes.
#[inline]
fn show_graph_menu(&mut self, pos: Pos2, ui: &mut Ui, scale: f32, snarl: &mut Snarl<T>) {
let _ = (pos, ui, scale, snarl);
}
/// Checks if the snarl 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, snarl: &mut Snarl<T>) -> bool {
let _ = (src_pins, snarl);
false
}
/// Show context menu for the snarl. 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,
scale: f32,
src_pins: AnyPins,
snarl: &mut Snarl<T>,
) {
let _ = (pos, ui, scale, src_pins, snarl);
}
/// 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 snarl.
///
/// 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,
scale: f32,
snarl: &mut Snarl<T>,
) {
let _ = (node, inputs, outputs, ui, scale, snarl);
}
/// 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, snarl: &mut Snarl<T>) {
snarl.connect(from.id, to.id);
}
/// Asks the viewer to disconnect two pins.
#[inline]
fn disconnect(&mut self, from: &OutPin, to: &InPin, snarl: &mut Snarl<T>) {
snarl.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, snarl: &mut Snarl<T>) {
snarl.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, snarl: &mut Snarl<T>) {
snarl.drop_inputs(pin.id);
}
}