use std::{collections::HashMap, fs::read_dir, path::PathBuf}; use raylib::prelude::*; #[derive(Default)] pub struct Textures { map: HashMap, } impl Textures { pub fn load_dir(&mut self, folder: &str, rl: &mut RaylibHandle, thread: &RaylibThread) { for d in read_dir(folder).unwrap().flatten() { let path = d.path(); if path.is_file() { let name = path.file_stem().unwrap().to_string_lossy(); let texture = rl .load_texture(thread, &format!("{folder}/{name}.png")) .unwrap(); self.map.insert(name.to_string(), texture); } } } pub fn get(&self, name: &str) -> &Texture2D { self.map .get(name) .unwrap_or_else(|| self.map.get("missing").unwrap()) } } pub fn userdata_dir() -> PathBuf { PathBuf::from("user") } pub fn draw_scaled_texture( d: &mut RaylibDrawHandle, texture: &Texture2D, x: i32, y: i32, scale: f32, ) { let pos = Vector2::new(x as f32, y as f32); d.draw_texture_ex(texture, pos, 0., scale, Color::WHITE); } pub fn get_free_id(items: &[T], id_fn: fn(&T) -> usize) -> usize { let mut id = 0; while items.iter().any(|i| id_fn(i) == id) { id += 1; } id } pub fn screen_centered_rect(rl: &RaylibHandle, width: i32, height: i32) -> Rectangle { let w = rl.get_screen_width(); let h = rl.get_screen_height(); Rectangle { x: (w / 2 - width / 2) as f32, y: (h / 2 - height / 2) as f32, width: width as f32, height: height as f32, } } pub fn screen_centered_rect_dyn(rl: &RaylibHandle, margin_x: i32, margin_y: i32) -> Rectangle { let w = rl.get_screen_width(); let h = rl.get_screen_height(); Rectangle { x: margin_x as f32, y: margin_y as f32, width: (w - margin_x * 2) as f32, height: (h - margin_y * 2) as f32, } } #[derive(Debug, Default)] pub struct MouseInput { pos: Vector2, left_click: bool, left_hold: bool, left_release: bool, right_hold: bool, scroll: Option, } impl MouseInput { pub fn update(&mut self, rl: &RaylibHandle) { self.pos = rl.get_mouse_position(); self.left_click = rl.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT); self.left_hold = rl.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT); self.left_release = rl.is_mouse_button_released(MouseButton::MOUSE_BUTTON_LEFT); self.right_hold = rl.is_mouse_button_down(MouseButton::MOUSE_BUTTON_RIGHT); self.scroll = get_scroll(rl); } pub fn is_over(&self, rect: Rectangle) -> bool { rect.check_collision_point_rec(self.pos) } pub fn clear(&mut self) { *self = Self::default(); } pub fn pos(&self) -> Vector2 { self.pos } pub fn left_click(&self) -> bool { self.left_click } pub fn left_hold(&self) -> bool { self.left_hold } pub fn left_release(&self) -> bool { self.left_release } pub fn right_hold(&self) -> bool { self.right_hold } pub fn scroll(&self) -> Option { self.scroll } } #[derive(Debug, Clone, Copy, PartialEq)] pub enum Scroll { Up, Down, } pub fn get_scroll(rl: &RaylibHandle) -> Option { const SCROLL_THRESHOLD: f32 = 0.5; let value = rl.get_mouse_wheel_move(); if value > SCROLL_THRESHOLD { Some(Scroll::Up) } else if value < -SCROLL_THRESHOLD { Some(Scroll::Down) } else { None } } pub fn rect(x: i32, y: i32, width: i32, height: i32) -> Rectangle { Rectangle::new(x as f32, y as f32, width as f32, height as f32) }