summaryrefslogtreecommitdiffstats
path: root/winit/src/program/window_manager.rs
diff options
context:
space:
mode:
Diffstat (limited to 'winit/src/program/window_manager.rs')
-rw-r--r--winit/src/program/window_manager.rs157
1 files changed, 157 insertions, 0 deletions
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<P, C>
+where
+ P: Program,
+ C: Compositor<Renderer = P::Renderer>,
+ P::Theme: DefaultStyle,
+{
+ aliases: BTreeMap<winit::window::WindowId, Id>,
+ entries: BTreeMap<Id, Window<P, C>>,
+}
+
+impl<P, C> WindowManager<P, C>
+where
+ P: Program,
+ C: Compositor<Renderer = P::Renderer>,
+ P::Theme: DefaultStyle,
+{
+ pub fn new() -> Self {
+ Self {
+ aliases: BTreeMap::new(),
+ entries: BTreeMap::new(),
+ }
+ }
+
+ pub fn insert(
+ &mut self,
+ id: Id,
+ window: Arc<winit::window::Window>,
+ application: &P,
+ compositor: &mut C,
+ exit_on_close_request: bool,
+ ) -> &mut Window<P, C> {
+ 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<Item = (Id, &mut Window<P, C>)> {
+ self.entries.iter_mut().map(|(k, v)| (*k, v))
+ }
+
+ pub fn get_mut(&mut self, id: Id) -> Option<&mut Window<P, C>> {
+ self.entries.get_mut(&id)
+ }
+
+ pub fn get_mut_alias(
+ &mut self,
+ id: winit::window::WindowId,
+ ) -> Option<(Id, &mut Window<P, C>)> {
+ let id = self.aliases.get(&id).copied()?;
+
+ Some((id, self.get_mut(id)?))
+ }
+
+ pub fn last_monitor(&self) -> Option<MonitorHandle> {
+ self.entries.values().last()?.raw.current_monitor()
+ }
+
+ pub fn remove(&mut self, id: Id) -> Option<Window<P, C>> {
+ let window = self.entries.remove(&id)?;
+ let _ = self.aliases.remove(&window.raw.id());
+
+ Some(window)
+ }
+}
+
+impl<P, C> Default for WindowManager<P, C>
+where
+ P: Program,
+ C: Compositor<Renderer = P::Renderer>,
+ P::Theme: DefaultStyle,
+{
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+#[allow(missing_debug_implementations)]
+pub struct Window<P, C>
+where
+ P: Program,
+ C: Compositor<Renderer = P::Renderer>,
+ P::Theme: DefaultStyle,
+{
+ pub raw: Arc<winit::window::Window>,
+ pub state: State<P>,
+ pub viewport_version: u64,
+ pub exit_on_close_request: bool,
+ pub mouse_interaction: mouse::Interaction,
+ pub surface: C::Surface,
+ pub renderer: P::Renderer,
+}
+
+impl<P, C> Window<P, C>
+where
+ P: Program,
+ C: Compositor<Renderer = P::Renderer>,
+ P::Theme: DefaultStyle,
+{
+ pub fn position(&self) -> Option<Point> {
+ 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)
+ }
+}