Skip to main content

rust_constructor/
basic_front.rs

1//! This file contains basic front resources. Basic front resources can be used independently or to create advanced front-end resources.
2//!
3//! 此文件包含基本前端资源。基本前端资源可以单独使用,也可被用于创建高级前端资源。
4use crate::{
5    BasicFrontResource, BasicFrontResourceConfig, BorderKind, DisplayInfo, PositionSizeConfig,
6    RustConstructorResource,
7};
8use eframe::egui::TextureHandle;
9use std::{
10    any::Any,
11    fmt::{Debug, Formatter},
12};
13
14/// Config options for custom rectangles.
15///
16/// 矩形的可配置选项。
17///
18/// This struct contains all configurable properties for creating and modifying
19/// rectangular UI elements with various visual properties.
20///
21/// 该结构体包含用于创建和修改具有各种视觉属性的矩形UI元素的所有可配置属性。
22#[derive(Debug, Default, Clone, PartialEq, PartialOrd)]
23pub struct CustomRectConfig {
24    /// Config for position, size, and layout of the rectangle.
25    ///
26    /// 矩形的位置、尺寸和布局配置。
27    pub position_size_config: Option<PositionSizeConfig>,
28
29    /// Optional clipping rectangle that defines the visible area.
30    ///
31    /// 定义可见区域的可选裁剪矩形。
32    pub clip_rect: Option<Option<PositionSizeConfig>>,
33
34    /// Controls whether the rectangle is visible or hidden.
35    ///
36    /// 控制矩形是否可见或隐藏。
37    pub hidden: Option<bool>,
38
39    /// If true, the rectangle ignores render layer.
40    ///
41    /// 如果为true,矩形忽略渲染层。
42    pub ignore_render_layer: Option<bool>,
43
44    /// Radius for rounded corners. Zero for sharp corners.
45    ///
46    /// 圆角半径。零表示直角。
47    pub rounding: Option<f32>,
48
49    /// Fill color of the rectangle as [R, G, B].
50    ///
51    /// 矩形的填充颜色,格式为[R, G, B]。
52    pub color: Option<[u8; 3]>,
53
54    /// Opacity of the rectangle (0-255).
55    ///
56    /// 矩形的不透明度(0-255)。
57    pub alpha: Option<u8>,
58
59    /// Fill color overlay of the rectangle as [R, G, B].
60    ///
61    /// 矩形的填充颜色覆盖层,格式为[R, G, B]。
62    pub overlay_color: Option<[u8; 3]>,
63
64    /// Opacity of the fill color overlay (0-255).
65    ///
66    /// 矩形的填充颜色覆盖层不透明度(0-255)。
67    pub overlay_alpha: Option<Option<u8>>,
68
69    /// Width of the border.
70    ///
71    /// 边框宽度。
72    pub border_width: Option<f32>,
73
74    /// Color of the border as [R, G, B].
75    ///
76    /// 边框颜色,格式为[R, G, B]。
77    pub border_color: Option<[u8; 3]>,
78
79    /// Opacity of the border (0-255).
80    ///
81    /// 边框的不透明度(0-255)。
82    pub border_alpha: Option<u8>,
83
84    /// Color overlay of the border as [R, G, B].
85    ///
86    /// 边框的颜色覆盖层,格式为[R, G, B]。
87    pub overlay_border_color: Option<[u8; 3]>,
88
89    /// Opacity of the border color overlay (0-255).
90    ///
91    /// 边框的颜色覆盖层不透明度(0-255)。
92    pub overlay_border_alpha: Option<Option<u8>>,
93
94    /// Placement of the border relative to the rectangle's bounds.
95    ///
96    /// 边框相对于矩形边界的放置方式。
97    pub border_kind: Option<BorderKind>,
98
99    /// Key-value pairs for categorization and metadata.
100    ///
101    /// 用于分类和元数据的键值对标签。
102    pub tags: Option<Vec<[String; 2]>>,
103}
104
105impl CustomRectConfig {
106    pub fn from_custom_rect(custom_rect: &CustomRect) -> Self {
107        Self {
108            position_size_config: Some(
109                custom_rect.basic_front_resource_config.position_size_config,
110            ),
111            clip_rect: Some(custom_rect.basic_front_resource_config.clip_rect),
112            hidden: Some(custom_rect.display_info.hidden),
113            ignore_render_layer: Some(custom_rect.display_info.ignore_render_layer),
114            rounding: Some(custom_rect.rounding),
115            color: Some(custom_rect.color),
116            alpha: Some(custom_rect.alpha),
117            overlay_color: Some(custom_rect.overlay_color),
118            overlay_alpha: Some(custom_rect.overlay_alpha),
119            border_width: Some(custom_rect.border_width),
120            border_color: Some(custom_rect.border_color),
121            border_alpha: Some(custom_rect.border_alpha),
122            overlay_border_color: Some(custom_rect.overlay_border_color),
123            overlay_border_alpha: Some(custom_rect.overlay_border_alpha),
124            border_kind: Some(custom_rect.border_kind),
125            tags: Some(custom_rect.tags.clone()),
126        }
127    }
128
129    #[inline]
130    pub fn position_size_config(
131        mut self,
132        position_size_config: Option<PositionSizeConfig>,
133    ) -> Self {
134        self.position_size_config = position_size_config;
135        self
136    }
137
138    #[inline]
139    pub fn clip_rect(mut self, clip_rect: Option<Option<PositionSizeConfig>>) -> Self {
140        self.clip_rect = clip_rect;
141        self
142    }
143
144    #[inline]
145    pub fn hidden(mut self, hidden: Option<bool>) -> Self {
146        self.hidden = hidden;
147        self
148    }
149
150    #[inline]
151    pub fn ignore_render_layer(mut self, ignore_render_layer: Option<bool>) -> Self {
152        self.ignore_render_layer = ignore_render_layer;
153        self
154    }
155
156    #[inline]
157    pub fn rounding(mut self, rounding: Option<f32>) -> Self {
158        self.rounding = rounding;
159        self
160    }
161
162    #[inline]
163    pub fn color(mut self, color: Option<[u8; 3]>) -> Self {
164        self.color = color;
165        self
166    }
167
168    #[inline]
169    pub fn alpha(mut self, alpha: Option<u8>) -> Self {
170        self.alpha = alpha;
171        self
172    }
173
174    #[inline]
175    pub fn overlay_color(mut self, overlay_color: Option<[u8; 3]>) -> Self {
176        self.overlay_color = overlay_color;
177        self
178    }
179
180    #[inline]
181    pub fn overlay_alpha(mut self, overlay_alpha: Option<Option<u8>>) -> Self {
182        self.overlay_alpha = overlay_alpha;
183        self
184    }
185
186    #[inline]
187    pub fn border_width(mut self, border_width: Option<f32>) -> Self {
188        self.border_width = border_width;
189        self
190    }
191
192    #[inline]
193    pub fn border_color(mut self, border_color: Option<[u8; 3]>) -> Self {
194        self.border_color = border_color;
195        self
196    }
197
198    #[inline]
199    pub fn border_alpha(mut self, border_alpha: Option<u8>) -> Self {
200        self.border_alpha = border_alpha;
201        self
202    }
203
204    #[inline]
205    pub fn overlay_border_color(mut self, overlay_border_color: Option<[u8; 3]>) -> Self {
206        self.overlay_border_color = overlay_border_color;
207        self
208    }
209
210    #[inline]
211    pub fn overlay_border_alpha(mut self, overlay_border_alpha: Option<Option<u8>>) -> Self {
212        self.overlay_border_alpha = overlay_border_alpha;
213        self
214    }
215
216    #[inline]
217    pub fn border_kind(mut self, border_kind: Option<BorderKind>) -> Self {
218        self.border_kind = border_kind;
219        self
220    }
221
222    #[inline]
223    pub fn tags(mut self, tags: Option<Vec<[String; 2]>>) -> Self {
224        self.tags = tags;
225        self
226    }
227}
228
229/// Custom rectangle resource for drawing rectangles with various visual properties.
230///
231/// 自定义矩形资源,用于绘制具有各种视觉属性的矩形。
232#[derive(Debug, Clone, PartialEq, PartialOrd)]
233pub struct CustomRect {
234    /// Config for basic front resource properties.
235    ///
236    /// 基本前端资源属性配置。
237    pub basic_front_resource_config: BasicFrontResourceConfig,
238
239    /// Current display position of the rectangle as [x, y].
240    ///
241    /// 矩形的当前显示位置,为[x, y]。
242    pub position: [f32; 2],
243
244    /// Current display size of the rectangle as [width, height].
245    ///
246    /// 矩形的当前显示尺寸,为[width, height]。
247    pub size: [f32; 2],
248
249    /// Display info controlling visibility and rendering.
250    ///
251    /// 显示信息,控制可见性和渲染。
252    pub display_info: DisplayInfo,
253
254    /// Radius for rounded corners.
255    ///
256    /// 圆角。
257    pub rounding: f32,
258
259    /// Fill color of the rectangle as [R, G, B].
260    ///
261    /// 填充矩形颜色,为[R, G, B]。
262    pub color: [u8; 3],
263
264    /// Opacity of the rectangle (0-255).
265    ///
266    /// 矩形的不透明度(0-255)。
267    pub alpha: u8,
268
269    /// Fill color overlay of the rectangle as [R, G, B].
270    ///
271    /// 矩形的填充颜色覆盖层,格式为[R, G, B]。
272    pub overlay_color: [u8; 3],
273
274    /// Opacity of the fill color overlay (0-255).
275    ///
276    /// 矩形的填充颜色覆盖层不透明度(0-255)。
277    pub overlay_alpha: Option<u8>,
278
279    /// Width of the border.
280    ///
281    /// 边框宽度。
282    pub border_width: f32,
283
284    /// Color of the border as [R, G, B].
285    ///
286    /// 边框颜色,为[R, G, B]。
287    pub border_color: [u8; 3],
288
289    /// Opacity of the border (0-255).
290    ///
291    /// 边框的不透明度(0-255)。
292    pub border_alpha: u8,
293
294    /// Color overlay of the border as [R, G, B].
295    ///
296    /// 边框的颜色覆盖层,格式为[R, G, B]。
297    pub overlay_border_color: [u8; 3],
298
299    /// Opacity of the border color overlay (0-255).
300    ///
301    /// 边框的颜色覆盖层不透明度(0-255)。
302    pub overlay_border_alpha: Option<u8>,
303
304    /// Placement of the border relative to the rectangle's bounds.
305    ///
306    /// 边框相对于矩形边界的位置。
307    pub border_kind: BorderKind,
308
309    /// Key-value pairs for categorization and metadata.
310    ///
311    /// 用于分类和元数据的键值对标签。
312    pub tags: Vec<[String; 2]>,
313}
314
315impl RustConstructorResource for CustomRect {
316    fn as_any(&self) -> &dyn Any {
317        self
318    }
319
320    fn as_any_mut(&mut self) -> &mut dyn Any {
321        self
322    }
323
324    fn display_display_info(&self) -> Option<DisplayInfo> {
325        Some(self.display_info)
326    }
327
328    fn modify_display_info(&mut self, display_info: DisplayInfo) {
329        self.display_info = display_info;
330    }
331
332    fn display_tags(&self) -> Vec<[String; 2]> {
333        self.tags.clone()
334    }
335
336    fn modify_tags(&mut self, tags: &[[String; 2]], replace: bool) {
337        if replace {
338            self.tags = tags.to_owned();
339        } else {
340            for tag in tags {
341                if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
342                    self.tags.remove(index);
343                };
344            }
345            self.tags.extend(tags.iter().cloned());
346        };
347    }
348}
349
350impl BasicFrontResource for CustomRect {
351    fn display_basic_front_resource_config(&self) -> BasicFrontResourceConfig {
352        self.basic_front_resource_config.clone()
353    }
354
355    fn display_position_size_config(&self) -> PositionSizeConfig {
356        self.basic_front_resource_config.position_size_config
357    }
358
359    fn display_clip_rect(&self) -> Option<PositionSizeConfig> {
360        self.basic_front_resource_config.clip_rect
361    }
362
363    fn display_position(&self) -> [f32; 2] {
364        self.position
365    }
366
367    fn display_size(&self) -> [f32; 2] {
368        self.size
369    }
370
371    fn modify_basic_front_resource_config(
372        &mut self,
373        basic_front_resource_config: BasicFrontResourceConfig,
374    ) {
375        self.basic_front_resource_config = basic_front_resource_config;
376    }
377
378    fn modify_position_size_config(&mut self, position_size_config: PositionSizeConfig) {
379        self.basic_front_resource_config.position_size_config = position_size_config;
380    }
381
382    fn modify_clip_rect(&mut self, clip_rect: Option<PositionSizeConfig>) {
383        self.basic_front_resource_config.clip_rect = clip_rect;
384    }
385}
386
387impl Default for CustomRect {
388    fn default() -> Self {
389        Self {
390            basic_front_resource_config: BasicFrontResourceConfig::default(),
391            position: [0_f32, 0_f32],
392            size: [0_f32, 0_f32],
393            display_info: DisplayInfo::default(),
394            rounding: 2_f32,
395            color: [255, 255, 255],
396            alpha: 255,
397            overlay_border_color: [255, 255, 255],
398            overlay_alpha: None,
399            border_width: 2_f32,
400            border_color: [0, 0, 0],
401            border_alpha: 255,
402            overlay_color: [255, 255, 255],
403            overlay_border_alpha: None,
404            border_kind: BorderKind::default(),
405            tags: Vec::new(),
406        }
407    }
408}
409
410impl CustomRect {
411    pub fn from_config(mut self, config: &CustomRectConfig) -> Self {
412        if let Some(position_size_config) = config.position_size_config {
413            self.basic_front_resource_config.position_size_config = position_size_config;
414        };
415        if let Some(clip_rect) = config.clip_rect {
416            self.basic_front_resource_config.clip_rect = clip_rect;
417        };
418        if let Some(hidden) = config.hidden {
419            self.display_info.hidden = hidden;
420        };
421        if let Some(ignore_render_layer) = config.ignore_render_layer {
422            self.display_info.ignore_render_layer = ignore_render_layer;
423        };
424        if let Some(rounding) = config.rounding {
425            self.rounding = rounding;
426        };
427        if let Some(color) = config.color {
428            self.color = color;
429        };
430        if let Some(alpha) = config.alpha {
431            self.alpha = alpha;
432        };
433        if let Some(overlay_color) = config.overlay_color {
434            self.overlay_color = overlay_color;
435        };
436        if let Some(overlay_alpha) = config.overlay_alpha {
437            self.overlay_alpha = overlay_alpha;
438        };
439        if let Some(border_width) = config.border_width {
440            self.border_width = border_width;
441        };
442        if let Some(border_color) = config.border_color {
443            self.border_color = border_color;
444        };
445        if let Some(border_alpha) = config.border_alpha {
446            self.border_alpha = border_alpha;
447        };
448        if let Some(overlay_border_color) = config.overlay_border_color {
449            self.overlay_border_color = overlay_border_color;
450        };
451        if let Some(overlay_border_alpha) = config.overlay_border_alpha {
452            self.overlay_border_alpha = overlay_border_alpha;
453        };
454        if let Some(border_kind) = config.border_kind {
455            self.border_kind = border_kind;
456        };
457        if let Some(tags) = config.tags.clone() {
458            self.tags = tags;
459        };
460        self
461    }
462
463    #[inline]
464    pub fn basic_front_resource_config(
465        mut self,
466        basic_front_resource_config: &BasicFrontResourceConfig,
467    ) -> Self {
468        self.basic_front_resource_config = basic_front_resource_config.clone();
469        self
470    }
471
472    #[inline]
473    pub fn hidden(mut self, hidden: bool) -> Self {
474        self.display_info.hidden = hidden;
475        self
476    }
477
478    #[inline]
479    pub fn ignore_render_layer(mut self, ignore_render_layer: bool) -> Self {
480        self.display_info.ignore_render_layer = ignore_render_layer;
481        self
482    }
483
484    #[inline]
485    pub fn rounding(mut self, rounding: f32) -> Self {
486        self.rounding = rounding;
487        self
488    }
489
490    #[inline]
491    pub fn color(mut self, r: u8, g: u8, b: u8) -> Self {
492        self.color = [r, g, b];
493        self
494    }
495
496    #[inline]
497    pub fn alpha(mut self, alpha: u8) -> Self {
498        self.alpha = alpha;
499        self
500    }
501
502    #[inline]
503    pub fn overlay_color(mut self, r: u8, g: u8, b: u8) -> Self {
504        self.overlay_color = [r, g, b];
505        self
506    }
507
508    #[inline]
509    pub fn overlay_alpha(mut self, overlay_alpha: Option<u8>) -> Self {
510        self.overlay_alpha = overlay_alpha;
511        self
512    }
513
514    #[inline]
515    pub fn border_width(mut self, border_width: f32) -> Self {
516        self.border_width = border_width;
517        self
518    }
519
520    #[inline]
521    pub fn border_color(mut self, r: u8, g: u8, b: u8) -> Self {
522        self.border_color = [r, g, b];
523        self
524    }
525
526    #[inline]
527    pub fn border_alpha(mut self, border_alpha: u8) -> Self {
528        self.border_alpha = border_alpha;
529        self
530    }
531
532    #[inline]
533    pub fn overlay_border_color(mut self, r: u8, g: u8, b: u8) -> Self {
534        self.overlay_border_color = [r, g, b];
535        self
536    }
537
538    #[inline]
539    pub fn overlay_border_alpha(mut self, overlay_border_alpha: Option<u8>) -> Self {
540        self.overlay_border_alpha = overlay_border_alpha;
541        self
542    }
543
544    #[inline]
545    pub fn border_kind(mut self, border_kind: BorderKind) -> Self {
546        self.border_kind = border_kind;
547        self
548    }
549
550    #[inline]
551    pub fn tags(mut self, tags: &[[String; 2]], replace: bool) -> Self {
552        if replace {
553            self.tags = tags.to_owned();
554        } else {
555            for tag in tags {
556                if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
557                    self.tags.remove(index);
558                };
559            }
560            self.tags.extend(tags.iter().cloned());
561        };
562        self
563    }
564}
565
566/// Wrapper for TextureHandle that supports Debug trait derivation.
567///
568/// 支持Debug特征派生的TextureHandle包装器。
569#[derive(Clone, PartialEq, Eq, Hash)]
570pub struct DebugTextureHandle(pub TextureHandle);
571
572impl Debug for DebugTextureHandle {
573    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
574        // 只输出类型信息,不输出具体纹理数据
575        f.debug_struct("DebugTextureHandle").finish()
576    }
577}
578
579impl DebugTextureHandle {
580    pub fn new(texture_handle: &TextureHandle) -> Self {
581        Self(texture_handle.clone())
582    }
583}
584
585/// Methods for loading images into the resource.
586///
587/// 将图像加载到资源中的方法。
588#[derive(Debug, Clone, PartialEq, Eq, Hash)]
589pub enum ImageLoadMethod {
590    /// Load image from a file path.
591    ///
592    /// 从文件路径加载图像。
593    ByPath((String, [bool; 2])),
594
595    /// Use an existing TextureHandle for the image.
596    ///
597    /// 使用现有的TextureHandle作为图像。
598    ByTexture(DebugTextureHandle),
599}
600
601/// Config options for image resources.
602///
603/// 图像资源的配置选项。
604#[derive(Debug, Default, Clone, PartialEq)]
605pub struct ImageConfig {
606    /// Config for position, size, and layout.
607    ///
608    /// 位置、尺寸和布局配置。
609    pub position_size_config: Option<PositionSizeConfig>,
610
611    /// Optional clipping rectangle that defines the visible area.
612    ///
613    /// 定义可见区域的可选裁剪矩形。
614    pub clip_rect: Option<Option<PositionSizeConfig>>,
615
616    /// Controls whether the image is visible or hidden.
617    ///
618    /// 控制图像是否可见或隐藏。
619    pub hidden: Option<bool>,
620
621    /// If true, the image ignores render layer.
622    ///
623    /// 如果为true,图像忽略渲染层。
624    pub ignore_render_layer: Option<bool>,
625
626    /// Opacity of the image (0-255).
627    ///
628    /// 图像的不透明度(0-255)。
629    pub alpha: Option<u8>,
630
631    /// Color overlay applied to the image as [R, G, B].
632    ///
633    /// 应用于图像的色彩覆盖,格式为[R, G, B]。
634    pub overlay_color: Option<[u8; 3]>,
635
636    /// Opacity of the overlay (0-255).
637    ///
638    /// 覆盖层的不透明度(0-255)。
639    pub overlay_alpha: Option<u8>,
640
641    /// Background color behind the image as [R, G, B].
642    ///
643    /// 图像背后的背景颜色,格式为[R, G, B]。
644    pub background_color: Option<[u8; 3]>,
645
646    /// Opacity of the background (0-255).
647    ///
648    /// 背景的不透明度(0-255)。
649    pub background_alpha: Option<u8>,
650
651    /// Rotation angle of the image in degrees.
652    ///
653    /// 图像的旋转角度(度)。
654    pub rotate_angle: Option<f32>,
655
656    /// Center point for rotation, compare it with the actual size to obtain as [width, height].
657    ///
658    /// 旋转中心点,通过与实际大小的比得出,为[width, height]。
659    pub rotate_center: Option<[f32; 2]>,
660
661    /// Method used to load the image.
662    ///
663    /// 用于加载图像的方法。
664    pub image_load_method: Option<ImageLoadMethod>,
665
666    /// Key-value pairs for categorization and metadata.
667    ///
668    /// 用于分类和元数据的键值对标签。
669    pub tags: Option<Vec<[String; 2]>>,
670}
671
672impl ImageConfig {
673    pub fn from_image(image: &Image) -> Self {
674        Self {
675            position_size_config: Some(image.basic_front_resource_config.position_size_config),
676            clip_rect: Some(image.basic_front_resource_config.clip_rect),
677            hidden: Some(image.display_info.hidden),
678            ignore_render_layer: Some(image.display_info.ignore_render_layer),
679            alpha: Some(image.alpha),
680            overlay_color: Some(image.overlay_color),
681            overlay_alpha: Some(image.overlay_alpha),
682            background_color: Some(image.background_color),
683            background_alpha: Some(image.background_alpha),
684            rotate_angle: Some(image.rotate_angle),
685            rotate_center: Some(image.rotate_center),
686            image_load_method: Some(image.image_load_method.clone()),
687            tags: Some(image.tags.clone()),
688        }
689    }
690
691    #[inline]
692    pub fn position_size_config(
693        mut self,
694        position_size_config: Option<PositionSizeConfig>,
695    ) -> Self {
696        self.position_size_config = position_size_config;
697        self
698    }
699
700    #[inline]
701    pub fn clip_rect(mut self, clip_rect: Option<Option<PositionSizeConfig>>) -> Self {
702        self.clip_rect = clip_rect;
703        self
704    }
705
706    #[inline]
707    pub fn hidden(mut self, hidden: Option<bool>) -> Self {
708        self.hidden = hidden;
709        self
710    }
711
712    #[inline]
713    pub fn ignore_render_layer(mut self, ignore_render_layer: Option<bool>) -> Self {
714        self.ignore_render_layer = ignore_render_layer;
715        self
716    }
717
718    #[inline]
719    pub fn alpha(mut self, alpha: Option<u8>) -> Self {
720        self.alpha = alpha;
721        self
722    }
723
724    #[inline]
725    pub fn overlay_color(mut self, overlay_color: Option<[u8; 3]>) -> Self {
726        self.overlay_color = overlay_color;
727        self
728    }
729
730    #[inline]
731    pub fn overlay_alpha(mut self, overlay_alpha: Option<u8>) -> Self {
732        self.overlay_alpha = overlay_alpha;
733        self
734    }
735
736    #[inline]
737    pub fn background_color(mut self, background_color: Option<[u8; 3]>) -> Self {
738        self.background_color = background_color;
739        self
740    }
741
742    #[inline]
743    pub fn background_alpha(mut self, background_alpha: Option<u8>) -> Self {
744        self.background_alpha = background_alpha;
745        self
746    }
747
748    #[inline]
749    pub fn rotate_angle(mut self, rotate_angle: Option<f32>) -> Self {
750        self.rotate_angle = rotate_angle;
751        self
752    }
753
754    #[inline]
755    pub fn rotate_center(mut self, rotate_center: Option<[f32; 2]>) -> Self {
756        self.rotate_center = rotate_center;
757        self
758    }
759
760    #[inline]
761    pub fn image_load_method(mut self, image_load_method: Option<ImageLoadMethod>) -> Self {
762        self.image_load_method = image_load_method;
763        self
764    }
765
766    #[inline]
767    pub fn tags(mut self, tags: Option<Vec<[String; 2]>>) -> Self {
768        self.tags = tags;
769        self
770    }
771}
772
773/// Image resource for displaying graphical content in the GUI.
774///
775/// 用于在GUI中显示图形内容的图像资源。
776#[derive(Debug, Clone, PartialEq)]
777pub struct Image {
778    /// Config for basic front resource properties.
779    ///
780    /// 基本前端资源属性配置。
781    pub basic_front_resource_config: BasicFrontResourceConfig,
782
783    /// Current display position of the image as [x, y].
784    ///
785    /// 图像的当前显示位置,坐标为[x, y]。
786    pub position: [f32; 2],
787
788    /// Current display size of the image as [width, height].
789    ///
790    /// 图像的当前显示尺寸,为[width, height]。
791    pub size: [f32; 2],
792
793    /// Display info controlling visibility and rendering.
794    ///
795    /// 显示信息,控制可见性和渲染。
796    pub display_info: DisplayInfo,
797
798    /// Handle to the loaded texture, if available.
799    ///
800    /// 已加载纹理的句柄(如果可用)。
801    pub texture: Option<DebugTextureHandle>,
802
803    /// Opacity of the image (0-255).
804    ///
805    /// 图像的不透明度(0-255)。
806    pub alpha: u8,
807
808    /// Color overlay applied to the image as [R, G, B].
809    ///
810    /// 应用于图像的色彩覆盖,格式为[R, G, B]。
811    pub overlay_color: [u8; 3],
812
813    /// Opacity of the overlay (0-255).
814    ///
815    /// 覆盖层的不透明度(0-255)。
816    pub overlay_alpha: u8,
817
818    /// Background color behind the image as [R, G, B].
819    ///
820    /// 图像背后的背景颜色,格式为[R, G, B]。
821    pub background_color: [u8; 3],
822
823    /// Opacity of the background (0-255).
824    ///
825    /// 背景的不透明度(0-255)。
826    pub background_alpha: u8,
827
828    /// Rotation angle of the image in degrees.
829    ///
830    /// 图像的旋转角度(度)。
831    pub rotate_angle: f32,
832
833    /// Center point for rotation, compare it with the actual size to obtain as [width, height].
834    ///
835    /// 旋转中心点,通过与实际大小的比得出,为[width, height]。
836    pub rotate_center: [f32; 2],
837
838    /// Method used to load the image.
839    ///
840    /// 用于加载图像的方法。
841    pub image_load_method: ImageLoadMethod,
842
843    /// The path for loading the image in the previous frame.
844    ///
845    /// 上一帧加载图片的路径。
846    pub last_frame_path: String,
847
848    /// Key-value pairs for categorization and metadata.
849    ///
850    /// 用于分类和元数据的键值对标签。
851    pub tags: Vec<[String; 2]>,
852}
853
854impl RustConstructorResource for Image {
855    fn as_any(&self) -> &dyn Any {
856        self
857    }
858
859    fn as_any_mut(&mut self) -> &mut dyn Any {
860        self
861    }
862
863    fn display_display_info(&self) -> Option<DisplayInfo> {
864        Some(self.display_info)
865    }
866
867    fn modify_display_info(&mut self, display_info: DisplayInfo) {
868        self.display_info = display_info;
869    }
870
871    fn display_tags(&self) -> Vec<[String; 2]> {
872        self.tags.clone()
873    }
874
875    fn modify_tags(&mut self, tags: &[[String; 2]], replace: bool) {
876        if replace {
877            self.tags = tags.to_owned();
878        } else {
879            for tag in tags {
880                if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
881                    self.tags.remove(index);
882                };
883            }
884            self.tags.extend(tags.iter().cloned());
885        };
886    }
887}
888
889impl BasicFrontResource for Image {
890    fn display_basic_front_resource_config(&self) -> BasicFrontResourceConfig {
891        self.basic_front_resource_config.clone()
892    }
893
894    fn display_position_size_config(&self) -> PositionSizeConfig {
895        self.basic_front_resource_config.position_size_config
896    }
897
898    fn display_clip_rect(&self) -> Option<PositionSizeConfig> {
899        self.basic_front_resource_config.clip_rect
900    }
901
902    fn display_position(&self) -> [f32; 2] {
903        self.position
904    }
905
906    fn display_size(&self) -> [f32; 2] {
907        self.size
908    }
909
910    fn modify_basic_front_resource_config(
911        &mut self,
912        basic_front_resource_config: BasicFrontResourceConfig,
913    ) {
914        self.basic_front_resource_config = basic_front_resource_config;
915    }
916
917    fn modify_position_size_config(&mut self, position_size_config: PositionSizeConfig) {
918        self.basic_front_resource_config.position_size_config = position_size_config;
919    }
920
921    fn modify_clip_rect(&mut self, clip_rect: Option<PositionSizeConfig>) {
922        self.basic_front_resource_config.clip_rect = clip_rect;
923    }
924}
925
926impl Default for Image {
927    fn default() -> Self {
928        Self {
929            basic_front_resource_config: BasicFrontResourceConfig::default(),
930            position: [0_f32, 0_f32],
931            size: [0_f32, 0_f32],
932            display_info: DisplayInfo::default(),
933            texture: None,
934            alpha: 255,
935            overlay_color: [255, 255, 255],
936            overlay_alpha: 255,
937            background_color: [0, 0, 0],
938            background_alpha: 0,
939            rotate_angle: 0_f32,
940            rotate_center: [0_f32, 0_f32],
941            image_load_method: ImageLoadMethod::ByPath((String::new(), [false, false])),
942            last_frame_path: String::new(),
943            tags: Vec::new(),
944        }
945    }
946}
947
948impl Image {
949    pub fn from_config(mut self, config: &ImageConfig) -> Self {
950        if let Some(position_size_config) = config.position_size_config {
951            self.basic_front_resource_config.position_size_config = position_size_config;
952        };
953        if let Some(clip_rect) = config.clip_rect {
954            self.basic_front_resource_config.clip_rect = clip_rect;
955        };
956        if let Some(hidden) = config.hidden {
957            self.display_info.hidden = hidden;
958        };
959        if let Some(ignore_render_layer) = config.ignore_render_layer {
960            self.display_info.ignore_render_layer = ignore_render_layer;
961        };
962        if let Some(alpha) = config.alpha {
963            self.alpha = alpha;
964        };
965        if let Some(overlay_color) = config.overlay_color {
966            self.overlay_color = overlay_color;
967        };
968        if let Some(overlay_alpha) = config.overlay_alpha {
969            self.overlay_alpha = overlay_alpha;
970        };
971        if let Some(background_color) = config.background_color {
972            self.background_color = background_color;
973        };
974        if let Some(background_alpha) = config.background_alpha {
975            self.background_alpha = background_alpha;
976        };
977        if let Some(rotate_angle) = config.rotate_angle {
978            self.rotate_angle = rotate_angle;
979        };
980        if let Some(rotate_center) = config.rotate_center {
981            self.rotate_center = rotate_center;
982        };
983        if let Some(image_load_method) = config.image_load_method.clone() {
984            self.image_load_method = image_load_method;
985        };
986        if let Some(tags) = config.tags.clone() {
987            self.tags = tags;
988        };
989        self
990    }
991
992    #[inline]
993    pub fn basic_front_resource_config(
994        mut self,
995        basic_front_resource_config: &BasicFrontResourceConfig,
996    ) -> Self {
997        self.basic_front_resource_config = basic_front_resource_config.clone();
998        self
999    }
1000
1001    #[inline]
1002    pub fn hidden(mut self, hidden: bool) -> Self {
1003        self.display_info.hidden = hidden;
1004        self
1005    }
1006
1007    #[inline]
1008    pub fn ignore_render_layer(mut self, ignore_render_layer: bool) -> Self {
1009        self.display_info.ignore_render_layer = ignore_render_layer;
1010        self
1011    }
1012
1013    #[inline]
1014    pub fn alpha(mut self, alpha: u8) -> Self {
1015        self.alpha = alpha;
1016        self
1017    }
1018
1019    #[inline]
1020    pub fn overlay_color(mut self, r: u8, g: u8, b: u8) -> Self {
1021        self.overlay_color = [r, g, b];
1022        self
1023    }
1024
1025    #[inline]
1026    pub fn overlay_alpha(mut self, overlay_alpha: u8) -> Self {
1027        self.overlay_alpha = overlay_alpha;
1028        self
1029    }
1030
1031    #[inline]
1032    pub fn background_color(mut self, r: u8, g: u8, b: u8) -> Self {
1033        self.background_color = [r, g, b];
1034        self
1035    }
1036
1037    #[inline]
1038    pub fn background_alpha(mut self, background_alpha: u8) -> Self {
1039        self.background_alpha = background_alpha;
1040        self
1041    }
1042
1043    #[inline]
1044    pub fn rotate_angle(mut self, rotate_angle: f32) -> Self {
1045        self.rotate_angle = rotate_angle;
1046        self
1047    }
1048
1049    #[inline]
1050    pub fn rotate_center(mut self, x: f32, y: f32) -> Self {
1051        self.rotate_center = [x, y];
1052        self
1053    }
1054
1055    #[inline]
1056    pub fn image_load_method(mut self, image_load_method: &ImageLoadMethod) -> Self {
1057        self.image_load_method = image_load_method.clone();
1058        self
1059    }
1060
1061    #[inline]
1062    pub fn tags(mut self, tags: &[[String; 2]], replace: bool) -> Self {
1063        if replace {
1064            self.tags = tags.to_owned();
1065        } else {
1066            for tag in tags {
1067                if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
1068                    self.tags.remove(index);
1069                };
1070            }
1071            self.tags.extend(tags.iter().cloned());
1072        };
1073        self
1074    }
1075}
1076
1077/// Control the selection method of hyperlinks.
1078///
1079/// 控制超链接的选取方法。
1080#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
1081pub enum HyperlinkSelectMethod {
1082    /// Selects all occurrences of the hyperlink text.
1083    ///
1084    /// 选取所有匹配的超链接文本。
1085    All(String),
1086    /// Selects specific segments of the hyperlink text with indices.
1087    ///
1088    /// 选取指定的超链接文本段。
1089    Segment(Vec<(usize, String)>),
1090}
1091
1092/// Config options for text resources.
1093///
1094/// 文本资源的配置选项。
1095#[derive(Debug, Default, Clone, PartialEq, PartialOrd)]
1096pub struct TextConfig {
1097    /// Config for position, size, and layout.
1098    ///
1099    /// 位置、尺寸和布局配置。
1100    pub position_size_config: Option<PositionSizeConfig>,
1101
1102    /// Optional clipping rectangle that defines the visible area.
1103    ///
1104    /// 定义可见区域的可选裁剪矩形。
1105    pub clip_rect: Option<Option<PositionSizeConfig>>,
1106
1107    /// Controls whether the text is visible or hidden.
1108    ///
1109    /// 控制文本是否可见或隐藏。
1110    pub hidden: Option<bool>,
1111
1112    /// If true, the text ignores render layer.
1113    ///
1114    /// 如果为true,文本忽略渲染层。
1115    pub ignore_render_layer: Option<bool>,
1116
1117    /// Text content to be displayed.
1118    ///
1119    /// 要显示的文本内容。
1120    pub content: Option<String>,
1121
1122    /// Font size in points.
1123    ///
1124    /// 字体大小(点)。
1125    pub font_size: Option<f32>,
1126
1127    /// Text color as [R, G, B].
1128    ///
1129    /// 文本颜色,格式为[R, G, B]。
1130    pub color: Option<[u8; 3]>,
1131
1132    /// Opacity of the text (0-255).
1133    ///
1134    /// 文本的不透明度(0-255)。
1135    pub alpha: Option<u8>,
1136
1137    /// Background color behind the text as [R, G, B].
1138    ///
1139    /// 文本背后的背景颜色,格式为[R, G, B]。
1140    pub background_color: Option<[u8; 3]>,
1141
1142    /// Opacity of the background (0-255).
1143    ///
1144    /// 背景的不透明度(0-255)。
1145    pub background_alpha: Option<u8>,
1146
1147    /// Radius for rounded corners of the background.
1148    ///
1149    /// 背景圆角半径。
1150    pub background_rounding: Option<f32>,
1151
1152    /// The font used for the specified text.
1153    ///
1154    /// 指定文本使用的字体。
1155    pub font: Option<String>,
1156
1157    /// Whether the text can be selected by the user.
1158    ///
1159    /// 文本是否可以被用户选择。
1160    pub selectable: Option<bool>,
1161
1162    /// Hyperlink texts for clickable regions.
1163    ///
1164    /// 可点击区域的超链接文本。
1165    pub hyperlink_text: Option<Vec<(String, HyperlinkSelectMethod)>>,
1166
1167    /// Automatically adjust size to fit content.
1168    ///
1169    /// 自动调整尺寸以适应内容。
1170    pub auto_fit: Option<[bool; 2]>,
1171
1172    /// Key-value pairs for categorization and metadata.
1173    ///
1174    /// 用于分类和元数据的键值对标签。
1175    pub tags: Option<Vec<[String; 2]>>,
1176}
1177
1178impl TextConfig {
1179    pub fn from_text(text: &Text) -> Self {
1180        Self {
1181            position_size_config: Some(text.basic_front_resource_config.position_size_config),
1182            clip_rect: Some(text.basic_front_resource_config.clip_rect),
1183            hidden: Some(text.display_info.hidden),
1184            ignore_render_layer: Some(text.display_info.ignore_render_layer),
1185            content: Some(text.content.clone()),
1186            font_size: Some(text.font_size),
1187            color: Some(text.color),
1188            alpha: Some(text.alpha),
1189            background_color: Some(text.background_color),
1190            background_alpha: Some(text.background_alpha),
1191            background_rounding: Some(text.background_rounding),
1192            font: Some(text.font.clone()),
1193            selectable: Some(text.selectable),
1194            hyperlink_text: Some(text.hyperlink_text.clone()),
1195            auto_fit: Some(text.auto_fit),
1196            tags: Some(text.tags.clone()),
1197        }
1198    }
1199
1200    #[inline]
1201    pub fn position_size_config(
1202        mut self,
1203        position_size_config: Option<PositionSizeConfig>,
1204    ) -> Self {
1205        self.position_size_config = position_size_config;
1206        self
1207    }
1208
1209    #[inline]
1210    pub fn clip_rect(mut self, clip_rect: Option<Option<PositionSizeConfig>>) -> Self {
1211        self.clip_rect = clip_rect;
1212        self
1213    }
1214
1215    #[inline]
1216    pub fn hidden(mut self, hidden: Option<bool>) -> Self {
1217        self.hidden = hidden;
1218        self
1219    }
1220
1221    #[inline]
1222    pub fn ignore_render_layer(mut self, ignore_render_layer: Option<bool>) -> Self {
1223        self.ignore_render_layer = ignore_render_layer;
1224        self
1225    }
1226
1227    #[inline]
1228    pub fn content(mut self, content: Option<String>) -> Self {
1229        self.content = content;
1230        self
1231    }
1232
1233    #[inline]
1234    pub fn font_size(mut self, font_size: Option<f32>) -> Self {
1235        self.font_size = font_size;
1236        self
1237    }
1238
1239    #[inline]
1240    pub fn color(mut self, color: Option<[u8; 3]>) -> Self {
1241        self.color = color;
1242        self
1243    }
1244
1245    #[inline]
1246    pub fn alpha(mut self, alpha: Option<u8>) -> Self {
1247        self.alpha = alpha;
1248        self
1249    }
1250
1251    #[inline]
1252    pub fn background_color(mut self, background_color: Option<[u8; 3]>) -> Self {
1253        self.background_color = background_color;
1254        self
1255    }
1256
1257    #[inline]
1258    pub fn background_alpha(mut self, background_alpha: Option<u8>) -> Self {
1259        self.background_alpha = background_alpha;
1260        self
1261    }
1262
1263    #[inline]
1264    pub fn background_rounding(mut self, background_rounding: Option<f32>) -> Self {
1265        self.background_rounding = background_rounding;
1266        self
1267    }
1268
1269    #[inline]
1270    pub fn font(mut self, font: Option<String>) -> Self {
1271        self.font = font;
1272        self
1273    }
1274
1275    #[inline]
1276    pub fn selectable(mut self, selectable: Option<bool>) -> Self {
1277        self.selectable = selectable;
1278        self
1279    }
1280
1281    #[inline]
1282    pub fn hyperlink_text(
1283        mut self,
1284        hyperlink_text: Option<Vec<(String, HyperlinkSelectMethod)>>,
1285    ) -> Self {
1286        self.hyperlink_text = hyperlink_text;
1287        self
1288    }
1289
1290    #[inline]
1291    pub fn auto_fit(mut self, auto_fit: Option<[bool; 2]>) -> Self {
1292        self.auto_fit = auto_fit;
1293        self
1294    }
1295
1296    #[inline]
1297    pub fn tags(mut self, tags: Option<Vec<[String; 2]>>) -> Self {
1298        self.tags = tags;
1299        self
1300    }
1301}
1302
1303/// Text resource for displaying and interacting with textual content.
1304///
1305/// 用于显示和交互文本内容的文本资源。
1306#[derive(Debug, Clone, PartialEq, PartialOrd)]
1307pub struct Text {
1308    /// Config for basic front resource properties.
1309    ///
1310    /// 基本前端资源属性配置。
1311    pub basic_front_resource_config: BasicFrontResourceConfig,
1312
1313    /// Current display position of the text as [x, y].
1314    ///
1315    /// 文本的当前显示位置,坐标为[x, y]。
1316    pub position: [f32; 2],
1317
1318    /// Current display size of the text as [width, height].
1319    ///
1320    /// 文本的当前显示尺寸,为[width, height]。
1321    pub size: [f32; 2],
1322
1323    /// Display info controlling visibility and rendering.
1324    ///
1325    /// 显示信息,控制可见性和渲染。
1326    pub display_info: DisplayInfo,
1327
1328    /// Text content to be displayed.
1329    ///
1330    /// 要显示的文本内容。
1331    pub content: String,
1332
1333    /// Font size in points.
1334    ///
1335    /// 字体大小(点)。
1336    pub font_size: f32,
1337
1338    /// Text color as [R, G, B].
1339    ///
1340    /// 文本颜色,格式为[R, G, B]。
1341    pub color: [u8; 3],
1342
1343    /// Opacity of the text (0-255).
1344    ///
1345    /// 文本的不透明度(0-255)。
1346    pub alpha: u8,
1347
1348    /// Background color behind the text as [R, G, B].
1349    ///
1350    /// 文本背后的背景颜色,格式为[R, G, B]。
1351    pub background_color: [u8; 3],
1352
1353    /// Opacity of the background (0-255).
1354    ///
1355    /// 背景的不透明度(0-255)。
1356    pub background_alpha: u8,
1357
1358    /// Radius for rounded corners of the background.
1359    ///
1360    /// 背景圆角半径。
1361    pub background_rounding: f32,
1362
1363    /// The font used for the specified text.
1364    ///
1365    /// 指定文本使用的字体。
1366    pub font: String,
1367
1368    /// Whether the text can be selected by the user.
1369    ///
1370    /// 文本是否可以被用户选择。
1371    pub selectable: bool,
1372
1373    /// Hyperlink texts with their selection methods for clickable regions.
1374    ///
1375    /// 可点击区域的超链接文本及其选择方法。
1376    pub hyperlink_text: Vec<(String, HyperlinkSelectMethod)>,
1377
1378    /// Hyperlink indices and URLs: (start_index, end_index, url).
1379    ///
1380    /// 超链接索引值和链接:(起始索引, 结束索引, 链接)。
1381    pub hyperlink_index: Vec<(usize, usize, String)>,
1382
1383    /// Auto-fit behavior: [horizontal_fit, vertical_fit].
1384    ///
1385    /// 是否让渲染层大小自动匹配实际大小:[水平适应, 垂直适应]。
1386    pub auto_fit: [bool; 2],
1387
1388    /// Text content from the previous frame for change detection.
1389    ///
1390    /// 上一帧的文本内容,用于变化检测。
1391    pub last_frame_content: String,
1392
1393    /// Currently selected text range (start_index, end_index).
1394    ///
1395    /// 框选选中的文本范围(起始索引, 结束索引)。
1396    pub selection: Option<(usize, usize)>,
1397
1398    /// Size at which text is truncated for display.
1399    ///
1400    /// 文本被截断以供显示的尺寸。
1401    pub truncate_size: [f32; 2],
1402
1403    /// Actual size of the text content.
1404    ///
1405    /// 文本内容的实际尺寸。
1406    pub actual_size: [f32; 2],
1407
1408    /// Key-value pairs for categorization and metadata.
1409    ///
1410    /// 用于分类和元数据的键值对标签。
1411    pub tags: Vec<[String; 2]>,
1412}
1413
1414impl RustConstructorResource for Text {
1415    fn as_any(&self) -> &dyn Any {
1416        self
1417    }
1418
1419    fn as_any_mut(&mut self) -> &mut dyn Any {
1420        self
1421    }
1422
1423    fn display_display_info(&self) -> Option<DisplayInfo> {
1424        Some(self.display_info)
1425    }
1426
1427    fn modify_display_info(&mut self, display_info: DisplayInfo) {
1428        self.display_info = display_info;
1429    }
1430
1431    fn display_tags(&self) -> Vec<[String; 2]> {
1432        self.tags.clone()
1433    }
1434
1435    fn modify_tags(&mut self, tags: &[[String; 2]], replace: bool) {
1436        if replace {
1437            self.tags = tags.to_owned();
1438        } else {
1439            for tag in tags {
1440                if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
1441                    self.tags.remove(index);
1442                };
1443            }
1444            self.tags.extend(tags.iter().cloned());
1445        };
1446    }
1447}
1448
1449impl BasicFrontResource for Text {
1450    fn display_basic_front_resource_config(&self) -> BasicFrontResourceConfig {
1451        self.basic_front_resource_config.clone()
1452    }
1453
1454    fn display_position_size_config(&self) -> PositionSizeConfig {
1455        self.basic_front_resource_config.position_size_config
1456    }
1457
1458    fn display_clip_rect(&self) -> Option<PositionSizeConfig> {
1459        self.basic_front_resource_config.clip_rect
1460    }
1461
1462    fn display_position(&self) -> [f32; 2] {
1463        self.position
1464    }
1465
1466    fn display_size(&self) -> [f32; 2] {
1467        self.size
1468    }
1469
1470    fn modify_basic_front_resource_config(
1471        &mut self,
1472        basic_front_resource_config: BasicFrontResourceConfig,
1473    ) {
1474        self.basic_front_resource_config = basic_front_resource_config;
1475    }
1476
1477    fn modify_position_size_config(&mut self, position_size_config: PositionSizeConfig) {
1478        self.basic_front_resource_config.position_size_config = position_size_config;
1479    }
1480
1481    fn modify_clip_rect(&mut self, clip_rect: Option<PositionSizeConfig>) {
1482        self.basic_front_resource_config.clip_rect = clip_rect;
1483    }
1484}
1485
1486impl Default for Text {
1487    fn default() -> Self {
1488        Self {
1489            basic_front_resource_config: BasicFrontResourceConfig::default(),
1490            position: [0_f32, 0_f32],
1491            size: [0_f32, 0_f32],
1492            display_info: DisplayInfo::default(),
1493            content: String::from("Hello world"),
1494            font_size: 16_f32,
1495            color: [255, 255, 255],
1496            alpha: 255,
1497            background_color: [0, 0, 0],
1498            background_alpha: 0,
1499            background_rounding: 2_f32,
1500            font: String::new(),
1501            selectable: true,
1502            auto_fit: [true, true],
1503            hyperlink_text: Vec::new(),
1504            hyperlink_index: Vec::new(),
1505            last_frame_content: String::from(""),
1506            selection: None,
1507            truncate_size: [0_f32, 0_f32],
1508            actual_size: [0_f32, 0_f32],
1509            tags: Vec::new(),
1510        }
1511    }
1512}
1513
1514impl Text {
1515    pub fn from_config(mut self, config: &TextConfig) -> Self {
1516        if let Some(position_size_config) = config.position_size_config {
1517            self.basic_front_resource_config.position_size_config = position_size_config;
1518        };
1519        if let Some(clip_rect) = config.clip_rect {
1520            self.basic_front_resource_config.clip_rect = clip_rect;
1521        };
1522        if let Some(hidden) = config.hidden {
1523            self.display_info.hidden = hidden;
1524        };
1525        if let Some(ignore_render_layer) = config.ignore_render_layer {
1526            self.display_info.ignore_render_layer = ignore_render_layer;
1527        };
1528        if let Some(content) = config.content.clone() {
1529            self.content = content;
1530        };
1531        if let Some(font_size) = config.font_size {
1532            self.font_size = font_size;
1533        };
1534        if let Some(color) = config.color {
1535            self.color = color;
1536        };
1537        if let Some(alpha) = config.alpha {
1538            self.alpha = alpha;
1539        };
1540        if let Some(background_color) = config.background_color {
1541            self.background_color = background_color;
1542        };
1543        if let Some(background_alpha) = config.background_alpha {
1544            self.background_alpha = background_alpha;
1545        };
1546        if let Some(background_rounding) = config.background_rounding {
1547            self.background_rounding = background_rounding;
1548        };
1549        if let Some(font) = config.font.clone() {
1550            self.font = font;
1551        };
1552        if let Some(selectable) = config.selectable {
1553            self.selectable = selectable;
1554        };
1555        if let Some(hyperlink_text) = config.hyperlink_text.clone() {
1556            self.hyperlink_text = hyperlink_text;
1557        };
1558        if let Some(auto_fit) = config.auto_fit {
1559            self.auto_fit = auto_fit;
1560        };
1561        if let Some(tags) = config.tags.clone() {
1562            self.tags = tags;
1563        };
1564        self
1565    }
1566
1567    #[inline]
1568    pub fn basic_front_resource_config(
1569        mut self,
1570        basic_front_resource_config: &BasicFrontResourceConfig,
1571    ) -> Self {
1572        self.basic_front_resource_config = basic_front_resource_config.clone();
1573        self
1574    }
1575
1576    #[inline]
1577    pub fn hidden(mut self, hidden: bool) -> Self {
1578        self.display_info.hidden = hidden;
1579        self
1580    }
1581
1582    #[inline]
1583    pub fn ignore_render_layer(mut self, ignore_render_layer: bool) -> Self {
1584        self.display_info.ignore_render_layer = ignore_render_layer;
1585        self
1586    }
1587
1588    #[inline]
1589    pub fn content(mut self, content: &str) -> Self {
1590        self.content = content.to_string();
1591        self
1592    }
1593
1594    #[inline]
1595    pub fn font_size(mut self, font_size: f32) -> Self {
1596        self.font_size = font_size;
1597        self
1598    }
1599
1600    #[inline]
1601    pub fn color(mut self, r: u8, g: u8, b: u8) -> Self {
1602        self.color = [r, g, b];
1603        self
1604    }
1605
1606    #[inline]
1607    pub fn alpha(mut self, alpha: u8) -> Self {
1608        self.alpha = alpha;
1609        self
1610    }
1611
1612    #[inline]
1613    pub fn background_color(mut self, r: u8, g: u8, b: u8) -> Self {
1614        self.background_color = [r, g, b];
1615        self
1616    }
1617
1618    #[inline]
1619    pub fn background_alpha(mut self, alpha: u8) -> Self {
1620        self.background_alpha = alpha;
1621        self
1622    }
1623
1624    #[inline]
1625    pub fn background_rounding(mut self, background_rounding: f32) -> Self {
1626        self.background_rounding = background_rounding;
1627        self
1628    }
1629
1630    #[inline]
1631    pub fn font(mut self, font: &str) -> Self {
1632        self.font = font.to_string();
1633        self
1634    }
1635
1636    #[inline]
1637    pub fn selectable(mut self, selectable: bool) -> Self {
1638        self.selectable = selectable;
1639        self
1640    }
1641
1642    #[inline]
1643    pub fn push_hyperlink_text(
1644        mut self,
1645        target_text: &str,
1646        select_method: HyperlinkSelectMethod,
1647    ) -> Self {
1648        self.hyperlink_text
1649            .push((target_text.to_string(), select_method));
1650        self
1651    }
1652
1653    #[inline]
1654    pub fn hyperlink_text(mut self, hyperlink_text: Vec<(String, HyperlinkSelectMethod)>) -> Self {
1655        self.hyperlink_text = hyperlink_text;
1656        self
1657    }
1658
1659    #[inline]
1660    pub fn auto_fit(mut self, x: bool, y: bool) -> Self {
1661        self.auto_fit = [x, y];
1662        self
1663    }
1664
1665    #[inline]
1666    pub fn tags(mut self, tags: &[[String; 2]], replace: bool) -> Self {
1667        if replace {
1668            self.tags = tags.to_owned();
1669        } else {
1670            for tag in tags {
1671                if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
1672                    self.tags.remove(index);
1673                };
1674            }
1675            self.tags.extend(tags.iter().cloned());
1676        };
1677        self
1678    }
1679}