lgui_core/window/
manager.rs1use std::sync::{Arc, RwLock};
2
3use crate::{
4 core::{Element, InputEvent, RenderCx},
5 platform::dpi::ScalePreference,
6};
7
8use super::{WindowCommand, WindowId, WindowMode, WindowOptions};
9
10type WindowCommandHandler = Arc<dyn Fn(WindowCommand) + Send + Sync>;
11
12#[derive(Clone)]
13pub struct WindowManager {
14 inner: Arc<WindowManagerInner>,
15}
16
17struct WindowManagerInner {
18 command: RwLock<Option<WindowCommandHandler>>,
19}
20
21impl WindowManager {
22 pub(crate) fn new() -> Self {
23 Self {
24 inner: Arc::new(WindowManagerInner {
25 command: RwLock::new(None),
26 }),
27 }
28 }
29
30 pub(crate) fn install(&self, command: impl Fn(WindowCommand) + Send + Sync + 'static) {
31 *self.inner.command.write().expect("window manager poisoned") = Some(Arc::new(command));
32 }
33
34 pub fn show(
35 &self,
36 options: WindowOptions,
37 view: impl for<'scope, 'context> Fn(&mut RenderCx<'scope, 'context>) -> Element
38 + Send
39 + Sync
40 + 'static,
41 ) -> bool {
42 self.send(WindowCommand::Show {
43 options,
44 view: Arc::new(view),
45 })
46 }
47
48 pub fn hide(&self, id: impl Into<WindowId>) -> bool {
49 self.send(WindowCommand::Hide(id.into()))
50 }
51
52 pub fn toggle(
53 &self,
54 options: WindowOptions,
55 view: impl for<'scope, 'context> Fn(&mut RenderCx<'scope, 'context>) -> Element
56 + Send
57 + Sync
58 + 'static,
59 ) -> bool {
60 self.send(WindowCommand::Toggle {
61 options,
62 view: Arc::new(view),
63 })
64 }
65
66 pub fn close(&self, id: impl Into<WindowId>) -> bool {
67 self.send(WindowCommand::Close(id.into()))
68 }
69
70 pub fn request_close(&self, id: impl Into<WindowId>) -> bool {
71 self.send(WindowCommand::RequestClose(id.into()))
72 }
73
74 pub fn minimize(&self, id: impl Into<WindowId>) -> bool {
75 self.send(WindowCommand::Minimize(id.into()))
76 }
77
78 pub fn set_scale_preference(&self, preference: ScalePreference) -> bool {
79 self.send(WindowCommand::SetScalePreference(preference))
80 }
81
82 pub fn set_mode(&self, id: impl Into<WindowId>, mode: WindowMode) -> bool {
83 self.send(WindowCommand::SetMode {
84 id: id.into(),
85 mode,
86 })
87 }
88
89 pub fn send_input(&self, id: impl Into<WindowId>, input: InputEvent) -> bool {
90 self.send(WindowCommand::Input {
91 id: id.into(),
92 input,
93 })
94 }
95
96 pub fn exit(&self) -> bool {
97 self.send(WindowCommand::Exit)
98 }
99
100 fn send(&self, command: WindowCommand) -> bool {
101 let handler = self
102 .inner
103 .command
104 .read()
105 .expect("window manager poisoned")
106 .clone();
107 let Some(handler) = handler else {
108 return false;
109 };
110 handler(command);
111 true
112 }
113}
114
115impl PartialEq for WindowManager {
116 fn eq(&self, other: &Self) -> bool {
117 Arc::ptr_eq(&self.inner, &other.inner)
118 }
119}
120
121#[derive(Clone)]
122pub struct WindowHandle {
123 id: WindowId,
124 windows: WindowManager,
125}
126
127impl WindowHandle {
128 pub(crate) fn new(id: WindowId, windows: WindowManager) -> Self {
129 Self { id, windows }
130 }
131
132 pub fn id(&self) -> &WindowId {
133 &self.id
134 }
135
136 pub fn close(&self) -> bool {
137 self.windows.close(self.id.clone())
138 }
139
140 pub fn request_close(&self) -> bool {
141 self.windows.request_close(self.id.clone())
142 }
143
144 pub fn minimize(&self) -> bool {
145 self.windows.minimize(self.id.clone())
146 }
147
148 pub fn hide(&self) -> bool {
149 self.windows.hide(self.id.clone())
150 }
151
152 pub fn set_mode(&self, mode: WindowMode) -> bool {
153 self.windows.set_mode(self.id.clone(), mode)
154 }
155}