1use 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#[derive(Clone, Debug, PartialEq)]
18pub enum BackgroundType {
19 Image(ImageConfig),
23
24 CustomRect(CustomRectConfig),
28}
29
30impl Default for BackgroundType {
31 fn default() -> Self {
32 BackgroundType::CustomRect(CustomRectConfig::default())
33 }
34}
35
36#[derive(Clone, Debug, Default, PartialEq)]
40pub struct Background {
41 pub background_type: BackgroundType,
45
46 pub auto_update: bool,
50
51 pub use_background_tags: bool,
55
56 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#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
134pub enum ScrollLengthMethod {
135 Fixed(f32),
139 AutoFit(f32),
143}
144
145#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
153pub enum ClickAim {
154 Move,
158 TopResize,
162 BottomResize,
166 LeftResize,
170 RightResize,
174 LeftTopResize,
178 RightTopResize,
182 LeftBottomResize,
186 RightBottomResize,
190}
191
192#[derive(Debug, Clone, PartialEq)]
200pub enum ScrollBarDisplayMethod {
201 Always(BackgroundType, [f32; 2], f32),
205 OnlyScroll(BackgroundType, [f32; 2], f32),
209 Hidden,
213}
214
215#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
223pub enum PanelMargin {
224 Vertical([f32; 4], bool),
228 Horizontal([f32; 4], bool),
232 None([f32; 4], bool),
236}
237
238#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
242pub struct PanelLayout {
243 pub panel_margin: PanelMargin,
247 pub panel_location: PanelLocation,
251}
252
253#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
261pub enum PanelLocation {
262 Absolute([f32; 2]),
266 Relative([[f32; 2]; 2]),
270}
271
272#[derive(Debug, Clone, PartialEq, PartialOrd)]
276pub enum CustomPanelLayout {
277 Type(String, PanelLayout),
281 Id(RustConstructorId, PanelLayout),
285}
286
287#[derive(Debug, Default, Clone, PartialEq, PartialOrd)]
296pub struct PanelStorage {
297 pub id: RustConstructorId,
301
302 pub ignore_render_layer: bool,
306
307 pub hidden: bool,
311}
312
313#[derive(Debug, Clone, PartialEq)]
317pub struct ResourcePanel {
318 pub resizable: [bool; 4],
322
323 pub background: BackgroundType,
327
328 pub min_size: [f32; 2],
332
333 pub max_size: Option<[f32; 2]>,
337
338 pub movable: [bool; 2],
342
343 pub scroll_length_method: [Option<ScrollLengthMethod>; 2],
347
348 pub scroll_sensitivity: f32,
352
353 pub scroll_bar_display_method: ScrollBarDisplayMethod,
357
358 pub overall_layout: PanelLayout,
362
363 pub custom_layout: Vec<CustomPanelLayout>,
367
368 pub hidden: bool,
372
373 pub reverse_scroll_direction: [bool; 2],
377
378 pub inner_margin: [f32; 4],
386
387 pub raise_on_focus: bool,
391
392 pub scroll_length: [f32; 2],
396
397 pub scroll_progress: [f32; 2],
401
402 pub last_frame_mouse_status: Option<([f32; 2], ClickAim, [f32; 2])>,
406
407 pub scrolled: [bool; 2],
411
412 pub scroll_bar_alpha: [u8; 2],
416
417 pub resource_storage: Vec<PanelStorage>,
421
422 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#[derive(Clone, Debug, Default, PartialEq)]
614pub struct SwitchAppearanceConfig {
615 pub background_config: BackgroundType,
619
620 pub text_config: TextConfig,
624
625 pub hint_text_config: TextConfig,
629}
630
631#[derive(Debug, Clone, Copy, PartialEq, Eq)]
635pub struct SwitchClickConfig {
636 pub click_method: PointerButton,
640
641 pub action: bool,
645}
646
647#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
651pub struct SwitchData {
652 pub switched: bool,
656
657 pub last_frame_clicked: Option<usize>,
661
662 pub state: usize,
666}
667
668#[derive(Debug, Clone, PartialEq)]
672pub struct Switch {
673 pub appearance: Vec<SwitchAppearanceConfig>,
677
678 pub background_type: BackgroundType,
682
683 pub text_config: TextConfig,
687
688 pub hint_text_config: TextConfig,
692
693 pub enable_animation: [bool; 2],
697
698 pub state_amount: u32,
702
703 pub click_method: Vec<SwitchClickConfig>,
707
708 pub radio_group: String,
716
717 pub enable: bool,
721
722 pub state: usize,
726
727 pub last_frame_hovered: bool,
731
732 pub last_frame_clicked: Option<usize>,
736
737 pub switched: bool,
741
742 pub use_switch_tags: bool,
746
747 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}