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

Simple way to detect if pointer is over *any* egui painted shape #2690

Open
Aceeri opened this issue Feb 8, 2023 · 2 comments
Open

Simple way to detect if pointer is over *any* egui painted shape #2690

Aceeri opened this issue Feb 8, 2023 · 2 comments
Labels
bug Something is broken

Comments

@Aceeri
Copy link

Aceeri commented Feb 8, 2023

Describe the bug
There isn't a clear way to tell if the pointer is currently over an egui painted region of a window when using non-Area/area derived containers. bevy_mod_picking tries to detect when it is over an egui piece using the Context::is_pointer_over_area

To Reproduce
Create a CentralPanel, pointer only detects background.

Expected behavior

Screenshots

Desktop (please complete the following information):

  • OS: Windows
  • Version 0.20

Additional context

@lvaroqui
Copy link
Contributor

lvaroqui commented Feb 9, 2023

See related comment here: Adanos020/egui_dock#95 (comment), the issue is same for egui_dock::DockArea and egui Panels.

@dmlary
Copy link
Contributor

dmlary commented Jun 15, 2023

The issue is that a handful of bevy crates are using Context::is_pointer_over_area() early in the frame cycle, after input has been processed, but before any egui panels have been drawn. If the check is performed after any panels have been drawn, is_pointer_over_area() returns the correct results. But if you call it before drawing anything, it will always return false for Background layers.

is_pointer_over_area() is using FrameState.unused_rect.contains(...) to determine if the cursor position for Background layers falls within the layer:

if let Some(layer) = self.layer_id_at(pointer_pos) {
if layer.order == Order::Background {
!self.frame_state(|state| state.unused_rect.contains(pointer_pos))

The problem is that FrameState::begin_frame() resets FrameState.unused_rect to the full input.screen_rect() at the start of every frame.

*unused_rect = input.screen_rect();

I can see why egui isn't just using the result from Context::layer_id_at(); the panels are all the same Layer as areas that don't contain egui windows.

Is the solution here to make Panels persistent layers similar to Windows?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is broken
Projects
None yet
Development

No branches or pull requests

3 participants