1use nuit_derive::Diff;
2use serde::{Serialize, Deserialize};
3
4use crate::{Alignment, Id, IdPath, IdPathBuf, Identified};
5
6use super::{GestureNode, ModifierNode, ShapeNode};
7
8#[derive(Debug, Clone, PartialEq, Diff, Serialize, Deserialize)]
10#[serde(rename_all = "camelCase", rename_all_fields = "camelCase")]
11pub enum Node {
12 Empty {}, Text { content: String },
16 TextField { content: String },
17 Button { label: Box<Identified<Node>> },
18 Picker { title: String, selection: Id, content: Box<Identified<Node>> },
19
20 Child { wrapped: Box<Identified<Node>> },
22 Group { children: Vec<Identified<Node>> },
23
24 VStack { spacing: f64, wrapped: Box<Identified<Node>> },
26 HStack { spacing: f64, wrapped: Box<Identified<Node>> },
27 ZStack { spacing: f64, wrapped: Box<Identified<Node>> },
28 List { wrapped: Box<Identified<Node>> },
29 Overlay { wrapped: Box<Identified<Node>>, alignment: Alignment, overlayed: Box<Identified<Node>> },
30
31 Shape { shape: ShapeNode },
33 Gestured { wrapped: Box<Identified<Node>>, gesture: Identified<GestureNode>, },
34 Modified { wrapped: Box<Identified<Node>>, modifier: ModifierNode, }
35}
36
37impl Node {
38 pub fn children(&self) -> Vec<(IdPathBuf, &Node)> {
39 self.children_from(IdPath::root())
40 }
41
42 pub fn children_from(&self, path: &IdPath) -> Vec<(IdPathBuf, &Node)> {
43 match self {
44 Self::Group { children } => children.iter()
45 .flat_map(|c| c.value().children_from(&path.child(c.id().clone())).into_iter())
46 .collect(),
47 _ => vec![(path.to_owned(), self)]
48 }
49 }
50}
51
52impl Default for Node {
53 fn default() -> Self {
54 Node::Empty {}
55 }
56}