use std::collections::HashMap; use glium::backend::glutin::DisplayCreationError; use glium::{glutin, Surface}; use glutin::event::{Event, WindowEvent}; use glutin::event_loop::{ControlFlow, EventLoop, EventLoopProxy, EventLoopWindowTarget}; use glutin::window::WindowId; use crate::gl::Graphics; use crate::ipc::{IpcMessage, IpcMessageSender}; pub enum WindowMessage { OpenWindow { id: usize }, CloseWindow { id: usize }, Quit, } pub type WindowMessageSender = EventLoopProxy; pub struct Window { pub graphics: Graphics, } impl Window { pub fn new( event_loop: &EventLoopWindowTarget, ) -> Result { let wb = glutin::window::WindowBuilder::new(); let cb = glutin::ContextBuilder::new(); let display = glium::Display::new(wb, cb, &event_loop)?; let graphics = Graphics::new(display); Ok(Self { graphics }) } pub fn get_id(&self) -> WindowId { self.graphics.display.gl_window().window().id() } pub fn request_redraw(&mut self) { self.graphics.display.gl_window().window().request_redraw(); } } pub struct WindowStore { pub ipc_sender: IpcMessageSender, pub ipc_to_window: HashMap, pub windows: HashMap, } impl WindowStore { pub fn new(ipc_sender: IpcMessageSender) -> Self { Self { ipc_sender, ipc_to_window: Default::default(), windows: Default::default(), } } pub fn run(mut self, event_loop: EventLoop) -> ! { event_loop.run(move |event, event_loop, control_flow| match event { Event::WindowEvent { window_id, event } => { if let Some(window) = self.windows.get_mut(&window_id) { match event { WindowEvent::Resized(_) => window.request_redraw(), _ => {} } } } Event::RedrawRequested(id) => { if let Some(window) = self.windows.get_mut(&id) { window.graphics.draw(&[]); } } Event::UserEvent(event) => match event { WindowMessage::OpenWindow { id } => { println!("Opening window {}", id); let window = Window::new(&event_loop).unwrap(); let window_id = window.get_id(); self.windows.insert(window_id, window); self.ipc_to_window.insert(id, window_id); } WindowMessage::CloseWindow { id } => { if let Some(window_id) = self.ipc_to_window.remove(&id) { self.windows.remove(&window_id); } } WindowMessage::Quit => *control_flow = ControlFlow::Exit, }, _ => {} }); } }