mirror of
https://github.com/emilk/egui.git
synced 2026-07-19 13:08:54 +00:00
a5076d4cc4
* egui-winit: don't assume window available at init On Android in particular we can only initialize render state once we have a native window, after a 'Resumed' lifecycle event. It's still practical to be able to initialize an egui_winit::State early on so this adds setters for the max_texture_side and pixels_per_point that can be called once we have a valid Window and have initialized a graphics context. On Wayland, where we need to access the Display for clipboard handling we now get the Display from the event loop instead of a window. * egui-wgpu: lazily initialize render + surface state Enable the renderer and surface state initialization to be deferred until we know that any winit window we created has a valid native window and enable the surface state to be updated in case the native window changes. In particular these changes help with running on Android where winit windows will only have a valid native window associated with them between Resumed and Paused lifecycle events, and so surface creation (and render state initialization) needs to wait until the first Resumed event, and the surface needs to be dropped/recreated based on Paused/Resumed events.
96 lines
3.3 KiB
Rust
96 lines
3.3 KiB
Rust
//! [`egui`] bindings for [`glium`](https://github.com/glium/glium).
|
|
//!
|
|
//! The main type you want to use is [`EguiGlium`].
|
|
//!
|
|
//! If you are writing an app, you may want to look at [`eframe`](https://docs.rs/eframe) instead.
|
|
|
|
#![allow(clippy::float_cmp)]
|
|
#![allow(clippy::manual_range_contains)]
|
|
|
|
mod painter;
|
|
pub use painter::Painter;
|
|
|
|
pub use egui_winit;
|
|
use egui_winit::winit::event_loop::EventLoopWindowTarget;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
/// Convenience wrapper for using [`egui`] from a [`glium`] app.
|
|
pub struct EguiGlium {
|
|
pub egui_ctx: egui::Context,
|
|
pub egui_winit: egui_winit::State,
|
|
pub painter: crate::Painter,
|
|
|
|
shapes: Vec<egui::epaint::ClippedShape>,
|
|
textures_delta: egui::TexturesDelta,
|
|
}
|
|
|
|
impl EguiGlium {
|
|
pub fn new<E>(display: &glium::Display, event_loop: &EventLoopWindowTarget<E>) -> Self {
|
|
let painter = crate::Painter::new(display);
|
|
|
|
let mut egui_winit = egui_winit::State::new(event_loop);
|
|
egui_winit.set_max_texture_side(painter.max_texture_side());
|
|
let pixels_per_point = display.gl_window().window().scale_factor() as f32;
|
|
egui_winit.set_pixels_per_point(pixels_per_point);
|
|
|
|
Self {
|
|
egui_ctx: Default::default(),
|
|
egui_winit,
|
|
painter,
|
|
shapes: Default::default(),
|
|
textures_delta: Default::default(),
|
|
}
|
|
}
|
|
|
|
/// Returns `true` if egui wants exclusive use of this event
|
|
/// (e.g. a mouse click on an egui window, or entering text into a text field).
|
|
/// For instance, if you use egui for a game, you want to first call this
|
|
/// and only when this returns `false` pass on the events to your game.
|
|
///
|
|
/// Note that egui uses `tab` to move focus between elements, so this will always return `true` for tabs.
|
|
pub fn on_event(&mut self, event: &glium::glutin::event::WindowEvent<'_>) -> bool {
|
|
self.egui_winit.on_event(&self.egui_ctx, event)
|
|
}
|
|
|
|
/// Returns `true` if egui requests a repaint.
|
|
///
|
|
/// Call [`Self::paint`] later to paint.
|
|
pub fn run(&mut self, display: &glium::Display, run_ui: impl FnMut(&egui::Context)) -> bool {
|
|
let raw_input = self
|
|
.egui_winit
|
|
.take_egui_input(display.gl_window().window());
|
|
let egui::FullOutput {
|
|
platform_output,
|
|
needs_repaint,
|
|
textures_delta,
|
|
shapes,
|
|
} = self.egui_ctx.run(raw_input, run_ui);
|
|
|
|
self.egui_winit.handle_platform_output(
|
|
display.gl_window().window(),
|
|
&self.egui_ctx,
|
|
platform_output,
|
|
);
|
|
|
|
self.shapes = shapes;
|
|
self.textures_delta.append(textures_delta);
|
|
|
|
needs_repaint
|
|
}
|
|
|
|
/// Paint the results of the last call to [`Self::run`].
|
|
pub fn paint<T: glium::Surface>(&mut self, display: &glium::Display, target: &mut T) {
|
|
let shapes = std::mem::take(&mut self.shapes);
|
|
let textures_delta = std::mem::take(&mut self.textures_delta);
|
|
let clipped_primitives = self.egui_ctx.tessellate(shapes);
|
|
self.painter.paint_and_update_textures(
|
|
display,
|
|
target,
|
|
self.egui_ctx.pixels_per_point(),
|
|
&clipped_primitives,
|
|
&textures_delta,
|
|
);
|
|
}
|
|
}
|