use std::{fs::File, io::BufReader, sync::Arc}; use ashpd::desktop::screenshot::Screenshot; use pollster::FutureExt; use winit::{ application::ApplicationHandler, event::{MouseScrollDelta, WindowEvent}, keyboard::{Key, NamedKey}, window::{Fullscreen, Window}, }; use crate::state::State; #[derive(Default)] pub struct App<'a> { pub state: Option>, } impl<'a> ApplicationHandler for App<'a> { fn resumed(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) { let response = Screenshot::request() .interactive(false) .modal(false) .send() .block_on() .expect("failed to send screenshot request") .response() .expect("failed to receive screenshot response"); let path = response.uri().to_file_path().unwrap(); let file = File::open(&path).unwrap(); let buffer = BufReader::new(file); let image = image::load(buffer, image::ImageFormat::Png).unwrap(); let window = event_loop .create_window( Window::default_attributes().with_fullscreen(Some(Fullscreen::Borderless(None))), ) .unwrap(); self.state = Some(State::new(Arc::new(window), image)); std::fs::remove_file(path).unwrap(); } fn window_event( &mut self, event_loop: &winit::event_loop::ActiveEventLoop, window_id: winit::window::WindowId, event: winit::event::WindowEvent, ) { let state = self.state.as_mut().unwrap(); match event { WindowEvent::CloseRequested => { event_loop.exit(); } WindowEvent::RedrawRequested => { state.window.request_redraw(); state.update(); state.render().unwrap(); } WindowEvent::Resized(new_size) => { state.resize(new_size); } WindowEvent::KeyboardInput { event, .. } => { state.key_input(&event); let key = event.logical_key; if key == Key::Named(NamedKey::Escape) { event_loop.exit(); } } WindowEvent::MouseWheel { device_id, delta, phase, } => match delta { MouseScrollDelta::LineDelta(x, y) => { if y > 0.0 { state.zoom += 0.1; state.zoom = state.zoom.clamp(0.0, 2.0); } else if y < 0.0 { state.zoom -= 0.1; state.zoom = state.zoom.clamp(0.0, 2.0); } } _ => (), }, _ => (), } } }