Refactor viewport ids in eframe (#3607)

Simplifies some things
This commit is contained in:
Emil Ernerfeldt 2023-11-22 13:50:43 +01:00 committed by GitHub
parent e037489ac2
commit ea53246c60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 49 additions and 55 deletions

View File

@ -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: // Persistence stuff:

View File

@ -506,7 +506,7 @@ impl GlowWinitRunning {
let window = viewport.window.as_ref().unwrap(); let window = viewport.window.as_ref().unwrap();
let egui_winit = viewport.egui_winit.as_mut().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(); let viewport_ui_cb = viewport.viewport_ui_cb.clone();
self.integration.pre_update(); self.integration.pre_update();
@ -562,7 +562,7 @@ impl GlowWinitRunning {
let egui_winit = viewport.egui_winit.as_mut().unwrap(); let egui_winit = viewport.egui_winit.as_mut().unwrap();
integration.post_update(); 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); let clipped_primitives = integration.egui_ctx.tessellate(shapes, pixels_per_point);
@ -1018,6 +1018,7 @@ impl GlutinWindowContext {
viewport.egui_winit.get_or_insert_with(|| { viewport.egui_winit.get_or_insert_with(|| {
egui_winit::State::new( egui_winit::State::new(
viewport_id,
event_loop, event_loop,
Some(window.scale_factor() as f32), Some(window.scale_factor() as f32),
self.max_texture_side, self.max_texture_side,
@ -1276,7 +1277,7 @@ fn render_immediate_viewport(
return; 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 raw_input.viewports = glutin
.viewports .viewports
.iter() .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); glutin.handle_viewport_output(viewport_output);
} }

View File

@ -196,6 +196,7 @@ impl WgpuWinitApp {
} }
let mut egui_winit = egui_winit::State::new( let mut egui_winit = egui_winit::State::new(
ViewportId::ROOT,
event_loop, event_loop,
Some(window.scale_factor() as f32), Some(window.scale_factor() as f32),
painter.max_texture_side(), painter.max_texture_side(),
@ -504,7 +505,6 @@ impl WgpuWinitRunning {
viewport.update_viewport_info(); viewport.update_viewport_info();
let Viewport { let Viewport {
ids,
viewport_ui_cb, viewport_ui_cb,
window, window,
egui_winit, egui_winit,
@ -525,10 +525,7 @@ impl WgpuWinitRunning {
} }
} }
let mut raw_input = egui_winit.as_mut().unwrap().take_egui_input( let mut raw_input = egui_winit.as_mut().unwrap().take_egui_input(window);
window,
ViewportIdPair::from_self_and_parent(viewport_id, ids.parent),
);
integration.pre_update(); integration.pre_update();
@ -581,7 +578,7 @@ impl WgpuWinitRunning {
viewport_output, viewport_output,
} = full_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); 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( self.egui_winit = Some(egui_winit::State::new(
viewport_id,
event_loop, event_loop,
Some(window.scale_factor() as f32), Some(window.scale_factor() as f32),
painter.max_texture_side(), painter.max_texture_side(),
@ -866,7 +864,7 @@ fn render_immediate_viewport(
return; return;
}; };
let mut input = winit_state.take_egui_input(window, ids); let mut input = winit_state.take_egui_input(window);
input.viewports = viewports input.viewports = viewports
.iter() .iter()
.map(|(id, viewport)| (*id, viewport.info.clone())) .map(|(id, viewport)| (*id, viewport.info.clone()))
@ -926,7 +924,7 @@ fn render_immediate_viewport(
false, 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); handle_viewport_output(viewport_output, viewports, *focused_viewport);
} }

View File

@ -14,9 +14,7 @@ pub use accesskit_winit;
pub use egui; pub use egui;
#[cfg(feature = "accesskit")] #[cfg(feature = "accesskit")]
use egui::accesskit; use egui::accesskit;
use egui::{ use egui::{Pos2, Rect, Vec2, ViewportBuilder, ViewportCommand, ViewportId, ViewportInfo};
Pos2, Rect, Vec2, ViewportBuilder, ViewportCommand, ViewportId, ViewportIdPair, ViewportInfo,
};
pub use winit; pub use winit;
pub mod clipboard; pub mod clipboard;
@ -59,6 +57,7 @@ pub struct EventResponse {
/// ///
/// Instantiate one of these per viewport/window. /// Instantiate one of these per viewport/window.
pub struct State { pub struct State {
viewport_id: ViewportId,
start_time: web_time::Instant, start_time: web_time::Instant,
egui_input: egui::RawInput, egui_input: egui::RawInput,
pointer_pos_in_points: Option<egui::Pos2>, pointer_pos_in_points: Option<egui::Pos2>,
@ -93,6 +92,7 @@ pub struct State {
impl State { impl State {
/// Construct a new instance /// Construct a new instance
pub fn new( pub fn new(
viewport_id: ViewportId,
display_target: &dyn HasRawDisplayHandle, display_target: &dyn HasRawDisplayHandle,
native_pixels_per_point: Option<f32>, native_pixels_per_point: Option<f32>,
max_texture_side: Option<usize>, max_texture_side: Option<usize>,
@ -105,6 +105,7 @@ impl State {
}; };
let mut slf = Self { let mut slf = Self {
viewport_id,
start_time: web_time::Instant::now(), start_time: web_time::Instant::now(),
egui_input, egui_input,
pointer_pos_in_points: None, pointer_pos_in_points: None,
@ -202,7 +203,7 @@ impl State {
/// You need to set [`egui::RawInput::viewports`] yourself though. /// You need to set [`egui::RawInput::viewports`] yourself though.
/// Use [`Self::update_viewport_info`] to update the info for each /// Use [`Self::update_viewport_info`] to update the info for each
/// viewport. /// 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!(); crate::profile_function!();
let pixels_per_point = self.pixels_per_point(); 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)); .then(|| Rect::from_min_size(Pos2::ZERO, screen_size_in_points));
// Tell egui which viewport is now active: // 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.native_pixels_per_point = Some(native_pixels_per_point(window));
self.egui_input.take() self.egui_input.take()
} }
@ -692,7 +693,6 @@ impl State {
pub fn handle_platform_output( pub fn handle_platform_output(
&mut self, &mut self,
window: &Window, window: &Window,
viewport_id: ViewportId,
egui_ctx: &egui::Context, egui_ctx: &egui::Context,
platform_output: egui::PlatformOutput, platform_output: egui::PlatformOutput,
) { ) {
@ -709,7 +709,8 @@ impl State {
accesskit_update, accesskit_update,
} = platform_output; } = 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); self.set_cursor_icon(window, cursor_icon);

View File

@ -227,8 +227,13 @@ struct ContextImpl {
impl ContextImpl { impl ContextImpl {
fn begin_frame_mut(&mut self, mut new_raw_input: RawInput) { fn begin_frame_mut(&mut self, mut new_raw_input: RawInput) {
let ids = new_raw_input.viewport_ids; let viewport_id = new_raw_input.viewport_id;
let viewport_id = ids.this; 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); self.viewport_stack.push(ids);
let viewport = self.viewports.entry(viewport_id).or_default(); let viewport = self.viewports.entry(viewport_id).or_default();

View File

@ -2,7 +2,7 @@
use epaint::ColorImage; 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. /// 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)] #[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct RawInput { pub struct RawInput {
/// The id of the active viewport, and out parent. /// The id of the active viewport.
pub viewport_ids: ViewportIdPair, pub viewport_id: ViewportId,
/// Information about all egui viewports. /// Information about all egui viewports.
pub viewports: ViewportIdMap<ViewportInfo>, pub viewports: ViewportIdMap<ViewportInfo>,
@ -89,7 +89,7 @@ pub struct RawInput {
impl Default for RawInput { impl Default for RawInput {
fn default() -> Self { fn default() -> Self {
Self { Self {
viewport_ids: Default::default(), viewport_id: Default::default(),
viewports: Default::default(), viewports: Default::default(),
screen_rect: None, screen_rect: None,
pixels_per_point: None, pixels_per_point: None,
@ -107,13 +107,19 @@ impl Default for RawInput {
} }
impl 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. /// Helper: move volatile (deltas and events), clone the rest.
/// ///
/// * [`Self::hovered_files`] is cloned. /// * [`Self::hovered_files`] is cloned.
/// * [`Self::dropped_files`] is moved. /// * [`Self::dropped_files`] is moved.
pub fn take(&mut self) -> RawInput { pub fn take(&mut self) -> RawInput {
RawInput { RawInput {
viewport_ids: self.viewport_ids, viewport_id: self.viewport_id,
viewports: self.viewports.clone(), viewports: self.viewports.clone(),
screen_rect: self.screen_rect.take(), screen_rect: self.screen_rect.take(),
pixels_per_point: self.pixels_per_point.take(), // take the diff pixels_per_point: self.pixels_per_point.take(), // take the diff
@ -132,7 +138,7 @@ impl RawInput {
/// Add on new input. /// Add on new input.
pub fn append(&mut self, newer: Self) { pub fn append(&mut self, newer: Self) {
let Self { let Self {
viewport_ids, viewport_id: viewport_ids,
viewports, viewports,
screen_rect, screen_rect,
pixels_per_point, pixels_per_point,
@ -147,7 +153,7 @@ impl RawInput {
focused, focused,
} = newer; } = newer;
self.viewport_ids = viewport_ids; self.viewport_id = viewport_ids;
self.viewports = viewports; self.viewports = viewports;
self.screen_rect = screen_rect.or(self.screen_rect); self.screen_rect = screen_rect.or(self.screen_rect);
self.pixels_per_point = pixels_per_point.or(self.pixels_per_point); self.pixels_per_point = pixels_per_point.or(self.pixels_per_point);
@ -1106,7 +1112,7 @@ fn format_kb_shortcut() {
impl RawInput { impl RawInput {
pub fn ui(&self, ui: &mut crate::Ui) { pub fn ui(&self, ui: &mut crate::Ui) {
let Self { let Self {
viewport_ids, viewport_id,
viewports, viewports,
screen_rect, screen_rect,
pixels_per_point, pixels_per_point,
@ -1121,10 +1127,7 @@ impl RawInput {
focused, focused,
} = self; } = self;
ui.label(format!( ui.label(format!("Active viwport: {viewport_id:?}"));
"Active viwport: {:?}, parent: {:?}",
viewport_ids.this, viewport_ids.parent,
));
for (id, viewport) in viewports { for (id, viewport) in viewports {
ui.group(|ui| { ui.group(|ui| {
ui.label(format!("Viewport {id:?}")); ui.label(format!("Viewport {id:?}"));

View File

@ -232,8 +232,9 @@ impl InputState {
} }
/// Info about the active viewport /// Info about the active viewport
#[inline]
pub fn viewport(&self) -> &ViewportInfo { 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)] #[inline(always)]

View File

@ -559,7 +559,7 @@ impl Memory {
self.window_interactions self.window_interactions
.retain(|id, _| viewports.contains(id)); .retain(|id, _| viewports.contains(id));
self.viewport_id = new_input.viewport_ids.this; self.viewport_id = new_input.viewport_id;
self.interactions self.interactions
.entry(self.viewport_id) .entry(self.viewport_id)
.or_default() .or_default()

View File

@ -1,7 +1,7 @@
pub use egui_winit; pub use egui_winit;
pub use egui_winit::EventResponse; pub use egui_winit::EventResponse;
use egui::{ViewportId, ViewportIdPair, ViewportOutput}; use egui::{ViewportId, ViewportOutput};
use egui_winit::winit; use egui_winit::winit;
use crate::shader_version::ShaderVersion; use crate::shader_version::ShaderVersion;
@ -35,6 +35,7 @@ impl EguiGlow {
.unwrap(); .unwrap();
let egui_winit = egui_winit::State::new( let egui_winit = egui_winit::State::new(
ViewportId::ROOT,
event_loop, event_loop,
native_pixels_per_point, native_pixels_per_point,
Some(painter.max_texture_side()), Some(painter.max_texture_side()),
@ -58,9 +59,7 @@ impl EguiGlow {
/// Call [`Self::paint`] later to paint. /// Call [`Self::paint`] later to paint.
pub fn run(&mut self, window: &winit::window::Window, run_ui: impl FnMut(&egui::Context)) { pub fn run(&mut self, window: &winit::window::Window, run_ui: impl FnMut(&egui::Context)) {
let raw_input = self let raw_input = self.egui_winit.take_egui_input(window);
.egui_winit
.take_egui_input(window, ViewportIdPair::ROOT);
let egui::FullOutput { let egui::FullOutput {
platform_output, platform_output,
@ -87,12 +86,8 @@ impl EguiGlow {
} }
} }
self.egui_winit.handle_platform_output( self.egui_winit
window, .handle_platform_output(window, &self.egui_ctx, platform_output);
ViewportId::ROOT,
&self.egui_ctx,
platform_output,
);
self.shapes = shapes; self.shapes = shapes;
self.pixels_per_point = pixels_per_point; self.pixels_per_point = pixels_per_point;