diff --git a/src/egui.rs b/src/egui.rs index 8dffe8c..c55ba94 100644 --- a/src/egui.rs +++ b/src/egui.rs @@ -1,6 +1,7 @@ use bevy::prelude::*; -/// A resource that tracks whether egui wants focus on the current and previous frames. +/// A resource that tracks whether egui wants focus on the current and previous frames, +/// in order to determine whether PanOrbitCamera should react to input events. /// /// The reason the previous frame's value is saved is because when you click inside an /// egui window, Context::wants_pointer_input() still returns false once before returning @@ -17,9 +18,20 @@ pub struct EguiWantsFocus { pub curr: bool, } +/// When true, just hovering over an egui panel/window will prevent PanOrbitCamera +/// from reacting to input events. This is an optional, and hopefully temporary, +/// workaround to this issue: https://github.com/Plonq/bevy_panorbit_camera/issues/75. +/// Note that this will prevent PanOrbitCamera using reacting to input whenever the cursor +/// is over an egui area, even if you're in the middle of dragging to rotate, so only use +/// this if you use egui Panels (as opposed to Windows). If you use Windows exclusively +/// then no workaround is required. +#[derive(Resource, PartialEq, Eq, Default)] +pub struct EguiFocusIncludesHover(pub bool); + pub fn check_egui_wants_focus( mut contexts: bevy_egui::EguiContexts, mut wants_focus: ResMut, + include_hover: Res, windows: Query>, ) { // The window that the user is interacting with and the window that contains the egui context @@ -28,7 +40,11 @@ pub fn check_egui_wants_focus( // interacting with. let new_wants_focus = windows.iter().any(|window| { let ctx = contexts.ctx_for_window_mut(window); - ctx.wants_pointer_input() || ctx.wants_keyboard_input() + let mut value = ctx.wants_pointer_input() || ctx.wants_keyboard_input(); + if include_hover.0 { + value |= ctx.is_pointer_over_area() + } + value }); let new_res = EguiWantsFocus { prev: wants_focus.curr, diff --git a/src/lib.rs b/src/lib.rs index 629515b..32ddf34 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,12 +6,13 @@ use std::f32::consts::{PI, TAU}; use bevy::input::mouse::MouseWheel; use bevy::prelude::*; use bevy::render::camera::RenderTarget; +use bevy::transform::TransformSystem; use bevy::window::{PrimaryWindow, WindowRef}; #[cfg(feature = "bevy_egui")] use bevy_egui::EguiSet; #[cfg(feature = "bevy_egui")] -pub use crate::egui::EguiWantsFocus; +pub use crate::egui::{EguiFocusIncludesHover, EguiWantsFocus}; use crate::input::{mouse_key_tracker, MouseKeyTracker}; pub use crate::touch::TouchControls; use crate::touch::{touch_tracker, TouchGestures, TouchTracker}; @@ -44,7 +45,7 @@ impl Plugin for PanOrbitCameraPlugin { .init_resource::() .init_resource::() .add_systems( - Update, + PostUpdate, ( ( active_viewport_data @@ -55,17 +56,20 @@ impl Plugin for PanOrbitCameraPlugin { pan_orbit_camera, ) .chain() - .in_set(PanOrbitCameraSystemSet), + .in_set(PanOrbitCameraSystemSet) + .before(TransformSystem::TransformPropagate), ); #[cfg(feature = "bevy_egui")] { - app.init_resource::().add_systems( - Update, - egui::check_egui_wants_focus - .after(EguiSet::InitContexts) - .before(PanOrbitCameraSystemSet), - ); + app.init_resource::() + .init_resource::() + .add_systems( + PostUpdate, + egui::check_egui_wants_focus + .after(EguiSet::InitContexts) + .before(PanOrbitCameraSystemSet), + ); } } }