use bevy::input::mouse::{MouseScrollUnit, MouseWheel}; use bevy::prelude::*; use bevy::window::PrimaryWindow; pub fn input_plugin(app: &mut App) { app .insert_resource(ShipEditorDrag::default()) .add_systems(Update, on_scroll) .add_systems(Update, on_click) .add_systems(Update, drag); } #[derive(Resource, Default)] struct ShipEditorDrag { is_dragging: bool, init_cursor_pos: Vec2, init_camera_pos: Vec2, } fn on_scroll( mut scroll_events: MessageReader, mut camera: Single<(&mut Transform, &mut Projection), With>, window: Single<&Window, With>, ) { let Some(cursor_pos) = window.cursor_position() else { return }; let cursor_pos = cursor_pos.with_y(-cursor_pos.y); let mut transform = camera.0.clone(); let Projection::Orthographic(ref mut projection) = *camera.1 else { return }; for ev in scroll_events.read() { match ev.unit { MouseScrollUnit::Line | MouseScrollUnit::Pixel => { if ev.y > 0.0 { let mut rel_pos = vec2(window.width() / 2.0, -window.height() / 2.0) - cursor_pos; rel_pos *= projection.scale; projection.scale *= 0.95; let scaled_rel_pos = rel_pos * 0.95; transform.translation += scaled_rel_pos.extend(0.0) - rel_pos.extend(0.0); } else { let mut rel_pos = vec2(window.width() / 2.0, -window.height() / 2.0) - cursor_pos; rel_pos *= projection.scale; projection.scale *= 1.05; let scaled_rel_pos = rel_pos * 1.05; transform.translation += scaled_rel_pos.extend(0.0) - rel_pos.extend(0.0); } } } } *camera.0 = transform; } fn on_click( ev: Res>, mut drag: ResMut, camera: Single<&Transform, With>, window: Single<&Window, With>, ) { let Some(cursor_pos) = window.cursor_position() else { return }; if ev.just_pressed(MouseButton::Left) { drag.is_dragging = true; drag.init_cursor_pos = cursor_pos.with_y(-cursor_pos.y); drag.init_camera_pos = camera.translation.truncate(); } if ev.just_released(MouseButton::Left) { drag.is_dragging = false; } } fn drag( drag: ResMut, mut camera: Single<(&mut Transform, &Projection), With>, window: Single<&Window, With>, ) { if !drag.is_dragging { return } let Some(cursor) = window.cursor_position() else { return }; let projection = camera.1.clone(); let Projection::Orthographic(projection) = projection else { return }; let transform = &mut camera.0; transform.translation = drag.init_camera_pos.extend(0.0) - (cursor.with_y(-cursor.y) - drag.init_cursor_pos).extend(0.0)*projection.scale; }