use crate::tui::ecs::events::{InputEvent, Message};
use crate::tui::ecs::resources::MouseButton;
use crate::tui::ecs::world::World;
use crate::tui::key_code::KeyCode;
use crossterm::event::{self, Event, KeyEventKind, MouseEventKind};
use std::time::Duration;
fn crossterm_button_to_mouse_button(button: crossterm::event::MouseButton) -> MouseButton {
match button {
crossterm::event::MouseButton::Left => MouseButton::Left,
crossterm::event::MouseButton::Right => MouseButton::Right,
crossterm::event::MouseButton::Middle => MouseButton::Middle,
}
}
pub fn poll_input(world: &mut World) {
world.resources.keyboard.clear_frame();
world.resources.mouse.clear_frame();
while let Ok(true) = event::poll(Duration::ZERO) {
let Ok(event) = event::read() else {
continue;
};
match event {
Event::Key(key_event) => {
let key: KeyCode = key_event.code.into();
match key_event.kind {
KeyEventKind::Press => {
world.resources.keyboard.pressed.insert(key);
world.resources.keyboard.just_pressed.insert(key);
world.resources.event_bus.publish(Message::Input {
event: InputEvent::KeyPress { key },
});
}
KeyEventKind::Release => {
world.resources.keyboard.pressed.remove(&key);
world.resources.keyboard.just_released.insert(key);
world.resources.event_bus.publish(Message::Input {
event: InputEvent::KeyRelease { key },
});
}
KeyEventKind::Repeat => {
world.resources.keyboard.just_pressed.insert(key);
world.resources.event_bus.publish(Message::Input {
event: InputEvent::KeyPress { key },
});
}
}
}
Event::Mouse(mouse_event) => {
let column = mouse_event.column;
let row = mouse_event.row;
match mouse_event.kind {
MouseEventKind::Down(button) => {
let button = crossterm_button_to_mouse_button(button);
world.resources.mouse.column = column;
world.resources.mouse.row = row;
match button {
MouseButton::Left => {
world.resources.mouse.left_pressed = true;
world.resources.mouse.left_just_pressed = true;
}
MouseButton::Right => {
world.resources.mouse.right_pressed = true;
world.resources.mouse.right_just_pressed = true;
}
MouseButton::Middle => {
world.resources.mouse.middle_pressed = true;
world.resources.mouse.middle_just_pressed = true;
}
}
world.resources.event_bus.publish(Message::Input {
event: InputEvent::MousePress {
button,
column,
row,
},
});
}
MouseEventKind::Up(button) => {
let button = crossterm_button_to_mouse_button(button);
world.resources.mouse.column = column;
world.resources.mouse.row = row;
match button {
MouseButton::Left => {
world.resources.mouse.left_pressed = false;
world.resources.mouse.left_just_released = true;
}
MouseButton::Right => {
world.resources.mouse.right_pressed = false;
world.resources.mouse.right_just_released = true;
}
MouseButton::Middle => {
world.resources.mouse.middle_pressed = false;
world.resources.mouse.middle_just_released = true;
}
}
world.resources.event_bus.publish(Message::Input {
event: InputEvent::MouseRelease {
button,
column,
row,
},
});
}
MouseEventKind::Moved | MouseEventKind::Drag(_) => {
world.resources.mouse.column = column;
world.resources.mouse.row = row;
world.resources.event_bus.publish(Message::Input {
event: InputEvent::MouseMove { column, row },
});
}
MouseEventKind::ScrollUp => {
world.resources.mouse.scroll_delta = 1;
world.resources.event_bus.publish(Message::Input {
event: InputEvent::MouseScroll {
delta: 1,
column,
row,
},
});
}
MouseEventKind::ScrollDown => {
world.resources.mouse.scroll_delta = -1;
world.resources.event_bus.publish(Message::Input {
event: InputEvent::MouseScroll {
delta: -1,
column,
row,
},
});
}
_ => {}
}
}
Event::Resize(columns, rows) => {
world.resources.terminal_size.columns = columns;
world.resources.terminal_size.rows = rows;
world.resources.event_bus.publish(Message::Input {
event: InputEvent::Resize { columns, rows },
});
}
_ => {}
}
}
}