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