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