use crate::display::TextBufferDisplayData;
use crate::TextBuffer;
use glutin::{MouseButton, VirtualKeyCode};
use std::collections::HashMap;
#[derive(Clone)]
pub struct Events {
pub keyboard: Input<VirtualKeyCode>,
pub mouse: Input<MouseButton>,
pub cursor: Cursor,
pub chars: Chars,
}
impl Events {
pub(crate) fn new(text_buffer_aspect_ratio: bool) -> Events {
Events {
keyboard: Input::new(),
mouse: Input::new(),
cursor: Cursor::new(text_buffer_aspect_ratio),
chars: Chars::new(),
}
}
pub(crate) fn clear_just_lists(&mut self) {
self.keyboard.clear_just_lists();
self.mouse.clear_just_lists();
self.cursor.clear_just_moved();
self.chars.clear_just_received();
}
}
#[derive(Clone)]
pub struct Chars {
just_received_chars: Vec<char>,
}
impl Chars {
pub(crate) fn new() -> Chars {
Chars {
just_received_chars: Vec::new(),
}
}
pub(crate) fn add_char(&mut self, character: char) {
self.just_received_chars.push(character);
}
pub(crate) fn clear_just_received(&mut self) {
self.just_received_chars = Vec::new();
}
pub fn get_chars(&self) -> Vec<char> {
self.just_received_chars.clone()
}
}
#[derive(Clone)]
pub struct Cursor {
location: Option<(f32, f32)>,
just_moved: bool,
use_text_buffer_overflows: bool,
display_overflows: (f32, f32),
display_relative_dimensions: (f32, f32),
text_buffer_datas: HashMap<u32, TextBufferDisplayData>,
}
impl Cursor {
pub(crate) fn new(use_text_buffer_overflows: bool) -> Cursor {
Cursor {
location: None,
just_moved: false,
use_text_buffer_overflows: use_text_buffer_overflows,
display_overflows: (0.0, 0.0),
display_relative_dimensions: (0.0, 0.0),
text_buffer_datas: HashMap::new(),
}
}
pub(crate) fn update_display_datas(
&mut self,
display_overflows: (f32, f32),
display_relative_dimensions: (f32, f32),
datas: HashMap<u32, TextBufferDisplayData>,
) {
self.display_overflows = display_overflows;
self.display_relative_dimensions = display_relative_dimensions;
self.text_buffer_datas = datas;
}
pub(crate) fn update_location(&mut self, location: (f32, f32)) {
self.just_moved = true;
self.location = Some((location.0, location.1));
}
pub(crate) fn cursor_left(&mut self) {
self.just_moved = true;
self.location = None;
}
pub(crate) fn clear_just_moved(&mut self) {
self.just_moved = false;
}
pub fn cursor_just_moved(&self) -> bool {
self.just_moved
}
pub fn get_location(&self, text_buffer: &TextBuffer) -> Option<(u32, u32)> {
if let Some(location) = self.location {
let mut overflows = self.display_overflows;
let mut relative_dimensions = self.display_relative_dimensions;
if self.use_text_buffer_overflows {
if let Some(data) = self.text_buffer_datas.get(&text_buffer.get_idx()) {
overflows = data.overflows;
relative_dimensions = data.relative_dimensions;
}
}
if location.0 > overflows.0
&& location.0 < 1.0 - overflows.0
&& location.1 > overflows.1
&& location.1 < 1.0 - overflows.1
{
let x = (location.0 - overflows.0) * relative_dimensions.0;
let y = (location.1 - overflows.1) * relative_dimensions.1;
Some((
(x * text_buffer.width as f32).floor() as u32,
(y * text_buffer.height as f32).floor() as u32,
))
} else {
None
}
} else {
None
}
}
}
#[derive(Clone)]
pub struct Input<T: PartialEq + Copy> {
pressed: Vec<T>,
just_released: Vec<T>,
just_pressed: Vec<T>,
}
impl<T: PartialEq + Copy> Input<T> {
pub(crate) fn new() -> Input<T> {
Input {
pressed: Vec::new(),
just_pressed: Vec::new(),
just_released: Vec::new(),
}
}
pub(crate) fn clear_just_lists(&mut self) {
self.just_pressed.clear();
self.just_released.clear();
}
pub(crate) fn update_button_press(&mut self, button: T, pressed: bool) {
if pressed && !self.pressed.contains(&button) {
self.pressed.push(button);
self.just_pressed.push(button);
} else if !pressed && self.pressed.contains(&button) {
self.just_released.push(button);
if let Some(idx) = self.find_buttonpress_idx_from_pressed(button) {
self.pressed.remove(idx);
}
}
}
pub fn is_pressed(&self, button: T) -> bool {
self.pressed.contains(&button)
}
pub fn was_just_pressed(&self, button: T) -> bool {
self.just_pressed.contains(&button)
}
pub fn was_just_released(&self, button: T) -> bool {
self.just_released.contains(&button)
}
pub fn get_just_pressed_list(&self) -> Vec<T> {
self.just_pressed.clone()
}
pub fn get_just_released_list(&self) -> Vec<T> {
self.just_released.clone()
}
pub fn get_pressed_list(&self) -> Vec<T> {
self.pressed.clone()
}
fn find_buttonpress_idx_from_pressed(&self, button: T) -> Option<usize> {
let mut idx: usize = 0;
let mut found = false;
for i in 0..self.pressed.len() {
if button == self.pressed[i] {
idx = i;
found = true;
}
}
if found {
Some(idx)
} else {
None
}
}
}