1use crate::{
5 DisplayInfo, RustConstructorId, RustConstructorResource,
6 basic_front::{CustomRectConfig, ImageConfig, TextConfig},
7};
8use egui::PointerButton;
9use std::any::Any;
10
11#[derive(Clone, Debug, PartialEq)]
15pub enum BackgroundType {
16 Image(ImageConfig),
20
21 CustomRect(CustomRectConfig),
25}
26
27impl Default for BackgroundType {
28 fn default() -> Self {
29 BackgroundType::CustomRect(CustomRectConfig::default())
30 }
31}
32
33#[derive(Clone, Debug, Default, PartialEq)]
37pub struct Background {
38 pub background_type: BackgroundType,
42
43 pub auto_update: bool,
47
48 pub use_background_tags: bool,
52
53 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#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
131pub enum ScrollLengthMethod {
132 Fixed(f32),
136 AutoFit(f32),
140}
141
142#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
150pub enum ClickAim {
151 Move,
155 TopResize,
159 BottomResize,
163 LeftResize,
167 RightResize,
171 LeftTopResize,
175 RightTopResize,
179 LeftBottomResize,
183 RightBottomResize,
187}
188
189#[derive(Debug, Clone, PartialEq)]
197pub enum ScrollBarDisplayMethod {
198 Always(BackgroundType, [f32; 2], f32),
202 OnlyScroll(BackgroundType, [f32; 2], f32),
206 Hidden,
210}
211
212#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
220pub enum PanelMargin {
221 Vertical([f32; 4], bool),
225 Horizontal([f32; 4], bool),
229 None([f32; 4], bool),
233}
234
235#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
239pub struct PanelLayout {
240 pub panel_margin: PanelMargin,
244 pub panel_location: PanelLocation,
248}
249
250#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
258pub enum PanelLocation {
259 Absolute([f32; 2]),
263 Relative([[f32; 2]; 2]),
267}
268
269#[derive(Debug, Clone, PartialEq, PartialOrd)]
273pub enum CustomPanelLayout {
274 Type(String, PanelLayout),
278 Id(RustConstructorId, PanelLayout),
282}
283
284#[derive(Debug, Default, Clone, PartialEq, PartialOrd)]
293pub struct PanelStorage {
294 pub id: RustConstructorId,
298
299 pub ignore_render_layer: bool,
303
304 pub hidden: bool,
308}
309
310#[derive(Debug, Clone, PartialEq)]
314pub struct ResourcePanel {
315 pub resizable: [bool; 4],
319
320 pub background: BackgroundType,
324
325 pub min_size: [f32; 2],
329
330 pub max_size: Option<[f32; 2]>,
334
335 pub movable: [bool; 2],
339
340 pub scroll_length_method: [Option<ScrollLengthMethod>; 2],
344
345 pub scroll_sensitivity: f32,
349
350 pub scroll_bar_display_method: ScrollBarDisplayMethod,
354
355 pub overall_layout: PanelLayout,
359
360 pub custom_layout: Vec<CustomPanelLayout>,
364
365 pub hidden: bool,
369
370 pub reverse_scroll_direction: [bool; 2],
374
375 pub inner_margin: [f32; 4],
383
384 pub raise_on_focus: bool,
388
389 pub scroll_length: [f32; 2],
393
394 pub scroll_progress: [f32; 2],
398
399 pub last_frame_mouse_status: Option<([f32; 2], ClickAim, [f32; 2])>,
403
404 pub scrolled: [bool; 2],
408
409 pub scroll_bar_alpha: [u8; 2],
413
414 pub resource_storage: Vec<PanelStorage>,
418
419 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 scroll_bar_display_method: ScrollBarDisplayMethod::OnlyScroll(
469 BackgroundType::default(),
470 [4_f32, 2_f32],
471 4_f32,
472 ),
473 overall_layout: (PanelLayout {
474 panel_margin: PanelMargin::Vertical([0_f32, 0_f32, 0_f32, 0_f32], false),
475 panel_location: PanelLocation::Absolute([0_f32, 0_f32]),
476 }),
477 custom_layout: Vec::new(),
478 hidden: false,
479 reverse_scroll_direction: [false, false],
480 inner_margin: [6_f32, 6_f32, 6_f32, 6_f32],
481 raise_on_focus: true,
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 scroll_bar_display_method(
542 mut self,
543 scroll_bar_display_method: ScrollBarDisplayMethod,
544 ) -> Self {
545 self.scroll_bar_display_method = scroll_bar_display_method;
546 self
547 }
548
549 #[inline]
550 pub fn overall_layout(mut self, overall_layout: PanelLayout) -> Self {
551 self.overall_layout = overall_layout;
552 self
553 }
554
555 #[inline]
556 pub fn push_custom_layout(mut self, custom_layout: CustomPanelLayout) -> Self {
557 self.custom_layout.push(custom_layout);
558 self
559 }
560
561 #[inline]
562 pub fn custom_layout(mut self, custom_layout: &[CustomPanelLayout]) -> Self {
563 self.custom_layout = custom_layout.to_owned();
564 self
565 }
566
567 #[inline]
568 pub fn hidden(mut self, hidden: bool) -> Self {
569 self.hidden = hidden;
570 self
571 }
572
573 #[inline]
574 pub fn reverse_scroll_direction(mut self, horizontal: bool, vertical: bool) -> Self {
575 self.reverse_scroll_direction = [horizontal, vertical];
576 self
577 }
578
579 #[inline]
580 pub fn inner_margin(mut self, top: f32, bottom: f32, left: f32, right: f32) -> Self {
581 self.inner_margin = [top, bottom, left, right];
582 self
583 }
584
585 #[inline]
586 pub fn raise_on_focus(mut self, raise_on_focus: bool) -> Self {
587 self.raise_on_focus = raise_on_focus;
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#[derive(Clone, Debug, Default, PartialEq)]
611pub struct SwitchAppearanceConfig {
612 pub background_config: BackgroundType,
616
617 pub text_config: TextConfig,
621
622 pub hint_text_config: TextConfig,
626}
627
628#[derive(Debug, Clone, Copy, PartialEq, Eq)]
632pub struct SwitchClickConfig {
633 pub click_method: PointerButton,
637
638 pub action: bool,
642}
643
644#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
648pub struct SwitchData {
649 pub switched: bool,
653
654 pub last_frame_clicked: Option<usize>,
658
659 pub state: usize,
663}
664
665#[derive(Debug, Clone, PartialEq)]
669pub struct Switch {
670 pub appearance: Vec<SwitchAppearanceConfig>,
674
675 pub background_type: BackgroundType,
679
680 pub text_config: TextConfig,
684
685 pub hint_text_config: TextConfig,
689
690 pub enable_animation: [bool; 2],
694
695 pub state_amount: u32,
699
700 pub click_method: Vec<SwitchClickConfig>,
704
705 pub radio_group: String,
713
714 pub enable: bool,
718
719 pub state: usize,
723
724 pub last_frame_hovered: bool,
728
729 pub last_frame_clicked: Option<usize>,
733
734 pub switched: bool,
738
739 pub use_switch_tags: bool,
743
744 pub tags: Vec<[String; 2]>,
748}
749
750impl RustConstructorResource for Switch {
751 fn as_any(&self) -> &dyn Any {
752 self
753 }
754
755 fn as_any_mut(&mut self) -> &mut dyn Any {
756 self
757 }
758
759 fn display_display_info(&self) -> Option<DisplayInfo> {
760 None
761 }
762
763 fn modify_display_info(&mut self, _display_info: DisplayInfo) {}
764
765 fn display_tags(&self) -> Vec<[String; 2]> {
766 self.tags.clone()
767 }
768
769 fn modify_tags(&mut self, tags: &[[String; 2]], replace: bool) {
770 if replace {
771 self.tags = tags.to_owned();
772 } else {
773 for tag in tags {
774 if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
775 self.tags.remove(index);
776 };
777 }
778 self.tags.extend(tags.iter().cloned());
779 };
780 }
781}
782
783impl Default for Switch {
784 fn default() -> Self {
785 Self {
786 appearance: vec![],
787 background_type: BackgroundType::default(),
788 text_config: TextConfig::default(),
789 hint_text_config: TextConfig::default(),
790 enable_animation: [false, false],
791 state_amount: 0,
792 click_method: vec![],
793 radio_group: String::new(),
794 enable: true,
795 state: 0,
796 last_frame_hovered: false,
797 last_frame_clicked: None,
798 switched: false,
799 use_switch_tags: false,
800 tags: Vec::new(),
801 }
802 }
803}
804
805impl Switch {
806 #[inline]
807 pub fn appearance(mut self, appearance: &[SwitchAppearanceConfig]) -> Self {
808 self.appearance = appearance.to_owned();
809 self
810 }
811
812 #[inline]
813 pub fn background_type(mut self, background_type: &BackgroundType) -> Self {
814 self.background_type = background_type.clone();
815 self
816 }
817
818 #[inline]
819 pub fn text_config(mut self, text_config: &TextConfig) -> Self {
820 self.text_config = text_config.clone();
821 self
822 }
823
824 #[inline]
825 pub fn hint_text_config(mut self, hint_text_config: &TextConfig) -> Self {
826 self.hint_text_config = hint_text_config.clone();
827 self
828 }
829
830 #[inline]
831 pub fn enable_animation(mut self, enable_hover: bool, enable_click: bool) -> Self {
832 self.enable_animation = [enable_hover, enable_click];
833 self
834 }
835
836 #[inline]
837 pub fn state_amount(mut self, state_amount: u32) -> Self {
838 self.state_amount = state_amount;
839 self
840 }
841
842 #[inline]
843 pub fn click_method(mut self, click_method: Vec<SwitchClickConfig>) -> Self {
844 self.click_method = click_method;
845 self
846 }
847
848 #[inline]
849 pub fn radio_group(mut self, radio_group: &str) -> Self {
850 self.radio_group = radio_group.to_string();
851 self
852 }
853
854 #[inline]
855 pub fn enable(mut self, enable: bool) -> Self {
856 self.enable = enable;
857 self
858 }
859
860 #[inline]
861 pub fn state(mut self, state: usize) -> Self {
862 self.state = state;
863 self
864 }
865
866 #[inline]
867 pub fn use_switch_tags(mut self, use_switch_tags: bool) -> Self {
868 self.use_switch_tags = use_switch_tags;
869 self
870 }
871
872 #[inline]
873 pub fn tags(mut self, tags: &[[String; 2]], replace: bool) -> Self {
874 if replace {
875 self.tags = tags.to_owned();
876 } else {
877 for tag in tags {
878 if let Some(index) = self.tags.iter().position(|x| x[0] == tag[0]) {
879 self.tags.remove(index);
880 };
881 }
882 self.tags.extend(tags.iter().cloned());
883 };
884 self
885 }
886}