bevy_egui/
helpers.rs

1use bevy_ecs::{
2    entity::Entity,
3    query::{QueryData, QueryEntityError, QueryFilter, QueryItem, ROQueryItem},
4    system::Query,
5};
6use bevy_input::keyboard::{Key, KeyCode};
7
8/// Translates [`egui::CursorIcon`] into [`bevy_window::SystemCursorIcon`].
9#[inline(always)]
10pub fn egui_to_winit_cursor_icon(
11    cursor_icon: egui::CursorIcon,
12) -> Option<bevy_window::SystemCursorIcon> {
13    match cursor_icon {
14        egui::CursorIcon::Default => Some(bevy_window::SystemCursorIcon::Default),
15        egui::CursorIcon::PointingHand => Some(bevy_window::SystemCursorIcon::Pointer),
16        egui::CursorIcon::ResizeHorizontal => Some(bevy_window::SystemCursorIcon::EwResize),
17        egui::CursorIcon::ResizeNeSw => Some(bevy_window::SystemCursorIcon::NeswResize),
18        egui::CursorIcon::ResizeNwSe => Some(bevy_window::SystemCursorIcon::NwseResize),
19        egui::CursorIcon::ResizeVertical => Some(bevy_window::SystemCursorIcon::NsResize),
20        egui::CursorIcon::Text => Some(bevy_window::SystemCursorIcon::Text),
21        egui::CursorIcon::Grab => Some(bevy_window::SystemCursorIcon::Grab),
22        egui::CursorIcon::Grabbing => Some(bevy_window::SystemCursorIcon::Grabbing),
23        egui::CursorIcon::ContextMenu => Some(bevy_window::SystemCursorIcon::ContextMenu),
24        egui::CursorIcon::Help => Some(bevy_window::SystemCursorIcon::Help),
25        egui::CursorIcon::Progress => Some(bevy_window::SystemCursorIcon::Progress),
26        egui::CursorIcon::Wait => Some(bevy_window::SystemCursorIcon::Wait),
27        egui::CursorIcon::Cell => Some(bevy_window::SystemCursorIcon::Cell),
28        egui::CursorIcon::Crosshair => Some(bevy_window::SystemCursorIcon::Crosshair),
29        egui::CursorIcon::VerticalText => Some(bevy_window::SystemCursorIcon::VerticalText),
30        egui::CursorIcon::Alias => Some(bevy_window::SystemCursorIcon::Alias),
31        egui::CursorIcon::Copy => Some(bevy_window::SystemCursorIcon::Copy),
32        egui::CursorIcon::Move => Some(bevy_window::SystemCursorIcon::Move),
33        egui::CursorIcon::NoDrop => Some(bevy_window::SystemCursorIcon::NoDrop),
34        egui::CursorIcon::NotAllowed => Some(bevy_window::SystemCursorIcon::NotAllowed),
35        egui::CursorIcon::AllScroll => Some(bevy_window::SystemCursorIcon::AllScroll),
36        egui::CursorIcon::ZoomIn => Some(bevy_window::SystemCursorIcon::ZoomIn),
37        egui::CursorIcon::ZoomOut => Some(bevy_window::SystemCursorIcon::ZoomOut),
38        egui::CursorIcon::ResizeEast => Some(bevy_window::SystemCursorIcon::EResize),
39        egui::CursorIcon::ResizeSouthEast => Some(bevy_window::SystemCursorIcon::SeResize),
40        egui::CursorIcon::ResizeSouth => Some(bevy_window::SystemCursorIcon::SResize),
41        egui::CursorIcon::ResizeSouthWest => Some(bevy_window::SystemCursorIcon::SwResize),
42        egui::CursorIcon::ResizeWest => Some(bevy_window::SystemCursorIcon::WResize),
43        egui::CursorIcon::ResizeNorthWest => Some(bevy_window::SystemCursorIcon::NwResize),
44        egui::CursorIcon::ResizeNorth => Some(bevy_window::SystemCursorIcon::NResize),
45        egui::CursorIcon::ResizeNorthEast => Some(bevy_window::SystemCursorIcon::NeResize),
46        egui::CursorIcon::ResizeColumn => Some(bevy_window::SystemCursorIcon::ColResize),
47        egui::CursorIcon::ResizeRow => Some(bevy_window::SystemCursorIcon::RowResize),
48        egui::CursorIcon::None => None,
49    }
50}
51
52/// Matches the implementation of <https://github.com/emilk/egui/blob/68b3ef7f6badfe893d3bbb1f791b481069d807d9/crates/egui-winit/src/lib.rs#L1005>.
53#[inline(always)]
54pub fn bevy_to_egui_key(key: &Key) -> Option<egui::Key> {
55    let key = match key {
56        Key::Character(str) => return egui::Key::from_name(str.as_str()),
57        Key::Unidentified(_) | Key::Dead(_) => return None,
58
59        Key::Enter => egui::Key::Enter,
60        Key::Tab => egui::Key::Tab,
61        Key::Space => egui::Key::Space,
62        Key::ArrowDown => egui::Key::ArrowDown,
63        Key::ArrowLeft => egui::Key::ArrowLeft,
64        Key::ArrowRight => egui::Key::ArrowRight,
65        Key::ArrowUp => egui::Key::ArrowUp,
66        Key::End => egui::Key::End,
67        Key::Home => egui::Key::Home,
68        Key::PageDown => egui::Key::PageDown,
69        Key::PageUp => egui::Key::PageUp,
70        Key::Backspace => egui::Key::Backspace,
71        Key::Delete => egui::Key::Delete,
72        Key::Insert => egui::Key::Insert,
73        Key::Escape => egui::Key::Escape,
74        Key::F1 => egui::Key::F1,
75        Key::F2 => egui::Key::F2,
76        Key::F3 => egui::Key::F3,
77        Key::F4 => egui::Key::F4,
78        Key::F5 => egui::Key::F5,
79        Key::F6 => egui::Key::F6,
80        Key::F7 => egui::Key::F7,
81        Key::F8 => egui::Key::F8,
82        Key::F9 => egui::Key::F9,
83        Key::F10 => egui::Key::F10,
84        Key::F11 => egui::Key::F11,
85        Key::F12 => egui::Key::F12,
86        Key::F13 => egui::Key::F13,
87        Key::F14 => egui::Key::F14,
88        Key::F15 => egui::Key::F15,
89        Key::F16 => egui::Key::F16,
90        Key::F17 => egui::Key::F17,
91        Key::F18 => egui::Key::F18,
92        Key::F19 => egui::Key::F19,
93        Key::F20 => egui::Key::F20,
94
95        _ => return None,
96    };
97    Some(key)
98}
99
100/// Matches the implementation of <https://github.com/emilk/egui/blob/68b3ef7f6badfe893d3bbb1f791b481069d807d9/crates/egui-winit/src/lib.rs#L1080>.
101#[inline(always)]
102pub fn bevy_to_egui_physical_key(key: &KeyCode) -> Option<egui::Key> {
103    let key = match key {
104        KeyCode::ArrowDown => egui::Key::ArrowDown,
105        KeyCode::ArrowLeft => egui::Key::ArrowLeft,
106        KeyCode::ArrowRight => egui::Key::ArrowRight,
107        KeyCode::ArrowUp => egui::Key::ArrowUp,
108
109        KeyCode::Escape => egui::Key::Escape,
110        KeyCode::Tab => egui::Key::Tab,
111        KeyCode::Backspace => egui::Key::Backspace,
112        KeyCode::Enter | KeyCode::NumpadEnter => egui::Key::Enter,
113
114        KeyCode::Insert => egui::Key::Insert,
115        KeyCode::Delete => egui::Key::Delete,
116        KeyCode::Home => egui::Key::Home,
117        KeyCode::End => egui::Key::End,
118        KeyCode::PageUp => egui::Key::PageUp,
119        KeyCode::PageDown => egui::Key::PageDown,
120
121        // Punctuation
122        KeyCode::Space => egui::Key::Space,
123        KeyCode::Comma => egui::Key::Comma,
124        KeyCode::Period => egui::Key::Period,
125        // KeyCode::Colon => egui::Key::Colon, // NOTE: there is no physical colon key on an american keyboard
126        KeyCode::Semicolon => egui::Key::Semicolon,
127        KeyCode::Backslash => egui::Key::Backslash,
128        KeyCode::Slash | KeyCode::NumpadDivide => egui::Key::Slash,
129        KeyCode::BracketLeft => egui::Key::OpenBracket,
130        KeyCode::BracketRight => egui::Key::CloseBracket,
131        KeyCode::Backquote => egui::Key::Backtick,
132
133        KeyCode::Cut => egui::Key::Cut,
134        KeyCode::Copy => egui::Key::Copy,
135        KeyCode::Paste => egui::Key::Paste,
136        KeyCode::Minus | KeyCode::NumpadSubtract => egui::Key::Minus,
137        KeyCode::NumpadAdd => egui::Key::Plus,
138        KeyCode::Equal => egui::Key::Equals,
139
140        KeyCode::Digit0 | KeyCode::Numpad0 => egui::Key::Num0,
141        KeyCode::Digit1 | KeyCode::Numpad1 => egui::Key::Num1,
142        KeyCode::Digit2 | KeyCode::Numpad2 => egui::Key::Num2,
143        KeyCode::Digit3 | KeyCode::Numpad3 => egui::Key::Num3,
144        KeyCode::Digit4 | KeyCode::Numpad4 => egui::Key::Num4,
145        KeyCode::Digit5 | KeyCode::Numpad5 => egui::Key::Num5,
146        KeyCode::Digit6 | KeyCode::Numpad6 => egui::Key::Num6,
147        KeyCode::Digit7 | KeyCode::Numpad7 => egui::Key::Num7,
148        KeyCode::Digit8 | KeyCode::Numpad8 => egui::Key::Num8,
149        KeyCode::Digit9 | KeyCode::Numpad9 => egui::Key::Num9,
150
151        KeyCode::KeyA => egui::Key::A,
152        KeyCode::KeyB => egui::Key::B,
153        KeyCode::KeyC => egui::Key::C,
154        KeyCode::KeyD => egui::Key::D,
155        KeyCode::KeyE => egui::Key::E,
156        KeyCode::KeyF => egui::Key::F,
157        KeyCode::KeyG => egui::Key::G,
158        KeyCode::KeyH => egui::Key::H,
159        KeyCode::KeyI => egui::Key::I,
160        KeyCode::KeyJ => egui::Key::J,
161        KeyCode::KeyK => egui::Key::K,
162        KeyCode::KeyL => egui::Key::L,
163        KeyCode::KeyM => egui::Key::M,
164        KeyCode::KeyN => egui::Key::N,
165        KeyCode::KeyO => egui::Key::O,
166        KeyCode::KeyP => egui::Key::P,
167        KeyCode::KeyQ => egui::Key::Q,
168        KeyCode::KeyR => egui::Key::R,
169        KeyCode::KeyS => egui::Key::S,
170        KeyCode::KeyT => egui::Key::T,
171        KeyCode::KeyU => egui::Key::U,
172        KeyCode::KeyV => egui::Key::V,
173        KeyCode::KeyW => egui::Key::W,
174        KeyCode::KeyX => egui::Key::X,
175        KeyCode::KeyY => egui::Key::Y,
176        KeyCode::KeyZ => egui::Key::Z,
177
178        KeyCode::F1 => egui::Key::F1,
179        KeyCode::F2 => egui::Key::F2,
180        KeyCode::F3 => egui::Key::F3,
181        KeyCode::F4 => egui::Key::F4,
182        KeyCode::F5 => egui::Key::F5,
183        KeyCode::F6 => egui::Key::F6,
184        KeyCode::F7 => egui::Key::F7,
185        KeyCode::F8 => egui::Key::F8,
186        KeyCode::F9 => egui::Key::F9,
187        KeyCode::F10 => egui::Key::F10,
188        KeyCode::F11 => egui::Key::F11,
189        KeyCode::F12 => egui::Key::F12,
190        KeyCode::F13 => egui::Key::F13,
191        KeyCode::F14 => egui::Key::F14,
192        KeyCode::F15 => egui::Key::F15,
193        KeyCode::F16 => egui::Key::F16,
194        KeyCode::F17 => egui::Key::F17,
195        KeyCode::F18 => egui::Key::F18,
196        KeyCode::F19 => egui::Key::F19,
197        KeyCode::F20 => egui::Key::F20,
198        _ => return None,
199    };
200    Some(key)
201}
202
203/// Converts [`bevy_math::Vec2`] into [`egui::Pos2`].
204#[inline(always)]
205pub fn vec2_into_egui_pos2(vec: bevy_math::Vec2) -> egui::Pos2 {
206    egui::Pos2::new(vec.x, vec.y)
207}
208
209/// Converts [`bevy_math::Vec2`] into [`egui::Vec2`].
210#[inline(always)]
211pub fn vec2_into_egui_vec2(vec: bevy_math::Vec2) -> egui::Vec2 {
212    egui::Vec2::new(vec.x, vec.y)
213}
214
215/// Converts [`bevy_math::Rect`] into [`egui::Rect`].
216#[inline(always)]
217pub fn rect_into_egui_rect(rect: bevy_math::Rect) -> egui::Rect {
218    egui::Rect {
219        min: vec2_into_egui_pos2(rect.min),
220        max: vec2_into_egui_pos2(rect.max),
221    }
222}
223
224/// Converts [`egui::Pos2`] into [`bevy_math::Vec2`].
225#[inline(always)]
226pub fn egui_pos2_into_vec2(pos: egui::Pos2) -> bevy_math::Vec2 {
227    bevy_math::Vec2::new(pos.x, pos.y)
228}
229
230/// Converts [`egui::Vec2`] into [`bevy_math::Vec2`].
231#[inline(always)]
232pub fn egui_vec2_into_vec2(pos: egui::Vec2) -> bevy_math::Vec2 {
233    bevy_math::Vec2::new(pos.x, pos.y)
234}
235
236/// Converts [`egui::Rect`] into [`bevy_math::Rect`].
237#[inline(always)]
238pub fn egui_rect_into_rect(rect: egui::Rect) -> bevy_math::Rect {
239    bevy_math::Rect {
240        min: egui_pos2_into_vec2(rect.min),
241        max: egui_pos2_into_vec2(rect.max),
242    }
243}
244
245pub(crate) trait QueryHelper<'w> {
246    type QueryData: bevy_ecs::query::QueryData;
247
248    fn get_some(&self, entity: Entity) -> Option<ROQueryItem<'_, Self::QueryData>>;
249
250    fn get_some_mut(&mut self, entity: Entity) -> Option<QueryItem<'_, Self::QueryData>>;
251}
252
253impl<'w, D: QueryData, F: QueryFilter> QueryHelper<'w> for Query<'w, '_, D, F> {
254    type QueryData = D;
255
256    fn get_some(&self, entity: Entity) -> Option<ROQueryItem<'_, Self::QueryData>> {
257        match self.get(entity) {
258            Ok(item) => Some(item),
259            Err(QueryEntityError::EntityDoesNotExist(_)) => None,
260            err => {
261                err.unwrap();
262                unreachable!()
263            }
264        }
265    }
266
267    fn get_some_mut(&mut self, entity: Entity) -> Option<QueryItem<'_, Self::QueryData>> {
268        match self.get_mut(entity) {
269            Ok(item) => Some(item),
270            Err(QueryEntityError::EntityDoesNotExist(_)) => None,
271            err => {
272                err.unwrap();
273                unreachable!()
274            }
275        }
276    }
277}