From ea53246c60ac234a11bc10781ddda5fbd268bed2 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 22 Nov 2023 13:50:43 +0100 Subject: [PATCH] Refactor viewport ids in eframe (#3607) Simplifies some things --- crates/eframe/src/native/epi_integration.rs | 10 -------- crates/eframe/src/native/glow_integration.rs | 9 ++++--- crates/eframe/src/native/wgpu_integration.rs | 14 +++++----- crates/egui-winit/src/lib.rs | 15 ++++++----- crates/egui/src/context.rs | 9 +++++-- crates/egui/src/data/input.rs | 27 +++++++++++--------- crates/egui/src/input_state.rs | 3 ++- crates/egui/src/memory.rs | 2 +- crates/egui_glow/src/winit.rs | 15 ++++------- 9 files changed, 49 insertions(+), 55 deletions(-) diff --git a/crates/eframe/src/native/epi_integration.rs b/crates/eframe/src/native/epi_integration.rs index 082c82b6..5cd245f8 100644 --- a/crates/eframe/src/native/epi_integration.rs +++ b/crates/eframe/src/native/epi_integration.rs @@ -309,16 +309,6 @@ impl EpiIntegration { } } - pub fn handle_platform_output( - &mut self, - window: &winit::window::Window, - viewport_id: ViewportId, - platform_output: egui::PlatformOutput, - egui_winit: &mut egui_winit::State, - ) { - egui_winit.handle_platform_output(window, viewport_id, &self.egui_ctx, platform_output); - } - // ------------------------------------------------------------------------ // Persistence stuff: diff --git a/crates/eframe/src/native/glow_integration.rs b/crates/eframe/src/native/glow_integration.rs index f4b0d547..37146b70 100644 --- a/crates/eframe/src/native/glow_integration.rs +++ b/crates/eframe/src/native/glow_integration.rs @@ -506,7 +506,7 @@ impl GlowWinitRunning { let window = viewport.window.as_ref().unwrap(); let egui_winit = viewport.egui_winit.as_mut().unwrap(); - let mut raw_input = egui_winit.take_egui_input(window, viewport.ids); + let mut raw_input = egui_winit.take_egui_input(window); let viewport_ui_cb = viewport.viewport_ui_cb.clone(); self.integration.pre_update(); @@ -562,7 +562,7 @@ impl GlowWinitRunning { let egui_winit = viewport.egui_winit.as_mut().unwrap(); integration.post_update(); - integration.handle_platform_output(window, viewport_id, platform_output, egui_winit); + egui_winit.handle_platform_output(window, &integration.egui_ctx, platform_output); let clipped_primitives = integration.egui_ctx.tessellate(shapes, pixels_per_point); @@ -1018,6 +1018,7 @@ impl GlutinWindowContext { viewport.egui_winit.get_or_insert_with(|| { egui_winit::State::new( + viewport_id, event_loop, Some(window.scale_factor() as f32), self.max_texture_side, @@ -1276,7 +1277,7 @@ fn render_immediate_viewport( return; }; - let mut raw_input = winit_state.take_egui_input(window, ids); + let mut raw_input = winit_state.take_egui_input(window); raw_input.viewports = glutin .viewports .iter() @@ -1360,7 +1361,7 @@ fn render_immediate_viewport( } } - winit_state.handle_platform_output(window, ids.this, egui_ctx, platform_output); + winit_state.handle_platform_output(window, egui_ctx, platform_output); glutin.handle_viewport_output(viewport_output); } diff --git a/crates/eframe/src/native/wgpu_integration.rs b/crates/eframe/src/native/wgpu_integration.rs index acded18d..02010a46 100644 --- a/crates/eframe/src/native/wgpu_integration.rs +++ b/crates/eframe/src/native/wgpu_integration.rs @@ -196,6 +196,7 @@ impl WgpuWinitApp { } let mut egui_winit = egui_winit::State::new( + ViewportId::ROOT, event_loop, Some(window.scale_factor() as f32), painter.max_texture_side(), @@ -504,7 +505,6 @@ impl WgpuWinitRunning { viewport.update_viewport_info(); let Viewport { - ids, viewport_ui_cb, window, egui_winit, @@ -525,10 +525,7 @@ impl WgpuWinitRunning { } } - let mut raw_input = egui_winit.as_mut().unwrap().take_egui_input( - window, - ViewportIdPair::from_self_and_parent(viewport_id, ids.parent), - ); + let mut raw_input = egui_winit.as_mut().unwrap().take_egui_input(window); integration.pre_update(); @@ -581,7 +578,7 @@ impl WgpuWinitRunning { viewport_output, } = full_output; - integration.handle_platform_output(window, viewport_id, platform_output, egui_winit); + egui_winit.handle_platform_output(window, &integration.egui_ctx, platform_output); { let clipped_primitives = integration.egui_ctx.tessellate(shapes, pixels_per_point); @@ -778,6 +775,7 @@ impl Viewport { } self.egui_winit = Some(egui_winit::State::new( + viewport_id, event_loop, Some(window.scale_factor() as f32), painter.max_texture_side(), @@ -866,7 +864,7 @@ fn render_immediate_viewport( return; }; - let mut input = winit_state.take_egui_input(window, ids); + let mut input = winit_state.take_egui_input(window); input.viewports = viewports .iter() .map(|(id, viewport)| (*id, viewport.info.clone())) @@ -926,7 +924,7 @@ fn render_immediate_viewport( false, ); - winit_state.handle_platform_output(window, ids.this, egui_ctx, platform_output); + winit_state.handle_platform_output(window, egui_ctx, platform_output); handle_viewport_output(viewport_output, viewports, *focused_viewport); } diff --git a/crates/egui-winit/src/lib.rs b/crates/egui-winit/src/lib.rs index 40f20f61..7c9b4d2e 100644 --- a/crates/egui-winit/src/lib.rs +++ b/crates/egui-winit/src/lib.rs @@ -14,9 +14,7 @@ pub use accesskit_winit; pub use egui; #[cfg(feature = "accesskit")] use egui::accesskit; -use egui::{ - Pos2, Rect, Vec2, ViewportBuilder, ViewportCommand, ViewportId, ViewportIdPair, ViewportInfo, -}; +use egui::{Pos2, Rect, Vec2, ViewportBuilder, ViewportCommand, ViewportId, ViewportInfo}; pub use winit; pub mod clipboard; @@ -59,6 +57,7 @@ pub struct EventResponse { /// /// Instantiate one of these per viewport/window. pub struct State { + viewport_id: ViewportId, start_time: web_time::Instant, egui_input: egui::RawInput, pointer_pos_in_points: Option, @@ -93,6 +92,7 @@ pub struct State { impl State { /// Construct a new instance pub fn new( + viewport_id: ViewportId, display_target: &dyn HasRawDisplayHandle, native_pixels_per_point: Option, max_texture_side: Option, @@ -105,6 +105,7 @@ impl State { }; let mut slf = Self { + viewport_id, start_time: web_time::Instant::now(), egui_input, pointer_pos_in_points: None, @@ -202,7 +203,7 @@ impl State { /// You need to set [`egui::RawInput::viewports`] yourself though. /// Use [`Self::update_viewport_info`] to update the info for each /// viewport. - pub fn take_egui_input(&mut self, window: &Window, ids: ViewportIdPair) -> egui::RawInput { + pub fn take_egui_input(&mut self, window: &Window) -> egui::RawInput { crate::profile_function!(); let pixels_per_point = self.pixels_per_point(); @@ -226,7 +227,7 @@ impl State { .then(|| Rect::from_min_size(Pos2::ZERO, screen_size_in_points)); // Tell egui which viewport is now active: - self.egui_input.viewport_ids = ids; + self.egui_input.viewport_id = self.viewport_id; self.egui_input.native_pixels_per_point = Some(native_pixels_per_point(window)); self.egui_input.take() } @@ -692,7 +693,6 @@ impl State { pub fn handle_platform_output( &mut self, window: &Window, - viewport_id: ViewportId, egui_ctx: &egui::Context, platform_output: egui::PlatformOutput, ) { @@ -709,7 +709,8 @@ impl State { accesskit_update, } = platform_output; - self.current_pixels_per_point = egui_ctx.input_for(viewport_id, |i| i.pixels_per_point); // someone can have changed it to scale the UI + self.current_pixels_per_point = + egui_ctx.input_for(self.viewport_id, |i| i.pixels_per_point); // someone can have changed it to scale the UI self.set_cursor_icon(window, cursor_icon); diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index a7702af4..8decb71a 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -227,8 +227,13 @@ struct ContextImpl { impl ContextImpl { fn begin_frame_mut(&mut self, mut new_raw_input: RawInput) { - let ids = new_raw_input.viewport_ids; - let viewport_id = ids.this; + let viewport_id = new_raw_input.viewport_id; + let parent_id = new_raw_input + .viewports + .get(&viewport_id) + .and_then(|v| v.parent) + .unwrap_or_default(); + let ids = ViewportIdPair::from_self_and_parent(viewport_id, parent_id); self.viewport_stack.push(ids); let viewport = self.viewports.entry(viewport_id).or_default(); diff --git a/crates/egui/src/data/input.rs b/crates/egui/src/data/input.rs index 61a50c11..53a3d976 100644 --- a/crates/egui/src/data/input.rs +++ b/crates/egui/src/data/input.rs @@ -2,7 +2,7 @@ use epaint::ColorImage; -use crate::{emath::*, ViewportIdMap, ViewportIdPair}; +use crate::{emath::*, ViewportId, ViewportIdMap}; /// What the integrations provides to egui at the start of each frame. /// @@ -15,8 +15,8 @@ use crate::{emath::*, ViewportIdMap, ViewportIdPair}; #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct RawInput { - /// The id of the active viewport, and out parent. - pub viewport_ids: ViewportIdPair, + /// The id of the active viewport. + pub viewport_id: ViewportId, /// Information about all egui viewports. pub viewports: ViewportIdMap, @@ -89,7 +89,7 @@ pub struct RawInput { impl Default for RawInput { fn default() -> Self { Self { - viewport_ids: Default::default(), + viewport_id: Default::default(), viewports: Default::default(), screen_rect: None, pixels_per_point: None, @@ -107,13 +107,19 @@ impl Default for RawInput { } impl RawInput { + /// Info about the active viewport + #[inline] + pub fn viewport(&self) -> &ViewportInfo { + self.viewports.get(&self.viewport_id).expect("Failed to find current viewport in egui RawInput. This is the fault of the egui backend") + } + /// Helper: move volatile (deltas and events), clone the rest. /// /// * [`Self::hovered_files`] is cloned. /// * [`Self::dropped_files`] is moved. pub fn take(&mut self) -> RawInput { RawInput { - viewport_ids: self.viewport_ids, + viewport_id: self.viewport_id, viewports: self.viewports.clone(), screen_rect: self.screen_rect.take(), pixels_per_point: self.pixels_per_point.take(), // take the diff @@ -132,7 +138,7 @@ impl RawInput { /// Add on new input. pub fn append(&mut self, newer: Self) { let Self { - viewport_ids, + viewport_id: viewport_ids, viewports, screen_rect, pixels_per_point, @@ -147,7 +153,7 @@ impl RawInput { focused, } = newer; - self.viewport_ids = viewport_ids; + self.viewport_id = viewport_ids; self.viewports = viewports; self.screen_rect = screen_rect.or(self.screen_rect); self.pixels_per_point = pixels_per_point.or(self.pixels_per_point); @@ -1106,7 +1112,7 @@ fn format_kb_shortcut() { impl RawInput { pub fn ui(&self, ui: &mut crate::Ui) { let Self { - viewport_ids, + viewport_id, viewports, screen_rect, pixels_per_point, @@ -1121,10 +1127,7 @@ impl RawInput { focused, } = self; - ui.label(format!( - "Active viwport: {:?}, parent: {:?}", - viewport_ids.this, viewport_ids.parent, - )); + ui.label(format!("Active viwport: {viewport_id:?}")); for (id, viewport) in viewports { ui.group(|ui| { ui.label(format!("Viewport {id:?}")); diff --git a/crates/egui/src/input_state.rs b/crates/egui/src/input_state.rs index 79aff9a9..f59c3501 100644 --- a/crates/egui/src/input_state.rs +++ b/crates/egui/src/input_state.rs @@ -232,8 +232,9 @@ impl InputState { } /// Info about the active viewport + #[inline] pub fn viewport(&self) -> &ViewportInfo { - self.raw.viewports.get(&self.raw.viewport_ids.this).expect("Failed to find current viewport in egui RawInput. This is the fault of the egui backend") + self.raw.viewport() } #[inline(always)] diff --git a/crates/egui/src/memory.rs b/crates/egui/src/memory.rs index 973147bd..92664273 100644 --- a/crates/egui/src/memory.rs +++ b/crates/egui/src/memory.rs @@ -559,7 +559,7 @@ impl Memory { self.window_interactions .retain(|id, _| viewports.contains(id)); - self.viewport_id = new_input.viewport_ids.this; + self.viewport_id = new_input.viewport_id; self.interactions .entry(self.viewport_id) .or_default() diff --git a/crates/egui_glow/src/winit.rs b/crates/egui_glow/src/winit.rs index 1b4ebf46..884b66eb 100644 --- a/crates/egui_glow/src/winit.rs +++ b/crates/egui_glow/src/winit.rs @@ -1,7 +1,7 @@ pub use egui_winit; pub use egui_winit::EventResponse; -use egui::{ViewportId, ViewportIdPair, ViewportOutput}; +use egui::{ViewportId, ViewportOutput}; use egui_winit::winit; use crate::shader_version::ShaderVersion; @@ -35,6 +35,7 @@ impl EguiGlow { .unwrap(); let egui_winit = egui_winit::State::new( + ViewportId::ROOT, event_loop, native_pixels_per_point, Some(painter.max_texture_side()), @@ -58,9 +59,7 @@ impl EguiGlow { /// Call [`Self::paint`] later to paint. pub fn run(&mut self, window: &winit::window::Window, run_ui: impl FnMut(&egui::Context)) { - let raw_input = self - .egui_winit - .take_egui_input(window, ViewportIdPair::ROOT); + let raw_input = self.egui_winit.take_egui_input(window); let egui::FullOutput { platform_output, @@ -87,12 +86,8 @@ impl EguiGlow { } } - self.egui_winit.handle_platform_output( - window, - ViewportId::ROOT, - &self.egui_ctx, - platform_output, - ); + self.egui_winit + .handle_platform_output(window, &self.egui_ctx, platform_output); self.shapes = shapes; self.pixels_per_point = pixels_per_point;