1use freya_core::{
2 integration::*,
3 prelude::{
4 Border,
5 Color,
6 CornerRadius,
7 Fill,
8 FontSlant,
9 Shadow,
10 TextAlign,
11 TextDecoration,
12 TextHeightBehavior,
13 TextOverflow,
14 TextShadow,
15 },
16};
17use serde::{
18 Deserialize,
19 Serialize,
20};
21use torin::{
22 alignment::Alignment,
23 direction::Direction,
24 gaps::Gaps,
25 geometry::Length,
26 order::Order,
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
60impl NodeState {
61 pub 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 ("order", AttributeType::Order(&self.layout.order)),
88 ("padding", AttributeType::Measures(self.layout.padding)),
89 ("margin", AttributeType::Measures(self.layout.margin)),
90 ("position", AttributeType::Position(&self.layout.position)),
91 (
92 "main_alignment",
93 AttributeType::Alignment(&self.layout.main_alignment),
94 ),
95 (
96 "cross_alignment",
97 AttributeType::Alignment(&self.layout.cross_alignment),
98 ),
99 (
100 "offset_x",
101 AttributeType::Measure(self.layout.offset_x.get()),
102 ),
103 (
104 "offset_y",
105 AttributeType::Measure(self.layout.offset_y.get()),
106 ),
107 ("content", AttributeType::Content(&self.layout.content)),
108 ("spacing", AttributeType::Length(self.layout.spacing)),
109 ]
110 }
111 pub fn style_attributes(&'_ self) -> Vec<(&'_ str, AttributeType<'_>)> {
112 let mut attributes = vec![
113 ("background", AttributeType::from(&self.style.background)),
114 (
115 "corner_radius",
116 AttributeType::CornerRadius(self.style.corner_radius),
117 ),
118 ];
119
120 let shadows = &self.style.shadows;
121 for shadow in shadows.iter() {
122 attributes.push(("shadow", AttributeType::Shadow(shadow)));
123 }
124
125 let borders = &self.style.borders;
126 for border in borders.iter() {
127 attributes.push(("border", AttributeType::Border(border)));
128 }
129
130 attributes
131 }
132
133 pub fn text_style_attributes(&'_ self) -> Vec<(&'_ str, AttributeType<'_>)> {
134 let mut attributes = vec![
135 ("color", AttributeType::from(&self.text_style.color)),
136 (
137 "font_family",
138 AttributeType::Text(self.text_style.font_families.join(", ")),
139 ),
140 (
141 "font_size",
142 AttributeType::Measure(f32::from(self.text_style.font_size)),
143 ),
144 (
145 "text_align",
146 AttributeType::TextAlignment(&self.text_style.text_align),
147 ),
148 (
149 "text_overflow",
150 AttributeType::TextOverflow(&self.text_style.text_overflow),
151 ),
152 (
153 "text_height",
154 AttributeType::TextHeightBehavior(&self.text_style.text_height),
155 ),
156 (
157 "font_slant",
158 AttributeType::FontSlant(self.text_style.font_slant),
159 ),
160 (
161 "font_weight",
162 AttributeType::Measure(self.text_style.font_weight.into()),
163 ),
164 (
165 "font_width",
166 AttributeType::Measure(self.text_style.font_width.into()),
167 ),
168 (
169 "text_decoration",
170 AttributeType::TextDecoration(self.text_style.text_decoration),
171 ),
172 ];
173
174 for shadow in self.style.shadows.iter() {
175 attributes.push(("shadow", AttributeType::Shadow(shadow)));
176 }
177
178 for text_shadow in self.text_style.text_shadows.iter() {
179 attributes.push(("text_shadow", AttributeType::TextShadow(text_shadow)));
180 }
181
182 attributes
183 }
184}
185
186pub enum AttributeType<'a> {
187 Color(Color),
188 Fill(Fill),
189 Size(&'a Size),
190 VisibleSize(&'a VisibleSize),
191 Measure(f32),
192 Measures(Gaps),
193 CornerRadius(CornerRadius),
194 Direction(&'a Direction),
195 Order(&'a Order),
196 Position(&'a Position),
197 Content(&'a Content),
198 Alignment(&'a Alignment),
199 Shadow(&'a Shadow),
200 TextShadow(&'a TextShadow),
201 Text(String),
202 Border(&'a Border),
203 TextAlignment(&'a TextAlign),
204 TextOverflow(&'a TextOverflow),
205 TextHeightBehavior(&'a TextHeightBehavior),
206 FontSlant(FontSlant),
207 TextDecoration(TextDecoration),
208 Length(Length),
209}
210
211impl<'a> From<&'a Fill> for AttributeType<'a> {
212 fn from(fill: &'a Fill) -> Self {
213 match fill.as_color() {
214 Some(color) => AttributeType::Color(color),
215 None => AttributeType::Fill(fill.clone()),
216 }
217 }
218}