use crate::core::{Handle, InputEvent, MouseButton, Point, Size, px};
use crate::view::render::View;
use crate::view::theme::Theme;
use crate::view::window::Window;
use std::time::{Duration, Instant};
const QUIET_PERIOD: Duration = Duration::from_millis(30);
const PARK_TIMEOUT: Duration = Duration::from_secs(10);
pub struct TestWindow {
pub window: Window,
}
impl TestWindow {
pub fn new<V: View>(view: impl FnOnce(&mut Window) -> V) -> (Self, Handle<V>) {
let mut window = Window::new(Theme::dark(), Size::new(px(800.0), px(600.0)), 1.0);
let root = view(&mut window);
let handle = window.set_root(root);
window.draw(None);
(Self { window }, handle)
}
fn event(&mut self, event: InputEvent) {
self.window.handle_event(&event);
self.window.draw(None);
}
pub fn simulate_keystrokes(&mut self, keystrokes: &str) {
for keystroke in keystrokes.split_whitespace() {
let mut chars = keystroke.chars();
let text = match (chars.next(), chars.next()) {
(Some(character), None) => Some(character.to_string()),
_ if keystroke == "space" => Some(" ".to_owned()),
_ => None,
};
self.event(InputEvent::KeyDown { keystroke: keystroke.to_owned(), text });
}
}
pub fn simulate_mouse_move(&mut self, x: f32, y: f32) {
self.event(InputEvent::MouseMove { position: Point::new(px(x), px(y)) });
}
pub fn simulate_mouse_down(&mut self, x: f32, y: f32) {
self.event(InputEvent::MouseDown { position: Point::new(px(x), px(y)), button: MouseButton::Left });
}
pub fn simulate_mouse_up(&mut self, x: f32, y: f32) {
self.event(InputEvent::MouseUp { position: Point::new(px(x), px(y)), button: MouseButton::Left });
}
pub fn simulate_click(&mut self, x: f32, y: f32) {
self.simulate_mouse_move(x, y);
self.simulate_mouse_down(x, y);
self.simulate_mouse_up(x, y);
}
pub fn simulate_drag(&mut self, from: (f32, f32), to: (f32, f32)) {
self.simulate_mouse_move(from.0, from.1);
self.simulate_mouse_down(from.0, from.1);
self.simulate_mouse_move((from.0 + to.0) / 2.0, (from.1 + to.1) / 2.0);
self.simulate_mouse_move(to.0, to.1);
self.simulate_mouse_up(to.0, to.1);
}
pub fn run_until_parked(&mut self) {
let deadline = Instant::now() + PARK_TIMEOUT;
let mut last_work = Instant::now();
while last_work.elapsed() < QUIET_PERIOD {
assert!(Instant::now() < deadline, "la ventana nunca quedó en reposo");
if self.window.run_pending() | self.window.wants_animation_frame() {
self.window.draw(None);
last_work = Instant::now();
}
std::thread::sleep(Duration::from_millis(1));
}
}
pub fn read<T: 'static, R>(&self, handle: Handle<T>, read: impl FnOnce(&T) -> R) -> R {
read(self.window.entities.read(handle).expect("la entidad existe"))
}
}