Skip to content
Snippets Groups Projects
Verified Commit e75eb3c7 authored by Louis's avatar Louis :fire:
Browse files

Scale mouse position events by window area

parent 93370f41
No related branches found
No related tags found
No related merge requests found
......@@ -12,6 +12,7 @@ use crate::{
event_dispatcher::EventDispatcher,
input_event::InputEvent,
};
use crate::unproject::UnprojectManager;
pub(crate) fn process_events(world: &mut World) {
let mut input_events = Vec::new();
......@@ -28,6 +29,7 @@ pub(crate) fn process_events(world: &mut World) {
ResMut<CustomEventReader<MouseWheel>>,
ResMut<CustomEventReader<ReceivedCharacter>>,
ResMut<CustomEventReader<KeyboardInput>>,
UnprojectManager,
),
_,
_,
......@@ -43,6 +45,7 @@ pub(crate) fn process_events(world: &mut World) {
mut custom_event_mouse_wheel,
mut custom_event_char_input,
mut custom_event_keyboard,
projector,
)| {
if let Some(event) = custom_event_reader_cursor
.0
......@@ -50,7 +53,9 @@ pub(crate) fn process_events(world: &mut World) {
.last()
{
// Currently, we can only handle a single MouseMoved event at a time so everything but the last needs to be skipped
input_events.push(InputEvent::MouseMoved(event.position.into()));
if let Ok(pos) = projector.unproject(event.position) {
input_events.push(InputEvent::MouseMoved(pos.into()));
}
}
for event in custom_event_mouse_button.0.read(&mouse_button_input_events) {
......
......@@ -29,6 +29,8 @@ mod widget_state;
pub mod widgets;
mod window_size;
pub(crate) mod unproject;
use context::KayakRootContext;
pub use window_size::WindowSize;
......
use bevy::ecs::system::SystemParam;
use bevy::math::Vec2;
use bevy::prelude::{OrthographicProjection, Query, Vec4Swizzles, Window, With};
use bevy::utils::thiserror::Error;
use bevy::window::PrimaryWindow;
use crate::CameraUIKayak;
pub fn unproject_from_physical(
point: Vec2,
window: &Window,
projection: &OrthographicProjection,
) -> Vec2 {
let projection_area = projection.area;
let projection_width = projection_area.width();
let projection_height = projection_area.height();
let window_width = window.width();
let window_height = window.height();
let width_ratio = projection_width / window_width;
let height_ratio = projection_height / window_height;
point * Vec2::new(width_ratio, height_ratio)
}
#[derive(SystemParam)]
pub struct UnprojectManager<'w, 's> {
windows: Query<'w, 's, &'static Window, With<PrimaryWindow>>,
camera: Query<'w, 's, &'static OrthographicProjection, With<CameraUIKayak>>,
}
#[derive(Debug, Error)]
#[error("Invalid ECS state to perform unprojection")]
pub struct InvalidUnprojection;
impl<'w, 's> UnprojectManager<'w, 's> {
pub fn unproject(&self, position: Vec2) -> Result<Vec2, InvalidUnprojection> {
let window = self.windows.get_single().map_err(|_| InvalidUnprojection)?;
let camera = self.camera.get_single().map_err(|_| InvalidUnprojection)?;
Ok(unproject_from_physical(
position,
window,
camera,
))
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment