use std::sync::{Arc, Mutex}; use winit::event::{ElementState, MouseButton, MouseScrollDelta}; use crate::domain::camera::Camera; use crate::domain::state::InputState; pub struct CameraService; impl CameraService { // Zoom constants const MIN_ZOOM: f32 = 20.0; const MAX_ZOOM: f32 = 50000.0; pub fn handle_resize(camera: &Arc>, width: u32, height: u32) { let mut cam = camera.lock().unwrap(); cam.aspect = width as f32 / height as f32; } pub fn handle_mouse_input(input: &mut InputState, state: ElementState, button: MouseButton) { if button == MouseButton::Left { input.is_dragging = state == ElementState::Pressed; input.last_cursor = None; } } pub fn handle_cursor_move( camera: &Arc>, input: &mut InputState, position_x: f64, position_y: f64, screen_height: f32 ) { if input.is_dragging { if let Some((lx, ly)) = input.last_cursor { let dx = position_x - lx; let dy = position_y - ly; let mut cam = camera.lock().unwrap(); // Use IDENTICAL formula for both X and Y // Since Y works correctly with 2/(zoom*height), use the same for X let scale = 2.0 / (cam.zoom * screen_height); cam.x -= (dx as f32) * scale; cam.y -= (dy as f32) * scale; } input.last_cursor = Some((position_x, position_y)); } } pub fn handle_wheel(camera: &Arc>, delta: MouseScrollDelta) { let scroll = match delta { MouseScrollDelta::LineDelta(_, y) => y as f64, MouseScrollDelta::PixelDelta(pos) => pos.y / 50.0, }; let mut cam = camera.lock().unwrap(); let factor = if scroll > 0.0 { 1.1f32 } else { 0.9f32 }; cam.zoom = (cam.zoom * factor).clamp(Self::MIN_ZOOM, Self::MAX_ZOOM); } // Helper to convert slider (0-100) to zoom (logarithmic) pub fn slider_to_zoom(val: f64) -> f32 { let t = val / 100.0; let log_min = Self::MIN_ZOOM.ln(); let log_max = Self::MAX_ZOOM.ln(); let log_zoom = log_min + (log_max - log_min) * t as f32; log_zoom.exp() } // Helper to convert zoom to slider (0-100) pub fn zoom_to_slider(zoom: f32) -> f64 { let log_min = Self::MIN_ZOOM.ln(); let log_max = Self::MAX_ZOOM.ln(); let log_zoom = zoom.ln(); let t = (log_zoom - log_min) / (log_max - log_min); (t * 100.0) as f64 } }