emilk / egui

egui: an easy-to-use immediate mode GUI in Rust that runs on both web and native
https://www.egui.rs/
Apache License 2.0
20.61k stars 1.49k forks source link

Fix: `Response::hover_pos` returns incorrect positions with layer transforms #4679

Closed Creative0708 closed 1 week ago

Creative0708 commented 1 week ago

When layer transforms are present, the Response::hover_pos function in egui returns transform * pos instead of transform.inverse() * pos. This is incorrect and isn't consistent with how egui calculates other interaction positions.

See: https://github.com/emilk/egui/blob/master/crates/egui/src/response.rs#L471

This PR fixes this bug, changing transform to transform.inverse(). Nothing fancy here, just a one-line change. scripts/check.sh runs successfully.

Below are videos of before and after with a modified version of the web demo. I added another entry after https://github.com/emilk/egui/blob/master/crates/egui_demo_lib/src/demo/pan_zoom.rs#L108 with a debug rectangle drawn at the return value of hover_pos:

(
    egui::Pos2::new(120.0, 120.0),
    Box::new(|ui, _state| {
        let response =
            ui.allocate_response(egui::Vec2::splat(128.0), egui::Sense::hover());
        ui.painter().rect_filled(
            egui::Rect::from_center_size(
                response.hover_pos().unwrap_or_default(),
                egui::Vec2::splat(8.0),
            ),
            egui::Rounding::ZERO,
            egui::Color32::DEBUG_COLOR,
        );
        response
    }),
),

Without the fix: https://github.com/emilk/egui/assets/104604363/241cfcab-88ab-459b-8f4d-3367da3aa392

With the fix: https://github.com/emilk/egui/assets/104604363/e52a7263-44c7-42c1-be46-1ecadc025625