Skip to main content

kvas_engine/
gui.rs

1//! Serializable screen/world UI components. Native shells paint them and publish button signals.
2use crate::{components::Component, reflect::Field};
3use glam::Vec3;
4use serde::{Deserialize, Serialize};
5
6crate::choice_enum!(
7    /// Element drawn by the native game UI shell.
8    UiKind { Label, Button, Progress } default Label
9);
10
11/// Camera-overlay or world-anchored interface element. Coordinates use logical pixels.
12#[derive(Clone, Serialize, Deserialize)]
13#[serde(default)]
14pub struct UiElement {
15    /// Visual/interaction kind.
16    pub kind: UiKind,
17    /// Text shown above the background.
18    pub text: String,
19    /// Normalized screen anchor X/Y, with Z used as draw order.
20    pub anchor: Vec3,
21    /// Width and height in pixels; Z is unused.
22    pub size: Vec3,
23    /// Pixel offset from anchor (X/Y); Z is unused.
24    pub offset: Vec3,
25    /// Text size in logical pixels.
26    pub font_size: f32,
27    /// Background RGBA.
28    pub background: [f32; 4],
29    /// Text / progress-fill RGBA.
30    pub foreground: [f32; 4],
31    /// Whether to draw the element.
32    pub visible: bool,
33    /// Whether button interaction is enabled.
34    pub interactable: bool,
35    /// Position the element at the object's projected world transform.
36    pub world_space: bool,
37    /// Signal channel broadcast on button click; source entity is the sender.
38    pub signal: String,
39    /// Progress fraction (0..1).
40    pub value: f32,
41}
42impl Default for UiElement {
43    fn default() -> Self {
44        Self { kind: UiKind::Label, text: "UI element".into(), anchor: Vec3::new(0.5, 0.1, 0.0), size: Vec3::new(240.0, 42.0, 0.0), offset: Vec3::ZERO, font_size: 18.0, background: [0.06, 0.08, 0.12, 0.88], foreground: [0.9, 0.95, 1.0, 1.0], visible: true, interactable: true, world_space: false, signal: "ui.click".into(), value: 0.5 }
45    }
46}
47impl Component for UiElement {
48    fn fields(&mut self) -> Vec<Field<'_>> {
49        vec![Field::choice("kind", &mut self.kind), Field::text("text", &mut self.text), Field::vec3("anchor", &mut self.anchor), Field::vec3("size", &mut self.size), Field::vec3("offset", &mut self.offset), Field::f32("font_size", &mut self.font_size), Field::color("background", &mut self.background), Field::color("foreground", &mut self.foreground), Field::bool("visible", &mut self.visible), Field::bool("interactable", &mut self.interactable), Field::bool("world_space", &mut self.world_space), Field::text("signal", &mut self.signal), Field::f32("value", &mut self.value)]
50    }
51}