1use super::core::NodeEditorFrame;
2use super::queries::{collect_link_ids, collect_node_ids};
3use super::validation::{assert_finite_vec4, assert_non_negative_finite_f32};
4use crate::{EditorContext, LinkId, NodeId, PinId, sys, vec4};
5use std::{marker::PhantomData, rc::Rc};
6
7impl<'ui> NodeEditorFrame<'ui> {
8 pub fn begin_create<'a>(
9 &'a self,
10 color: [f32; 4],
11 thickness: f32,
12 ) -> Option<CreateSession<'a>> {
13 assert_finite_vec4("NodeEditorFrame::begin_create()", "color", color);
14 assert_non_negative_finite_f32("NodeEditorFrame::begin_create()", "thickness", thickness);
15 let _current_editor = self.bind("NodeEditorFrame::begin_create()");
16 unsafe { sys::dne_begin_create(vec4(color), thickness) }.then_some(CreateSession {
17 editor: self._editor,
18 ended: false,
19 _not_send_sync: PhantomData,
20 })
21 }
22
23 pub fn begin_delete<'a>(&'a self) -> Option<DeleteSession<'a>> {
24 let _current_editor = self.bind("NodeEditorFrame::begin_delete()");
25 unsafe { sys::dne_begin_delete() }.then_some(DeleteSession {
26 editor: self._editor,
27 ended: false,
28 _not_send_sync: PhantomData,
29 })
30 }
31
32 pub fn begin_shortcut<'a>(&'a self) -> Option<ShortcutSession<'a>> {
33 let _current_editor = self.bind("NodeEditorFrame::begin_shortcut()");
34 unsafe { sys::dne_begin_shortcut() }.then_some(ShortcutSession {
35 editor: self._editor,
36 ended: false,
37 _not_send_sync: PhantomData,
38 })
39 }
40}
41
42pub struct CreateSession<'a> {
43 editor: &'a EditorContext,
44 ended: bool,
45 _not_send_sync: PhantomData<Rc<()>>,
46}
47
48impl CreateSession<'_> {
49 pub fn query_new_link(&self) -> Option<(PinId, PinId)> {
50 let _current_editor = self.editor.bind_current("CreateSession::query_new_link()");
51 let mut start = 0usize;
52 let mut end = 0usize;
53 unsafe { sys::dne_query_new_link(&mut start, &mut end) }
54 .then_some((PinId(start), PinId(end)))
55 }
56
57 pub fn query_new_link_styled(&self, color: [f32; 4], thickness: f32) -> Option<(PinId, PinId)> {
58 assert_finite_vec4("CreateSession::query_new_link_styled()", "color", color);
59 assert_non_negative_finite_f32(
60 "CreateSession::query_new_link_styled()",
61 "thickness",
62 thickness,
63 );
64 let _current_editor = self
65 .editor
66 .bind_current("CreateSession::query_new_link_styled()");
67 let mut start = 0usize;
68 let mut end = 0usize;
69 unsafe { sys::dne_query_new_link_styled(&mut start, &mut end, vec4(color), thickness) }
70 .then_some((PinId(start), PinId(end)))
71 }
72
73 pub fn query_new_node(&self) -> Option<PinId> {
74 let _current_editor = self.editor.bind_current("CreateSession::query_new_node()");
75 let mut pin = 0usize;
76 unsafe { sys::dne_query_new_node(&mut pin) }.then_some(PinId(pin))
77 }
78
79 pub fn query_new_node_styled(&self, color: [f32; 4], thickness: f32) -> Option<PinId> {
80 assert_finite_vec4("CreateSession::query_new_node_styled()", "color", color);
81 assert_non_negative_finite_f32(
82 "CreateSession::query_new_node_styled()",
83 "thickness",
84 thickness,
85 );
86 let _current_editor = self
87 .editor
88 .bind_current("CreateSession::query_new_node_styled()");
89 let mut pin = 0usize;
90 unsafe { sys::dne_query_new_node_styled(&mut pin, vec4(color), thickness) }
91 .then_some(PinId(pin))
92 }
93
94 pub fn accept_new_item(&self) -> bool {
95 let _current_editor = self.editor.bind_current("CreateSession::accept_new_item()");
96 unsafe { sys::dne_accept_new_item() }
97 }
98
99 pub fn accept_new_item_styled(&self, color: [f32; 4], thickness: f32) -> bool {
100 assert_finite_vec4("CreateSession::accept_new_item_styled()", "color", color);
101 assert_non_negative_finite_f32(
102 "CreateSession::accept_new_item_styled()",
103 "thickness",
104 thickness,
105 );
106 let _current_editor = self
107 .editor
108 .bind_current("CreateSession::accept_new_item_styled()");
109 unsafe { sys::dne_accept_new_item_styled(vec4(color), thickness) }
110 }
111
112 pub fn reject_new_item(&self) {
113 let _current_editor = self.editor.bind_current("CreateSession::reject_new_item()");
114 unsafe { sys::dne_reject_new_item() };
115 }
116
117 pub fn reject_new_item_styled(&self, color: [f32; 4], thickness: f32) {
118 assert_finite_vec4("CreateSession::reject_new_item_styled()", "color", color);
119 assert_non_negative_finite_f32(
120 "CreateSession::reject_new_item_styled()",
121 "thickness",
122 thickness,
123 );
124 let _current_editor = self
125 .editor
126 .bind_current("CreateSession::reject_new_item_styled()");
127 unsafe { sys::dne_reject_new_item_styled(vec4(color), thickness) };
128 }
129
130 pub fn end(mut self) {
131 self.end_inner();
132 }
133
134 fn end_inner(&mut self) {
135 if !self.ended {
136 let _current_editor = self.editor.bind_current("CreateSession::end()");
137 unsafe { sys::dne_end_create() };
138 self.ended = true;
139 }
140 }
141}
142
143impl Drop for CreateSession<'_> {
144 fn drop(&mut self) {
145 self.end_inner();
146 }
147}
148
149pub struct DeleteSession<'a> {
150 editor: &'a EditorContext,
151 ended: bool,
152 _not_send_sync: PhantomData<Rc<()>>,
153}
154
155impl DeleteSession<'_> {
156 pub fn query_deleted_link(&self) -> Option<(LinkId, PinId, PinId)> {
157 let _current_editor = self
158 .editor
159 .bind_current("DeleteSession::query_deleted_link()");
160 let mut link = 0usize;
161 let mut start = 0usize;
162 let mut end = 0usize;
163 unsafe { sys::dne_query_deleted_link(&mut link, &mut start, &mut end) }.then_some((
164 LinkId(link),
165 PinId(start),
166 PinId(end),
167 ))
168 }
169
170 pub fn query_deleted_node(&self) -> Option<NodeId> {
171 let _current_editor = self
172 .editor
173 .bind_current("DeleteSession::query_deleted_node()");
174 let mut node = 0usize;
175 unsafe { sys::dne_query_deleted_node(&mut node) }.then_some(NodeId(node))
176 }
177
178 pub fn accept_deleted_item(&self, delete_dependencies: bool) -> bool {
179 let _current_editor = self
180 .editor
181 .bind_current("DeleteSession::accept_deleted_item()");
182 unsafe { sys::dne_accept_deleted_item(delete_dependencies) }
183 }
184
185 pub fn reject_deleted_item(&self) {
186 let _current_editor = self
187 .editor
188 .bind_current("DeleteSession::reject_deleted_item()");
189 unsafe { sys::dne_reject_deleted_item() };
190 }
191
192 pub fn end(mut self) {
193 self.end_inner();
194 }
195
196 fn end_inner(&mut self) {
197 if !self.ended {
198 let _current_editor = self.editor.bind_current("DeleteSession::end()");
199 unsafe { sys::dne_end_delete() };
200 self.ended = true;
201 }
202 }
203}
204
205impl Drop for DeleteSession<'_> {
206 fn drop(&mut self) {
207 self.end_inner();
208 }
209}
210
211pub struct ShortcutSession<'a> {
212 editor: &'a EditorContext,
213 ended: bool,
214 _not_send_sync: PhantomData<Rc<()>>,
215}
216
217impl ShortcutSession<'_> {
218 pub fn accept_cut(&self) -> bool {
219 let _current_editor = self.editor.bind_current("ShortcutSession::accept_cut()");
220 unsafe { sys::dne_accept_cut() }
221 }
222
223 pub fn accept_copy(&self) -> bool {
224 let _current_editor = self.editor.bind_current("ShortcutSession::accept_copy()");
225 unsafe { sys::dne_accept_copy() }
226 }
227
228 pub fn accept_paste(&self) -> bool {
229 let _current_editor = self.editor.bind_current("ShortcutSession::accept_paste()");
230 unsafe { sys::dne_accept_paste() }
231 }
232
233 pub fn accept_duplicate(&self) -> bool {
234 let _current_editor = self
235 .editor
236 .bind_current("ShortcutSession::accept_duplicate()");
237 unsafe { sys::dne_accept_duplicate() }
238 }
239
240 pub fn accept_create_node(&self) -> bool {
241 let _current_editor = self
242 .editor
243 .bind_current("ShortcutSession::accept_create_node()");
244 unsafe { sys::dne_accept_create_node() }
245 }
246
247 pub fn action_context_size(&self) -> usize {
248 let _current_editor = self
249 .editor
250 .bind_current("ShortcutSession::action_context_size()");
251 unsafe { sys::dne_get_action_context_size() }.max(0) as usize
252 }
253
254 pub fn action_context_nodes(&self) -> Vec<NodeId> {
255 let count = self.action_context_size();
256 let _current_editor = self
257 .editor
258 .bind_current("ShortcutSession::action_context_nodes()");
259 collect_node_ids(count, |ptr, len| unsafe {
260 sys::dne_get_action_context_nodes(ptr, len)
261 })
262 }
263
264 pub fn action_context_links(&self) -> Vec<LinkId> {
265 let count = self.action_context_size();
266 let _current_editor = self
267 .editor
268 .bind_current("ShortcutSession::action_context_links()");
269 collect_link_ids(count, |ptr, len| unsafe {
270 sys::dne_get_action_context_links(ptr, len)
271 })
272 }
273
274 pub fn end(mut self) {
275 self.end_inner();
276 }
277
278 fn end_inner(&mut self) {
279 if !self.ended {
280 let _current_editor = self.editor.bind_current("ShortcutSession::end()");
281 unsafe { sys::dne_end_shortcut() };
282 self.ended = true;
283 }
284 }
285}
286
287impl Drop for ShortcutSession<'_> {
288 fn drop(&mut self) {
289 self.end_inner();
290 }
291}