Skip to main content

rust_constructor/
lib.rs

1//! # Rust Constructor V2
2//!
3//! A cross-platform `GUI` framework built on `egui`, the simplest way to develop `GUI` projects with `Rust`
4//!
5//! 基于`egui`构建的跨平台`GUI`框架, 用`Rust`开发`GUI`项目最简单的方式
6//!
7//! ## Overview 概述
8//!
9//! `Rust Constructor` is a fully functional GUI framework that leverages the power of `egui` to provide
10//! a simple and intuitive instrument for building cross-platform applications.
11//!
12//! `Rust Constructor`是一个功能全面的GUI框架,它利用了`egui`的强大功能,为构建跨平台应用程序提供了一个简单直观的工具。
13//!
14//! ## Quick Start 快速入门
15//!
16//! Due to dependency issues, we cannot provide the test cases directly within the code. However, you can
17//! find the directly usable code in the `README`.
18//!
19//! 由于依赖问题,我们无法直接在代码中提供测试用例,你可以在`README`中找到能直接使用的代码。
20//!
21//! ## Documentation 文档
22//!
23//! - [Rust Constructor Guide](https://github.com/ChepleBob30/Rust-Constructor-Guide)
24//! - [GitHub Repository](https://github.com/ChepleBob30/Rust-Constructor)
25//! - [Binder 必达](https://github.com/Binder-organize) - Other projects from our organization 我们组织的其他项目
26pub mod advance_front;
27pub mod app;
28pub mod background;
29pub mod basic_front;
30use egui::Ui;
31use std::{
32    any::{Any, type_name, type_name_of_val},
33    error::Error,
34    fmt::{Debug, Display, Formatter},
35    time::Instant,
36    vec::Vec,
37};
38
39/// Core trait for managing Rust Constructor resources uniformly.
40///
41/// 统一管理Rust Constructor资源的核心特性。
42///
43/// This trait provides a common interface for all GUI resources in the framework,
44/// allowing for the acquisition and modification of specific resources and their details.
45///
46/// 此特征为框架中的所有GUI资源提供了一个公共接口,允许获取具体资源及其细节并对其进行修改。
47///
48/// # Thread Safety
49///
50/// This trait is automatically impl'd for types that implement `Send` and `Sync`,
51/// allowing `App` to be used in multi-threaded contexts (e.g., Bevy).
52///
53/// # 线程安全
54///
55/// 此特征自动为实现了 `Send` 和 `Sync` 的类型 impl,使 `App` 可以在多线程上下文中使用(例如 Bevy)。
56pub trait RustConstructorResource: Debug + Send + Sync {
57    /// Returns a reference to the resource as `Any` for extract the specific type.
58    ///
59    /// 以`Any`返回对资源的引用,用于取出具体类型。
60    ///
61    /// This allows downcasting to the concrete type when the actual type is known.
62    ///
63    /// 当实际类型已知时,允许向下转换到具体类型。
64    fn as_any(&self) -> &dyn Any;
65
66    /// Returns a mutable reference to the resource as `Any` for extract the specific type.
67    ///
68    /// 以`Any`返回对资源的可变引用,用于取出具体类型。
69    ///
70    /// This allows mutable downcasting when the actual type is known.
71    ///
72    /// 当实际类型已知时,允许向下可变转换到具体类型。
73    fn as_any_mut(&mut self) -> &mut dyn Any;
74
75    /// Retrieves the display info field for this resource.
76    ///
77    /// 取出此资源的显示信息字段。
78    ///
79    /// Returns `Some(DisplayInfo)` if the resource has display info field,
80    /// or `None` if it doesn't have display info field.
81    ///
82    /// 如果资源具有显示信息字段则返回`Some(DisplayInfo)`,如果资源没有显示信息字段则返回`None`。
83    fn display_display_info(&self) -> Option<DisplayInfo>;
84
85    /// Updates the display info field for this resource.
86    ///
87    /// 更新此资源的显示信息字段。
88    fn modify_display_info(&mut self, display_info: DisplayInfo);
89
90    /// Returns all tags associated with this resource.
91    ///
92    /// 返回与此资源关联的所有标签。
93    ///
94    /// Tags are stored as key-value pairs (`[String; 2]`) and can be used
95    /// for categorization, filtering, or metadata storage.
96    ///
97    /// 标签以键值对(`[String; 2]`)的形式存储,可用于分类、过滤或元数据存储。
98    fn display_tags(&self) -> Vec<[String; 2]>;
99
100    /// Updates the tags for this resource.
101    ///
102    /// 更新此资源的标签。
103    ///
104    /// # Arguments
105    ///
106    /// * `replace` - If `true`, replaces all existing tags;
107    ///   if `false`, merges with existing tags.
108    ///
109    /// # 参数
110    ///
111    /// * `replace` - 若为`true`,则替换所有现有的标签;
112    ///   若为`false`,则与现有标签合并。
113    fn modify_tags(&mut self, tags: &[[String; 2]], replace: bool);
114}
115
116/// Trait for managing basic front resources that are displayed to the user.
117///
118/// 用于管理显示给用户的基本前端资源的特征。
119///
120/// This trait extends `RustConstructorResource` with additional methods specific
121/// to visual elements.
122///
123/// 此特征扩展了`RustConstructorResource`,添加了特定视觉元素的方法。
124pub trait BasicFrontResource: RustConstructorResource {
125    /// Returns the complete basic resource config.
126    ///
127    /// 返回完整的基本前端资源配置。
128    ///
129    /// This includes both position/size config and clipping information.
130    ///
131    /// 包括位置/大小配置和裁剪信息。
132    fn display_basic_front_resource_config(&self) -> BasicFrontResourceConfig;
133
134    /// Returns the position and size config for this resource.
135    ///
136    /// 返回此资源的位置和大小配置。
137    ///
138    /// Includes grid-based positioning, alignment settings, and offset values.
139    ///
140    /// 包括基于网格的定位、对齐设置和偏移值。
141    fn display_position_size_config(&self) -> PositionSizeConfig;
142
143    /// Returns the clipping rectangle config if this resource has one.
144    ///
145    /// 返回裁剪矩形配置(如果此资源有的话)。
146    ///
147    /// Clipping rectangles define the visible area of the resource.
148    ///
149    /// 裁剪矩形定义资源的可见区域。
150    ///
151    /// Returns `None` if no clipping is applied.
152    ///
153    /// 如果没有应用裁剪矩形,则返回`None`。
154    fn display_clip_rect(&self) -> Option<PositionSizeConfig>;
155
156    /// Returns the current display position of the resource.
157    ///
158    /// 返回资源的当前显示位置。
159    ///
160    /// The position is returned as `[x, y]` coordinates.
161    ///
162    /// 位置以`[x, y]`坐标返回。
163    fn display_position(&self) -> [f32; 2];
164
165    /// Returns the current display size of the resource.
166    ///
167    /// 返回资源的当前显示大小。
168    ///
169    /// The size is returned as `[width, height]`.
170    ///
171    /// 大小以`[width, height]`返回。
172    fn display_size(&self) -> [f32; 2];
173
174    /// Updates the complete basic resource config.
175    ///
176    /// 更新完整的前端资源配置。
177    fn modify_basic_front_resource_config(
178        &mut self,
179        basic_front_resource_config: BasicFrontResourceConfig,
180    );
181
182    /// Updates the position and size config.
183    ///
184    /// 更新位置和大小配置。
185    fn modify_position_size_config(&mut self, position_size_config: PositionSizeConfig);
186
187    /// Updates the clipping rectangle config.
188    ///
189    /// 更新裁剪矩形配置。
190    fn modify_clip_rect(&mut self, clip_rect: Option<PositionSizeConfig>);
191}
192
193/// Unique identifier for Rust Constructor resources.
194///
195/// Rust Constructor资源的唯一标识符。
196///
197/// This struct combines a resource name and type to create a unique identifier
198/// that can be used to reference resources throughout the application.
199///
200/// 这个结构体结合了资源名称和类型来创建一个唯一的标识符,可以在整个应用程序中用来引用资源。
201#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
202pub struct RustConstructorId {
203    /// Unique name identifying the resource instance, Resources of different
204    /// types can have the same name.
205    ///
206    /// 标识资源实例的唯一名称,不同类型的资源可以重名。
207    pub name: String,
208
209    /// Type of the resource (e.g., `Image`).
210    ///
211    /// 资源的类型(例如`Image`)。
212    pub discern_type: String,
213}
214
215/// Container for Rust Constructor resources with type-erased storage.
216///
217/// 具有类型擦除存储的Rust Constructor资源的容器。
218///
219/// This struct pairs a resource identifier with the actual resource content,
220/// allowing for heterogeneous storage of different resource types while
221/// maintaining the ability to identify and manage them individually.
222///
223/// 这个结构体将资源标识符与实际资源内容配对,允许不同资源类型的异构存储,同时保持单独识别和管理它们的能力。
224///
225/// # Type Erasure 类型擦除
226///
227/// The `content` field uses a `Box<dyn RustConstructorResource>` to store
228/// any type that implements the `RustConstructorResource` trait, enabling
229/// polymorphic behavior and storage.
230///
231/// `content`字段使用`Box<dyn RustConstructorResource>`来存储任何实现`RustConstructorResource`
232/// 特征的类型,从而启用多态行为和存储。
233#[derive(Debug)]
234pub struct RustConstructorResourceBox {
235    /// Unique identifier for the contained resource.
236    ///
237    /// 所包含资源的唯一标识符。
238    pub id: RustConstructorId,
239
240    /// Type-erased resource content.
241    ///
242    /// 类型擦除的资源内容。
243    pub content: Box<dyn RustConstructorResource>,
244}
245
246unsafe impl Send for RustConstructorResourceBox {}
247
248unsafe impl Sync for RustConstructorResourceBox {}
249
250impl RustConstructorResourceBox {
251    pub fn new(name: &str, discern_type: &str, content: Box<dyn RustConstructorResource>) -> Self {
252        Self {
253            id: RustConstructorId {
254                name: name.to_string(),
255                discern_type: discern_type.to_string(),
256            },
257            content,
258        }
259    }
260}
261
262/// Config for basic front resources.
263///
264/// 基本前端资源的配置。
265///
266/// This struct contains all the essential config needed for positioning,
267/// sizing, and clipping visual elements in the GUI.
268///
269/// 这个结构体包含了在GUI中定位、调整大小和裁剪可视元素所需的所有配置。
270#[derive(Debug, Default, Clone, PartialEq, PartialOrd)]
271pub struct BasicFrontResourceConfig {
272    /// Config for position, size, and layout properties.
273    ///
274    /// 位置、大小和布局属性的配置。
275    pub position_size_config: PositionSizeConfig,
276
277    /// Optional clipping rectangle that defines the visible area.
278    /// If `None`, the resource is rendered without clipping.
279    ///
280    /// 可选的裁剪矩形,用于定义可见区域。如果为`None`,则渲染资源时不进行裁剪。
281    pub clip_rect: Option<PositionSizeConfig>,
282}
283
284impl BasicFrontResourceConfig {
285    #[inline]
286    pub fn position_size_config(mut self, position_size_config: PositionSizeConfig) -> Self {
287        self.position_size_config = position_size_config;
288        self
289    }
290
291    #[inline]
292    pub fn clip_rect(mut self, clip_rect: Option<PositionSizeConfig>) -> Self {
293        self.clip_rect = clip_rect;
294        self
295    }
296}
297
298/// Config for positioning and sizing resources in a flexible grid system.
299///
300/// 用于在灵活的网格系统中定位和调整资源大小的配置。
301///
302/// This struct provides comprehensive control over how resources are positioned
303/// and sized within the GUI, supporting grid-based layouts with multiple alignment options.
304///
305/// 这个结构体提供了对GUI中资源如何定位和大小的全面控制,支持具有多种对齐选项的基于网格的布局。
306///
307/// # Grid System 网格系统
308///
309/// The grid system allows for relative positioning and sizing using fractions of
310/// the available space, making layouts responsive and adaptable to different screen sizes.
311///
312/// 网格系统允许使用可用空间的一部分进行相对定位和大小调整,使布局响应并适应不同的屏幕尺寸。
313#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
314pub struct PositionSizeConfig {
315    /// Absolute position coordinates in pixels (`[x, y]`).
316    ///
317    /// 以像素为单位的绝对位置坐标(`[x, y]`)。
318    pub origin_position: [f32; 2],
319
320    /// Absolute size dimensions in pixels (`[width, height]`).
321    ///
322    /// 以像素为单位的绝对尺寸(`[width, height]`)。
323    pub origin_size: [f32; 2],
324
325    /// Grid-based X-axis positioning (`[numerator, denominator]`).
326    ///
327    /// 基于网格的x轴定位(`[numerator, denominator]`)。
328    ///
329    /// Position = (total_width * numerator / denominator)
330    ///
331    /// 位置 = (总宽度 * 分子 / 分母)
332    pub x_location_grid: [f32; 2],
333
334    /// Grid-based Y-axis positioning (`[numerator, denominator]`).
335    ///
336    /// 基于网格的y轴定位(`[numerator, denominator]`)。
337    ///
338    /// Position = (total_height * numerator / denominator)
339    ///
340    /// 位置 = (总高度 * 分子 / 分母)
341    pub y_location_grid: [f32; 2],
342
343    /// Grid-based X-axis sizing (`[numerator, denominator]`).
344    ///
345    /// 基于网格的x轴缩放(`[numerator, denominator]`)。
346    ///
347    /// Width = (total_width * numerator / denominator)
348    ///
349    /// 宽度 = (总宽度 * 分子 / 分母)
350    pub x_size_grid: [f32; 2],
351
352    /// Grid-based Y-axis sizing (`[numerator, denominator]`).
353    ///
354    /// 基于网格的y轴缩放(`[numerator, denominator]`)。
355    ///
356    /// Height = (total_height * numerator / denominator)
357    ///
358    /// 高度 = (总高度 * 分子 / 分母)
359    pub y_size_grid: [f32; 2],
360
361    /// Horizontal and vertical alignment methods.
362    ///
363    /// 水平和垂直对齐方法。
364    pub display_method: (HorizontalAlign, VerticalAlign),
365
366    /// Additional offset in pixels (`[x_offset, y_offset]`).
367    ///
368    /// 额外的像素偏移量(`[x_offset, y_offset]`)。
369    pub offset: [f32; 2],
370}
371
372impl Default for PositionSizeConfig {
373    fn default() -> Self {
374        PositionSizeConfig {
375            origin_position: [0_f32, 0_f32],
376            origin_size: [0_f32, 0_f32],
377            x_location_grid: [0_f32, 0_f32],
378            y_location_grid: [0_f32, 0_f32],
379            x_size_grid: [0_f32, 0_f32],
380            y_size_grid: [0_f32, 0_f32],
381            display_method: (HorizontalAlign::default(), VerticalAlign::default()),
382            offset: [0_f32, 0_f32],
383        }
384    }
385}
386
387impl PositionSizeConfig {
388    #[inline]
389    pub fn origin_position(mut self, x: f32, y: f32) -> Self {
390        self.origin_position = [x, y];
391        self
392    }
393
394    #[inline]
395    pub fn origin_size(mut self, width: f32, height: f32) -> Self {
396        self.origin_size = [width, height];
397        self
398    }
399
400    #[inline]
401    pub fn x_size_grid(mut self, fetch: f32, total: f32) -> Self {
402        self.x_size_grid = [fetch, total];
403        self
404    }
405
406    #[inline]
407    pub fn y_size_grid(mut self, fetch: f32, total: f32) -> Self {
408        self.y_size_grid = [fetch, total];
409        self
410    }
411
412    #[inline]
413    pub fn x_location_grid(mut self, fetch: f32, total: f32) -> Self {
414        self.x_location_grid = [fetch, total];
415        self
416    }
417
418    #[inline]
419    pub fn y_location_grid(mut self, fetch: f32, total: f32) -> Self {
420        self.y_location_grid = [fetch, total];
421        self
422    }
423
424    #[inline]
425    pub fn display_method(
426        mut self,
427        horizontal_align: HorizontalAlign,
428        vertical_align: VerticalAlign,
429    ) -> Self {
430        self.display_method = (horizontal_align, vertical_align);
431        self
432    }
433
434    #[inline]
435    pub fn offset(mut self, x: f32, y: f32) -> Self {
436        self.offset = [x, y];
437        self
438    }
439}
440
441/// Timer for tracking application and page runtimes.
442///
443/// 用于跟踪应用程序和页面运行时间的计时器。
444#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
445pub struct Timer {
446    /// Time when the current page was entered, in milliseconds.
447    ///
448    /// 进入当前页面的时间(毫秒)。
449    pub start_time: u128,
450
451    /// Total runtime of the application since start, in milliseconds.
452    ///
453    /// 应用程序自启动以来的总运行时间(毫秒)。
454    pub total_time: u128,
455
456    /// Core timer instance for precise timing.
457    ///
458    /// 用于精确计时的核心计时器实例。
459    pub timer: Instant,
460
461    /// Runtime of the current page, in milliseconds.
462    ///
463    /// 当前页面的运行时间(毫秒)。
464    pub now_time: u128,
465}
466
467impl Default for Timer {
468    fn default() -> Self {
469        Timer {
470            start_time: 0,
471            total_time: 0,
472            timer: Instant::now(),
473            now_time: 0,
474        }
475    }
476}
477
478/// Error type for Rust Constructor framework.
479///
480/// Rust Constructor框架的错误类型。
481#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
482pub struct RustConstructorError {
483    /// Identifier for the error type.
484    ///
485    /// 错误类型的标识符。
486    pub error_id: String,
487
488    /// Description of the error.
489    ///
490    /// 对此错误的描述。
491    pub description: String,
492}
493
494impl Display for RustConstructorError {
495    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
496        Debug::fmt(self, f)
497    }
498}
499
500impl Error for RustConstructorError {}
501
502/// Horizontal alignment options for UI elements.
503///
504/// UI元素的水平对齐选项。
505#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
506pub enum HorizontalAlign {
507    /// Align to the left.
508    ///
509    /// 左对齐。
510    #[default]
511    Left,
512    /// Center align horizontally.
513    ///
514    /// 居中对齐。
515    Center,
516    /// Align to the right.
517    ///
518    /// 右对齐。
519    Right,
520}
521
522/// Vertical alignment options for UI elements.
523///
524/// UI元素的垂直对齐选项。
525#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
526pub enum VerticalAlign {
527    /// Align to the top.
528    ///
529    /// 顶部对齐。
530    #[default]
531    Top,
532    /// Center align vertically.
533    ///
534    /// 居中对齐。
535    Center,
536    /// Align to the bottom.
537    ///
538    /// 底部对齐。
539    Bottom,
540}
541
542/// Defines the placement of borders relative to the element's bounds.
543///
544/// 定义边框相对于元素边界的放置方式。
545#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
546pub enum BorderKind {
547    /// Border is drawn inside the element's bounds, reducing the content area.
548    ///
549    /// 边框在元素边界内部绘制,减少内容区域。
550    #[default]
551    Inside,
552    /// Border is centered on the element's bounds, half inside and half outside.
553    ///
554    /// 边框以元素边界为中心,一半在内部一半在外部。
555    Middle,
556    /// Border is drawn outside the element's bounds, preserving the content area.
557    ///
558    /// 边框在元素边界外部绘制,保持内容区域不变。
559    Outside,
560}
561
562/// Config for rendering.
563///
564/// 渲染的配置。
565#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
566pub enum RenderConfig {
567    /// Line with width and color.
568    ///
569    /// 线段,包含宽度和颜色。
570    Line(f32, [u8; 4]),
571    /// Rectangle with corner radius, fill color, border color, border width, and border kind.
572    ///
573    /// 矩形,包含圆角半径,填充颜色,边框颜色,边框宽度,边框类型。
574    Rect([u8; 4], [u8; 4], [u8; 4], f32, BorderKind),
575}
576
577/// Display config for resources, controlling visibility and rendering behavior.
578///
579/// 资源的显示配置,控制可见性和渲染行为。
580#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
581pub struct DisplayInfo {
582    /// Enables or disables the resource. If false, the resource is not processed.
583    ///
584    /// 启用或禁用资源。如果为false,资源不会被处理。
585    pub enable: bool,
586
587    /// Hides the resource visually but keeps it active for event handling.
588    ///
589    /// 隐藏资源视觉显示但保持其事件处理活性。
590    pub hidden: bool,
591
592    /// If true, the resource ignores the rendering layer and does not occupy the mouse focus.
593    ///
594    /// 如果为true,资源忽略渲染层,不占用鼠标焦点。
595    pub ignore_render_layer: bool,
596}
597
598/// The lookup method for requesting resources to skip the rendering queue.
599///
600/// 请求资源跳过渲染队列的查找方法。
601#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
602pub enum RequestMethod {
603    /// Request by resource identifier.
604    ///
605    /// 按资源标识符请求。
606    Id(RustConstructorId),
607    /// Request by resource citer.
608    ///
609    /// 通过资源引用者请求。
610    Citer(RustConstructorId),
611}
612
613/// Types of rendering layer requests.
614///
615/// 渲染层请求类型。
616#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
617pub enum RequestType {
618    /// Move resource to the top layer.
619    ///
620    /// 移动资源到顶层。
621    Top,
622    /// Move resource up by specified number of layers.
623    ///
624    /// 按指定层数向上移动资源。
625    Up(usize),
626}
627
628/// Methods for describing list information.
629///
630/// 用于描述列表信息的方法。
631#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
632pub enum ListInfoDescribeMethod {
633    /// Detailed display including resource and ID (with optional formatting).
634    ///
635    /// 详细显示,包括资源和ID(可选格式)。
636    Detailed(bool),
637    /// Simple display showing only resource IDs.
638    ///
639    /// 简单显示,只显示资源ID。
640    #[default]
641    Simple,
642}
643
644/// Obtain the type name of the target resource.
645///
646/// 获取目标资源的类型名称。
647///
648/// # Arguments
649///
650/// * `target` - Target resource
651///
652/// # Returns
653///
654/// Returns the type name of the target resource.
655///
656/// # 参数
657///
658/// * `target` - 目标资源
659///
660/// # 返回值
661///
662/// 目标资源的类型名称。
663pub fn type_processor(target: &impl RustConstructorResource) -> String {
664    let result: Vec<_> = if let Some(list) = type_name_of_val(target).split_once("<") {
665        list.0
666    } else {
667        type_name_of_val(&target)
668    }
669    .split("::")
670    .collect();
671    result[result.len() - 1].to_string()
672}
673
674/// Gets a tag value from the specified tag list by name.
675///
676/// 从指定标签列表中根据名称获取标签值。
677///
678/// # Arguments
679///
680/// * `tag_name` - The name of the tag to retrieve
681/// * `target` - The list of tags to search through
682///
683/// # Returns
684///
685/// Returns `Some((index, value))` if the tag is found, or `None` if not found.
686///
687/// # 参数
688///
689/// * `tag_name` - 要检索的标签名称
690/// * `target` - 要搜索的标签列表
691///
692/// # 返回值
693///
694/// 如果找到标签则返回`Some((索引, 值))`,否则返回`None`。
695pub fn get_tag(tag_name: &str, target: &[[String; 2]]) -> Option<(usize, String)> {
696    target
697        .iter()
698        .position(|x| x[0] == tag_name)
699        .map(|index| (index, target[index][1].clone()))
700}
701
702/// Safely convert resource references to references of specific types of resources.
703///
704/// 安全地将资源引用转换为具体类型资源的引用。
705///
706/// When using the traversal method to retrieve resources, it should be combined with this method to obtain
707/// the reference of the specific type of resource.
708///
709/// 当采用遍历的方式取出资源时,应和此方法配合来获取具体类型的资源引用。
710///
711/// # Arguments
712///
713/// * `resource` - Reference to resources
714///
715/// # Returns
716///
717/// Return a reference to the specific type of resource on success; otherwise, return `Err(RustConstructorError)`.
718///
719/// # 参数
720///
721/// * `resource` - 资源的引用
722///
723/// # 返回值
724///
725/// 成功时返回具体类型资源的引用,否则返回`Err(RustConstructorError)`。
726pub fn downcast_resource<T: RustConstructorResource + 'static>(
727    resource: &dyn RustConstructorResource,
728) -> Result<&T, RustConstructorError> {
729    if let Some(resource) = resource.as_any().downcast_ref::<T>() {
730        Ok(resource)
731    } else {
732        Err(RustConstructorError {
733            error_id: "ResourceDowncastTypeMismatch".to_string(),
734            description: format!(
735                "Failed to downcast resource to type '{}'.",
736                type_name::<T>()
737            ),
738        })
739    }
740}
741
742/// Safely convert mutable references to resources to mutable references to resources of specific types.
743///
744/// 安全地将资源可变引用转换为具体类型资源的可变引用。
745///
746/// When using the traversal method to retrieve resources, it should be combined with this method to obtain
747/// the mutable reference of the specific type of resource.
748///
749/// 当采用遍历的方式取出资源时,应和此方法配合来获取具体类型的资源可变引用。
750///
751/// # Arguments
752///
753/// * `resource` - Mutable reference to resources
754///
755/// # Returns
756///
757/// Return a mutable reference to the specific type of resource on success; otherwise, return `Err(RustConstructorError)`.
758///
759/// # 参数
760///
761/// * `resource` - 资源的可变引用
762///
763/// # 返回值
764///
765/// 成功时返回具体类型资源的可变引用,否则返回`Err(RustConstructorError)`。
766pub fn downcast_resource_mut<T: RustConstructorResource + 'static>(
767    resource: &mut dyn RustConstructorResource,
768) -> Result<&mut T, RustConstructorError> {
769    if let Some(resource) = resource.as_any_mut().downcast_mut::<T>() {
770        Ok(resource)
771    } else {
772        Err(RustConstructorError {
773            error_id: "ResourceDowncastTypeMismatch".to_string(),
774            description: format!(
775                "Failed to downcast resource to type '{}'.",
776                type_name::<T>()
777            ),
778        })
779    }
780}
781
782/// Processes position and size calculations for resources.
783///
784/// 处理资源的最基本位置和尺寸计算。
785///
786/// This method handles the complex positioning logic including grid-based layout,
787/// alignment, and offset calculations for UI resources.
788///
789/// 此方法处理复杂的定位逻辑,包括基于网格的布局、对齐方式和UI资源的偏移计算。
790///
791/// # Arguments
792///
793/// * `position_size_config` - The configuration for position and size
794/// * `ctx` - The egui context for available space calculations
795///
796/// # Returns
797///
798/// Returns `[position, size]` as computed from the configuration
799///
800/// # 参数
801///
802/// * `position_size_config` - 位置和尺寸的配置
803/// * `ctx` - 用于可用空间计算的egui上下文
804///
805/// # 返回值
806///
807/// 返回根据配置计算出的 `[位置, 尺寸]`
808pub fn position_size_processor(position_size_config: PositionSizeConfig, ui: &Ui) -> [[f32; 2]; 2] {
809    let mut position = [0_f32, 0_f32];
810    let mut size = [0_f32, 0_f32];
811    size[0] = match position_size_config.x_size_grid[0] {
812        0_f32 => position_size_config.origin_size[0],
813        _ => {
814            (ui.available_width() / position_size_config.x_size_grid[1]
815                * position_size_config.x_size_grid[0])
816                + position_size_config.origin_size[0]
817        }
818    };
819    size[1] = match position_size_config.y_size_grid[0] {
820        0_f32 => position_size_config.origin_size[1],
821        _ => {
822            (ui.available_height() / position_size_config.y_size_grid[1]
823                * position_size_config.y_size_grid[0])
824                + position_size_config.origin_size[1]
825        }
826    };
827    position[0] = match position_size_config.x_location_grid[1] {
828        0_f32 => position_size_config.origin_position[0],
829        _ => {
830            (ui.available_width() / position_size_config.x_location_grid[1]
831                * position_size_config.x_location_grid[0])
832                + position_size_config.origin_position[0]
833        }
834    };
835    position[1] = match position_size_config.y_location_grid[1] {
836        0_f32 => position_size_config.origin_position[1],
837        _ => {
838            (ui.available_height() / position_size_config.y_location_grid[1]
839                * position_size_config.y_location_grid[0])
840                + position_size_config.origin_position[1]
841        }
842    };
843    match position_size_config.display_method.0 {
844        HorizontalAlign::Left => {}
845        HorizontalAlign::Center => position[0] -= size[0] / 2.0,
846        HorizontalAlign::Right => position[0] -= size[0],
847    };
848    match position_size_config.display_method.1 {
849        VerticalAlign::Top => {}
850        VerticalAlign::Center => position[1] -= size[1] / 2.0,
851        VerticalAlign::Bottom => position[1] -= size[1],
852    };
853    position[0] += position_size_config.offset[0];
854    position[1] += position_size_config.offset[1];
855    [position, size]
856}