Skip to main content

itools_gui/
components.rs

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