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