use crate::core::mouse; use crate::core::time::Instant; use crate::core::window::Id; use crate::core::{Point, Size}; use crate::graphics::Compositor; use crate::program::{DefaultStyle, Program, State}; use std::collections::BTreeMap; use std::sync::Arc; use winit::monitor::MonitorHandle; #[allow(missing_debug_implementations)] pub struct WindowManager where P: Program, C: Compositor, P::Theme: DefaultStyle, { aliases: BTreeMap, entries: BTreeMap>, } impl WindowManager where P: Program, C: Compositor, P::Theme: DefaultStyle, { pub fn new() -> Self { Self { aliases: BTreeMap::new(), entries: BTreeMap::new(), } } pub fn insert( &mut self, id: Id, window: Arc, application: &P, compositor: &mut C, exit_on_close_request: bool, ) -> &mut Window { let state = State::new(application, id, &window); let viewport_version = state.viewport_version(); let physical_size = state.physical_size(); let surface = compositor.create_surface( window.clone(), physical_size.width, physical_size.height, ); let renderer = compositor.create_renderer(); let _ = self.aliases.insert(window.id(), id); let _ = self.entries.insert( id, Window { raw: window, state, viewport_version, exit_on_close_request, surface, renderer, mouse_interaction: mouse::Interaction::None, redraw_at: None, }, ); self.entries .get_mut(&id) .expect("Get window that was just inserted") } pub fn is_empty(&self) -> bool { self.entries.is_empty() } pub fn is_idle(&self) -> bool { self.entries .values() .all(|window| window.redraw_at.is_none()) } pub fn redraw_at(&self) -> Option { self.entries .values() .filter_map(|window| window.redraw_at) .min() } pub fn first(&self) -> Option<&Window> { self.entries.first_key_value().map(|(_id, window)| window) } pub fn iter_mut( &mut self, ) -> impl Iterator)> { self.entries.iter_mut().map(|(k, v)| (*k, v)) } pub fn get(&self, id: Id) -> Option<&Window> { self.entries.get(&id) } pub fn get_mut(&mut self, id: Id) -> Option<&mut Window> { self.entries.get_mut(&id) } pub fn get_mut_alias( &mut self, id: winit::window::WindowId, ) -> Option<(Id, &mut Window)> { let id = self.aliases.get(&id).copied()?; Some((id, self.get_mut(id)?)) } pub fn last_monitor(&self) -> Option { self.entries.values().last()?.raw.current_monitor() } pub fn remove(&mut self, id: Id) -> Option> { let window = self.entries.remove(&id)?; let _ = self.aliases.remove(&window.raw.id()); Some(window) } } impl Default for WindowManager where P: Program, C: Compositor, P::Theme: DefaultStyle, { fn default() -> Self { Self::new() } } #[allow(missing_debug_implementations)] pub struct Window where P: Program, C: Compositor, P::Theme: DefaultStyle, { pub raw: Arc, pub state: State

, pub viewport_version: u64, pub exit_on_close_request: bool, pub mouse_interaction: mouse::Interaction, pub surface: C::Surface, pub renderer: P::Renderer, pub redraw_at: Option, } impl Window where P: Program, C: Compositor, P::Theme: DefaultStyle, { pub fn position(&self) -> Option { self.raw .inner_position() .ok() .map(|position| position.to_logical(self.raw.scale_factor())) .map(|position| Point { x: position.x, y: position.y, }) } pub fn size(&self) -> Size { let size = self.raw.inner_size().to_logical(self.raw.scale_factor()); Size::new(size.width, size.height) } }