properly center editor view and make zoom follow mouse position

This commit is contained in:
Crispy 2024-10-07 21:21:37 +02:00
parent 355a5af15e
commit 82d0ff0f37
3 changed files with 40 additions and 9 deletions

View file

@ -4,9 +4,6 @@
logic mostly like https://git.crispypin.cc/CrispyPin/marble
## todo
cleanup: unpowered texture names x_off -> x
scroll output
properly center view
make marble movement not order-dependent (`>ooo <` does not behave symmetrically)
blueprints
scroll level list

View file

@ -17,6 +17,7 @@ use crate::{
const HEADER_HEIGHT: i32 = 40;
const FOOTER_HEIGHT: i32 = 95;
const MAX_ZOOM_IN: i32 = 3;
#[derive(Debug)]
pub struct Editor {
@ -212,6 +213,37 @@ impl Editor {
}
}
pub fn center_view(&mut self, d: &RaylibHandle) {
let tile_size = (16 << self.zoom) as f32;
let tile_x = self.source_board.width() as f32 / 2. * tile_size;
let tile_y = self.source_board.height() as f32 / 2. * tile_size;
let screen_x = d.get_screen_width() as f32 / 2.;
let screen_y = d.get_screen_height() as f32 / 2.;
self.view_offset.x = screen_x - tile_x;
self.view_offset.y = screen_y - tile_y;
}
fn change_zoom_level(&mut self, d: &RaylibHandle, delta: i32) {
let tile_size = (16 << self.zoom) as f32;
let mouse_pos = d.get_mouse_position();
let tile_pos_of_mouse = (mouse_pos - self.view_offset) / tile_size;
self.zoom += delta;
let tile_size = (16 << self.zoom) as f32;
self.view_offset = mouse_pos - tile_pos_of_mouse * tile_size;
}
fn zoom_in(&mut self, d: &RaylibHandle) {
if self.zoom < MAX_ZOOM_IN {
self.change_zoom_level(d, 1);
}
}
fn zoom_out(&mut self, d: &RaylibHandle) {
if self.zoom > 0 {
self.change_zoom_level(d, -1);
}
}
fn set_tile(&mut self, mut pos: Pos, tile: Tile) {
let tile_size = (16 << self.zoom) as f32;
let (x, y) = self.source_board.grow_to_include(pos);
@ -271,17 +303,17 @@ impl Editor {
}
}
if rl.get_mouse_wheel_move() > 0. && self.zoom < 3 {
self.zoom += 1;
if rl.get_mouse_wheel_move() > 0. {
self.zoom_in(rl);
}
if rl.get_mouse_wheel_move() < 0. && self.zoom > 0 {
self.zoom -= 1;
if rl.get_mouse_wheel_move() < 0. {
self.zoom_out(rl);
}
if rl.is_mouse_button_down(MouseButton::MOUSE_BUTTON_MIDDLE) {
self.view_offset += rl.get_mouse_delta()
}
if rl.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_RIGHT) {
self.view_offset = Vector2::zero();
self.center_view(rl);
}
if rl.is_key_pressed(KeyboardKey::KEY_R) {

View file

@ -213,7 +213,9 @@ impl Game {
d.draw_text(solution.id(), column_x, y + 35, 10, Color::GRAY);
if simple_button(d, column_x, y + 50, 220, 30) {
self.open_editor = Some(Editor::new(solution.clone(), level.clone()));
let mut editor = Editor::new(solution.clone(), level.clone());
editor.center_view(d);
self.open_editor = Some(editor);
}
d.draw_text("edit", column_x + 5, y + 55, 20, Color::WHITE);
}