Skip to main content

w_gui/
element.rs

1use serde::{Deserialize, Serialize};
2
3pub type ElementId = String;
4
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
6#[serde(tag = "type", content = "data")]
7pub enum Value {
8    Float(f64),
9    Bool(bool),
10    Color3([f32; 3]),
11    Color4([f32; 4]),
12    Vec2([f32; 2]),
13    Vec3([f32; 3]),
14    Int(i64),
15    String(String),
16    Enum {
17        selected: usize,
18        options: Vec<String>,
19    },
20    /// Transient: true for one frame when clicked
21    Button(bool),
22    /// Progress value (0.0 to 1.0)
23    Progress(f64),
24    /// Stat card value with optional subvalue
25    StatValue { value: String, subvalue: Option<String> },
26    /// Status indicator state
27    StatusValue {
28        active: bool,
29        #[serde(skip_serializing_if = "Option::is_none")]
30        active_text: Option<String>,
31        #[serde(skip_serializing_if = "Option::is_none")]
32        inactive_text: Option<String>,
33        #[serde(skip_serializing_if = "Option::is_none")]
34        active_color: Option<String>,
35        #[serde(skip_serializing_if = "Option::is_none")]
36        inactive_color: Option<String>,
37    },
38    /// Mini chart data
39    ChartValue {
40        values: Vec<f32>,
41        #[serde(skip_serializing_if = "Option::is_none")]
42        current: Option<f32>,
43        #[serde(skip_serializing_if = "Option::is_none")]
44        unit: Option<String>,
45    },
46    /// Grid container data
47    GridValue {
48        cols: usize,
49        children: Vec<String>,
50    },
51    /// Plot data for larger charts
52    PlotValue {
53        series: Vec<PlotSeries>,
54        #[serde(skip_serializing_if = "Option::is_none")]
55        x_label: Option<String>,
56        #[serde(skip_serializing_if = "Option::is_none")]
57        y_label: Option<String>,
58    },
59    /// Null value for container elements
60    Null,
61}
62
63/// A data series for plotting
64#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
65pub struct PlotSeries {
66    pub name: String,
67    pub values: Vec<f32>,
68    pub color: String,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
72#[serde(tag = "type", content = "data")]
73pub enum ElementKind {
74    Slider,
75    Checkbox,
76    ColorPicker3,
77    ColorPicker4,
78    TextInput,
79    Dropdown,
80    Button,
81    Label,
82    Separator,
83    /// Section header for grouping
84    Section,
85    /// Progress bar with percentage
86    ProgressBar,
87    /// Stat card display
88    Stat,
89    /// Status indicator with colored dot
90    Status,
91    /// Mini sparkline chart
92    MiniChart,
93    /// Grid layout container
94    Grid,
95    /// Larger plot/chart for data visualization
96    Plot,
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
100pub struct ElementMeta {
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub min: Option<f64>,
103    #[serde(skip_serializing_if = "Option::is_none")]
104    pub max: Option<f64>,
105    #[serde(skip_serializing_if = "Option::is_none")]
106    pub step: Option<f64>,
107    /// Accent color for the element (coral, teal, blue, green, purple, orange, yellow, red)
108    #[serde(skip_serializing_if = "Option::is_none")]
109    pub accent: Option<String>,
110    /// Subtitle or secondary text
111    #[serde(skip_serializing_if = "Option::is_none")]
112    pub subtitle: Option<String>,
113    /// Number of columns for grid layout
114    #[serde(skip_serializing_if = "Option::is_none")]
115    pub cols: Option<usize>,
116    /// Child element IDs for grid layout
117    #[serde(skip_serializing_if = "Option::is_none")]
118    pub children: Option<Vec<String>>,
119}
120
121impl Default for ElementMeta {
122    fn default() -> Self {
123        Self {
124            min: None,
125            max: None,
126            step: None,
127            accent: None,
128            subtitle: None,
129            cols: None,
130            children: None,
131        }
132    }
133}
134
135#[derive(Debug, Clone, Serialize, Deserialize)]
136pub struct ElementDecl {
137    pub id: ElementId,
138    pub kind: ElementKind,
139    pub label: String,
140    pub value: Value,
141    pub meta: ElementMeta,
142    pub window: String,
143}
144
145/// Accent colors available for UI elements
146#[derive(Debug, Clone, Copy, PartialEq, Eq)]
147pub enum AccentColor {
148    Coral,
149    Teal,
150    Blue,
151    Green,
152    Purple,
153    Orange,
154    Yellow,
155    Red,
156}
157
158impl AccentColor {
159    pub fn as_str(&self) -> &'static str {
160        match self {
161            AccentColor::Coral => "coral",
162            AccentColor::Teal => "teal",
163            AccentColor::Blue => "blue",
164            AccentColor::Green => "green",
165            AccentColor::Purple => "purple",
166            AccentColor::Orange => "orange",
167            AccentColor::Yellow => "yellow",
168            AccentColor::Red => "red",
169        }
170    }
171}