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([[u32; 2]; 2]),
267}
268
269/// Storage structure for panel resource metadata.
270///
271/// 面板资源元数据的存储结构。
272///
273/// This struct holds essential information about resources stored within panels,
274/// including visibility, rendering behavior, and sizing information.
275///
276/// 该结构体保存面板内存储资源的基本信息,包括可见性、渲染行为和尺寸信息。
277#[derive(Debug, Default, Clone, PartialEq, PartialOrd)]
278pub struct PanelStorage {
279    /// Unique identifier for the stored resource.
280    ///
281    /// 存储资源的唯一标识符。
282    pub id: RustConstructorId,
283
284    /// If true, the resource ignores render layer.
285    ///
286    /// 如果为true,则资源忽略渲染层。
287    pub ignore_render_layer: bool,
288
289    /// Controls whether the resource is visible.
290    ///
291    /// 控制资源是否可见。
292    pub hidden: bool,
293
294    /// Original size of the resource before any panel adjustments.
295    ///
296    /// 存储资源原始尺寸(面板调整前的尺寸)。
297    pub origin_size: [f32; 2],
298}
299
300/// Resource panel for organizing and managing UI elements with scrolling capabilities.
301///
302/// 资源板,用于组织和管理具有滚动能力的UI元素。
303#[derive(Debug, Clone, PartialEq)]
304pub struct ResourcePanel {
305    /// Which edges can be resized: [top, bottom, left, right].
306    ///
307    /// 哪些边可以调整尺寸:[top, bottom, left, right]。
308    pub resizable: [bool; 4],
309
310    /// Background display for the panel.
311    ///
312    /// 面板的背景显示。
313    pub background: BackgroundType,
314
315    /// Minimum size constraints for the panel.
316    ///
317    /// 面板的最小尺寸限制。
318    pub min_size: [f32; 2],
319
320    /// Optional maximum size constraints for the panel.
321    ///
322    /// 面板的可选最大尺寸限制。
323    pub max_size: Option<[f32; 2]>,
324
325    /// Whether the panel can be moved: [horizontal, vertical].
326    ///
327    /// 面板是否可以移动:[horizontal, vertical]。
328    pub movable: [bool; 2],
329
330    /// Methods for calculating scroll length: [horizontal, vertical].
331    ///
332    /// 计算滚动长度的方法:[horizontal, vertical]。
333    pub scroll_length_method: [Option<ScrollLengthMethod>; 2],
334
335    /// Sensitivity of scrolling interactions.
336    ///
337    /// 滚动交互的敏感性。
338    pub scroll_sensitivity: f32,
339
340    /// Whether to use smooth scrolling with delta values.
341    ///
342    /// 是否使用平滑滚动。
343    pub use_smooth_scroll_delta: bool,
344
345    /// Display behavior of the scroll bar.
346    ///
347    /// 显示滚动条的方法。
348    pub scroll_bar_display_method: ScrollBarDisplayMethod,
349
350    /// Layout config for resources within the panel.
351    ///
352    /// 面板内资源的布局配置。
353    pub layout: PanelLayout,
354
355    /// Whether the panel is visible.
356    ///
357    /// 面板是否可见。
358    pub hidden: bool,
359
360    /// Reverse scroll direction: [horizontal, vertical].
361    ///
362    /// 反转滚动方向:[horizontal, vertical]。
363    pub reverse_scroll_direction: [bool; 2],
364
365    /// Auto-shrink behavior: [horizontal, vertical].
366    ///
367    /// 自动缩放行为:[horizontal, vertical]。
368    pub auto_shrink: [bool; 2],
369
370    /// Current scroll length: [horizontal, vertical].
371    ///
372    /// 当前滚动长度:[horizontal, vertical]。
373    pub scroll_length: [f32; 2],
374
375    /// Current scroll progress: [horizontal, vertical].
376    ///
377    /// 当前滚动进度:[horizontal, vertical]。
378    pub scroll_progress: [f32; 2],
379
380    /// Mouse state from previous frame: (position, click_aim, scroll_delta).
381    ///
382    /// 上一帧的鼠标状态:(位置,点击目标,滚动增量)。
383    pub last_frame_mouse_status: Option<([f32; 2], ClickAim, [f32; 2])>,
384
385    /// Whether scrolling occurred in this frame: [horizontal, vertical].
386    ///
387    /// 在这一帧中是否发生了滚动:[horizontal, vertical]。
388    pub scrolled: [bool; 2],
389
390    /// Scroll bar transparency: [horizontal, vertical].
391    ///
392    /// 滚动条透明度:[horizontal, vertical]。
393    pub scroll_bar_alpha: [u8; 2],
394
395    /// Storage for resource metadata within the panel.
396    ///
397    /// 面板内资源元数据的存储。
398    pub resource_storage: Vec<PanelStorage>,
399
400    /// Key-value pairs for categorization and metadata.
401    ///
402    /// 用于分类和元数据的键值对标签。
403    pub tags: Vec<[String; 2]>,
404}
405
406impl RustConstructorResource for ResourcePanel {
407    fn as_any(&self) -> &dyn Any {
408        self
409    }
410
411    fn as_any_mut(&mut self) -> &mut dyn Any {
412        self
413    }
414
415    fn display_display_info(&self) -> Option<DisplayInfo> {
416        None
417    }
418
419    fn modify_display_info(&mut self, _display_info: DisplayInfo) {}
420
421    fn display_tags(&self) -> Vec<[String; 2]> {
422        self.tags.clone()
423    }
424
425    fn modify_tags(&mut self, tags: &[[String; 2]], replace: bool) {
426        if replace {
427            self.tags = tags.to_owned();
428        } else {
429            for tag in tags {
430                if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
431                    self.tags.remove(index);
432                };
433            }
434            self.tags.extend(tags.iter().cloned());
435        };
436    }
437}
438
439impl Default for ResourcePanel {
440    fn default() -> Self {
441        Self {
442            resizable: [true, true, true, true],
443            background: BackgroundType::default(),
444            min_size: [10_f32, 10_f32],
445            max_size: None,
446            movable: [true, true],
447            scroll_length_method: [None, None],
448            scroll_sensitivity: 0_f32,
449            use_smooth_scroll_delta: true,
450            scroll_bar_display_method: ScrollBarDisplayMethod::OnlyScroll(
451                BackgroundType::default(),
452                [4_f32, 2_f32],
453                4_f32,
454            ),
455            layout: (PanelLayout {
456                panel_margin: PanelMargin::Vertical([0_f32, 0_f32, 0_f32, 0_f32], false),
457                panel_location: PanelLocation::Absolute([0_f32, 0_f32]),
458            }),
459            hidden: false,
460            reverse_scroll_direction: [false, false],
461            auto_shrink: [true, false],
462            scroll_length: [0_f32, 0_f32],
463            scroll_progress: [0_f32, 0_f32],
464            last_frame_mouse_status: None,
465            scrolled: [false, false],
466            scroll_bar_alpha: [0, 0],
467            resource_storage: Vec::new(),
468            tags: Vec::new(),
469        }
470    }
471}
472
473impl ResourcePanel {
474    #[inline]
475    pub fn resizable(mut self, top: bool, bottom: bool, left: bool, right: bool) -> Self {
476        self.resizable = [top, bottom, left, right];
477        self
478    }
479
480    #[inline]
481    pub fn background(mut self, background: &BackgroundType) -> Self {
482        self.background = background.clone();
483        self
484    }
485
486    #[inline]
487    pub fn min_size(mut self, width: f32, height: f32) -> Self {
488        self.min_size = [width, height];
489        self
490    }
491
492    #[inline]
493    pub fn max_size(mut self, max_size: Option<[f32; 2]>) -> Self {
494        self.max_size = max_size;
495        self
496    }
497
498    #[inline]
499    pub fn movable(mut self, horizontal: bool, vertical: bool) -> Self {
500        self.movable = [horizontal, vertical];
501        self
502    }
503
504    #[inline]
505    pub fn scroll_length_method(
506        mut self,
507        horizontal: Option<ScrollLengthMethod>,
508        vertical: Option<ScrollLengthMethod>,
509    ) -> Self {
510        self.scroll_length_method = [horizontal, vertical];
511        self
512    }
513
514    #[inline]
515    pub fn scroll_sensitivity(mut self, scroll_sensitivity: f32) -> Self {
516        self.scroll_sensitivity = scroll_sensitivity;
517        self
518    }
519
520    #[inline]
521    pub fn use_smooth_scroll_delta(mut self, use_smooth_scroll_delta: bool) -> Self {
522        self.use_smooth_scroll_delta = use_smooth_scroll_delta;
523        self
524    }
525
526    #[inline]
527    pub fn scroll_bar_display_method(
528        mut self,
529        scroll_bar_display_method: ScrollBarDisplayMethod,
530    ) -> Self {
531        self.scroll_bar_display_method = scroll_bar_display_method;
532        self
533    }
534
535    #[inline]
536    pub fn layout(mut self, layout: PanelLayout) -> Self {
537        self.layout = layout;
538        self
539    }
540
541    #[inline]
542    pub fn hidden(mut self, hidden: bool) -> Self {
543        self.hidden = hidden;
544        self
545    }
546
547    #[inline]
548    pub fn reverse_scroll_direction(mut self, horizontal: bool, vertical: bool) -> Self {
549        self.reverse_scroll_direction = [horizontal, vertical];
550        self
551    }
552
553    #[inline]
554    pub fn auto_shrink(mut self, horizontal: bool, vertical: bool) -> Self {
555        self.auto_shrink = [horizontal, vertical];
556        self
557    }
558
559    #[inline]
560    pub fn tags(mut self, tags: &[[String; 2]], replace: bool) -> Self {
561        if replace {
562            self.tags = tags.to_owned();
563        } else {
564            for tag in tags {
565                if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
566                    self.tags.remove(index);
567                };
568            }
569            self.tags.extend(tags.iter().cloned());
570        };
571        self
572    }
573}
574
575/// Appearance config for switch resources.
576///
577/// 开关资源的外观配置。
578#[derive(Clone, Debug, Default, PartialEq)]
579pub struct SwitchAppearanceConfig {
580    /// Config for the background element.
581    ///
582    /// 背景元素的配置项。
583    pub background_config: BackgroundType,
584
585    /// Config for the main text.
586    ///
587    /// 主要文本的配置项。
588    pub text_config: TextConfig,
589
590    /// Config for the hint text.
591    ///
592    /// 提示文本的配置项。
593    pub hint_text_config: TextConfig,
594}
595
596/// Click config for switch resources.
597///
598/// 开关资源的点击配置。
599#[derive(Debug, Clone, Copy, PartialEq, Eq)]
600pub struct SwitchClickConfig {
601    /// Mouse button used to trigger the switch.
602    ///
603    /// 用于触发开关的鼠标按钮。
604    pub click_method: PointerButton,
605
606    /// Whether clicking changes the switch state.
607    ///
608    /// 单击是否改变开关状态。
609    pub action: bool,
610}
611
612/// Data structure for tracking switch state and interactions.
613///
614/// 用于跟踪开关状态和交互的数据结构。
615#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
616pub struct SwitchData {
617    /// Whether the switch was toggled by a click.
618    ///
619    /// 是否通过点击打开开关。
620    pub switched: bool,
621
622    /// Click method from the previous frame, if any.
623    ///
624    /// 前一帧中的单击方法(如果有的话)。
625    pub last_frame_clicked: Option<usize>,
626
627    /// Current state of the switch.
628    ///
629    /// 开关当前的状态。
630    pub state: u32,
631}
632
633/// Switch resource for toggleable UI elements.
634///
635/// 用于可切换UI元素的开关资源。
636#[derive(Debug, Clone, PartialEq)]
637pub struct Switch {
638    /// Appearance configs for each state combination.
639    ///
640    /// 每个状态组合的外观配置。
641    pub appearance: Vec<SwitchAppearanceConfig>,
642
643    /// Type of background to display.
644    ///
645    /// 要显示的背景类型。
646    pub background_type: BackgroundType,
647
648    /// Config for the main text display.
649    ///
650    /// 主文本显示的配置。
651    pub text_config: TextConfig,
652
653    /// Config for the hint text display.
654    ///
655    /// 提示文本显示的配置。
656    pub hint_text_config: TextConfig,
657
658    /// Enable animations for hover and click: [hover, click].
659    ///
660    /// 启用悬停动画和单击动画:[hover, click]。
661    pub enable_animation: [bool; 2],
662
663    /// Total number of possible switch states.
664    ///
665    /// 开关可能的状态总数。
666    pub state_amount: u32,
667
668    /// Configs for click interactions.
669    ///
670    /// 单击交互的配置。
671    pub click_method: Vec<SwitchClickConfig>,
672
673    /// Whether the switch is enabled (disabled shows but not interactive).
674    ///
675    /// 开关是否启用(disabled会显示,但无法交互)。
676    pub enable: bool,
677
678    /// Current state of the switch.
679    ///
680    /// 开关当前状态。
681    pub state: u32,
682
683    /// Whether the mouse was hovering in the previous frame.
684    ///
685    /// 鼠标是否在前一帧中悬停。
686    pub last_frame_hovered: bool,
687
688    /// Click method from the previous frame, if any.
689    ///
690    /// 前一帧中的单击方法(如果有的话)。
691    pub last_frame_clicked: Option<usize>,
692
693    /// Whether the switch was toggled.
694    ///
695    /// 开关是否被切换。
696    pub switched: bool,
697
698    /// If true, resources created by the switch use its tags.
699    ///
700    /// 如果为true,则开关创建的资源使用其标签。
701    pub use_switch_tags: bool,
702
703    /// Key-value pairs for categorization and metadata.
704    ///
705    /// 用于分类和元数据的键值对标签。
706    pub tags: Vec<[String; 2]>,
707}
708
709impl RustConstructorResource for Switch {
710    fn as_any(&self) -> &dyn Any {
711        self
712    }
713
714    fn as_any_mut(&mut self) -> &mut dyn Any {
715        self
716    }
717
718    fn display_display_info(&self) -> Option<DisplayInfo> {
719        None
720    }
721
722    fn modify_display_info(&mut self, _display_info: DisplayInfo) {}
723
724    fn display_tags(&self) -> Vec<[String; 2]> {
725        self.tags.clone()
726    }
727
728    fn modify_tags(&mut self, tags: &[[String; 2]], replace: bool) {
729        if replace {
730            self.tags = tags.to_owned();
731        } else {
732            for tag in tags {
733                if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
734                    self.tags.remove(index);
735                };
736            }
737            self.tags.extend(tags.iter().cloned());
738        };
739    }
740}
741
742impl Default for Switch {
743    fn default() -> Self {
744        Self {
745            appearance: vec![],
746            background_type: BackgroundType::default(),
747            text_config: TextConfig::default(),
748            hint_text_config: TextConfig::default(),
749            enable_animation: [false, false],
750            state_amount: 0,
751            click_method: vec![],
752            enable: true,
753            state: 0,
754            last_frame_hovered: false,
755            last_frame_clicked: None,
756            switched: false,
757            use_switch_tags: false,
758            tags: Vec::new(),
759        }
760    }
761}
762
763impl Switch {
764    #[inline]
765    pub fn appearance(mut self, appearance: &[SwitchAppearanceConfig]) -> Self {
766        self.appearance = appearance.to_owned();
767        self
768    }
769
770    #[inline]
771    pub fn background_type(mut self, background_type: &BackgroundType) -> Self {
772        self.background_type = background_type.clone();
773        self
774    }
775
776    #[inline]
777    pub fn text_config(mut self, text_config: &TextConfig) -> Self {
778        self.text_config = text_config.clone();
779        self
780    }
781
782    #[inline]
783    pub fn hint_text_config(mut self, hint_text_config: &TextConfig) -> Self {
784        self.hint_text_config = hint_text_config.clone();
785        self
786    }
787
788    #[inline]
789    pub fn enable_animation(mut self, enable_hover: bool, enable_click: bool) -> Self {
790        self.enable_animation = [enable_hover, enable_click];
791        self
792    }
793
794    #[inline]
795    pub fn state_amount(mut self, state_amount: u32) -> Self {
796        self.state_amount = state_amount;
797        self
798    }
799
800    #[inline]
801    pub fn click_method(mut self, click_method: Vec<SwitchClickConfig>) -> Self {
802        self.click_method = click_method;
803        self
804    }
805
806    #[inline]
807    pub fn enable(mut self, enable: bool) -> Self {
808        self.enable = enable;
809        self
810    }
811
812    #[inline]
813    pub fn use_switch_tags(mut self, use_switch_tags: bool) -> Self {
814        self.use_switch_tags = use_switch_tags;
815        self
816    }
817
818    #[inline]
819    pub fn tags(mut self, tags: &[[String; 2]], replace: bool) -> Self {
820        if replace {
821            self.tags = tags.to_owned();
822        } else {
823            for tag in tags {
824                if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
825                    self.tags.remove(index);
826                };
827            }
828            self.tags.extend(tags.iter().cloned());
829        };
830        self
831    }
832}