Skip to main content

rust_constructor/
advance_front.rs

1//! This file contains advanced front-end resources, which can be used to handle complex tasks.
2//!
3//! 此文件包含高级前端资源,高级前端资源可以用于处理复杂的任务。
4use crate::{
5    DisplayInfo, RustConstructorId, RustConstructorResource,
6    basic_front::{CustomRectConfig, ImageConfig, TextConfig},
7};
8#[cfg(feature = "bevy")]
9use egui_bevy::PointerButton;
10#[cfg(feature = "standard")]
11use egui_standard::PointerButton;
12use std::any::Any;
13
14/// Control the basic front resource type for Background selection.
15///
16/// 控制Background选择的基础前端资源类型。
17#[derive(Clone, Debug, PartialEq)]
18pub enum BackgroundType {
19    /// Use an image as the background.
20    ///
21    /// 选择图像作为背景。
22    Image(ImageConfig),
23
24    /// Use a custom rectangle as the background.
25    ///
26    /// 选择自定义矩形作为背景。
27    CustomRect(CustomRectConfig),
28}
29
30impl Default for BackgroundType {
31    fn default() -> Self {
32        BackgroundType::CustomRect(CustomRectConfig::default())
33    }
34}
35
36/// Background resource for UI elements.
37///
38/// UI元素的背景资源。
39#[derive(Clone, Debug, Default, PartialEq)]
40pub struct Background {
41    /// Type of background to display.
42    ///
43    /// 要显示的背景类型。
44    pub background_type: BackgroundType,
45
46    /// If true, the background config updates automatically.
47    ///
48    /// 如果为true,则背景会自动更新。
49    pub auto_update: bool,
50
51    /// If true, resources created by the background use its tags.
52    ///
53    /// 如果为true,则背景创建的资源使用其标签。
54    pub use_background_tags: bool,
55
56    /// Key-value pairs for categorization and metadata.
57    ///
58    /// 用于分类和元数据的键值对标签。
59    pub tags: Vec<[String; 2]>,
60}
61
62impl RustConstructorResource for Background {
63    fn as_any(&self) -> &dyn Any {
64        self
65    }
66
67    fn as_any_mut(&mut self) -> &mut dyn Any {
68        self
69    }
70
71    fn display_display_info(&self) -> Option<DisplayInfo> {
72        None
73    }
74
75    fn modify_display_info(&mut self, _display_info: DisplayInfo) {}
76
77    fn display_tags(&self) -> Vec<[String; 2]> {
78        self.tags.clone()
79    }
80
81    fn modify_tags(&mut self, tags: &[[String; 2]], replace: bool) {
82        if replace {
83            self.tags = tags.to_owned();
84        } else {
85            for tag in tags {
86                if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
87                    self.tags.remove(index);
88                };
89            }
90            self.tags.extend(tags.iter().cloned());
91        };
92    }
93}
94
95impl Background {
96    #[inline]
97    pub fn background_type(mut self, background_type: &BackgroundType) -> Self {
98        self.background_type = background_type.clone();
99        self
100    }
101
102    #[inline]
103    pub fn auto_update(mut self, auto_update: bool) -> Self {
104        self.auto_update = auto_update;
105        self
106    }
107
108    #[inline]
109    pub fn use_background_tags(mut self, use_background_tags: bool) -> Self {
110        self.use_background_tags = use_background_tags;
111        self
112    }
113
114    #[inline]
115    pub fn tags(mut self, tags: &[[String; 2]], replace: bool) -> Self {
116        if replace {
117            self.tags = tags.to_owned();
118        } else {
119            for tag in tags {
120                if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
121                    self.tags.remove(index);
122                };
123            }
124            self.tags.extend(tags.iter().cloned());
125        };
126        self
127    }
128}
129
130/// Methods for determining scroll bar length in panels.
131///
132/// 面板中滚动条长度的确定方法。
133#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
134pub enum ScrollLengthMethod {
135    /// Fixed length in pixels regardless of content size.
136    ///
137    /// 固定的像素长度,与内容大小无关。
138    Fixed(f32),
139    /// Automatically adjusts based on visible content proportion.
140    ///
141    /// 根据可见内容比例自动调整。
142    AutoFit(f32),
143}
144
145/// Mouse click interaction types for panels.
146///
147/// 面板的鼠标点击交互类型。
148///
149/// Defines the intended action when clicking on different parts of a panel's border or interior.
150///
151/// 定义点击面板边框或内部不同区域时的预期操作。
152#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
153pub enum ClickAim {
154    /// Move the entire panel.
155    ///
156    /// 移动资源板。
157    Move,
158    /// Resize from the top edge.
159    ///
160    /// 在上方缩放。
161    TopResize,
162    /// Resize from the bottom edge.
163    ///
164    /// 在下方缩放。
165    BottomResize,
166    /// Resize from the left edge.
167    ///
168    /// 在左侧缩放。
169    LeftResize,
170    /// Resize from the right edge.
171    ///
172    /// 在右侧缩放。
173    RightResize,
174    /// Resize from the top-left corner.
175    ///
176    /// 在左上方缩放。
177    LeftTopResize,
178    /// Resize from the top-right corner.
179    ///
180    /// 在右上方缩放。
181    RightTopResize,
182    /// Resize from the bottom-left corner.
183    ///
184    /// 在左下方缩放。
185    LeftBottomResize,
186    /// Resize from the bottom-right corner.
187    ///
188    /// 在右下方缩放。
189    RightBottomResize,
190}
191
192/// Scroll bar display behavior for panels.
193///
194/// 面板的滚动条显示行为。
195///
196/// Defines when and how the scroll bar should be displayed to the user.
197///
198/// 定义滚动条何时以及如何向用户显示。
199#[derive(Debug, Clone, PartialEq)]
200pub enum ScrollBarDisplayMethod {
201    /// Always show the scroll bar with specified background, offset, and width.
202    ///
203    /// 持续显示滚动条,使用指定的背景、偏移量和宽度。
204    Always(BackgroundType, [f32; 2], f32),
205    /// Show the scroll bar only during scrolling with specified properties.
206    ///
207    /// 仅在滚动时显示滚动条,使用指定的属性。
208    OnlyScroll(BackgroundType, [f32; 2], f32),
209    /// Never show the scroll bar (scrollable but no visual indicator).
210    ///
211    /// 隐藏滚动条(可滚动但无视觉指示器)。
212    Hidden,
213}
214
215/// Margin config for resources within panels.
216///
217/// 面板内资源的外边距配置。
218///
219/// Defines spacing and layout behavior for resources placed inside panel containers.
220///
221/// 定义放置在面板容器内的资源的间距和布局行为。
222#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
223pub enum PanelMargin {
224    /// Vertical layout with margins [top, bottom, left, right] and reverse flag.
225    ///
226    /// 垂直布局,外边距为[top, bottom, left, right],包含反转标志。
227    Vertical([f32; 4], bool),
228    /// Horizontal layout with margins [top, bottom, left, right] and reverse flag.
229    ///
230    /// 水平布局,外边距为[top, bottom, left, right],包含反转标志。
231    Horizontal([f32; 4], bool),
232    /// No layout with margins [top, bottom, left, right] and influence layout flag.
233    ///
234    /// 无布局,外边距为[top, bottom, left, right],包含影响布局标志。
235    None([f32; 4], bool),
236}
237
238/// Panel layout config determining how resources are arranged within panels.
239///
240/// 面板布局配置,确定资源如何在面板内排列。
241#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
242pub struct PanelLayout {
243    /// Margin config for resources within the panel.
244    ///
245    /// 面板内资源的边距配置。
246    pub panel_margin: PanelMargin,
247    /// Location config for resources within the panel.
248    ///
249    /// 面板内资源的位置配置。
250    pub panel_location: PanelLocation,
251}
252
253/// Positioning method for resources within panels.
254///
255/// 面板内资源的定位方式。
256///
257/// Defines how resources are positioned relative to their containing panel.
258///
259/// 定义资源相对于其包含面板的定位方法。
260#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
261pub enum PanelLocation {
262    /// Absolute positioning using pixel coordinates relative to panel's top-left corner.
263    ///
264    /// 依照此资源到资源板左上角的距离定位(绝对定位)。
265    Absolute([f32; 2]),
266    /// Relative positioning using grid-based coordinates.
267    ///
268    /// 依照网格式定位方法进行定位(相对定位)。
269    Relative([[f32; 2]; 2]),
270}
271
272/// Used for customizing the layout of resources.
273///
274/// 用于自定义资源排版方式。
275#[derive(Debug, Clone, PartialEq, PartialOrd)]
276pub enum CustomPanelLayout {
277    /// Locate resources by type.
278    ///
279    /// 通过类型定位资源。
280    Type(String, PanelLayout),
281    /// Locate resources through ID.
282    ///
283    /// 通过ID定位资源。
284    Id(RustConstructorId, PanelLayout),
285}
286
287/// Storage structure for panel resource metadata.
288///
289/// 面板资源元数据的存储结构。
290///
291/// This struct holds essential information about resources stored within panels,
292/// including visibility, rendering behavior, and sizing information.
293///
294/// 该结构体保存面板内存储资源的基本信息,包括可见性、渲染行为和尺寸信息。
295#[derive(Debug, Default, Clone, PartialEq, PartialOrd)]
296pub struct PanelStorage {
297    /// Unique identifier for the stored resource.
298    ///
299    /// 存储资源的唯一标识符。
300    pub id: RustConstructorId,
301
302    /// If true, the resource ignores render layer.
303    ///
304    /// 如果为true,则资源忽略渲染层。
305    pub ignore_render_layer: bool,
306
307    /// Controls whether the resource is visible.
308    ///
309    /// 控制资源是否可见。
310    pub hidden: bool,
311}
312
313/// Resource panel for organizing and managing UI elements with scrolling capabilities.
314///
315/// 资源板,用于组织和管理具有滚动能力的UI元素。
316#[derive(Debug, Clone, PartialEq)]
317pub struct ResourcePanel {
318    /// Which edges can be resized: [top, bottom, left, right].
319    ///
320    /// 哪些边可以调整尺寸:[top, bottom, left, right]。
321    pub resizable: [bool; 4],
322
323    /// Background display for the panel.
324    ///
325    /// 面板的背景显示。
326    pub background: BackgroundType,
327
328    /// Minimum size constraints for the panel.
329    ///
330    /// 面板的最小尺寸限制。
331    pub min_size: [f32; 2],
332
333    /// Optional maximum size constraints for the panel.
334    ///
335    /// 面板的可选最大尺寸限制。
336    pub max_size: Option<[f32; 2]>,
337
338    /// Whether the panel can be moved: [horizontal, vertical].
339    ///
340    /// 面板是否可以移动:[horizontal, vertical]。
341    pub movable: [bool; 2],
342
343    /// Methods for calculating scroll length: [horizontal, vertical].
344    ///
345    /// 计算滚动长度的方法:[horizontal, vertical]。
346    pub scroll_length_method: [Option<ScrollLengthMethod>; 2],
347
348    /// Sensitivity of scrolling interactions.
349    ///
350    /// 滚动交互的敏感性。
351    pub scroll_sensitivity: f32,
352
353    /// Display behavior of the scroll bar.
354    ///
355    /// 显示滚动条的方法。
356    pub scroll_bar_display_method: ScrollBarDisplayMethod,
357
358    /// Layout config for resources within the panel.
359    ///
360    /// 面板内资源的布局配置。
361    pub overall_layout: PanelLayout,
362
363    /// Custom layout config of specific resources within the panel.
364    ///
365    /// 面板内特定资源的自定义布局配置。
366    pub custom_layout: Vec<CustomPanelLayout>,
367
368    /// Whether the panel is visible.
369    ///
370    /// 面板是否可见。
371    pub hidden: bool,
372
373    /// Reverse scroll direction: [horizontal, vertical].
374    ///
375    /// 反转滚动方向:[horizontal, vertical]。
376    pub reverse_scroll_direction: [bool; 2],
377
378    /// Inner margin of the panel.
379    ///
380    /// 面板内边距。
381    ///
382    /// Use this field to ensure that functions such as resizing can be used normally.
383    ///
384    /// 使用此字段以保证缩放等功能可以正常使用。
385    pub inner_margin: [f32; 4],
386
387    /// Whether to place the panel in the front when clicking
388    ///
389    /// 是否在点击时将面板前置。
390    pub raise_on_focus: bool,
391
392    /// Current scroll length: [horizontal, vertical].
393    ///
394    /// 当前滚动长度:[horizontal, vertical]。
395    pub scroll_length: [f32; 2],
396
397    /// Current scroll progress: [horizontal, vertical].
398    ///
399    /// 当前滚动进度:[horizontal, vertical]。
400    pub scroll_progress: [f32; 2],
401
402    /// Mouse state from previous frame: (position, click_aim, scroll_delta).
403    ///
404    /// 上一帧的鼠标状态:(位置,点击目标,滚动增量)。
405    pub last_frame_mouse_status: Option<([f32; 2], ClickAim, [f32; 2])>,
406
407    /// Whether scrolling occurred in this frame: [horizontal, vertical].
408    ///
409    /// 在这一帧中是否发生了滚动:[horizontal, vertical]。
410    pub scrolled: [bool; 2],
411
412    /// Scroll bar transparency: [horizontal, vertical].
413    ///
414    /// 滚动条透明度:[horizontal, vertical]。
415    pub scroll_bar_alpha: [u8; 2],
416
417    /// Storage for resource metadata within the panel.
418    ///
419    /// 面板内资源元数据的存储。
420    pub resource_storage: Vec<PanelStorage>,
421
422    /// Key-value pairs for categorization and metadata.
423    ///
424    /// 用于分类和元数据的键值对标签。
425    pub tags: Vec<[String; 2]>,
426}
427
428impl RustConstructorResource for ResourcePanel {
429    fn as_any(&self) -> &dyn Any {
430        self
431    }
432
433    fn as_any_mut(&mut self) -> &mut dyn Any {
434        self
435    }
436
437    fn display_display_info(&self) -> Option<DisplayInfo> {
438        None
439    }
440
441    fn modify_display_info(&mut self, _display_info: DisplayInfo) {}
442
443    fn display_tags(&self) -> Vec<[String; 2]> {
444        self.tags.clone()
445    }
446
447    fn modify_tags(&mut self, tags: &[[String; 2]], replace: bool) {
448        if replace {
449            self.tags = tags.to_owned();
450        } else {
451            for tag in tags {
452                if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
453                    self.tags.remove(index);
454                };
455            }
456            self.tags.extend(tags.iter().cloned());
457        };
458    }
459}
460
461impl Default for ResourcePanel {
462    fn default() -> Self {
463        Self {
464            resizable: [true, true, true, true],
465            background: BackgroundType::default(),
466            min_size: [10_f32, 10_f32],
467            max_size: None,
468            movable: [true, true],
469            scroll_length_method: [None, None],
470            scroll_sensitivity: 0_f32,
471            scroll_bar_display_method: ScrollBarDisplayMethod::OnlyScroll(
472                BackgroundType::default(),
473                [4_f32, 2_f32],
474                4_f32,
475            ),
476            overall_layout: (PanelLayout {
477                panel_margin: PanelMargin::Vertical([0_f32, 0_f32, 0_f32, 0_f32], false),
478                panel_location: PanelLocation::Absolute([0_f32, 0_f32]),
479            }),
480            custom_layout: Vec::new(),
481            hidden: false,
482            reverse_scroll_direction: [false, false],
483            inner_margin: [6_f32, 6_f32, 6_f32, 6_f32],
484            raise_on_focus: true,
485            scroll_length: [0_f32, 0_f32],
486            scroll_progress: [0_f32, 0_f32],
487            last_frame_mouse_status: None,
488            scrolled: [false, false],
489            scroll_bar_alpha: [0, 0],
490            resource_storage: Vec::new(),
491            tags: Vec::new(),
492        }
493    }
494}
495
496impl ResourcePanel {
497    #[inline]
498    pub fn resizable(mut self, top: bool, bottom: bool, left: bool, right: bool) -> Self {
499        self.resizable = [top, bottom, left, right];
500        self
501    }
502
503    #[inline]
504    pub fn background(mut self, background: &BackgroundType) -> Self {
505        self.background = background.clone();
506        self
507    }
508
509    #[inline]
510    pub fn min_size(mut self, width: f32, height: f32) -> Self {
511        self.min_size = [width, height];
512        self
513    }
514
515    #[inline]
516    pub fn max_size(mut self, max_size: Option<[f32; 2]>) -> Self {
517        self.max_size = max_size;
518        self
519    }
520
521    #[inline]
522    pub fn movable(mut self, horizontal: bool, vertical: bool) -> Self {
523        self.movable = [horizontal, vertical];
524        self
525    }
526
527    #[inline]
528    pub fn scroll_length_method(
529        mut self,
530        horizontal: Option<ScrollLengthMethod>,
531        vertical: Option<ScrollLengthMethod>,
532    ) -> Self {
533        self.scroll_length_method = [horizontal, vertical];
534        self
535    }
536
537    #[inline]
538    pub fn scroll_sensitivity(mut self, scroll_sensitivity: f32) -> Self {
539        self.scroll_sensitivity = scroll_sensitivity;
540        self
541    }
542
543    #[inline]
544    pub fn scroll_bar_display_method(
545        mut self,
546        scroll_bar_display_method: ScrollBarDisplayMethod,
547    ) -> Self {
548        self.scroll_bar_display_method = scroll_bar_display_method;
549        self
550    }
551
552    #[inline]
553    pub fn overall_layout(mut self, overall_layout: PanelLayout) -> Self {
554        self.overall_layout = overall_layout;
555        self
556    }
557
558    #[inline]
559    pub fn push_custom_layout(mut self, custom_layout: CustomPanelLayout) -> Self {
560        self.custom_layout.push(custom_layout);
561        self
562    }
563
564    #[inline]
565    pub fn custom_layout(mut self, custom_layout: &[CustomPanelLayout]) -> Self {
566        self.custom_layout = custom_layout.to_owned();
567        self
568    }
569
570    #[inline]
571    pub fn hidden(mut self, hidden: bool) -> Self {
572        self.hidden = hidden;
573        self
574    }
575
576    #[inline]
577    pub fn reverse_scroll_direction(mut self, horizontal: bool, vertical: bool) -> Self {
578        self.reverse_scroll_direction = [horizontal, vertical];
579        self
580    }
581
582    #[inline]
583    pub fn inner_margin(mut self, top: f32, bottom: f32, left: f32, right: f32) -> Self {
584        self.inner_margin = [top, bottom, left, right];
585        self
586    }
587
588    #[inline]
589    pub fn raise_on_focus(mut self, raise_on_focus: bool) -> Self {
590        self.raise_on_focus = raise_on_focus;
591        self
592    }
593
594    #[inline]
595    pub fn tags(mut self, tags: &[[String; 2]], replace: bool) -> Self {
596        if replace {
597            self.tags = tags.to_owned();
598        } else {
599            for tag in tags {
600                if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
601                    self.tags.remove(index);
602                };
603            }
604            self.tags.extend(tags.iter().cloned());
605        };
606        self
607    }
608}
609
610/// Appearance config for switch resources.
611///
612/// 开关资源的外观配置。
613#[derive(Clone, Debug, Default, PartialEq)]
614pub struct SwitchAppearanceConfig {
615    /// Config for the background element.
616    ///
617    /// 背景元素的配置项。
618    pub background_config: BackgroundType,
619
620    /// Config for the main text.
621    ///
622    /// 主要文本的配置项。
623    pub text_config: TextConfig,
624
625    /// Config for the hint text.
626    ///
627    /// 提示文本的配置项。
628    pub hint_text_config: TextConfig,
629}
630
631/// Click config for switch resources.
632///
633/// 开关资源的点击配置。
634#[derive(Debug, Clone, Copy, PartialEq, Eq)]
635pub struct SwitchClickConfig {
636    /// Mouse button used to trigger the switch.
637    ///
638    /// 用于触发开关的鼠标按钮。
639    pub click_method: PointerButton,
640
641    /// Whether clicking changes the switch state.
642    ///
643    /// 单击是否改变开关状态。
644    pub action: bool,
645}
646
647/// Data structure for tracking switch state and interactions.
648///
649/// 用于跟踪开关状态和交互的数据结构。
650#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
651pub struct SwitchData {
652    /// Whether the switch was toggled by a click.
653    ///
654    /// 是否通过点击打开开关。
655    pub switched: bool,
656
657    /// Click method from the previous frame, if any.
658    ///
659    /// 前一帧中的单击方法(如果有的话)。
660    pub last_frame_clicked: Option<usize>,
661
662    /// Current state of the switch.
663    ///
664    /// 开关当前的状态。
665    pub state: usize,
666}
667
668/// Switch resource for toggleable UI elements.
669///
670/// 用于可切换UI元素的开关资源。
671#[derive(Debug, Clone, PartialEq)]
672pub struct Switch {
673    /// Appearance configs for each state combination.
674    ///
675    /// 每个状态组合的外观配置。
676    pub appearance: Vec<SwitchAppearanceConfig>,
677
678    /// Type of background to display.
679    ///
680    /// 要显示的背景类型。
681    pub background_type: BackgroundType,
682
683    /// Config for the main text display.
684    ///
685    /// 主文本显示的配置。
686    pub text_config: TextConfig,
687
688    /// Config for the hint text display.
689    ///
690    /// 提示文本显示的配置。
691    pub hint_text_config: TextConfig,
692
693    /// Enable animations for hover and click: [hover, click].
694    ///
695    /// 启用悬停动画和单击动画:[hover, click]。
696    pub enable_animation: [bool; 2],
697
698    /// Total number of possible switch states.
699    ///
700    /// 开关可能的状态总数。
701    pub state_amount: u32,
702
703    /// Configs for click interactions.
704    ///
705    /// 单击交互的配置。
706    pub click_method: Vec<SwitchClickConfig>,
707
708    /// Set the single-choice grouping of the switch.
709    ///
710    /// 设置开关的单选分组。
711    ///
712    /// Only one switch can be activated within the same single-choice group.
713    ///
714    /// 同一单选分组内只能有一个开关被激活。
715    pub radio_group: String,
716
717    /// Whether the switch is enabled (disabled shows but not interactive).
718    ///
719    /// 开关是否启用(disabled会显示,但无法交互)。
720    pub enable: bool,
721
722    /// Current state of the switch.
723    ///
724    /// 开关当前状态。
725    pub state: usize,
726
727    /// Whether the mouse was hovering in the previous frame.
728    ///
729    /// 鼠标是否在前一帧中悬停。
730    pub last_frame_hovered: bool,
731
732    /// Click method from the previous frame, if any.
733    ///
734    /// 前一帧中的单击方法(如果有的话)。
735    pub last_frame_clicked: Option<usize>,
736
737    /// Whether the switch was toggled.
738    ///
739    /// 开关是否被切换。
740    pub switched: bool,
741
742    /// If true, resources created by the switch use its tags.
743    ///
744    /// 如果为true,则开关创建的资源使用其标签。
745    pub use_switch_tags: bool,
746
747    /// Key-value pairs for categorization and metadata.
748    ///
749    /// 用于分类和元数据的键值对标签。
750    pub tags: Vec<[String; 2]>,
751}
752
753impl RustConstructorResource for Switch {
754    fn as_any(&self) -> &dyn Any {
755        self
756    }
757
758    fn as_any_mut(&mut self) -> &mut dyn Any {
759        self
760    }
761
762    fn display_display_info(&self) -> Option<DisplayInfo> {
763        None
764    }
765
766    fn modify_display_info(&mut self, _display_info: DisplayInfo) {}
767
768    fn display_tags(&self) -> Vec<[String; 2]> {
769        self.tags.clone()
770    }
771
772    fn modify_tags(&mut self, tags: &[[String; 2]], replace: bool) {
773        if replace {
774            self.tags = tags.to_owned();
775        } else {
776            for tag in tags {
777                if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
778                    self.tags.remove(index);
779                };
780            }
781            self.tags.extend(tags.iter().cloned());
782        };
783    }
784}
785
786impl Default for Switch {
787    fn default() -> Self {
788        Self {
789            appearance: vec![],
790            background_type: BackgroundType::default(),
791            text_config: TextConfig::default(),
792            hint_text_config: TextConfig::default(),
793            enable_animation: [false, false],
794            state_amount: 0,
795            click_method: vec![],
796            radio_group: String::new(),
797            enable: true,
798            state: 0,
799            last_frame_hovered: false,
800            last_frame_clicked: None,
801            switched: false,
802            use_switch_tags: false,
803            tags: Vec::new(),
804        }
805    }
806}
807
808impl Switch {
809    #[inline]
810    pub fn appearance(mut self, appearance: &[SwitchAppearanceConfig]) -> Self {
811        self.appearance = appearance.to_owned();
812        self
813    }
814
815    #[inline]
816    pub fn background_type(mut self, background_type: &BackgroundType) -> Self {
817        self.background_type = background_type.clone();
818        self
819    }
820
821    #[inline]
822    pub fn text_config(mut self, text_config: &TextConfig) -> Self {
823        self.text_config = text_config.clone();
824        self
825    }
826
827    #[inline]
828    pub fn hint_text_config(mut self, hint_text_config: &TextConfig) -> Self {
829        self.hint_text_config = hint_text_config.clone();
830        self
831    }
832
833    #[inline]
834    pub fn enable_animation(mut self, enable_hover: bool, enable_click: bool) -> Self {
835        self.enable_animation = [enable_hover, enable_click];
836        self
837    }
838
839    #[inline]
840    pub fn state_amount(mut self, state_amount: u32) -> Self {
841        self.state_amount = state_amount;
842        self
843    }
844
845    #[inline]
846    pub fn click_method(mut self, click_method: Vec<SwitchClickConfig>) -> Self {
847        self.click_method = click_method;
848        self
849    }
850
851    #[inline]
852    pub fn radio_group(mut self, radio_group: &str) -> Self {
853        self.radio_group = radio_group.to_string();
854        self
855    }
856
857    #[inline]
858    pub fn enable(mut self, enable: bool) -> Self {
859        self.enable = enable;
860        self
861    }
862
863    #[inline]
864    pub fn state(mut self, state: usize) -> Self {
865        self.state = state;
866        self
867    }
868
869    #[inline]
870    pub fn use_switch_tags(mut self, use_switch_tags: bool) -> Self {
871        self.use_switch_tags = use_switch_tags;
872        self
873    }
874
875    #[inline]
876    pub fn tags(mut self, tags: &[[String; 2]], replace: bool) -> Self {
877        if replace {
878            self.tags = tags.to_owned();
879        } else {
880            for tag in tags {
881                if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
882                    self.tags.remove(index);
883                };
884            }
885            self.tags.extend(tags.iter().cloned());
886        };
887        self
888    }
889}