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 Dropdown,
102 Button,
103 Label,
104 Separator,
105 Section,
107 ProgressBar,
109 Stat,
111 Status,
113 MiniChart,
115 Grid,
117 Plot,
119 KeyValue,
121 ButtonCompact,
123 Horizontal,
125 ButtonInline,
127 TextInputInline,
129 LabelInline,
131 Image,
133}
134
135#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
136pub struct ElementMeta {
137 #[serde(skip_serializing_if = "Option::is_none")]
138 pub min: Option<f64>,
139 #[serde(skip_serializing_if = "Option::is_none")]
140 pub max: Option<f64>,
141 #[serde(skip_serializing_if = "Option::is_none")]
142 pub step: Option<f64>,
143 #[serde(skip_serializing_if = "Option::is_none")]
145 pub accent: Option<AccentColor>,
146 #[serde(skip_serializing_if = "Option::is_none")]
148 pub subtitle: Option<String>,
149 #[serde(skip_serializing_if = "Option::is_none")]
151 pub cols: Option<usize>,
152 #[serde(skip_serializing_if = "Option::is_none")]
154 pub children: Option<Vec<String>>,
155}
156
157#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
158pub struct ElementDecl {
159 pub id: ElementId,
160 pub kind: ElementKind,
161 pub label: String,
162 pub value: Value,
163 pub meta: ElementMeta,
164 pub window: Arc<str>,
165}
166
167#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
169#[serde(rename_all = "lowercase")]
170pub enum AccentColor {
171 Coral,
172 Teal,
173 Blue,
174 Green,
175 Purple,
176 Orange,
177 Yellow,
178 Red,
179 Black,
180 White,
181 Gray,
182}
183
184impl AccentColor {
185 pub fn as_str(&self) -> &'static str {
186 match self {
187 AccentColor::Coral => "coral",
188 AccentColor::Teal => "teal",
189 AccentColor::Blue => "blue",
190 AccentColor::Green => "green",
191 AccentColor::Purple => "purple",
192 AccentColor::Orange => "orange",
193 AccentColor::Yellow => "yellow",
194 AccentColor::Red => "red",
195 AccentColor::Black => "black",
196 AccentColor::White => "white",
197 AccentColor::Gray => "gray",
198 }
199 }
200}