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