From ace4aee9ed7dff9c4498565efe68a8b3f205e937 Mon Sep 17 00:00:00 2001 From: Vladyslav Batyrenko Date: Sun, 5 Jan 2025 20:35:11 +0200 Subject: [PATCH] Make input systems disable-able (#346) * Make input systems disable-able * Fix the docs --- examples/color_test.rs | 4 +- examples/simple_multipass.rs | 6 +- examples/ui.rs | 4 +- src/egui_node.rs | 4 +- src/input.rs | 209 +++++++++++++++++++++++++++-------- src/lib.rs | 127 +++++++++++++++++---- src/output.rs | 4 +- src/render_systems.rs | 9 +- src/text_agent.rs | 14 ++- src/web_clipboard.rs | 15 ++- 10 files changed, 311 insertions(+), 85 deletions(-) diff --git a/examples/color_test.rs b/examples/color_test.rs index 4d44e758..f5543e28 100644 --- a/examples/color_test.rs +++ b/examples/color_test.rs @@ -6,7 +6,7 @@ use bevy::{ use bevy_egui::{ helpers::vec2_into_egui_pos2, input::{EguiContextPointerPosition, HoveredNonWindowEguiContext}, - EguiContext, EguiContexts, EguiInputSet, EguiPlugin, EguiRenderToImage, EguiSettings, + EguiContext, EguiContextSettings, EguiContexts, EguiInputSet, EguiPlugin, EguiRenderToImage, }; fn main() { @@ -157,7 +157,7 @@ fn update_egui_hovered_context( ( Entity, &mut EguiContextPointerPosition, - &EguiSettings, + &EguiContextSettings, Option<&Mesh2d>, ), (With, Without), diff --git a/examples/simple_multipass.rs b/examples/simple_multipass.rs index fc611f92..ea70e331 100644 --- a/examples/simple_multipass.rs +++ b/examples/simple_multipass.rs @@ -1,7 +1,9 @@ use std::num::NonZero; use bevy::prelude::*; -use bevy_egui::{EguiContext, EguiFullOutput, EguiInput, EguiPlugin, EguiSettings, EguiStartupSet}; +use bevy_egui::{ + EguiContext, EguiContextSettings, EguiFullOutput, EguiInput, EguiPlugin, EguiStartupSet, +}; fn main() { App::new() @@ -15,7 +17,7 @@ fn main() { .run(); } -fn configure_context(mut egui_settings: Query<&mut EguiSettings>) { +fn configure_context(mut egui_settings: Query<&mut EguiContextSettings>) { egui_settings.single_mut().run_manually = true; } diff --git a/examples/ui.rs b/examples/ui.rs index 8548bc49..f4e9fd3a 100644 --- a/examples/ui.rs +++ b/examples/ui.rs @@ -2,7 +2,7 @@ use bevy::{ log::{Level, LogPlugin}, prelude::*, }; -use bevy_egui::{EguiContexts, EguiPlugin, EguiSettings}; +use bevy_egui::{EguiContextSettings, EguiContexts, EguiPlugin}; struct Images { bevy_icon: Handle, @@ -74,7 +74,7 @@ fn configure_ui_state_system(mut ui_state: ResMut) { fn update_ui_scale_factor_system( keyboard_input: Res>, mut toggle_scale_factor: Local>, - mut contexts: Query<(&mut EguiSettings, &Window)>, + mut contexts: Query<(&mut EguiContextSettings, &Window)>, ) { if keyboard_input.just_pressed(KeyCode::Slash) || toggle_scale_factor.is_none() { *toggle_scale_factor = Some(!toggle_scale_factor.unwrap_or(true)); diff --git a/src/egui_node.rs b/src/egui_node.rs index 1015e1de..2e04c3a8 100644 --- a/src/egui_node.rs +++ b/src/egui_node.rs @@ -2,7 +2,7 @@ use crate::{ render_systems::{ EguiPipelines, EguiTextureBindGroups, EguiTextureId, EguiTransform, EguiTransforms, }, - EguiRenderOutput, EguiRenderToImage, EguiSettings, RenderTargetSize, + EguiContextSettings, EguiRenderOutput, EguiRenderToImage, RenderTargetSize, }; use bevy_asset::prelude::*; use bevy_ecs::{ @@ -248,7 +248,7 @@ impl EguiNode { impl Node for EguiNode { fn update(&mut self, world: &mut World) { let mut render_target_query = world.query::<( - &EguiSettings, + &EguiContextSettings, &RenderTargetSize, &mut EguiRenderOutput, Option<&EguiRenderToImage>, diff --git a/src/input.rs b/src/input.rs index 3953b70c..e2faa210 100644 --- a/src/input.rs +++ b/src/input.rs @@ -2,7 +2,7 @@ use crate::text_agent::{is_mobile_safari, update_text_agent}; use crate::{ helpers::{vec2_into_egui_pos2, QueryHelper}, - EguiContext, EguiGlobalSettings, EguiInput, EguiOutput, EguiSettings, + EguiContext, EguiContextSettings, EguiGlobalSettings, EguiInput, EguiOutput, }; use bevy_ecs::prelude::*; use bevy_input::{ @@ -177,7 +177,7 @@ pub fn write_window_pointer_moved_events_system( mut cursor_moved_reader: EventReader, mut egui_input_event_writer: EventWriter, mut egui_contexts: Query< - (&EguiSettings, &mut EguiContextPointerPosition), + (&EguiContextSettings, &mut EguiContextPointerPosition), (With, With), >, ) { @@ -188,6 +188,13 @@ pub fn write_window_pointer_moved_events_system( continue; }; + if !context_settings + .input_system_settings + .run_write_window_pointer_moved_events_system + { + continue; + } + let scale_factor = context_settings.scale_factor; let pointer_position = vec2_into_egui_pos2(event.position / scale_factor); context_pointer_position.position = pointer_position; @@ -207,7 +214,7 @@ pub fn write_pointer_button_events_system( modifier_keys_state: Res, mut mouse_button_input_reader: EventReader, mut egui_input_event_writer: EventWriter, - egui_contexts: Query<&EguiContextPointerPosition, With>, + egui_contexts: Query<(&EguiContextSettings, &EguiContextPointerPosition), With>, ) { let modifiers = modifier_keys_state.to_egui_modifiers(); for event in mouse_button_input_reader.read() { @@ -215,10 +222,19 @@ pub fn write_pointer_button_events_system( .as_deref() .map_or(event.window, |hovered| hovered.0); - let Some(context_pointer_position) = egui_contexts.get_some(hovered_context) else { + let Some((context_settings, context_pointer_position)) = + egui_contexts.get_some(hovered_context) + else { continue; }; + if !context_settings + .input_system_settings + .run_write_pointer_button_events_system + { + continue; + } + let button = match event.button { MouseButton::Left => Some(egui::PointerButton::Primary), MouseButton::Right => Some(egui::PointerButton::Secondary), @@ -262,7 +278,7 @@ pub fn write_non_window_pointer_moved_events_system( hovered_non_window_egui_context: Option>, mut cursor_moved_reader: EventReader, mut egui_input_event_writer: EventWriter, - egui_contexts: Query<&EguiContextPointerPosition, With>, + egui_contexts: Query<(&EguiContextSettings, &EguiContextPointerPosition), With>, ) { if cursor_moved_reader.is_empty() { return; @@ -275,11 +291,19 @@ pub fn write_non_window_pointer_moved_events_system( return; }; - let Some(context_pointer_position) = egui_contexts.get_some(*hovered_non_window_egui_context) + let Some((context_settings, context_pointer_position)) = + egui_contexts.get_some(*hovered_non_window_egui_context) else { return; }; + if !context_settings + .input_system_settings + .run_write_non_window_pointer_moved_events_system + { + return; + } + egui_input_event_writer.send(EguiInputEvent { context: *hovered_non_window_egui_context, event: egui::Event::PointerMoved(context_pointer_position.position), @@ -292,6 +316,7 @@ pub fn write_mouse_wheel_events_system( hovered_non_window_egui_context: Option>, mut mouse_wheel_reader: EventReader, mut egui_input_event_writer: EventWriter, + egui_contexts: Query<&EguiContextSettings, With>, ) { let modifiers = modifier_keys_state.to_egui_modifiers(); for event in mouse_wheel_reader.read() { @@ -301,10 +326,23 @@ pub fn write_mouse_wheel_events_system( MouseScrollUnit::Pixel => egui::MouseWheelUnit::Point, }; + let context = hovered_non_window_egui_context + .as_deref() + .map_or(event.window, |hovered| hovered.0); + + let Some(context_settings) = egui_contexts.get_some(context) else { + continue; + }; + + if !context_settings + .input_system_settings + .run_write_mouse_wheel_events_system + { + continue; + } + egui_input_event_writer.send(EguiInputEvent { - context: hovered_non_window_egui_context - .as_deref() - .map_or(event.window, |hovered| hovered.0), + context, event: egui::Event::MouseWheel { unit, delta, @@ -326,6 +364,7 @@ pub fn write_keyboard_input_events_system( mut egui_clipboard: ResMut, mut keyboard_input_reader: EventReader, mut egui_input_event_writer: EventWriter, + egui_contexts: Query<&EguiContextSettings, With>, ) { let modifiers = modifier_keys_state.to_egui_modifiers(); for event in keyboard_input_reader.read() { @@ -333,6 +372,17 @@ pub fn write_keyboard_input_events_system( .as_deref() .map_or(event.window, |context| context.0); + let Some(context_settings) = egui_contexts.get_some(context) else { + continue; + }; + + if !context_settings + .input_system_settings + .run_write_keyboard_input_events_system + { + continue; + } + if modifier_keys_state.text_input_is_allowed() && event.state.is_pressed() { match &event.logical_key { Key::Character(char) if char.matches(char::is_control).count() == 0 => { @@ -410,7 +460,15 @@ pub fn write_ime_events_system( focused_non_window_egui_context: Option>, mut ime_reader: EventReader, mut egui_input_event_writer: EventWriter, - mut egui_contexts: Query<(Entity, &mut EguiContextImeState, &EguiOutput), With>, + mut egui_contexts: Query< + ( + Entity, + &EguiContextSettings, + &mut EguiContextImeState, + &EguiOutput, + ), + With, + >, ) { for event in ime_reader.read() { let window = match &event { @@ -423,11 +481,19 @@ pub fn write_ime_events_system( .as_deref() .map_or(window, |context| context.0); - let Some((_entity, mut ime_state, _egui_output)) = egui_contexts.get_some_mut(context) + let Some((_entity, context_settings, mut ime_state, _egui_output)) = + egui_contexts.get_some_mut(context) else { continue; }; + if !context_settings + .input_system_settings + .run_write_ime_events_system + { + continue; + } + let ime_event_enable = |ime_state: &mut EguiContextImeState, egui_input_event_writer: &mut EventWriter| { @@ -492,7 +558,7 @@ pub fn write_window_touch_events_system( mut egui_input_event_writer: EventWriter, mut egui_contexts: Query< ( - &EguiSettings, + &EguiContextSettings, &mut EguiContextPointerPosition, &mut EguiContextPointerTouchId, &EguiOutput, @@ -500,53 +566,43 @@ pub fn write_window_touch_events_system( (With, With), >, ) { - #[cfg(target_arch = "wasm32")] - let mut editing_text = false; - #[cfg(target_arch = "wasm32")] - for (_, _, _, egui_output) in egui_contexts.iter() { - let platform_output = &egui_output.platform_output; - if platform_output.ime.is_some() || platform_output.mutable_text_under_cursor { - editing_text = true; - break; - } - } - let modifiers = modifier_keys_state.to_egui_modifiers(); for event in touch_input_reader.read() { - let Some((context_settings, mut context_pointer_position, mut context_pointer_touch_id, _)) = - egui_contexts.get_some_mut(event.window) + let Some(( + context_settings, + mut context_pointer_position, + mut context_pointer_touch_id, + output, + )) = egui_contexts.get_some_mut(event.window) else { continue; }; - if let Some(hovered_non_window_egui_context) = hovered_non_window_egui_context.as_deref() { - #[cfg(target_arch = "wasm32")] - if context_pointer_touch_id.pointer_touch_id.is_none() - || context_pointer_touch_id.pointer_touch_id.unwrap() == event.id - { - if let bevy_input::touch::TouchPhase::Ended = event.phase { - if !is_mobile_safari() { - update_text_agent(editing_text); + if egui_global_settings.enable_focused_non_window_context_updates { + if let bevy_input::touch::TouchPhase::Started = event.phase { + if let Some(hovered_non_window_egui_context) = + hovered_non_window_egui_context.as_deref() + { + if let bevy_input::touch::TouchPhase::Started = event.phase { + commands.insert_resource(FocusedNonWindowEguiContext( + hovered_non_window_egui_context.0, + )); } - } - } - if egui_global_settings.enable_focused_non_window_context_updates { - if let bevy_input::touch::TouchPhase::Started = event.phase { - commands.insert_resource(FocusedNonWindowEguiContext( - hovered_non_window_egui_context.0, - )); + continue; } - } - continue; - } - if egui_global_settings.enable_focused_non_window_context_updates { - if let bevy_input::touch::TouchPhase::Started = event.phase { commands.remove_resource::(); } } + if !context_settings + .input_system_settings + .run_write_window_touch_events_system + { + continue; + } + let scale_factor = context_settings.scale_factor; let touch_position = vec2_into_egui_pos2(event.position / scale_factor); context_pointer_position.position = touch_position; @@ -554,6 +610,7 @@ pub fn write_window_touch_events_system( &mut egui_input_event_writer, event, event.window, + output, touch_position, modifiers, &mut context_pointer_touch_id, @@ -561,10 +618,64 @@ pub fn write_window_touch_events_system( } } +/// Reads [`TouchInput`] events and wraps them into [`EguiInputEvent`] for a [`HoveredNonWindowEguiContext`] context (if one exists). +pub fn write_non_window_touch_events_system( + focused_non_window_egui_context: Option>, + mut touch_input_reader: EventReader, + mut egui_input_event_writer: EventWriter, + modifier_keys_state: Res, + mut egui_contexts: Query< + ( + &EguiContextSettings, + &EguiContextPointerPosition, + &mut EguiContextPointerTouchId, + &EguiOutput, + ), + With, + >, +) { + let modifiers = modifier_keys_state.to_egui_modifiers(); + for event in touch_input_reader.read() { + let Some(&FocusedNonWindowEguiContext(focused_non_window_egui_context)) = + focused_non_window_egui_context.as_deref() + else { + continue; + }; + + let Some(( + context_settings, + context_pointer_position, + mut context_pointer_touch_id, + output, + )) = egui_contexts.get_some_mut(focused_non_window_egui_context) + else { + continue; + }; + + if !context_settings + .input_system_settings + .run_write_non_window_touch_events_system + { + continue; + } + + write_touch_event( + &mut egui_input_event_writer, + event, + focused_non_window_egui_context, + output, + context_pointer_position.position, + modifiers, + &mut context_pointer_touch_id, + ); + } +} + fn write_touch_event( egui_input_event_writer: &mut EventWriter, event: &TouchInput, context: Entity, + _output: &EguiOutput, pointer_position: egui::Pos2, modifiers: Modifiers, context_pointer_touch_id: &mut EguiContextPointerTouchId, @@ -642,6 +753,14 @@ fn write_touch_event( context, event: egui::Event::PointerGone, }); + + #[cfg(target_arch = "wasm32")] + if !is_mobile_safari() { + update_text_agent( + _output.platform_output.ime.is_some() + || _output.platform_output.mutable_text_under_cursor, + ); + } } bevy_input::touch::TouchPhase::Canceled => { context_pointer_touch_id.pointer_touch_id = None; diff --git a/src/lib.rs b/src/lib.rs index f492e927..0872a712 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -186,12 +186,15 @@ pub struct EguiGlobalSettings { /// /// For more info, see the [`FocusedNonWindowEguiContext`] documentation. pub enable_focused_non_window_context_updates: bool, + /// Controls running of the input systems. + pub input_system_settings: EguiInputSystemSettings, } impl Default for EguiGlobalSettings { fn default() -> Self { Self { enable_focused_non_window_context_updates: true, + input_system_settings: EguiInputSystemSettings::default(), } } } @@ -199,7 +202,7 @@ impl Default for EguiGlobalSettings { /// A component for storing Egui context settings. #[derive(Clone, Debug, Component, Reflect)] #[cfg_attr(feature = "render", derive(ExtractComponent))] -pub struct EguiSettings { +pub struct EguiContextSettings { /// Controls if Egui is run manually. /// /// If set to `true`, a user is expected to call [`egui::Context::run`] or [`egui::Context::begin_pass`] and [`egui::Context::end_pass`] manually. @@ -209,9 +212,9 @@ pub struct EguiSettings { /// This setting can be used to force the UI to render in physical pixels regardless of DPI as follows: /// ```rust /// use bevy::{prelude::*, window::PrimaryWindow}; - /// use bevy_egui::EguiSettings; + /// use bevy_egui::EguiContextSettings; /// - /// fn update_ui_scale_factor(mut windows: Query<(&mut EguiSettings, &Window), With>) { + /// fn update_ui_scale_factor(mut windows: Query<(&mut EguiContextSettings, &Window), With>) { /// if let Ok((mut egui_settings, window)) = windows.get_single_mut() { /// egui_settings.scale_factor = 1.0 / window.scale_factor(); /// } @@ -225,10 +228,12 @@ pub struct EguiSettings { /// Controls if Egui should capture pointer input when using [`bevy_picking`] (i.e. suppress `bevy_picking` events when a pointer is over an Egui window). #[cfg(feature = "render")] pub capture_pointer_input: bool, + /// Controls running of the input systems. + pub input_system_settings: EguiInputSystemSettings, } // Just to keep the PartialEq -impl PartialEq for EguiSettings { +impl PartialEq for EguiContextSettings { #[allow(clippy::let_and_return)] fn eq(&self, other: &Self) -> bool { let eq = self.scale_factor == other.scale_factor; @@ -238,7 +243,7 @@ impl PartialEq for EguiSettings { } } -impl Default for EguiSettings { +impl Default for EguiContextSettings { fn default() -> Self { Self { run_manually: false, @@ -247,6 +252,56 @@ impl Default for EguiSettings { default_open_url_target: None, #[cfg(feature = "render")] capture_pointer_input: true, + input_system_settings: EguiInputSystemSettings::default(), + } + } +} + +#[derive(Clone, Debug, Reflect, PartialEq, Eq)] +/// All the systems are enabled by default. These settings exist within both [`EguiGlobalSettings`] and [`EguiContextSettings`]. +pub struct EguiInputSystemSettings { + /// Controls running of the [`write_modifiers_keys_state_system`] system. + pub run_write_modifiers_keys_state_system: bool, + /// Controls running of the [`write_window_pointer_moved_events_system`] system. + pub run_write_window_pointer_moved_events_system: bool, + /// Controls running of the [`write_pointer_button_events_system`] system. + pub run_write_pointer_button_events_system: bool, + /// Controls running of the [`write_window_touch_events_system`] system. + pub run_write_window_touch_events_system: bool, + /// Controls running of the [`write_non_window_pointer_moved_events_system`] system. + pub run_write_non_window_pointer_moved_events_system: bool, + /// Controls running of the [`write_mouse_wheel_events_system`] system. + pub run_write_mouse_wheel_events_system: bool, + /// Controls running of the [`write_non_window_touch_events_system`] system. + pub run_write_non_window_touch_events_system: bool, + /// Controls running of the [`write_keyboard_input_events_system`] system. + pub run_write_keyboard_input_events_system: bool, + /// Controls running of the [`write_ime_events_system`] system. + pub run_write_ime_events_system: bool, + /// Controls running of the [`write_text_agent_channel_events_system`] system. + #[cfg(target_arch = "wasm32")] + pub run_write_text_agent_channel_events_system: bool, + /// Controls running of the [`web_clipboard::write_web_clipboard_events_system`] system. + #[cfg(all(feature = "manage_clipboard", target_arch = "wasm32"))] + pub run_write_web_clipboard_events_system: bool, +} + +impl Default for EguiInputSystemSettings { + fn default() -> Self { + Self { + run_write_modifiers_keys_state_system: true, + run_write_window_pointer_moved_events_system: true, + run_write_pointer_button_events_system: true, + run_write_window_touch_events_system: true, + run_write_non_window_pointer_moved_events_system: true, + run_write_mouse_wheel_events_system: true, + run_write_non_window_touch_events_system: true, + run_write_keyboard_input_events_system: true, + run_write_ime_events_system: true, + #[cfg(target_arch = "wasm32")] + run_write_text_agent_channel_events_system: true, + #[cfg(all(feature = "manage_clipboard", target_arch = "wasm32"))] + run_write_web_clipboard_events_system: true, } } } @@ -304,7 +359,7 @@ pub struct EguiOutput { #[derive(Clone, Component, Default)] #[cfg_attr(feature = "render", derive(ExtractComponent))] #[require( - EguiSettings, + EguiContextSettings, EguiInput, EguiContextPointerPosition, EguiContextPointerTouchId, @@ -719,7 +774,7 @@ pub enum EguiPostUpdateSet { impl Plugin for EguiPlugin { fn build(&self, app: &mut App) { app.register_type::(); - app.register_type::(); + app.register_type::(); app.init_resource::(); app.init_resource::(); app.add_event::(); @@ -731,7 +786,7 @@ impl Plugin for EguiPlugin { app.add_plugins(ExtractResourcePlugin::::default()); app.add_plugins(ExtractResourcePlugin::::default()); app.add_plugins(ExtractComponentPlugin::::default()); - app.add_plugins(ExtractComponentPlugin::::default()); + app.add_plugins(ExtractComponentPlugin::::default()); app.add_plugins(ExtractComponentPlugin::::default()); app.add_plugins(ExtractComponentPlugin::::default()); app.add_plugins(ExtractComponentPlugin::::default()); @@ -803,20 +858,38 @@ impl Plugin for EguiPlugin { PreUpdate, ( ( - write_modifiers_keys_state_system, - write_window_pointer_moved_events_system, + write_modifiers_keys_state_system.run_if(input_system_is_enabled(|s| { + s.run_write_modifiers_keys_state_system + })), + write_window_pointer_moved_events_system.run_if(input_system_is_enabled(|s| { + s.run_write_window_pointer_moved_events_system + })), ) .in_set(EguiInputSet::InitReading), ( - write_pointer_button_events_system, - write_window_touch_events_system, + write_pointer_button_events_system.run_if(input_system_is_enabled(|s| { + s.run_write_pointer_button_events_system + })), + write_window_touch_events_system.run_if(input_system_is_enabled(|s| { + s.run_write_window_touch_events_system + })), ) .in_set(EguiInputSet::FocusContext), ( - write_non_window_pointer_moved_events_system, - write_mouse_wheel_events_system, - write_keyboard_input_events_system, - write_ime_events_system, + write_non_window_pointer_moved_events_system.run_if(input_system_is_enabled( + |s| s.run_write_non_window_pointer_moved_events_system, + )), + write_non_window_touch_events_system.run_if(input_system_is_enabled(|s| { + s.run_write_non_window_touch_events_system + })), + write_mouse_wheel_events_system.run_if(input_system_is_enabled(|s| { + s.run_write_mouse_wheel_events_system + })), + write_keyboard_input_events_system.run_if(input_system_is_enabled(|s| { + s.run_write_keyboard_input_events_system + })), + write_ime_events_system + .run_if(input_system_is_enabled(|s| s.run_write_ime_events_system)), ) .in_set(EguiInputSet::ReadBevyEvents), write_egui_input_system.in_set(EguiInputSet::WriteEguiEvents), @@ -864,6 +937,9 @@ impl Plugin for EguiPlugin { app.add_systems( PreUpdate, write_text_agent_channel_events_system + .run_if(input_system_is_enabled(|s| { + s.run_write_text_agent_channel_events_system + })) .in_set(EguiPreUpdateSet::ProcessInput) .in_set(EguiInputSet::ReadBevyEvents), ); @@ -872,6 +948,9 @@ impl Plugin for EguiPlugin { app.add_systems( PreUpdate, web_clipboard::write_web_clipboard_events_system + .run_if(input_system_is_enabled(|s| { + s.run_write_web_clipboard_events_system + })) .in_set(EguiPreUpdateSet::ProcessInput) .in_set(EguiInputSet::ReadBevyEvents), ); @@ -960,6 +1039,12 @@ impl Plugin for EguiPlugin { } } +fn input_system_is_enabled( + test: impl Fn(&EguiInputSystemSettings) -> bool, +) -> impl Fn(Res) -> bool { + move |settings| test(&settings.input_system_settings) +} + /// Contains textures allocated and painted by Egui. #[cfg(feature = "render")] #[derive(bevy_ecs::system::Resource, Deref, DerefMut, Default)] @@ -1074,7 +1159,7 @@ pub const PICKING_ORDER: f32 = 1_000_000.0; #[cfg(feature = "render")] pub fn capture_pointer_input_system( pointers: Query<(&PointerId, &PointerLocation)>, - mut egui_context: Query<(Entity, &mut EguiContext, &EguiSettings), With>, + mut egui_context: Query<(Entity, &mut EguiContext, &EguiContextSettings), With>, mut output: EventWriter, ) { use helpers::QueryHelper; @@ -1256,7 +1341,7 @@ pub struct UpdateUiSizeAndScaleQuery { ctx: &'static mut EguiContext, egui_input: &'static mut EguiInput, render_target_size: &'static mut RenderTargetSize, - egui_settings: &'static EguiSettings, + egui_settings: &'static EguiContextSettings, window: Option<&'static Window>, #[cfg(feature = "render")] render_to_image: Option<&'static EguiRenderToImage>, @@ -1319,7 +1404,9 @@ pub fn update_ui_size_and_scale_system( } /// Marks a pass start for Egui. -pub fn begin_pass_system(mut contexts: Query<(&mut EguiContext, &EguiSettings, &mut EguiInput)>) { +pub fn begin_pass_system( + mut contexts: Query<(&mut EguiContext, &EguiContextSettings, &mut EguiInput)>, +) { for (mut ctx, egui_settings, mut egui_input) in contexts.iter_mut() { if !egui_settings.run_manually { ctx.get_mut().begin_pass(egui_input.take()); @@ -1329,7 +1416,7 @@ pub fn begin_pass_system(mut contexts: Query<(&mut EguiContext, &EguiSettings, & /// Marks a pass end for Egui. pub fn end_pass_system( - mut contexts: Query<(&mut EguiContext, &EguiSettings, &mut EguiFullOutput)>, + mut contexts: Query<(&mut EguiContext, &EguiContextSettings, &mut EguiFullOutput)>, ) { for (mut ctx, egui_settings, mut full_output) in contexts.iter_mut() { if !egui_settings.run_manually { diff --git a/src/output.rs b/src/output.rs index 40a80330..3aed9079 100644 --- a/src/output.rs +++ b/src/output.rs @@ -1,4 +1,4 @@ -use crate::{helpers, EguiContext, EguiFullOutput, EguiRenderOutput, EguiSettings}; +use crate::{helpers, EguiContext, EguiContextSettings, EguiFullOutput, EguiRenderOutput}; #[cfg(windows)] use bevy_ecs::system::Local; use bevy_ecs::{ @@ -18,7 +18,7 @@ pub fn process_output_system( &mut EguiFullOutput, &mut EguiRenderOutput, Option<&mut CursorIcon>, - &EguiSettings, + &EguiContextSettings, )>, #[cfg(all(feature = "manage_clipboard", not(target_os = "android")))] mut egui_clipboard: bevy_ecs::system::ResMut, diff --git a/src/render_systems.rs b/src/render_systems.rs index 28e8d35d..c2fbb6c4 100644 --- a/src/render_systems.rs +++ b/src/render_systems.rs @@ -1,6 +1,7 @@ use crate::{ egui_node::{EguiNode, EguiPipeline, EguiPipelineKey, EguiRenderTargetType}, - EguiManagedTextures, EguiRenderToImage, EguiSettings, EguiUserTextures, RenderTargetSize, + EguiContextSettings, EguiManagedTextures, EguiRenderToImage, EguiUserTextures, + RenderTargetSize, }; use bevy_asset::prelude::*; use bevy_derive::{Deref, DerefMut}; @@ -27,7 +28,7 @@ use bevy_window::Window; /// Extracted Egui settings. #[derive(Resource, Deref, DerefMut, Default)] -pub struct ExtractedEguiSettings(pub EguiSettings); +pub struct ExtractedEguiSettings(pub EguiContextSettings); /// The extracted version of [`EguiManagedTextures`]. #[derive(Debug, Resource)] @@ -190,7 +191,7 @@ pub struct EguiTransforms { /// the screen space with the center at (0, 0) to the normalised viewport space. #[derive(encase::ShaderType, Default)] pub struct EguiTransform { - /// Is affected by window size and [`EguiSettings::scale_factor`]. + /// Is affected by window size and [`EguiContextSettings::scale_factor`]. pub scale: Vec2, /// Normally equals `Vec2::new(-1.0, 1.0)`. pub translation: Vec2, @@ -215,7 +216,7 @@ impl EguiTransform { /// Prepares Egui transforms. pub fn prepare_egui_transforms_system( mut egui_transforms: ResMut, - render_targets: Query<(Option<&MainEntity>, &EguiSettings, &RenderTargetSize)>, + render_targets: Query<(Option<&MainEntity>, &EguiContextSettings, &RenderTargetSize)>, render_device: Res, render_queue: Res, egui_pipeline: Res, diff --git a/src/text_agent.rs b/src/text_agent.rs index 941deedc..052c60f7 100644 --- a/src/text_agent.rs +++ b/src/text_agent.rs @@ -3,7 +3,7 @@ use crate::{ input::{EguiInputEvent, FocusedNonWindowEguiContext}, - EguiContext, EguiInput, EguiOutput, EventClosure, SubscribedEvents, + EguiContext, EguiContextSettings, EguiInput, EguiOutput, EventClosure, SubscribedEvents, }; use bevy_ecs::prelude::*; use bevy_window::{PrimaryWindow, RequestRedraw}; @@ -81,14 +81,22 @@ pub fn write_text_agent_channel_events_system( channel: Res, focused_non_window_egui_context: Option>, // We can safely assume that we have only 1 window in WASM. - primary_context: Single, With)>, + egui_context: Single<(Entity, &EguiContextSettings), (With, With)>, mut egui_input_event_writer: EventWriter, mut redraw_event: EventWriter, ) { + let (primary_context, context_settings) = *egui_context; + if !context_settings + .input_system_settings + .run_write_text_agent_channel_events_system + { + return; + } + let mut redraw = false; let context = focused_non_window_egui_context .as_deref() - .map_or(*primary_context, |context| context.0); + .map_or(primary_context, |context| context.0); while let Ok(event) = channel.receiver.try_recv() { redraw = true; egui_input_event_writer.send(EguiInputEvent { context, event }); diff --git a/src/web_clipboard.rs b/src/web_clipboard.rs index 8a44fd0d..cf81faf8 100644 --- a/src/web_clipboard.rs +++ b/src/web_clipboard.rs @@ -1,6 +1,7 @@ use crate::{ input::{EguiInputEvent, FocusedNonWindowEguiContext}, - string_from_js_value, EguiClipboard, EguiContext, EventClosure, SubscribedEvents, + string_from_js_value, EguiClipboard, EguiContext, EguiContextSettings, EventClosure, + SubscribedEvents, }; use bevy_ecs::prelude::*; use bevy_log as log; @@ -25,13 +26,21 @@ pub fn startup_setup_web_events_system( pub fn write_web_clipboard_events_system( focused_non_window_egui_context: Option>, // We can safely assume that we have only 1 window in WASM. - primary_context: Single, With)>, + egui_context: Single<(Entity, &EguiContextSettings), (With, With)>, mut egui_clipboard: ResMut, mut egui_input_event_writer: EventWriter, ) { + let (primary_context, context_settings) = *egui_context; + if !context_settings + .input_system_settings + .run_write_web_clipboard_events_system + { + return; + } + let context = focused_non_window_egui_context .as_deref() - .map_or(*primary_context, |context| context.0); + .map_or(primary_context, |context| context.0); while let Some(event) = egui_clipboard.try_receive_clipboard_event() { match event { crate::web_clipboard::WebClipboardEvent::Copy => {