Files
dashboard/src/trekstor.rs
2026-08-06 12:06:07 +02:00

99 lines
2.8 KiB
Rust

use std::rc::Rc;
use std::thread::sleep;
use std::time::{Duration, Instant};
use evdev::KeyCode;
use slint::LogicalPosition;
use slint::platform::software_renderer::{MinimalSoftwareWindow, RepaintBufferType};
use slint::platform::{Platform, WindowEvent};
use self::input::InputState;
use self::screen::Screen;
type UpdateFn<S> = fn(&mut Context, &mut S) -> bool;
mod input;
mod screen;
pub struct Context {
pub screen: Screen,
pub input: InputState,
}
pub struct Trekstor<S> {
state: S,
ctx: Context,
window: Rc<MinimalSoftwareWindow>,
last_time: Instant,
current_time: Instant,
update_timestep: Duration,
}
impl<S> Trekstor<S> {
pub fn new(update_fps: i32, state: S) -> Self {
let screen = Screen::new();
let input = InputState::new(&screen);
let window = MinimalSoftwareWindow::new(RepaintBufferType::ReusedBuffer);
Self {
state,
ctx: Context { screen, input },
window,
current_time: Instant::now(),
last_time: Instant::now(),
update_timestep: Duration::from_nanos(
(1_000_000_000f64 / update_fps as f64).round() as u64
),
}
}
pub fn update(&mut self) {
loop {
self.current_time = Instant::now();
let dt = self.current_time - self.last_time;
self.last_time = self.current_time;
if dt < self.update_timestep {
sleep(self.update_timestep - dt);
}
self.ctx.input.handle_event();
slint::platform::update_timers_and_animations();
if self.ctx.input.is_just_pressed(KeyCode::BTN_TOUCH) {
self.window.try_dispatch_event(WindowEvent::PointerPressed {
position: LogicalPosition::new(
self.ctx.input.x as f32,
self.ctx.input.y as f32,
),
button: slint::platform::PointerEventButton::Left,
});
}
if self.ctx.input.is_just_released(KeyCode::BTN_TOUCH) {
self.window
.try_dispatch_event(WindowEvent::PointerReleased {
position: LogicalPosition::new(
self.ctx.input.x as f32,
self.ctx.input.y as f32,
),
button: slint::platform::PointerEventButton::Left,
});
}
self.ctx.screen.flush();
self.ctx.input.finish();
}
}
}
impl<S> Platform for Trekstor<S> {
fn create_window_adapter(
&self,
) -> Result<Rc<dyn slint::platform::WindowAdapter>, slint::PlatformError> {
Ok(self.window.clone())
}
// ..
}