Browse Source

Refactor viewport ids in eframe (#3607)

Simplifies some things
pull/3610/head
Emil Ernerfeldt 12 months ago
committed by GitHub
parent
commit
ea53246c60
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      crates/eframe/src/native/epi_integration.rs
  2. 9
      crates/eframe/src/native/glow_integration.rs
  3. 14
      crates/eframe/src/native/wgpu_integration.rs
  4. 15
      crates/egui-winit/src/lib.rs
  5. 9
      crates/egui/src/context.rs
  6. 27
      crates/egui/src/data/input.rs
  7. 3
      crates/egui/src/input_state.rs
  8. 2
      crates/egui/src/memory.rs
  9. 15
      crates/egui_glow/src/winit.rs

10
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:

9
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);
}

14
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);
}

15
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<egui::Pos2>,
@ -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<f32>,
max_texture_side: Option<usize>,
@ -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);

9
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();

27
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<ViewportInfo>,
@ -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:?}"));

3
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)]

2
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()

15
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;

Loading…
Cancel
Save