Skip to main content

itools_gui/
components.rs

1//! 组件系统模块
2//!
3//! 提供 GUI 组件系统,包括基础组件和复合组件。
4
5use crate::style::Style;
6use serde::{Deserialize, Serialize};
7
8/// 组件类型
9#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
10pub enum ComponentType {
11    /// 按钮
12    Button,
13    /// 文本框
14    TextBox,
15    /// 标签
16    Label,
17    /// 容器
18    Container,
19    /// 面板
20    Panel,
21    /// 列表
22    List,
23    /// 下拉菜单
24    Dropdown,
25    /// 复选框
26    Checkbox,
27    /// 单选框
28    Radio,
29    /// 滑块
30    Slider,
31    /// 自定义组件
32    Custom(String),
33}
34
35/// 组件结构体
36#[derive(Debug)]
37pub struct Component {
38    /// 组件类型
39    component_type: ComponentType,
40    /// 组件ID
41    id: String,
42    /// 组件样式
43    style: Style,
44    /// 组件属性
45    properties: ComponentProperties,
46    /// 子组件
47    children: Vec<Component>,
48}
49
50/// 组件属性
51#[derive(Debug, Deserialize, Serialize)]
52pub struct ComponentProperties {
53    /// 文本内容
54    pub text: Option<String>,
55    /// 是否启用
56    pub enabled: bool,
57    /// 是否可见
58    pub visible: bool,
59    /// 是否选中
60    pub checked: bool,
61    /// 最小值
62    pub min: Option<f32>,
63    /// 最大值
64    pub max: Option<f32>,
65    /// 当前值
66    pub value: Option<serde_json::Value>,
67    /// 选项列表
68    pub options: Option<Vec<(String, String)>>,
69    /// 自定义属性
70    pub custom: serde_json::Value,
71}
72
73impl ComponentProperties {
74    /// 创建默认组件属性
75    ///
76    /// # 返回值
77    /// 默认组件属性
78    pub fn default() -> Self {
79        Self {
80            text: None,
81            enabled: true,
82            visible: true,
83            checked: false,
84            min: None,
85            max: None,
86            value: None,
87            options: None,
88            custom: serde_json::Value::Object(serde_json::Map::new()),
89        }
90    }
91}
92
93impl Component {
94    /// 创建新的组件
95    ///
96    /// # 参数
97    /// - `component_type`: 组件类型
98    /// - `id`: 组件ID
99    /// - `style`: 组件样式
100    /// - `properties`: 组件属性
101    ///
102    /// # 返回值
103    /// 组件实例
104    pub fn new(component_type: ComponentType, id: &str, style: Style, properties: ComponentProperties) -> Self {
105        Self { component_type, id: id.to_string(), style, properties, children: Vec::new() }
106    }
107
108    /// 添加子组件
109    ///
110    /// # 参数
111    /// - `child`: 子组件
112    pub fn add_child(&mut self, child: Component) {
113        self.children.push(child);
114    }
115
116    /// 获取子组件
117    ///
118    /// # 参数
119    /// - `id`: 子组件ID
120    ///
121    /// # 返回值
122    /// 子组件引用
123    pub fn get_child(&self, id: &str) -> Option<&Component> {
124        self.children.iter().find(|child| child.id == id)
125    }
126
127    /// 获取可变子组件
128    ///
129    /// # 参数
130    /// - `id`: 子组件ID
131    ///
132    /// # 返回值
133    /// 可变子组件引用
134    pub fn get_child_mut(&mut self, id: &str) -> Option<&mut Component> {
135        self.children.iter_mut().find(|child| child.id == id)
136    }
137
138    /// 设置文本内容
139    ///
140    /// # 参数
141    /// - `text`: 文本内容
142    pub fn set_text(&mut self, text: &str) {
143        self.properties.text = Some(text.to_string());
144    }
145
146    /// 设置是否启用
147    ///
148    /// # 参数
149    /// - `enabled`: 是否启用
150    pub fn set_enabled(&mut self, enabled: bool) {
151        self.properties.enabled = enabled;
152    }
153
154    /// 设置是否可见
155    ///
156    /// # 参数
157    /// - `visible`: 是否可见
158    pub fn set_visible(&mut self, visible: bool) {
159        self.properties.visible = visible;
160    }
161
162    /// 设置是否选中
163    ///
164    /// # 参数
165    /// - `checked`: 是否选中
166    pub fn set_checked(&mut self, checked: bool) {
167        self.properties.checked = checked;
168    }
169
170    /// 设置值
171    ///
172    /// # 参数
173    /// - `value`: 值
174    pub fn set_value(&mut self, value: serde_json::Value) {
175        self.properties.value = Some(value);
176    }
177
178    /// 获取组件类型
179    ///
180    /// # 返回值
181    /// 组件类型
182    pub fn component_type(&self) -> &ComponentType {
183        &self.component_type
184    }
185
186    /// 获取组件ID
187    ///
188    /// # 返回值
189    /// 组件ID
190    pub fn id(&self) -> &str {
191        &self.id
192    }
193
194    /// 获取组件样式
195    ///
196    /// # 返回值
197    /// 组件样式引用
198    pub fn style(&self) -> &Style {
199        &self.style
200    }
201
202    /// 获取可变组件样式
203    ///
204    /// # 返回值
205    /// 可变组件样式引用
206    pub fn style_mut(&mut self) -> &mut Style {
207        &mut self.style
208    }
209
210    /// 获取组件属性
211    ///
212    /// # 返回值
213    /// 组件属性引用
214    pub fn properties(&self) -> &ComponentProperties {
215        &self.properties
216    }
217
218    /// 获取可变组件属性
219    ///
220    /// # 返回值
221    /// 可变组件属性引用
222    pub fn properties_mut(&mut self) -> &mut ComponentProperties {
223        &mut self.properties
224    }
225
226    /// 获取子组件列表
227    ///
228    /// # 返回值
229    /// 子组件列表引用
230    pub fn children(&self) -> &Vec<Component> {
231        &self.children
232    }
233
234    /// 获取可变子组件列表
235    ///
236    /// # 返回值
237    /// 可变子组件列表引用
238    pub fn children_mut(&mut self) -> &mut Vec<Component> {
239        &mut self.children
240    }
241}
242
243/// 创建按钮组件
244///
245/// # 参数
246/// - `id`: 组件ID
247/// - `text`: 按钮文本
248/// - `style`: 组件样式
249///
250/// # 返回值
251/// 按钮组件实例
252pub fn create_button(id: &str, text: &str, style: Style) -> Component {
253    let mut properties = ComponentProperties::default();
254    properties.text = Some(text.to_string());
255    Component::new(ComponentType::Button, id, style, properties)
256}
257
258/// 创建标签组件
259///
260/// # 参数
261/// - `id`: 组件ID
262/// - `text`: 标签文本
263/// - `style`: 组件样式
264///
265/// # 返回值
266/// 标签组件实例
267pub fn create_label(id: &str, text: &str, style: Style) -> Component {
268    let mut properties = ComponentProperties::default();
269    properties.text = Some(text.to_string());
270    Component::new(ComponentType::Label, id, style, properties)
271}
272
273/// 创建文本框组件
274///
275/// # 参数
276/// - `id`: 组件ID
277/// - `value`: 文本框值
278/// - `style`: 组件样式
279///
280/// # 返回值
281/// 文本框组件实例
282pub fn create_text_box(id: &str, value: &str, style: Style) -> Component {
283    let mut properties = ComponentProperties::default();
284    properties.value = Some(serde_json::Value::String(value.to_string()));
285    Component::new(ComponentType::TextBox, id, style, properties)
286}
287
288/// 创建容器组件
289///
290/// # 参数
291/// - `id`: 组件ID
292/// - `style`: 组件样式
293///
294/// # 返回值
295/// 容器组件实例
296pub fn create_container(id: &str, style: Style) -> Component {
297    let properties = ComponentProperties::default();
298    Component::new(ComponentType::Container, id, style, properties)
299}