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<MouseWheel>,
mut camera: Single<(&mut Transform, &mut Projection), With<Camera2d>>,
window: Single<&Window, With<PrimaryWindow>>,
) {
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<ButtonInput<MouseButton>>,
mut drag: ResMut<ShipEditorDrag>,
camera: Single<&Transform, With<Camera2d>>,
window: Single<&Window, With<PrimaryWindow>>,
) {
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<ShipEditorDrag>,
mut camera: Single<(&mut Transform, &Projection), With<Camera2d>>,
window: Single<&Window, With<PrimaryWindow>>,
) {
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;
}