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