marble-machinations/src/util.rs

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)
}