1use std::sync::Arc;
2
3use serde::{Deserialize, Serialize};
4
5pub type ElementId = String;
6
7#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
8#[serde(tag = "type", content = "data")]
9pub enum Value {
10 Float(f64),
11 Bool(bool),
12 Color3([f32; 3]),
13 Color4([f32; 4]),
14 Vec2([f32; 2]),
15 Vec3([f32; 3]),
16 Int(i64),
17 String(String),
18 Enum {
19 selected: usize,
20 options: Vec<String>,
21 },
22 Button(bool),
24 Progress(f64),
26 StatValue {
28 value: String,
29 subvalue: Option<String>,
30 },
31 StatusValue {
33 active: bool,
34 #[serde(skip_serializing_if = "Option::is_none")]
35 active_text: Option<String>,
36 #[serde(skip_serializing_if = "Option::is_none")]
37 inactive_text: Option<String>,
38 #[serde(skip_serializing_if = "Option::is_none")]
39 active_color: Option<String>,
40 #[serde(skip_serializing_if = "Option::is_none")]
41 inactive_color: Option<String>,
42 },
43 ChartValue {
45 values: Vec<f32>,
46 #[serde(skip_serializing_if = "Option::is_none")]
47 current: Option<f32>,
48 #[serde(skip_serializing_if = "Option::is_none")]
49 unit: Option<String>,
50 },
51 GridValue {
53 cols: usize,
54 children: Vec<String>,
55 },
56 PlotValue {
58 series: Vec<PlotSeries>,
59 #[serde(skip_serializing_if = "Option::is_none")]
60 x_label: Option<String>,
61 #[serde(skip_serializing_if = "Option::is_none")]
62 y_label: Option<String>,
63 },
64 Null,
66 ImageValue {
68 data: String,
69 #[serde(skip_serializing_if = "Option::is_none")]
70 width: Option<u32>,
71 #[serde(skip_serializing_if = "Option::is_none")]
72 height: Option<u32>,
73 },
74}
75
76#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
78pub struct PlotSeries {
79 pub name: String,
80 pub values: Vec<f32>,
81 pub color: String,
82 #[serde(default = "default_autoscale")]
86 pub autoscale: bool,
87}
88
89fn default_autoscale() -> bool {
90 true
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
94#[serde(tag = "type", content = "data")]
95pub enum ElementKind {
96 Slider,
97 Checkbox,
98 ColorPicker3,
99 ColorPicker4,
100 TextInput,
101 NumberInput,
103 Dropdown,
104 Button,
105 Label,
106 Separator,
107 Section,
109 ProgressBar,
111 Stat,
113 Status,
115 MiniChart,
117 Grid,
119 Plot,
121 KeyValue,
123 ButtonCompact,
125 Horizontal,
127 ButtonInline,
129 TextInputInline,
131 LabelInline,
133 Image,
135 ImageButton,
137}
138
139#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
140pub struct ElementMeta {
141 #[serde(skip_serializing_if = "Option::is_none")]
142 pub min: Option<f64>,
143 #[serde(skip_serializing_if = "Option::is_none")]
144 pub max: Option<f64>,
145 #[serde(skip_serializing_if = "Option::is_none")]
146 pub step: Option<f64>,
147 #[serde(skip_serializing_if = "Option::is_none")]
149 pub accent: Option<AccentColor>,
150 #[serde(skip_serializing_if = "Option::is_none")]
152 pub subtitle: Option<String>,
153 #[serde(skip_serializing_if = "Option::is_none")]
155 pub cols: Option<usize>,
156 #[serde(skip_serializing_if = "Option::is_none")]
158 pub children: Option<Vec<String>>,
159}
160
161#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
162pub struct ElementDecl {
163 pub id: ElementId,
164 pub kind: ElementKind,
165 pub label: String,
166 pub value: Value,
167 pub meta: ElementMeta,
168 pub window: Arc<str>,
169}
170
171#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
173#[serde(rename_all = "lowercase")]
174pub enum AccentColor {
175 Coral,
176 Teal,
177 Blue,
178 Green,
179 Purple,
180 Orange,
181 Yellow,
182 Red,
183 Black,
184 White,
185 Gray,
186}
187
188impl AccentColor {
189 pub fn as_str(&self) -> &'static str {
190 match self {
191 AccentColor::Coral => "coral",
192 AccentColor::Teal => "teal",
193 AccentColor::Blue => "blue",
194 AccentColor::Green => "green",
195 AccentColor::Purple => "purple",
196 AccentColor::Orange => "orange",
197 AccentColor::Yellow => "yellow",
198 AccentColor::Red => "red",
199 AccentColor::Black => "black",
200 AccentColor::White => "white",
201 AccentColor::Gray => "gray",
202 }
203 }
204}