1#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6use crate::error::Result;
7use crate::handle::{Handle, HandleId, HandleManager};
8use crate::types::{NodeId, Position, Rect, Size};
9
10#[derive(Debug, Clone, PartialEq)]
12#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
13pub struct Node<T = ()> {
14 pub id: NodeId,
15 pub position: Position,
16 pub size: Size,
17 pub data: T,
18
19 pub node_type: Option<String>,
21 pub selected: bool,
22 pub dragging: bool,
23 pub selectable: bool,
24 pub connectable: bool,
25 pub deletable: bool,
26 pub drag_handle: Option<String>,
27 pub parent_node: Option<NodeId>,
28 pub z_index: Option<i32>,
29 pub hidden: bool,
30
31 #[cfg_attr(feature = "serde", serde(skip))]
33 pub measured: Option<Size>,
34
35 #[cfg_attr(feature = "serde", serde(skip))]
37 handle_manager: HandleManager,
38}
39
40impl<T: Clone> Node<T> {
41 pub fn new(id: impl Into<NodeId>, position: Position, data: T) -> Self {
43 let node_id = id.into();
44 Self {
45 id: node_id.clone(),
46 position,
47 size: Size::default(),
48 data,
49 node_type: None,
50 selected: false,
51 dragging: false,
52 selectable: true,
53 connectable: true,
54 deletable: true,
55 drag_handle: None,
56 parent_node: None,
57 z_index: None,
58 hidden: false,
59 measured: None,
60 handle_manager: HandleManager::new(node_id),
61 }
62 }
63
64 pub fn builder(id: impl Into<NodeId>) -> NodeBuilder<T>
66 where
67 T: Default,
68 {
69 NodeBuilder::new(id)
70 }
71
72 pub fn bounds(&self) -> Rect {
74 Rect::from_pos_size(self.position, self.size)
75 }
76
77 pub fn center(&self) -> Position {
79 self.bounds().center()
80 }
81
82 pub fn contains_point(&self, point: Position) -> bool {
84 self.bounds().contains_point(point)
85 }
86
87 pub fn set_position(&mut self, position: Position) {
89 self.position = position;
90 }
91
92 pub fn set_size(&mut self, size: Size) {
94 self.size = size;
95 }
96
97 pub fn set_selected(&mut self, selected: bool) {
99 self.selected = selected;
100 }
101
102 pub fn set_dragging(&mut self, dragging: bool) {
104 self.dragging = dragging;
105 }
106
107 pub fn map_data<U>(self, f: impl FnOnce(T) -> U) -> Node<U> {
109 Node {
110 id: self.id.clone(),
111 position: self.position,
112 size: self.size,
113 data: f(self.data),
114 node_type: self.node_type,
115 selected: self.selected,
116 dragging: self.dragging,
117 selectable: self.selectable,
118 connectable: self.connectable,
119 deletable: self.deletable,
120 drag_handle: self.drag_handle,
121 parent_node: self.parent_node,
122 z_index: self.z_index,
123 hidden: self.hidden,
124 measured: self.measured,
125 handle_manager: HandleManager::new(self.id),
126 }
127 }
128}
129
130impl<T> Node<T> {
131 pub fn add_handle(&mut self, handle: Handle) -> Result<()> {
133 self.handle_manager.add_handle(handle)
134 }
135
136 pub fn remove_handle(&mut self, handle_id: &HandleId) -> Result<Handle> {
138 self.handle_manager.remove_handle(handle_id)
139 }
140
141 pub fn get_handle(&self, handle_id: &HandleId) -> Option<&Handle> {
143 self.handle_manager.get_handle(handle_id)
144 }
145
146 pub fn handles(&self) -> &[Handle] {
148 self.handle_manager.handles()
149 }
150
151 pub fn handle_at_position(&self, point: Position, handle_size: f64) -> Option<&Handle> {
153 self.handle_manager
154 .handle_at_position(point, self.position, self.size, handle_size)
155 }
156
157 pub fn source_handles(&self) -> impl Iterator<Item = &Handle> {
159 self.handle_manager.source_handles()
160 }
161
162 pub fn target_handles(&self) -> impl Iterator<Item = &Handle> {
164 self.handle_manager.target_handles()
165 }
166}
167
168impl Node<()> {
169 pub fn simple(id: impl Into<NodeId>, position: Position) -> Self {
171 Self::new(id, position, ())
172 }
173}
174
175impl<T: Default> Node<T> {
176 pub fn with_default_data(id: impl Into<NodeId>, position: Position) -> Self
178 where
179 T: Default + Clone,
180 {
181 Self::new(id, position, T::default())
182 }
183}
184
185#[derive(Debug)]
187pub struct NodeBuilder<T> {
188 node: Node<T>,
189}
190
191impl<T: Default + Clone> NodeBuilder<T> {
192 pub fn new(id: impl Into<NodeId>) -> Self {
194 Self {
195 node: Node::new(id, Position::zero(), T::default()),
196 }
197 }
198}
199
200impl<T: Clone> NodeBuilder<T> {
201 pub fn with_data(id: impl Into<NodeId>, data: T) -> Self {
203 Self {
204 node: Node::new(id, Position::zero(), data),
205 }
206 }
207
208 pub fn position(mut self, x: f64, y: f64) -> Self {
210 self.node.position = Position::new(x, y);
211 self
212 }
213
214 pub fn at(mut self, position: Position) -> Self {
216 self.node.position = position;
217 self
218 }
219
220 pub fn size(mut self, width: f64, height: f64) -> Self {
222 self.node.size = Size::new(width, height);
223 self
224 }
225
226 pub fn with_size(mut self, size: Size) -> Self {
228 self.node.size = size;
229 self
230 }
231
232 pub fn node_type(mut self, node_type: impl Into<String>) -> Self {
234 self.node.node_type = Some(node_type.into());
235 self
236 }
237
238 pub fn selectable(mut self, selectable: bool) -> Self {
240 self.node.selectable = selectable;
241 self
242 }
243
244 pub fn connectable(mut self, connectable: bool) -> Self {
246 self.node.connectable = connectable;
247 self
248 }
249
250 pub fn deletable(mut self, deletable: bool) -> Self {
252 self.node.deletable = deletable;
253 self
254 }
255
256 pub fn drag_handle(mut self, handle: impl Into<String>) -> Self {
258 self.node.drag_handle = Some(handle.into());
259 self
260 }
261
262 pub fn parent(mut self, parent_id: impl Into<NodeId>) -> Self {
264 self.node.parent_node = Some(parent_id.into());
265 self
266 }
267
268 pub fn z_index(mut self, z_index: i32) -> Self {
270 self.node.z_index = Some(z_index);
271 self
272 }
273
274 pub fn hidden(mut self, hidden: bool) -> Self {
276 self.node.hidden = hidden;
277 self
278 }
279
280 pub fn build(self) -> Node<T> {
282 self.node
283 }
284}