Skip to main content

itools_gui/
utils.rs

1//! 工具函数模块
2//!
3//! 提供 GUI 相关的工具函数和辅助方法。
4
5/// 计算两点之间的距离
6///
7/// # 参数
8/// - `x1`: 第一个点的 x 坐标
9/// - `y1`: 第一个点的 y 坐标
10/// - `x2`: 第二个点的 x 坐标
11/// - `y2`: 第二个点的 y 坐标
12///
13/// # 返回值
14/// 两点之间的距离
15pub fn distance(x1: f32, y1: f32, x2: f32, y2: f32) -> f32 {
16    ((x2 - x1).powi(2) + (y2 - y1).powi(2)).sqrt()
17}
18
19/// 限制值在指定范围内
20///
21/// # 参数
22/// - `value`: 要限制的值
23/// - `min`: 最小值
24/// - `max`: 最大值
25///
26/// # 返回值
27/// 限制后的值
28pub fn clamp(value: f32, min: f32, max: f32) -> f32 {
29    value.max(min).min(max)
30}
31
32/// 线性插值
33///
34/// # 参数
35/// - `start`: 起始值
36/// - `end`: 结束值
37/// - `t`: 插值参数 (0.0-1.0)
38///
39/// # 返回值
40/// 插值结果
41pub fn lerp(start: f32, end: f32, t: f32) -> f32 {
42    start + (end - start) * clamp(t, 0.0, 1.0)
43}
44
45/// 从 0-255 范围的 RGB 值转换为 0-1 范围的浮点数
46///
47/// # 参数
48/// - `value`: 0-255 范围的 RGB 值
49///
50/// # 返回值
51/// 0-1 范围的浮点数
52pub fn rgb_to_float(value: u8) -> f32 {
53    value as f32 / 255.0
54}
55
56/// 从 0-1 范围的浮点数转换为 0-255 范围的 RGB 值
57///
58/// # 参数
59/// - `value`: 0-1 范围的浮点数
60///
61/// # 返回值
62/// 0-255 范围的 RGB 值
63pub fn float_to_rgb(value: f32) -> u8 {
64    (clamp(value, 0.0, 1.0) * 255.0).round() as u8
65}
66
67/// 检查点是否在矩形内
68///
69/// # 参数
70/// - `x`: 点的 x 坐标
71/// - `y`: 点的 y 坐标
72/// - `rect_x`: 矩形的 x 坐标
73/// - `rect_y`: 矩形的 y 坐标
74/// - `rect_width`: 矩形的宽度
75/// - `rect_height`: 矩形的高度
76///
77/// # 返回值
78/// 点是否在矩形内
79pub fn point_in_rect(x: f32, y: f32, rect_x: f32, rect_y: f32, rect_width: f32, rect_height: f32) -> bool {
80    x >= rect_x && x <= rect_x + rect_width && y >= rect_y && y <= rect_y + rect_height
81}
82
83/// 生成唯一 ID
84///
85/// # 返回值
86/// 唯一 ID 字符串
87pub fn generate_id() -> String {
88    use std::time::{SystemTime, UNIX_EPOCH};
89    let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_nanos();
90    format!("{:x}", timestamp)
91}
92
93/// 格式化错误信息
94///
95/// # 参数
96/// - `error`: 错误
97///
98/// # 返回值
99/// 格式化后的错误信息
100pub fn format_error(error: &dyn std::error::Error) -> String {
101    let mut message = error.to_string();
102    let mut current_error = error.source();
103    while let Some(cause) = current_error {
104        message.push_str(&format!("\nCaused by: {}", cause));
105        current_error = cause.source();
106    }
107    message
108}