From 341c9a3c12aa9d327ef1d8f168ea0adb9b5ad10b Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 19 Jun 2024 01:53:40 +0200 Subject: Introduce `daemon` API and unify shell runtimes --- winit/src/program/window_manager.rs | 157 ++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 winit/src/program/window_manager.rs (limited to 'winit/src/program/window_manager.rs') diff --git a/winit/src/program/window_manager.rs b/winit/src/program/window_manager.rs new file mode 100644 index 00000000..fcbf79f6 --- /dev/null +++ b/winit/src/program/window_manager.rs @@ -0,0 +1,157 @@ +use crate::core::mouse; +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, + }, + ); + + self.entries + .get_mut(&id) + .expect("Get window that was just inserted") + } + + pub fn is_empty(&self) -> bool { + self.entries.is_empty() + } + + pub fn iter_mut( + &mut self, + ) -> impl Iterator)> { + self.entries.iter_mut().map(|(k, v)| (*k, v)) + } + + 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, +} + +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) + } +} -- cgit