2021-01-02 10:59:20 +00:00
|
|
|
//! [`egui`] bindings for [`glium`](https://github.com/glium/glium).
|
|
|
|
//!
|
2021-04-25 15:02:27 +00:00
|
|
|
//! The main type you want to use is [`EguiGlium`].
|
2021-01-02 10:59:20 +00:00
|
|
|
//!
|
2021-04-25 15:02:27 +00:00
|
|
|
//! This library is an [`epi`] backend.
|
2021-01-02 10:59:20 +00:00
|
|
|
//! If you are writing an app, you may want to look at [`eframe`](https://docs.rs/eframe) instead.
|
|
|
|
|
2021-06-23 07:16:39 +00:00
|
|
|
// Forbid warnings in release builds:
|
|
|
|
#![cfg_attr(not(debug_assertions), deny(warnings))]
|
2021-04-15 08:35:15 +00:00
|
|
|
#![forbid(unsafe_code)]
|
2021-09-28 15:33:28 +00:00
|
|
|
#![warn(
|
|
|
|
clippy::all,
|
|
|
|
clippy::await_holding_lock,
|
|
|
|
clippy::char_lit_as_u8,
|
|
|
|
clippy::checked_conversions,
|
|
|
|
clippy::dbg_macro,
|
|
|
|
clippy::debug_assert_with_mut_call,
|
2021-10-20 14:30:39 +00:00
|
|
|
clippy::disallowed_method,
|
2021-09-28 15:33:28 +00:00
|
|
|
clippy::doc_markdown,
|
|
|
|
clippy::empty_enum,
|
|
|
|
clippy::enum_glob_use,
|
|
|
|
clippy::exit,
|
|
|
|
clippy::expl_impl_clone_on_copy,
|
|
|
|
clippy::explicit_deref_methods,
|
|
|
|
clippy::explicit_into_iter_loop,
|
|
|
|
clippy::fallible_impl_from,
|
|
|
|
clippy::filter_map_next,
|
2021-10-20 14:30:39 +00:00
|
|
|
clippy::flat_map_option,
|
2021-09-28 15:33:28 +00:00
|
|
|
clippy::float_cmp_const,
|
|
|
|
clippy::fn_params_excessive_bools,
|
2021-10-20 14:30:39 +00:00
|
|
|
clippy::from_iter_instead_of_collect,
|
2021-09-28 15:33:28 +00:00
|
|
|
clippy::if_let_mutex,
|
2021-10-20 14:30:39 +00:00
|
|
|
clippy::implicit_clone,
|
2021-09-28 15:33:28 +00:00
|
|
|
clippy::imprecise_flops,
|
|
|
|
clippy::inefficient_to_string,
|
|
|
|
clippy::invalid_upcast_comparisons,
|
2021-10-20 14:30:39 +00:00
|
|
|
clippy::large_digit_groups,
|
|
|
|
clippy::large_stack_arrays,
|
2021-09-28 15:33:28 +00:00
|
|
|
clippy::large_types_passed_by_value,
|
|
|
|
clippy::let_unit_value,
|
|
|
|
clippy::linkedlist,
|
|
|
|
clippy::lossy_float_literal,
|
|
|
|
clippy::macro_use_imports,
|
|
|
|
clippy::manual_ok_or,
|
|
|
|
clippy::map_err_ignore,
|
|
|
|
clippy::map_flatten,
|
2021-10-20 14:30:39 +00:00
|
|
|
clippy::map_unwrap_or,
|
2021-09-28 15:33:28 +00:00
|
|
|
clippy::match_on_vec_items,
|
|
|
|
clippy::match_same_arms,
|
2021-10-20 14:30:39 +00:00
|
|
|
clippy::match_wild_err_arm,
|
2021-09-28 15:33:28 +00:00
|
|
|
clippy::match_wildcard_for_single_variants,
|
|
|
|
clippy::mem_forget,
|
|
|
|
clippy::mismatched_target_os,
|
|
|
|
clippy::missing_errors_doc,
|
|
|
|
clippy::missing_safety_doc,
|
|
|
|
clippy::mut_mut,
|
|
|
|
clippy::mutex_integer,
|
|
|
|
clippy::needless_borrow,
|
|
|
|
clippy::needless_continue,
|
2021-10-20 14:30:39 +00:00
|
|
|
clippy::needless_for_each,
|
2021-09-28 15:33:28 +00:00
|
|
|
clippy::needless_pass_by_value,
|
|
|
|
clippy::option_option,
|
|
|
|
clippy::path_buf_push_overwrite,
|
|
|
|
clippy::ptr_as_ptr,
|
|
|
|
clippy::ref_option_ref,
|
|
|
|
clippy::rest_pat_in_fully_bound_structs,
|
|
|
|
clippy::same_functions_in_if_condition,
|
2021-10-20 14:30:39 +00:00
|
|
|
clippy::semicolon_if_nothing_returned,
|
|
|
|
clippy::single_match_else,
|
2021-09-28 15:33:28 +00:00
|
|
|
clippy::string_add_assign,
|
|
|
|
clippy::string_add,
|
|
|
|
clippy::string_lit_as_bytes,
|
|
|
|
clippy::string_to_string,
|
|
|
|
clippy::todo,
|
|
|
|
clippy::trait_duplication_in_bounds,
|
|
|
|
clippy::unimplemented,
|
|
|
|
clippy::unnested_or_patterns,
|
|
|
|
clippy::unused_self,
|
|
|
|
clippy::useless_transmute,
|
|
|
|
clippy::verbose_file_reads,
|
|
|
|
clippy::zero_sized_map_values,
|
|
|
|
future_incompatible,
|
|
|
|
missing_crate_level_docs,
|
|
|
|
nonstandard_style,
|
|
|
|
rust_2018_idioms
|
|
|
|
)]
|
|
|
|
#![allow(clippy::float_cmp)]
|
|
|
|
#![allow(clippy::manual_range_contains)]
|
2020-07-22 16:01:27 +00:00
|
|
|
|
2019-04-21 08:13:05 +00:00
|
|
|
mod painter;
|
|
|
|
pub use painter::Painter;
|
2020-04-29 19:58:14 +00:00
|
|
|
|
2021-10-19 19:40:55 +00:00
|
|
|
#[cfg(feature = "epi")]
|
|
|
|
mod epi_backend;
|
|
|
|
#[cfg(feature = "epi")]
|
|
|
|
pub use epi_backend::{run, NativeOptions};
|
|
|
|
|
2021-09-28 15:33:28 +00:00
|
|
|
pub use egui_winit;
|
2021-05-08 08:14:56 +00:00
|
|
|
|
2021-09-28 15:33:28 +00:00
|
|
|
use glium::glutin;
|
2020-07-22 10:10:14 +00:00
|
|
|
|
2020-05-02 09:37:12 +00:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
2021-04-25 15:02:27 +00:00
|
|
|
/// Use [`egui`] from a [`glium`] app.
|
|
|
|
pub struct EguiGlium {
|
|
|
|
egui_ctx: egui::CtxRef,
|
2021-09-28 15:33:28 +00:00
|
|
|
egui_winit: egui_winit::State,
|
2021-04-25 15:02:27 +00:00
|
|
|
painter: crate::Painter,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl EguiGlium {
|
|
|
|
pub fn new(display: &glium::Display) -> Self {
|
|
|
|
Self {
|
|
|
|
egui_ctx: Default::default(),
|
2021-09-28 15:33:28 +00:00
|
|
|
egui_winit: egui_winit::State::new(display.gl_window().window()),
|
2021-04-25 15:02:27 +00:00
|
|
|
painter: crate::Painter::new(display),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn ctx(&self) -> &egui::CtxRef {
|
|
|
|
&self.egui_ctx
|
|
|
|
}
|
|
|
|
|
2021-11-01 20:30:10 +00:00
|
|
|
/// useful for calling e.g. [`crate::Painter::alloc_user_texture`].
|
2021-09-20 19:36:56 +00:00
|
|
|
pub fn painter_mut(&mut self) -> &mut crate::Painter {
|
|
|
|
&mut self.painter
|
|
|
|
}
|
|
|
|
|
2021-04-25 15:02:27 +00:00
|
|
|
pub fn ctx_and_painter_mut(&mut self) -> (&egui::CtxRef, &mut crate::Painter) {
|
|
|
|
(&self.egui_ctx, &mut self.painter)
|
|
|
|
}
|
|
|
|
|
2021-09-20 19:36:56 +00:00
|
|
|
pub fn pixels_per_point(&self) -> f32 {
|
2021-09-28 15:33:28 +00:00
|
|
|
self.egui_winit.pixels_per_point()
|
2021-09-20 19:36:56 +00:00
|
|
|
}
|
|
|
|
|
2021-09-28 15:33:28 +00:00
|
|
|
pub fn egui_input(&self) -> &egui::RawInput {
|
|
|
|
self.egui_winit.egui_input()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 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)
|
2021-04-25 15:02:27 +00:00
|
|
|
}
|
|
|
|
|
2021-06-24 14:24:05 +00:00
|
|
|
/// Is this a close event or a Cmd-Q/Alt-F4 keyboard command?
|
|
|
|
pub fn is_quit_event(&self, event: &glutin::event::WindowEvent<'_>) -> bool {
|
2021-09-28 15:33:28 +00:00
|
|
|
self.egui_winit.is_quit_event(event)
|
2021-06-24 14:24:05 +00:00
|
|
|
}
|
|
|
|
|
2021-04-25 15:02:27 +00:00
|
|
|
pub fn begin_frame(&mut self, display: &glium::Display) {
|
2021-09-20 19:36:56 +00:00
|
|
|
let raw_input = self.take_raw_input(display);
|
|
|
|
self.begin_frame_with_input(raw_input);
|
|
|
|
}
|
|
|
|
|
2021-09-28 15:33:28 +00:00
|
|
|
pub fn begin_frame_with_input(&mut self, raw_input: egui::RawInput) {
|
2021-09-20 19:36:56 +00:00
|
|
|
self.egui_ctx.begin_frame(raw_input);
|
|
|
|
}
|
2021-04-25 15:02:27 +00:00
|
|
|
|
2021-09-20 19:36:56 +00:00
|
|
|
/// Prepare for a new frame. Normally you would call [`Self::begin_frame`] instead.
|
|
|
|
pub fn take_raw_input(&mut self, display: &glium::Display) -> egui::RawInput {
|
2021-09-28 15:33:28 +00:00
|
|
|
self.egui_winit
|
|
|
|
.take_egui_input(display.gl_window().window())
|
2021-04-25 15:02:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns `needs_repaint` and shapes to draw.
|
|
|
|
pub fn end_frame(
|
|
|
|
&mut self,
|
|
|
|
display: &glium::Display,
|
|
|
|
) -> (bool, Vec<egui::epaint::ClippedShape>) {
|
|
|
|
let (egui_output, shapes) = self.egui_ctx.end_frame();
|
2021-09-20 19:36:56 +00:00
|
|
|
let needs_repaint = egui_output.needs_repaint;
|
|
|
|
self.handle_output(display, egui_output);
|
|
|
|
(needs_repaint, shapes)
|
|
|
|
}
|
2021-04-25 15:02:27 +00:00
|
|
|
|
2021-09-28 15:33:28 +00:00
|
|
|
pub fn handle_output(&mut self, display: &glium::Display, output: egui::Output) {
|
|
|
|
self.egui_winit
|
|
|
|
.handle_output(display.gl_window().window(), &self.egui_ctx, output);
|
2021-04-25 15:02:27 +00:00
|
|
|
}
|
|
|
|
|
2021-09-02 12:44:50 +00:00
|
|
|
pub fn paint<T: glium::Surface>(
|
2021-04-25 15:02:27 +00:00
|
|
|
&mut self,
|
|
|
|
display: &glium::Display,
|
2021-09-02 12:44:50 +00:00
|
|
|
target: &mut T,
|
2021-04-25 15:02:27 +00:00
|
|
|
shapes: Vec<egui::epaint::ClippedShape>,
|
|
|
|
) {
|
|
|
|
let clipped_meshes = self.egui_ctx.tessellate(shapes);
|
|
|
|
self.painter.paint_meshes(
|
|
|
|
display,
|
|
|
|
target,
|
|
|
|
self.egui_ctx.pixels_per_point(),
|
|
|
|
clipped_meshes,
|
|
|
|
&self.egui_ctx.texture(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|