1use bincode::{Decode, Encode};
18use khora_core::asset::AssetUUID;
19use khora_core::math::{Vec2, Vec4};
20pub use khora_core::ui::types::{UiFlexDirection, UiRect, UiVal};
21use khora_macros::Component;
22use serde::{Deserialize, Serialize};
23
24#[derive(Debug, Clone, PartialEq, Component, Default)]
27#[component(domain = Ui)]
28pub struct UiNode {
29 pub width: UiVal,
31 pub height: UiVal,
33
34 pub min_width: UiVal,
36 pub min_height: UiVal,
38
39 pub max_width: UiVal,
41 pub max_height: UiVal,
43
44 pub padding: UiRect<UiVal>,
46 pub margin: UiRect<UiVal>,
48
49 pub flex_direction: UiFlexDirection,
51 pub flex_grow: f32,
53 pub flex_shrink: f32,
55}
56
57impl From<UiNode> for khora_core::ui::types::UiNode {
58 fn from(node: UiNode) -> Self {
59 Self {
60 width: node.width,
61 height: node.height,
62 min_width: node.min_width,
63 min_height: node.min_height,
64 max_width: node.max_width,
65 max_height: node.max_height,
66 padding: node.padding,
67 margin: node.margin,
68 flex_direction: node.flex_direction,
69 flex_grow: node.flex_grow,
70 flex_shrink: node.flex_shrink,
71 }
72 }
73}
74
75#[derive(Debug, Clone, Copy, PartialEq, Component)]
78#[component(domain = Ui)]
79pub struct UiTransform {
80 pub pos: Vec2,
82 pub size: Vec2,
84 pub z_index: i32,
86}
87
88impl From<UiTransform> for khora_core::ui::types::UiTransform {
89 fn from(t: UiTransform) -> Self {
90 Self {
91 pos: t.pos,
92 size: t.size,
93 z_index: t.z_index,
94 }
95 }
96}
97
98impl From<khora_core::ui::types::UiTransform> for UiTransform {
99 fn from(t: khora_core::ui::types::UiTransform) -> Self {
100 Self {
101 pos: t.pos,
102 size: t.size,
103 z_index: t.z_index,
104 }
105 }
106}
107
108impl Default for UiTransform {
109 fn default() -> Self {
110 Self {
111 pos: Vec2::ZERO,
112 size: Vec2::ZERO,
113 z_index: 0,
114 }
115 }
116}
117
118impl UiTransform {
119 pub fn rect(&self) -> (Vec2, Vec2) {
121 (self.pos, self.pos + self.size)
122 }
123
124 pub fn contains(&self, point: Vec2) -> bool {
126 point.x >= self.pos.x
127 && point.x <= self.pos.x + self.size.x
128 && point.y >= self.pos.y
129 && point.y <= self.pos.y + self.size.y
130 }
131}
132
133#[derive(Debug, Clone, PartialEq, Component)]
135#[component(domain = Ui)]
136pub struct UiStyle {
137 pub background_color: Vec4,
139 pub border_radius: Vec4, pub border_color: Vec4,
143 pub border_width: f32,
145 pub texture_id: Option<u64>,
147}
148
149impl Default for UiStyle {
150 fn default() -> Self {
151 Self {
152 background_color: Vec4::new(1.0, 1.0, 1.0, 1.0),
153 border_radius: Vec4::ZERO,
154 border_color: Vec4::ZERO,
155 border_width: 0.0,
156 texture_id: None,
157 }
158 }
159}
160
161#[derive(
163 Debug, Clone, Copy, PartialEq, Component, Default, Serialize, Deserialize, Encode, Decode,
164)]
165#[component(domain = Ui)]
166pub struct UiColor(pub Vec4);
167
168impl UiColor {
169 pub fn to_core(&self) -> khora_core::ui::types::UiColor {
171 khora_core::ui::types::UiColor(self.0)
172 }
173}
174
175#[derive(Debug, Clone, Copy, Default, PartialEq, Component)]
177#[component(domain = Ui)]
178pub struct UiImage {
179 pub texture: AssetUUID,
181}
182
183impl UiImage {
184 pub fn to_core(&self) -> khora_core::ui::types::UiImage {
186 khora_core::ui::types::UiImage {
187 texture: self.texture,
188 }
189 }
190}
191
192#[derive(
194 Debug, Clone, Copy, PartialEq, Component, Default, Serialize, Deserialize, Encode, Decode,
195)]
196#[component(domain = Ui)]
197pub struct UiBorder {
198 pub width: UiRect<f32>,
200 pub color: UiColor,
202 pub radius: f32,
204}
205
206impl UiBorder {
207 pub fn to_core(&self) -> khora_core::ui::types::UiBorder {
209 khora_core::ui::types::UiBorder {
210 width: self.width,
211 color: self.color.to_core(),
212 radius: self.radius,
213 }
214 }
215}
216
217#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize, Encode, Decode)]
219pub enum UiInteractionState {
220 #[default]
221 Normal,
223 Hovered,
225 Pressed,
227 Focused,
229}
230
231#[derive(Debug, Clone, Default, Component)]
233#[component(domain = Ui)]
234pub struct UiInteraction {
235 pub state: UiInteractionState,
237
238 pub focusable: bool,
240
241 pub blocks_input: bool,
243}
244
245#[derive(Debug, Clone, PartialEq, Component)]
247#[component(domain = Ui)]
248pub struct UiText {
249 pub content: String,
251 pub font: AssetUUID,
253 pub size: f32,
255 pub color: Vec4,
257}
258
259impl UiText {
260 pub fn to_core(&self) -> khora_core::ui::types::UiText {
262 khora_core::ui::types::UiText {
263 content: self.content.clone(),
264 font: self.font,
265 size: self.size,
266 color: self.color,
267 }
268 }
269}
270
271impl Default for UiText {
272 fn default() -> Self {
273 Self {
274 content: String::new(),
275 font: AssetUUID::default(),
276 size: 16.0,
277 color: Vec4::new(0.0, 0.0, 0.0, 1.0), }
279 }
280}