158 lines
5.0 KiB
Rust
158 lines
5.0 KiB
Rust
use std::cell::OnceCell;
|
|
use std::rc::Rc;
|
|
use std::sync::Arc;
|
|
use std::sync::atomic::AtomicUsize;
|
|
|
|
use evdev::KeyCode;
|
|
use linfb::shape::Color;
|
|
use slint::platform::software_renderer::{MinimalSoftwareWindow, RepaintBufferType, Rgb565Pixel};
|
|
use slint::platform::{EventLoopProxy, Platform, WindowEvent};
|
|
use slint::{EventLoopError, LogicalPosition, PhysicalSize, Rgb8Pixel, WindowSize};
|
|
|
|
use self::input::InputState;
|
|
use self::screen::Screen;
|
|
|
|
mod input;
|
|
mod screen;
|
|
|
|
static EVENTLOOP_PROXY: OnceCell<Box<dyn EventLoopProxy + 'static>> = OnceCell::new();
|
|
|
|
pub struct Context {
|
|
pub screen: Screen,
|
|
pub input: InputState,
|
|
}
|
|
|
|
pub struct Trekstor {
|
|
window: Rc<MinimalSoftwareWindow>,
|
|
}
|
|
|
|
impl Trekstor {
|
|
pub fn new() -> Self {
|
|
let window = MinimalSoftwareWindow::new(RepaintBufferType::NewBuffer);
|
|
|
|
Self { window }
|
|
}
|
|
}
|
|
|
|
impl Platform for Trekstor {
|
|
fn create_window_adapter(
|
|
&self,
|
|
) -> Result<Rc<dyn slint::platform::WindowAdapter>, slint::PlatformError> {
|
|
Ok(self.window.clone())
|
|
}
|
|
|
|
fn run_event_loop(&self) -> Result<(), slint::PlatformError> {
|
|
let screen = Screen::new();
|
|
let input = InputState::new(&screen);
|
|
let mut ctx = Context { screen, input };
|
|
|
|
let mut buffer1 = [Rgb565Pixel(0); 614400];
|
|
|
|
let window_width = ctx.screen.width();
|
|
let window_height = ctx.screen.height();
|
|
|
|
self.window.set_size(WindowSize::Physical(PhysicalSize::new(
|
|
window_width,
|
|
window_height,
|
|
)));
|
|
|
|
loop {
|
|
ctx.input.handle_event();
|
|
|
|
slint::platform::update_timers_and_animations();
|
|
|
|
if ctx.input.is_just_pressed(KeyCode::BTN_TOUCH) {
|
|
self.window
|
|
.try_dispatch_event(WindowEvent::PointerPressed {
|
|
position: LogicalPosition::new(ctx.input.x as f32, ctx.input.y as f32),
|
|
button: slint::platform::PointerEventButton::Left,
|
|
})
|
|
.unwrap();
|
|
}
|
|
|
|
if ctx.input.is_just_released(KeyCode::BTN_TOUCH) {
|
|
self.window
|
|
.try_dispatch_event(WindowEvent::PointerReleased {
|
|
position: LogicalPosition::new(ctx.input.x as f32, ctx.input.y as f32),
|
|
button: slint::platform::PointerEventButton::Left,
|
|
})
|
|
.unwrap();
|
|
}
|
|
|
|
if ctx.input.is_down(KeyCode::BTN_TOUCH) {
|
|
self.window
|
|
.try_dispatch_event(WindowEvent::PointerMoved {
|
|
position: LogicalPosition::new(ctx.input.x as f32, ctx.input.y as f32),
|
|
})
|
|
.unwrap();
|
|
}
|
|
|
|
self.window.draw_if_needed(|renderer| {
|
|
renderer.render(&mut buffer1, window_width as usize);
|
|
|
|
for (i, px) in buffer1.into_iter().enumerate() {
|
|
let x = (i % window_width as usize) as u32;
|
|
let y = (i / window_width as usize) as u32;
|
|
|
|
let pixel = Rgb8Pixel::from(px);
|
|
let c = Color::from((pixel.r, pixel.g, pixel.b, 255));
|
|
|
|
ctx.screen.framebuffer.set_pixel(x, y, c);
|
|
}
|
|
ctx.screen.flush();
|
|
});
|
|
|
|
ctx.input.finish();
|
|
}
|
|
}
|
|
|
|
fn new_event_loop_proxy(&self) -> Option<Box<dyn EventLoopProxy>> {
|
|
// struct Proxy(
|
|
// winit::event_loop::EventLoopProxy<SlintEvent>,
|
|
// Arc<AtomicUsize>,
|
|
// );
|
|
// impl EventLoopProxy for Proxy {
|
|
// fn quit_event_loop(&self) -> Result<(), EventLoopError> {
|
|
// Err(EventLoopError::EventLoopTerminated)
|
|
// }
|
|
|
|
// fn invoke_from_event_loop(
|
|
// &self,
|
|
// event: Box<dyn FnOnce() + Send>,
|
|
// ) -> Result<(), EventLoopError> {
|
|
// self.0
|
|
// .send_event(SlintEvent(CustomEvent::UserEvent(event)))
|
|
// .map_err(|_| EventLoopError::EventLoopTerminated)
|
|
// }
|
|
// }
|
|
// Some(Box::new(Proxy(
|
|
// self.shared_data.event_loop_proxy.clone(),
|
|
// Arc::clone(&self.shared_data.event_loop_generation),
|
|
// )))
|
|
None
|
|
}
|
|
|
|
fn click_interval(&self) -> core::time::Duration {
|
|
// 500ms is the default delay according to https://en.wikipedia.org/wiki/Double-click#Speed_and_timing
|
|
core::time::Duration::from_millis(500)
|
|
}
|
|
|
|
fn cursor_flash_cycle(&self) -> core::time::Duration {
|
|
core::time::Duration::from_millis(1000)
|
|
}
|
|
|
|
fn set_clipboard_text(&self, _text: &str, _clipboard: slint::platform::Clipboard) {}
|
|
|
|
fn clipboard_text(&self, _clipboard: slint::platform::Clipboard) -> Option<String> {
|
|
None
|
|
}
|
|
|
|
fn debug_log(&self, _arguments: core::fmt::Arguments) {
|
|
crate::debug_log::default_log_message(_arguments);
|
|
}
|
|
|
|
fn open_url(&self, _url: &str) -> Result<(), slint::PlatformError> {
|
|
Err(slint::PlatformError::Unsupported)
|
|
}
|
|
}
|