Skip to main content

rust_constructor/
lib.rs

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