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::{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 unsafe { sys::dne_begin_create(vec4(color), thickness) }.then_some(CreateSession {
16 ended: false,
17 _scope: PhantomData,
18 _not_send_sync: PhantomData,
19 })
20 }
21
22 pub fn begin_delete<'a>(&'a self) -> Option<DeleteSession<'a>> {
23 unsafe { sys::dne_begin_delete() }.then_some(DeleteSession {
24 ended: false,
25 _scope: PhantomData,
26 _not_send_sync: PhantomData,
27 })
28 }
29
30 pub fn begin_shortcut<'a>(&'a self) -> Option<ShortcutSession<'a>> {
31 unsafe { sys::dne_begin_shortcut() }.then_some(ShortcutSession {
32 ended: false,
33 _scope: PhantomData,
34 _not_send_sync: PhantomData,
35 })
36 }
37}
38
39pub struct CreateSession<'a> {
40 ended: bool,
41 _scope: PhantomData<&'a ()>,
42 _not_send_sync: PhantomData<Rc<()>>,
43}
44
45impl CreateSession<'_> {
46 pub fn query_new_link(&self) -> Option<(PinId, PinId)> {
47 let mut start = 0usize;
48 let mut end = 0usize;
49 unsafe { sys::dne_query_new_link(&mut start, &mut end) }
50 .then_some((PinId(start), PinId(end)))
51 }
52
53 pub fn query_new_link_styled(&self, color: [f32; 4], thickness: f32) -> Option<(PinId, PinId)> {
54 assert_finite_vec4("CreateSession::query_new_link_styled()", "color", color);
55 assert_non_negative_finite_f32(
56 "CreateSession::query_new_link_styled()",
57 "thickness",
58 thickness,
59 );
60 let mut start = 0usize;
61 let mut end = 0usize;
62 unsafe { sys::dne_query_new_link_styled(&mut start, &mut end, vec4(color), thickness) }
63 .then_some((PinId(start), PinId(end)))
64 }
65
66 pub fn query_new_node(&self) -> Option<PinId> {
67 let mut pin = 0usize;
68 unsafe { sys::dne_query_new_node(&mut pin) }.then_some(PinId(pin))
69 }
70
71 pub fn query_new_node_styled(&self, color: [f32; 4], thickness: f32) -> Option<PinId> {
72 assert_finite_vec4("CreateSession::query_new_node_styled()", "color", color);
73 assert_non_negative_finite_f32(
74 "CreateSession::query_new_node_styled()",
75 "thickness",
76 thickness,
77 );
78 let mut pin = 0usize;
79 unsafe { sys::dne_query_new_node_styled(&mut pin, vec4(color), thickness) }
80 .then_some(PinId(pin))
81 }
82
83 pub fn accept_new_item(&self) -> bool {
84 unsafe { sys::dne_accept_new_item() }
85 }
86
87 pub fn accept_new_item_styled(&self, color: [f32; 4], thickness: f32) -> bool {
88 assert_finite_vec4("CreateSession::accept_new_item_styled()", "color", color);
89 assert_non_negative_finite_f32(
90 "CreateSession::accept_new_item_styled()",
91 "thickness",
92 thickness,
93 );
94 unsafe { sys::dne_accept_new_item_styled(vec4(color), thickness) }
95 }
96
97 pub fn reject_new_item(&self) {
98 unsafe { sys::dne_reject_new_item() };
99 }
100
101 pub fn reject_new_item_styled(&self, color: [f32; 4], thickness: f32) {
102 assert_finite_vec4("CreateSession::reject_new_item_styled()", "color", color);
103 assert_non_negative_finite_f32(
104 "CreateSession::reject_new_item_styled()",
105 "thickness",
106 thickness,
107 );
108 unsafe { sys::dne_reject_new_item_styled(vec4(color), thickness) };
109 }
110
111 pub fn end(mut self) {
112 self.end_inner();
113 }
114
115 fn end_inner(&mut self) {
116 if !self.ended {
117 unsafe { sys::dne_end_create() };
118 self.ended = true;
119 }
120 }
121}
122
123impl Drop for CreateSession<'_> {
124 fn drop(&mut self) {
125 self.end_inner();
126 }
127}
128
129pub struct DeleteSession<'a> {
130 ended: bool,
131 _scope: PhantomData<&'a ()>,
132 _not_send_sync: PhantomData<Rc<()>>,
133}
134
135impl DeleteSession<'_> {
136 pub fn query_deleted_link(&self) -> Option<(LinkId, PinId, PinId)> {
137 let mut link = 0usize;
138 let mut start = 0usize;
139 let mut end = 0usize;
140 unsafe { sys::dne_query_deleted_link(&mut link, &mut start, &mut end) }.then_some((
141 LinkId(link),
142 PinId(start),
143 PinId(end),
144 ))
145 }
146
147 pub fn query_deleted_node(&self) -> Option<NodeId> {
148 let mut node = 0usize;
149 unsafe { sys::dne_query_deleted_node(&mut node) }.then_some(NodeId(node))
150 }
151
152 pub fn accept_deleted_item(&self, delete_dependencies: bool) -> bool {
153 unsafe { sys::dne_accept_deleted_item(delete_dependencies) }
154 }
155
156 pub fn reject_deleted_item(&self) {
157 unsafe { sys::dne_reject_deleted_item() };
158 }
159
160 pub fn end(mut self) {
161 self.end_inner();
162 }
163
164 fn end_inner(&mut self) {
165 if !self.ended {
166 unsafe { sys::dne_end_delete() };
167 self.ended = true;
168 }
169 }
170}
171
172impl Drop for DeleteSession<'_> {
173 fn drop(&mut self) {
174 self.end_inner();
175 }
176}
177
178pub struct ShortcutSession<'a> {
179 ended: bool,
180 _scope: PhantomData<&'a ()>,
181 _not_send_sync: PhantomData<Rc<()>>,
182}
183
184impl ShortcutSession<'_> {
185 pub fn accept_cut(&self) -> bool {
186 unsafe { sys::dne_accept_cut() }
187 }
188
189 pub fn accept_copy(&self) -> bool {
190 unsafe { sys::dne_accept_copy() }
191 }
192
193 pub fn accept_paste(&self) -> bool {
194 unsafe { sys::dne_accept_paste() }
195 }
196
197 pub fn accept_duplicate(&self) -> bool {
198 unsafe { sys::dne_accept_duplicate() }
199 }
200
201 pub fn accept_create_node(&self) -> bool {
202 unsafe { sys::dne_accept_create_node() }
203 }
204
205 pub fn action_context_size(&self) -> usize {
206 unsafe { sys::dne_get_action_context_size() }.max(0) as usize
207 }
208
209 pub fn action_context_nodes(&self) -> Vec<NodeId> {
210 let count = self.action_context_size();
211 collect_node_ids(count, |ptr, len| unsafe {
212 sys::dne_get_action_context_nodes(ptr, len)
213 })
214 }
215
216 pub fn action_context_links(&self) -> Vec<LinkId> {
217 let count = self.action_context_size();
218 collect_link_ids(count, |ptr, len| unsafe {
219 sys::dne_get_action_context_links(ptr, len)
220 })
221 }
222
223 pub fn end(mut self) {
224 self.end_inner();
225 }
226
227 fn end_inner(&mut self) {
228 if !self.ended {
229 unsafe { sys::dne_end_shortcut() };
230 self.ended = true;
231 }
232 }
233}
234
235impl Drop for ShortcutSession<'_> {
236 fn drop(&mut self) {
237 self.end_inner();
238 }
239}