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}
67
68#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
70pub struct PlotSeries {
71 pub name: String,
72 pub values: Vec<f32>,
73 pub color: String,
74 #[serde(default = "default_autoscale")]
78 pub autoscale: bool,
79}
80
81fn default_autoscale() -> bool {
82 true
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
86#[serde(tag = "type", content = "data")]
87pub enum ElementKind {
88 Slider,
89 Checkbox,
90 ColorPicker3,
91 ColorPicker4,
92 TextInput,
93 Dropdown,
94 Button,
95 Label,
96 Separator,
97 Section,
99 ProgressBar,
101 Stat,
103 Status,
105 MiniChart,
107 Grid,
109 Plot,
111 KeyValue,
113 ButtonCompact,
115 Horizontal,
117 ButtonInline,
119 TextInputInline,
121 LabelInline,
123}
124
125#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
126pub struct ElementMeta {
127 #[serde(skip_serializing_if = "Option::is_none")]
128 pub min: Option<f64>,
129 #[serde(skip_serializing_if = "Option::is_none")]
130 pub max: Option<f64>,
131 #[serde(skip_serializing_if = "Option::is_none")]
132 pub step: Option<f64>,
133 #[serde(skip_serializing_if = "Option::is_none")]
135 pub accent: Option<AccentColor>,
136 #[serde(skip_serializing_if = "Option::is_none")]
138 pub subtitle: Option<String>,
139 #[serde(skip_serializing_if = "Option::is_none")]
141 pub cols: Option<usize>,
142 #[serde(skip_serializing_if = "Option::is_none")]
144 pub children: Option<Vec<String>>,
145}
146
147#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
148pub struct ElementDecl {
149 pub id: ElementId,
150 pub kind: ElementKind,
151 pub label: String,
152 pub value: Value,
153 pub meta: ElementMeta,
154 pub window: Arc<str>,
155}
156
157#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
159#[serde(rename_all = "lowercase")]
160pub enum AccentColor {
161 Coral,
162 Teal,
163 Blue,
164 Green,
165 Purple,
166 Orange,
167 Yellow,
168 Red,
169}
170
171impl AccentColor {
172 pub fn as_str(&self) -> &'static str {
173 match self {
174 AccentColor::Coral => "coral",
175 AccentColor::Teal => "teal",
176 AccentColor::Blue => "blue",
177 AccentColor::Green => "green",
178 AccentColor::Purple => "purple",
179 AccentColor::Orange => "orange",
180 AccentColor::Yellow => "yellow",
181 AccentColor::Red => "red",
182 }
183 }
184}