use crate::style::Style;
use serde::{Deserialize, Serialize};
use oak_json::{JsonValueNode, ast::{JsonObject, JsonString}};
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
pub enum ComponentType {
Button,
TextBox,
Label,
Container,
Panel,
List,
Dropdown,
Checkbox,
Radio,
Slider,
Custom(String),
}
#[derive(Debug)]
pub struct Component {
component_type: ComponentType,
id: String,
style: Style,
properties: ComponentProperties,
children: Vec<Component>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct ComponentProperties {
pub text: Option<String>,
pub enabled: bool,
pub visible: bool,
pub checked: bool,
pub min: Option<f32>,
pub max: Option<f32>,
pub value: Option<JsonValueNode>,
pub options: Option<Vec<(String, String)>>,
pub custom: JsonValueNode,
}
impl ComponentProperties {
pub fn default() -> Self {
Self {
text: None,
enabled: true,
visible: true,
checked: false,
min: None,
max: None,
value: None,
options: None,
custom: JsonValueNode::Object(JsonObject { fields: Vec::new(), span: (0..0).into() }),
}
}
}
impl Component {
pub fn new(component_type: ComponentType, id: &str, style: Style, properties: ComponentProperties) -> Self {
Self { component_type, id: id.to_string(), style, properties, children: Vec::new() }
}
pub fn add_child(&mut self, child: Component) {
self.children.push(child);
}
pub fn get_child(&self, id: &str) -> Option<&Component> {
self.children.iter().find(|child| child.id == id)
}
pub fn get_child_mut(&mut self, id: &str) -> Option<&mut Component> {
self.children.iter_mut().find(|child| child.id == id)
}
pub fn set_text(&mut self, text: &str) {
self.properties.text = Some(text.to_string());
}
pub fn set_enabled(&mut self, enabled: bool) {
self.properties.enabled = enabled;
}
pub fn set_visible(&mut self, visible: bool) {
self.properties.visible = visible;
}
pub fn set_checked(&mut self, checked: bool) {
self.properties.checked = checked;
}
pub fn set_value(&mut self, value: JsonValueNode) {
self.properties.value = Some(value);
}
pub fn component_type(&self) -> &ComponentType {
&self.component_type
}
pub fn id(&self) -> &str {
&self.id
}
pub fn style(&self) -> &Style {
&self.style
}
pub fn style_mut(&mut self) -> &mut Style {
&mut self.style
}
pub fn properties(&self) -> &ComponentProperties {
&self.properties
}
pub fn properties_mut(&mut self) -> &mut ComponentProperties {
&mut self.properties
}
pub fn children(&self) -> &Vec<Component> {
&self.children
}
pub fn children_mut(&mut self) -> &mut Vec<Component> {
&mut self.children
}
}
pub fn create_button(id: &str, text: &str, style: Style) -> Component {
let mut properties = ComponentProperties::default();
properties.text = Some(text.to_string());
Component::new(ComponentType::Button, id, style, properties)
}
pub fn create_label(id: &str, text: &str, style: Style) -> Component {
let mut properties = ComponentProperties::default();
properties.text = Some(text.to_string());
Component::new(ComponentType::Label, id, style, properties)
}
pub fn create_text_box(id: &str, value: &str, style: Style) -> Component {
let mut properties = ComponentProperties::default();
properties.value = Some(JsonValueNode::String(JsonString { value: value.to_string(), span: (0..0).into() }));
Component::new(ComponentType::TextBox, id, style, properties)
}
pub fn create_container(id: &str, style: Style) -> Component {
let properties = ComponentProperties::default();
Component::new(ComponentType::Container, id, style, properties)
}