149 lines
3.3 KiB
Rust
149 lines
3.3 KiB
Rust
use std::{collections::HashMap, fs::read_dir, path::PathBuf};
|
|
|
|
use raylib::prelude::*;
|
|
|
|
#[derive(Default)]
|
|
pub struct Textures {
|
|
map: HashMap<String, Texture2D>,
|
|
}
|
|
|
|
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<T>(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<Scroll>,
|
|
}
|
|
|
|
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<Scroll> {
|
|
self.scroll
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
|
pub enum Scroll {
|
|
Up,
|
|
Down,
|
|
}
|
|
|
|
pub fn get_scroll(rl: &RaylibHandle) -> Option<Scroll> {
|
|
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)
|
|
}
|