Skip to main content

gdext_egui/
lib.rs

1macro_rules! symbol_string {
2    ($base:ty, $ident:ident) => {{
3        // Just ensure ident exist
4        let str = stringify!($ident);
5        let _ = <$base>::$ident;
6
7        str
8    }};
9}
10
11pub mod context;
12mod surface;
13pub mod widgets;
14
15pub extern crate egui;
16
17pub use context::EguiBridge;
18pub use egui::{ViewportBuilder, ViewportId};
19
20pub mod helpers {
21    use godot::{classes::WeakRef, prelude::*};
22
23    pub trait ToCounterpart {
24        type Counterpart;
25        type Alternative;
26
27        fn to_counterpart(&self) -> Self::Counterpart;
28        fn to_alternative(&self) -> Self::Alternative;
29    }
30
31    impl ToCounterpart for Vector2 {
32        type Counterpart = egui::Vec2;
33        type Alternative = egui::Pos2;
34
35        fn to_counterpart(&self) -> Self::Counterpart {
36            egui::Vec2::new(self.x, self.y)
37        }
38
39        fn to_alternative(&self) -> Self::Alternative {
40            egui::Pos2::new(self.x, self.y)
41        }
42    }
43
44    impl ToCounterpart for egui::Vec2 {
45        type Counterpart = Vector2;
46        type Alternative = Vector2i;
47
48        fn to_counterpart(&self) -> Self::Counterpart {
49            Vector2::new(self.x, self.y)
50        }
51
52        fn to_alternative(&self) -> Self::Alternative {
53            Vector2i::new(self.x as i32, self.y as i32)
54        }
55    }
56
57    impl ToCounterpart for egui::Pos2 {
58        type Counterpart = Vector2;
59        type Alternative = Vector2i;
60
61        fn to_counterpart(&self) -> Self::Counterpart {
62            Vector2::new(self.x, self.y)
63        }
64
65        fn to_alternative(&self) -> Self::Alternative {
66            Vector2i::new(self.x as i32, self.y as i32)
67        }
68    }
69
70    impl ToCounterpart for Vector2i {
71        type Counterpart = egui::Vec2;
72        type Alternative = egui::Pos2;
73
74        fn to_counterpart(&self) -> Self::Counterpart {
75            egui::Vec2::new(self.x as f32, self.y as f32)
76        }
77
78        fn to_alternative(&self) -> Self::Alternative {
79            egui::Pos2::new(self.x as f32, self.y as f32)
80        }
81    }
82
83    impl ToCounterpart for Rect2 {
84        type Counterpart = egui::Rect;
85        type Alternative = Self::Counterpart;
86
87        fn to_counterpart(&self) -> Self::Counterpart {
88            egui::Rect::from_min_size(
89                self.position.to_counterpart().to_pos2(),
90                self.size.to_counterpart(),
91            )
92        }
93
94        fn to_alternative(&self) -> Self::Alternative {
95            self.to_counterpart()
96        }
97    }
98
99    impl ToCounterpart for egui::Rect {
100        type Counterpart = Rect2;
101        type Alternative = Rect2i;
102
103        fn to_counterpart(&self) -> Self::Counterpart {
104            Rect2::new(self.min.to_counterpart(), self.max.to_counterpart())
105        }
106
107        fn to_alternative(&self) -> Self::Alternative {
108            Rect2i::new(self.min.to_alternative(), self.max.to_alternative())
109        }
110    }
111
112    pub fn downgrade_gd<T: GodotClass>(gd: Gd<T>) -> Gd<WeakRef> {
113        godot::global::weakref(&gd.to_variant()).try_to().unwrap()
114    }
115
116    pub fn try_upgrade_gd<T: GodotClass>(gd: Gd<WeakRef>) -> Option<Gd<T>> {
117        gd.get_ref().try_to().ok()
118    }
119}
120
121fn default<T: Default>() -> T {
122    T::default()
123}
124
125/* ------------------------------------------ DnD Util ------------------------------------------ */
126
127/// A wrapper around `godot::prelude::Variant` that forcibly implements `Send` and `Sync`.
128///
129/// This is the primary `Payload` type for [`egui::DragAndDrop`] utility. This is not
130/// intended to use carry 'heavy' data, but rather to carry references to the data which
131/// is relatively cheap to clone.
132#[derive(Debug, Clone)]
133pub struct DragAndDropVariant(godot::prelude::Variant);
134
135unsafe impl Send for DragAndDropVariant {}
136unsafe impl Sync for DragAndDropVariant {}
137
138impl DragAndDropVariant {
139    pub fn new(variant: godot::prelude::Variant) -> Self {
140        Self(variant)
141    }
142
143    pub fn into_inner(self) -> godot::prelude::Variant {
144        self.0
145    }
146}