1use freya_core::{
2 integration::*,
3 prelude::{
4 Border,
5 Color,
6 CornerRadius,
7 Fill,
8 Shadow,
9 TextAlign,
10 TextOverflow,
11 TextShadow,
12 },
13};
14use serde::{
15 Deserialize,
16 Serialize,
17};
18use torin::{
19 alignment::Alignment,
20 direction::Direction,
21 gaps::Gaps,
22 prelude::{
23 Area,
24 AreaOf,
25 Content,
26 Inner,
27 Position,
28 VisibleSize,
29 },
30 size::Size,
31};
32
33#[derive(Deserialize, Serialize, Clone, PartialEq, Debug)]
34pub struct NodeInfo {
35 pub window_id: u64,
36 pub is_window: bool,
37 pub node_id: NodeId,
38 pub parent_id: Option<NodeId>,
39 pub children_len: usize,
40 pub height: u16,
41 pub state: NodeState,
42 pub area: Area,
43 pub inner_area: AreaOf<Inner>,
44}
45
46#[derive(Clone, PartialEq, Debug, serde::Serialize, serde::Deserialize)]
47pub struct NodeState {
48 pub style: StyleState,
49 pub text_style: TextStyleState,
50 pub layout: torin::node::Node,
51 pub accessibility: AccessibilityData,
52}
53
54pub trait NodeStateAttributes {
55 fn layout_attributes(&'_ self) -> Vec<(&'_ str, AttributeType<'_>)>;
56 fn text_style_attributes(&'_ self) -> Vec<(&'_ str, AttributeType<'_>)>;
57 fn style_attributes(&'_ self) -> Vec<(&'_ str, AttributeType<'_>)>;
58}
59
60impl NodeStateAttributes for NodeState {
61 fn layout_attributes(&'_ self) -> Vec<(&'_ str, AttributeType<'_>)> {
62 vec![
63 ("width", AttributeType::Size(&self.layout.width)),
64 ("height", AttributeType::Size(&self.layout.height)),
65 ("min_width", AttributeType::Size(&self.layout.minimum_width)),
66 (
67 "min_height",
68 AttributeType::Size(&self.layout.minimum_height),
69 ),
70 ("max_width", AttributeType::Size(&self.layout.maximum_width)),
71 (
72 "max_height",
73 AttributeType::Size(&self.layout.maximum_height),
74 ),
75 (
76 "visible_width",
77 AttributeType::VisibleSize(&self.layout.visible_width),
78 ),
79 (
80 "visible_height",
81 AttributeType::VisibleSize(&self.layout.visible_height),
82 ),
83 (
84 "direction",
85 AttributeType::Direction(&self.layout.direction),
86 ),
87 ("padding", AttributeType::Measures(self.layout.padding)),
88 ("margin", AttributeType::Measures(self.layout.margin)),
89 ("position", AttributeType::Position(&self.layout.position)),
90 (
91 "main_alignment",
92 AttributeType::Alignment(&self.layout.main_alignment),
93 ),
94 (
95 "cross_alignment",
96 AttributeType::Alignment(&self.layout.cross_alignment),
97 ),
98 (
99 "offset_x",
100 AttributeType::Measure(self.layout.offset_x.get()),
101 ),
102 (
103 "offset_y",
104 AttributeType::Measure(self.layout.offset_y.get()),
105 ),
106 ("content", AttributeType::Content(&self.layout.content)),
107 ]
108 }
109 fn style_attributes(&'_ self) -> Vec<(&'_ str, AttributeType<'_>)> {
110 let mut attributes = vec![
111 {
112 let background = &self.style.background;
113 let fill = match *background {
114 Fill::Color(background) => AttributeType::Color(background),
115 Fill::LinearGradient(_) => AttributeType::Gradient(background.clone()),
116 Fill::RadialGradient(_) => AttributeType::Gradient(background.clone()),
117 Fill::ConicGradient(_) => AttributeType::Gradient(background.clone()),
118 };
119 ("background", fill)
120 },
121 (
122 "corner_radius",
123 AttributeType::CornerRadius(self.style.corner_radius),
124 ),
125 ];
126
127 let shadows = &self.style.shadows;
128 for shadow in shadows.iter() {
129 attributes.push(("shadow", AttributeType::Shadow(shadow)));
130 }
131
132 let borders = &self.style.borders;
133 for border in borders.iter() {
134 attributes.push(("border", AttributeType::Border(border)));
135 }
136
137 attributes
138 }
139
140 fn text_style_attributes(&'_ self) -> Vec<(&'_ str, AttributeType<'_>)> {
141 let mut attributes = vec![
142 ("color", AttributeType::Color(self.text_style.color)),
143 (
144 "font_family",
145 AttributeType::Text(self.text_style.font_families.join(", ")),
146 ),
147 (
148 "font_size",
149 AttributeType::Measure(f32::from(self.text_style.font_size)),
150 ),
151 (
152 "text_align",
153 AttributeType::TextAlignment(&self.text_style.text_align),
154 ),
155 (
156 "text_overflow",
157 AttributeType::TextOverflow(&self.text_style.text_overflow),
158 ),
159 ];
160
161 for shadow in self.style.shadows.iter() {
162 attributes.push(("shadow", AttributeType::Shadow(shadow)));
163 }
164
165 for text_shadow in self.text_style.text_shadows.iter() {
166 attributes.push(("text_shadow", AttributeType::TextShadow(text_shadow)));
167 }
168
169 attributes
170 }
171}
172
173pub enum AttributeType<'a> {
174 Color(Color),
175 OptionalColor(Option<Color>),
176 Gradient(Fill),
177 Size(&'a Size),
178 VisibleSize(&'a VisibleSize),
179 Measure(f32),
180 OptionalMeasure(Option<f32>),
181 Measures(Gaps),
182 CornerRadius(CornerRadius),
183 Direction(&'a Direction),
184 Position(&'a Position),
185 Content(&'a Content),
186 Alignment(&'a Alignment),
187 Shadow(&'a Shadow),
188 TextShadow(&'a TextShadow),
189 Text(String),
190 Border(&'a Border),
191 TextAlignment(&'a TextAlign),
192 TextOverflow(&'a TextOverflow),
193}