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