Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement workaround for egui issue with panels #76

Merged
merged 8 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions src/egui.rs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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<EguiWantsFocus>,
include_hover: Res<EguiFocusIncludesHover>,
windows: Query<Entity, With<Window>>,
) {
// The window that the user is interacting with and the window that contains the egui context
Expand All @@ -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,
Expand Down
22 changes: 13 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -44,7 +45,7 @@ impl Plugin for PanOrbitCameraPlugin {
.init_resource::<MouseKeyTracker>()
.init_resource::<TouchTracker>()
.add_systems(
Update,
PostUpdate,
(
(
active_viewport_data
Expand All @@ -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::<EguiWantsFocus>().add_systems(
Update,
egui::check_egui_wants_focus
.after(EguiSet::InitContexts)
.before(PanOrbitCameraSystemSet),
);
app.init_resource::<EguiWantsFocus>()
.init_resource::<EguiFocusIncludesHover>()
.add_systems(
PostUpdate,
egui::check_egui_wants_focus
.after(EguiSet::InitContexts)
.before(PanOrbitCameraSystemSet),
);
}
}
}
Expand Down
Loading