Simplify `egui_winit::State` (#3678)
By storing a clone of the egui context in it, we can be sure to always use the correct `pixels_per_point`
This commit is contained in:
parent
80d7143b15
commit
a4e389431d
|
|
@ -255,8 +255,7 @@ impl EpiIntegration {
|
|||
_ => {}
|
||||
}
|
||||
|
||||
egui_winit.update_pixels_per_point(&self.egui_ctx, window);
|
||||
egui_winit.on_window_event(&self.egui_ctx, event)
|
||||
egui_winit.on_window_event(window, event)
|
||||
}
|
||||
|
||||
pub fn pre_update(&mut self) {
|
||||
|
|
|
|||
|
|
@ -517,7 +517,6 @@ impl GlowWinitRunning {
|
|||
egui_winit::update_viewport_info(&mut viewport.info, &egui_ctx, window);
|
||||
|
||||
let egui_winit = viewport.egui_winit.as_mut().unwrap();
|
||||
egui_winit.update_pixels_per_point(&egui_ctx, window);
|
||||
let mut raw_input = egui_winit.take_egui_input(window);
|
||||
let viewport_ui_cb = viewport.viewport_ui_cb.clone();
|
||||
|
||||
|
|
@ -600,7 +599,7 @@ impl GlowWinitRunning {
|
|||
let egui_winit = viewport.egui_winit.as_mut().unwrap();
|
||||
|
||||
integration.post_update();
|
||||
egui_winit.handle_platform_output(window, &integration.egui_ctx, platform_output);
|
||||
egui_winit.handle_platform_output(window, platform_output);
|
||||
|
||||
let clipped_primitives = integration.egui_ctx.tessellate(shapes, pixels_per_point);
|
||||
|
||||
|
|
@ -1066,6 +1065,7 @@ impl GlutinWindowContext {
|
|||
|
||||
viewport.egui_winit.get_or_insert_with(|| {
|
||||
egui_winit::State::new(
|
||||
self.egui_ctx.clone(),
|
||||
viewport_id,
|
||||
event_loop,
|
||||
Some(window.scale_factor() as f32),
|
||||
|
|
@ -1318,7 +1318,6 @@ fn render_immediate_viewport(
|
|||
};
|
||||
egui_winit::update_viewport_info(&mut viewport.info, egui_ctx, window);
|
||||
|
||||
egui_winit.update_pixels_per_point(egui_ctx, window);
|
||||
let mut raw_input = egui_winit.take_egui_input(window);
|
||||
raw_input.viewports = glutin
|
||||
.viewports
|
||||
|
|
@ -1414,7 +1413,7 @@ fn render_immediate_viewport(
|
|||
}
|
||||
}
|
||||
|
||||
egui_winit.handle_platform_output(window, egui_ctx, platform_output);
|
||||
egui_winit.handle_platform_output(window, platform_output);
|
||||
|
||||
glutin.handle_viewport_output(egui_ctx, viewport_output);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@ impl WgpuWinitApp {
|
|||
|
||||
#[allow(unused_mut)] // used for accesskit
|
||||
let mut egui_winit = egui_winit::State::new(
|
||||
egui_ctx.clone(),
|
||||
ViewportId::ROOT,
|
||||
event_loop,
|
||||
Some(window.scale_factor() as f32),
|
||||
|
|
@ -488,10 +489,7 @@ impl WgpuWinitRunning {
|
|||
let mut shared_lock = shared.borrow_mut();
|
||||
|
||||
let SharedState {
|
||||
egui_ctx,
|
||||
viewports,
|
||||
painter,
|
||||
..
|
||||
viewports, painter, ..
|
||||
} = &mut *shared_lock;
|
||||
|
||||
if viewport_id != ViewportId::ROOT {
|
||||
|
|
@ -539,7 +537,6 @@ impl WgpuWinitRunning {
|
|||
}
|
||||
|
||||
let egui_winit = egui_winit.as_mut().unwrap();
|
||||
egui_winit.update_pixels_per_point(egui_ctx, window);
|
||||
let mut raw_input = egui_winit.take_egui_input(window);
|
||||
|
||||
integration.pre_update();
|
||||
|
|
@ -596,7 +593,7 @@ impl WgpuWinitRunning {
|
|||
viewport_output,
|
||||
} = full_output;
|
||||
|
||||
egui_winit.handle_platform_output(window, egui_ctx, platform_output);
|
||||
egui_winit.handle_platform_output(window, platform_output);
|
||||
|
||||
{
|
||||
let clipped_primitives = egui_ctx.tessellate(shapes, pixels_per_point);
|
||||
|
|
@ -799,6 +796,7 @@ impl Viewport {
|
|||
}
|
||||
|
||||
self.egui_winit = Some(egui_winit::State::new(
|
||||
egui_ctx.clone(),
|
||||
viewport_id,
|
||||
event_loop,
|
||||
Some(window.scale_factor() as f32),
|
||||
|
|
@ -880,7 +878,6 @@ fn render_immediate_viewport(
|
|||
};
|
||||
egui_winit::update_viewport_info(&mut viewport.info, egui_ctx, window);
|
||||
|
||||
egui_winit.update_pixels_per_point(egui_ctx, window);
|
||||
let mut input = egui_winit.take_egui_input(window);
|
||||
input.viewports = viewports
|
||||
.iter()
|
||||
|
|
@ -944,7 +941,7 @@ fn render_immediate_viewport(
|
|||
false,
|
||||
);
|
||||
|
||||
egui_winit.handle_platform_output(window, &egui_ctx, platform_output);
|
||||
egui_winit.handle_platform_output(window, platform_output);
|
||||
|
||||
handle_viewport_output(&egui_ctx, viewport_output, viewports, *focused_viewport);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,9 @@ pub struct EventResponse {
|
|||
///
|
||||
/// Instantiate one of these per viewport/window.
|
||||
pub struct State {
|
||||
/// Shared clone.
|
||||
egui_ctx: egui::Context,
|
||||
|
||||
viewport_id: ViewportId,
|
||||
start_time: web_time::Instant,
|
||||
egui_input: egui::RawInput,
|
||||
|
|
@ -76,9 +79,6 @@ pub struct State {
|
|||
any_pointer_button_down: bool,
|
||||
current_cursor_icon: Option<egui::CursorIcon>,
|
||||
|
||||
/// What egui uses.
|
||||
current_pixels_per_point: f32, // TODO: remove - calculate with [`pixels_per_point`] instead
|
||||
|
||||
clipboard: clipboard::Clipboard,
|
||||
|
||||
/// If `true`, mouse inputs will be treated as touches.
|
||||
|
|
@ -104,6 +104,7 @@ pub struct State {
|
|||
impl State {
|
||||
/// Construct a new instance
|
||||
pub fn new(
|
||||
egui_ctx: egui::Context,
|
||||
viewport_id: ViewportId,
|
||||
display_target: &dyn HasRawDisplayHandle,
|
||||
native_pixels_per_point: Option<f32>,
|
||||
|
|
@ -117,13 +118,13 @@ impl State {
|
|||
};
|
||||
|
||||
let mut slf = Self {
|
||||
egui_ctx,
|
||||
viewport_id,
|
||||
start_time: web_time::Instant::now(),
|
||||
egui_input,
|
||||
pointer_pos_in_points: None,
|
||||
any_pointer_button_down: false,
|
||||
current_cursor_icon: None,
|
||||
current_pixels_per_point: native_pixels_per_point.unwrap_or(1.0),
|
||||
|
||||
clipboard: clipboard::Clipboard::new(display_target),
|
||||
|
||||
|
|
@ -172,9 +173,8 @@ impl State {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[deprecated = "Use egui_winit::pixels_per_point instead"]
|
||||
pub fn pixels_per_point(&self) -> f32 {
|
||||
self.current_pixels_per_point
|
||||
pub fn egui_ctx(&self) -> &egui::Context {
|
||||
&self.egui_ctx
|
||||
}
|
||||
|
||||
/// The current input state.
|
||||
|
|
@ -191,18 +191,12 @@ impl State {
|
|||
&mut self.egui_input
|
||||
}
|
||||
|
||||
/// Update the given viewport info with the current state of the window.
|
||||
#[deprecated = "Use egui_winit::update_viewport_info instead"]
|
||||
pub fn update_viewport_info(&self, info: &mut ViewportInfo, window: &Window) {
|
||||
update_viewport_info_impl(info, window, self.current_pixels_per_point);
|
||||
}
|
||||
|
||||
/// Prepare for a new frame by extracting the accumulated input,
|
||||
///
|
||||
/// as well as setting [the time](egui::RawInput::time) and [screen rectangle](egui::RawInput::screen_rect).
|
||||
///
|
||||
/// You need to set [`egui::RawInput::viewports`] yourself though.
|
||||
/// Use [`Self::update_viewport_info`] to update the info for each
|
||||
/// Use [`update_viewport_info`] to update the info for each
|
||||
/// viewport.
|
||||
pub fn take_egui_input(&mut self, window: &Window) -> egui::RawInput {
|
||||
crate::profile_function!();
|
||||
|
|
@ -213,7 +207,8 @@ impl State {
|
|||
// See: https://github.com/rust-windowing/winit/issues/208
|
||||
// This solves an issue where egui window positions would be changed when minimizing on Windows.
|
||||
let screen_size_in_pixels = screen_size_in_pixels(window);
|
||||
let screen_size_in_points = screen_size_in_pixels / self.current_pixels_per_point;
|
||||
let screen_size_in_points =
|
||||
screen_size_in_pixels / pixels_per_point(&self.egui_ctx, window);
|
||||
|
||||
self.egui_input.screen_rect = (screen_size_in_points.x > 0.0
|
||||
&& screen_size_in_points.y > 0.0)
|
||||
|
|
@ -231,18 +226,12 @@ impl State {
|
|||
self.egui_input.take()
|
||||
}
|
||||
|
||||
// TODO(emilk): remove asap.
|
||||
#[doc(hidden)]
|
||||
pub fn update_pixels_per_point(&mut self, egui_ctx: &egui::Context, window: &Window) {
|
||||
self.current_pixels_per_point = pixels_per_point(egui_ctx, window);
|
||||
}
|
||||
|
||||
/// Call this when there is a new event.
|
||||
///
|
||||
/// The result can be found in [`Self::egui_input`] and be extracted with [`Self::take_egui_input`].
|
||||
pub fn on_window_event(
|
||||
&mut self,
|
||||
egui_ctx: &egui::Context,
|
||||
window: &Window,
|
||||
event: &winit::event::WindowEvent<'_>,
|
||||
) -> EventResponse {
|
||||
crate::profile_function!(short_window_event_description(event));
|
||||
|
|
@ -257,7 +246,7 @@ impl State {
|
|||
.entry(self.viewport_id)
|
||||
.or_default()
|
||||
.native_pixels_per_point = Some(native_pixels_per_point);
|
||||
self.current_pixels_per_point = egui_ctx.zoom_factor() * native_pixels_per_point;
|
||||
|
||||
EventResponse {
|
||||
repaint: true,
|
||||
consumed: false,
|
||||
|
|
@ -267,21 +256,21 @@ impl State {
|
|||
self.on_mouse_button_input(*state, *button);
|
||||
EventResponse {
|
||||
repaint: true,
|
||||
consumed: egui_ctx.wants_pointer_input(),
|
||||
consumed: self.egui_ctx.wants_pointer_input(),
|
||||
}
|
||||
}
|
||||
WindowEvent::MouseWheel { delta, .. } => {
|
||||
self.on_mouse_wheel(*delta);
|
||||
self.on_mouse_wheel(window, *delta);
|
||||
EventResponse {
|
||||
repaint: true,
|
||||
consumed: egui_ctx.wants_pointer_input(),
|
||||
consumed: self.egui_ctx.wants_pointer_input(),
|
||||
}
|
||||
}
|
||||
WindowEvent::CursorMoved { position, .. } => {
|
||||
self.on_cursor_moved(*position);
|
||||
self.on_cursor_moved(window, *position);
|
||||
EventResponse {
|
||||
repaint: true,
|
||||
consumed: egui_ctx.is_using_pointer(),
|
||||
consumed: self.egui_ctx.is_using_pointer(),
|
||||
}
|
||||
}
|
||||
WindowEvent::CursorLeft { .. } => {
|
||||
|
|
@ -294,12 +283,12 @@ impl State {
|
|||
}
|
||||
// WindowEvent::TouchpadPressure {device_id, pressure, stage, .. } => {} // TODO
|
||||
WindowEvent::Touch(touch) => {
|
||||
self.on_touch(touch);
|
||||
self.on_touch(window, touch);
|
||||
let consumed = match touch.phase {
|
||||
winit::event::TouchPhase::Started
|
||||
| winit::event::TouchPhase::Ended
|
||||
| winit::event::TouchPhase::Cancelled => egui_ctx.wants_pointer_input(),
|
||||
winit::event::TouchPhase::Moved => egui_ctx.is_using_pointer(),
|
||||
| winit::event::TouchPhase::Cancelled => self.egui_ctx.wants_pointer_input(),
|
||||
winit::event::TouchPhase::Moved => self.egui_ctx.is_using_pointer(),
|
||||
};
|
||||
EventResponse {
|
||||
repaint: true,
|
||||
|
|
@ -316,7 +305,7 @@ impl State {
|
|||
self.egui_input
|
||||
.events
|
||||
.push(egui::Event::Text(ch.to_string()));
|
||||
egui_ctx.wants_keyboard_input()
|
||||
self.egui_ctx.wants_keyboard_input()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
|
@ -361,13 +350,13 @@ impl State {
|
|||
|
||||
EventResponse {
|
||||
repaint: true,
|
||||
consumed: egui_ctx.wants_keyboard_input(),
|
||||
consumed: self.egui_ctx.wants_keyboard_input(),
|
||||
}
|
||||
}
|
||||
WindowEvent::KeyboardInput { input, .. } => {
|
||||
self.on_keyboard_input(input);
|
||||
// When pressing the Tab key, egui focuses the first focusable element, hence Tab always consumes.
|
||||
let consumed = egui_ctx.wants_keyboard_input()
|
||||
let consumed = self.egui_ctx.wants_keyboard_input()
|
||||
|| input.virtual_keycode == Some(winit::event::VirtualKeyCode::Tab);
|
||||
EventResponse {
|
||||
repaint: true,
|
||||
|
|
@ -459,7 +448,7 @@ impl State {
|
|||
self.egui_input.events.push(egui::Event::Zoom(zoom_factor));
|
||||
EventResponse {
|
||||
repaint: true,
|
||||
consumed: egui_ctx.wants_pointer_input(),
|
||||
consumed: self.egui_ctx.wants_pointer_input(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -520,10 +509,16 @@ impl State {
|
|||
}
|
||||
}
|
||||
|
||||
fn on_cursor_moved(&mut self, pos_in_pixels: winit::dpi::PhysicalPosition<f64>) {
|
||||
fn on_cursor_moved(
|
||||
&mut self,
|
||||
window: &Window,
|
||||
pos_in_pixels: winit::dpi::PhysicalPosition<f64>,
|
||||
) {
|
||||
let pixels_per_point = pixels_per_point(&self.egui_ctx, window);
|
||||
|
||||
let pos_in_points = egui::pos2(
|
||||
pos_in_pixels.x as f32 / self.current_pixels_per_point,
|
||||
pos_in_pixels.y as f32 / self.current_pixels_per_point,
|
||||
pos_in_pixels.x as f32 / pixels_per_point,
|
||||
pos_in_pixels.y as f32 / pixels_per_point,
|
||||
);
|
||||
self.pointer_pos_in_points = Some(pos_in_points);
|
||||
|
||||
|
|
@ -548,7 +543,9 @@ impl State {
|
|||
}
|
||||
}
|
||||
|
||||
fn on_touch(&mut self, touch: &winit::event::Touch) {
|
||||
fn on_touch(&mut self, window: &Window, touch: &winit::event::Touch) {
|
||||
let pixels_per_point = pixels_per_point(&self.egui_ctx, window);
|
||||
|
||||
// Emit touch event
|
||||
self.egui_input.events.push(egui::Event::Touch {
|
||||
device_id: egui::TouchDeviceId(egui::epaint::util::hash(touch.device_id)),
|
||||
|
|
@ -560,8 +557,8 @@ impl State {
|
|||
winit::event::TouchPhase::Cancelled => egui::TouchPhase::Cancel,
|
||||
},
|
||||
pos: egui::pos2(
|
||||
touch.location.x as f32 / self.current_pixels_per_point,
|
||||
touch.location.y as f32 / self.current_pixels_per_point,
|
||||
touch.location.x as f32 / pixels_per_point,
|
||||
touch.location.y as f32 / pixels_per_point,
|
||||
),
|
||||
force: match touch.force {
|
||||
Some(winit::event::Force::Normalized(force)) => Some(force as f32),
|
||||
|
|
@ -581,14 +578,14 @@ impl State {
|
|||
winit::event::TouchPhase::Started => {
|
||||
self.pointer_touch_id = Some(touch.id);
|
||||
// First move the pointer to the right location
|
||||
self.on_cursor_moved(touch.location);
|
||||
self.on_cursor_moved(window, touch.location);
|
||||
self.on_mouse_button_input(
|
||||
winit::event::ElementState::Pressed,
|
||||
winit::event::MouseButton::Left,
|
||||
);
|
||||
}
|
||||
winit::event::TouchPhase::Moved => {
|
||||
self.on_cursor_moved(touch.location);
|
||||
self.on_cursor_moved(window, touch.location);
|
||||
}
|
||||
winit::event::TouchPhase::Ended => {
|
||||
self.pointer_touch_id = None;
|
||||
|
|
@ -610,7 +607,9 @@ impl State {
|
|||
}
|
||||
}
|
||||
|
||||
fn on_mouse_wheel(&mut self, delta: winit::event::MouseScrollDelta) {
|
||||
fn on_mouse_wheel(&mut self, window: &Window, delta: winit::event::MouseScrollDelta) {
|
||||
let pixels_per_point = pixels_per_point(&self.egui_ctx, window);
|
||||
|
||||
{
|
||||
let (unit, delta) = match delta {
|
||||
winit::event::MouseScrollDelta::LineDelta(x, y) => {
|
||||
|
|
@ -621,7 +620,7 @@ impl State {
|
|||
y,
|
||||
}) => (
|
||||
egui::MouseWheelUnit::Point,
|
||||
egui::vec2(x as f32, y as f32) / self.current_pixels_per_point,
|
||||
egui::vec2(x as f32, y as f32) / pixels_per_point,
|
||||
),
|
||||
};
|
||||
let modifiers = self.egui_input.modifiers;
|
||||
|
|
@ -637,7 +636,7 @@ impl State {
|
|||
egui::vec2(x, y) * points_per_scroll_line
|
||||
}
|
||||
winit::event::MouseScrollDelta::PixelDelta(delta) => {
|
||||
egui::vec2(delta.x as f32, delta.y as f32) / self.current_pixels_per_point
|
||||
egui::vec2(delta.x as f32, delta.y as f32) / pixels_per_point
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -699,7 +698,6 @@ impl State {
|
|||
pub fn handle_platform_output(
|
||||
&mut self,
|
||||
window: &Window,
|
||||
egui_ctx: &egui::Context,
|
||||
platform_output: egui::PlatformOutput,
|
||||
) {
|
||||
crate::profile_function!();
|
||||
|
|
@ -715,8 +713,6 @@ impl State {
|
|||
accesskit_update,
|
||||
} = platform_output;
|
||||
|
||||
self.current_pixels_per_point = egui_ctx.pixels_per_point(); // someone can have changed it to scale the UI
|
||||
|
||||
self.set_cursor_icon(window, cursor_icon);
|
||||
|
||||
if let Some(open_url) = open_url {
|
||||
|
|
@ -772,17 +768,15 @@ impl State {
|
|||
/// Update the given viewport info with the current state of the window.
|
||||
///
|
||||
/// Call before [`State::take_egui_input`].
|
||||
pub fn update_viewport_info(info: &mut ViewportInfo, egui_ctx: &egui::Context, window: &Window) {
|
||||
update_viewport_info_impl(info, window, pixels_per_point(egui_ctx, window));
|
||||
}
|
||||
|
||||
fn update_viewport_info_impl(
|
||||
pub fn update_viewport_info(
|
||||
viewport_info: &mut ViewportInfo,
|
||||
egui_ctx: &egui::Context,
|
||||
window: &Window,
|
||||
pixels_per_point: f32,
|
||||
) {
|
||||
crate::profile_function!();
|
||||
|
||||
let pixels_per_point = pixels_per_point(egui_ctx, window);
|
||||
|
||||
let has_a_position = match window.is_minimized() {
|
||||
None | Some(true) => false,
|
||||
Some(false) => true,
|
||||
|
|
@ -1433,16 +1427,6 @@ pub fn create_winit_window_builder<T>(
|
|||
window_builder
|
||||
}
|
||||
|
||||
/// Applies what `create_winit_window_builder` couldn't
|
||||
#[deprecated = "Use apply_viewport_builder_to_window instead"]
|
||||
pub fn apply_viewport_builder_to_new_window(window: &Window, builder: &ViewportBuilder) {
|
||||
if let Some(mouse_passthrough) = builder.mouse_passthrough {
|
||||
if let Err(err) = window.set_cursor_hittest(!mouse_passthrough) {
|
||||
log::warn!("set_cursor_hittest failed: {err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Applies what `create_winit_window_builder` couldn't
|
||||
pub fn apply_viewport_builder_to_window(
|
||||
egui_ctx: &egui::Context,
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ fn main() {
|
|||
gl_window.resize(**new_inner_size);
|
||||
}
|
||||
|
||||
let event_response = egui_glow.on_window_event(&event);
|
||||
let event_response = egui_glow.on_window_event(gl_window.window(), &event);
|
||||
|
||||
if event_response.repaint {
|
||||
gl_window.window().request_redraw();
|
||||
|
|
|
|||
|
|
@ -34,7 +34,10 @@ impl EguiGlow {
|
|||
})
|
||||
.unwrap();
|
||||
|
||||
let egui_ctx = egui::Context::default();
|
||||
|
||||
let egui_winit = egui_winit::State::new(
|
||||
egui_ctx.clone(),
|
||||
ViewportId::ROOT,
|
||||
event_loop,
|
||||
native_pixels_per_point,
|
||||
|
|
@ -42,7 +45,7 @@ impl EguiGlow {
|
|||
);
|
||||
|
||||
Self {
|
||||
egui_ctx: Default::default(),
|
||||
egui_ctx,
|
||||
egui_winit,
|
||||
painter,
|
||||
viewport_info: Default::default(),
|
||||
|
|
@ -52,8 +55,12 @@ impl EguiGlow {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn on_window_event(&mut self, event: &winit::event::WindowEvent<'_>) -> EventResponse {
|
||||
self.egui_winit.on_window_event(&self.egui_ctx, event)
|
||||
pub fn on_window_event(
|
||||
&mut self,
|
||||
window: &winit::window::Window,
|
||||
event: &winit::event::WindowEvent<'_>,
|
||||
) -> EventResponse {
|
||||
self.egui_winit.on_window_event(window, event)
|
||||
}
|
||||
|
||||
/// Call [`Self::paint`] later to paint.
|
||||
|
|
@ -87,7 +94,7 @@ impl EguiGlow {
|
|||
}
|
||||
|
||||
self.egui_winit
|
||||
.handle_platform_output(window, &self.egui_ctx, platform_output);
|
||||
.handle_platform_output(window, platform_output);
|
||||
|
||||
self.shapes = shapes;
|
||||
self.pixels_per_point = pixels_per_point;
|
||||
|
|
|
|||
Loading…
Reference in New Issue