1use crate::{
2 Placement, Root,
3 dialog::{AlertDialog, Dialog},
4 input::AnyInputState,
5 notification::Notification,
6 sheet::Sheet,
7};
8use gpui::{App, ElementId, Entity, Window};
9use std::rc::Rc;
10
11pub trait WindowExt: Sized {
13 fn open_sheet<F>(&mut self, cx: &mut App, build: F)
15 where
16 F: Fn(Sheet, &mut Window, &mut App) -> Sheet + 'static;
17
18 fn open_sheet_at<F>(&mut self, placement: Placement, cx: &mut App, build: F)
20 where
21 F: Fn(Sheet, &mut Window, &mut App) -> Sheet + 'static;
22
23 fn has_active_sheet(&mut self, cx: &mut App) -> bool;
25
26 fn close_sheet(&mut self, cx: &mut App);
28
29 fn open_dialog<F>(&mut self, cx: &mut App, build: F)
31 where
32 F: Fn(Dialog, &mut Window, &mut App) -> Dialog + 'static;
33
34 fn open_alert_dialog<F>(&mut self, cx: &mut App, build: F)
52 where
53 F: Fn(AlertDialog, &mut Window, &mut App) -> AlertDialog + 'static;
54
55 fn has_active_dialog(&mut self, cx: &mut App) -> bool;
57
58 fn close_dialog(&mut self, cx: &mut App);
60
61 fn close_all_dialogs(&mut self, cx: &mut App);
63
64 fn push_notification(&mut self, note: impl Into<Notification>, cx: &mut App);
66
67 fn remove_notification<T: Sized + 'static>(&mut self, cx: &mut App);
70
71 fn remove_notification1<T: Sized + 'static>(&mut self, key: impl Into<ElementId>, cx: &mut App);
73
74 fn clear_notifications(&mut self, cx: &mut App);
76
77 fn notifications(&mut self, cx: &mut App) -> Rc<Vec<Entity<Notification>>>;
79
80 fn focused_input(&mut self, cx: &mut App) -> Option<AnyInputState>;
87 fn has_focused_input(&mut self, cx: &mut App) -> bool;
89
90 #[deprecated(note = "use gpui_base::TextSelection::selected_text instead")]
93 fn selected_text(&mut self, cx: &mut App) -> String;
94
95 #[deprecated(note = "use gpui_base::TextSelection::has_selection instead")]
98 fn has_text_selection(&mut self, cx: &mut App) -> bool;
99
100 #[deprecated(note = "use gpui_base::TextSelection::clear instead")]
102 fn clear_text_selection(&mut self, cx: &mut App);
103
104 #[deprecated(note = "use gpui_base::TextSelection::end instead")]
106 fn end_text_selection(&mut self, cx: &mut App);
107}
108
109impl WindowExt for Window {
110 #[inline]
111 fn open_sheet<F>(&mut self, cx: &mut App, build: F)
112 where
113 F: Fn(Sheet, &mut Window, &mut App) -> Sheet + 'static,
114 {
115 self.open_sheet_at(Placement::Right, cx, build)
116 }
117
118 #[inline]
119 fn open_sheet_at<F>(&mut self, placement: Placement, cx: &mut App, build: F)
120 where
121 F: Fn(Sheet, &mut Window, &mut App) -> Sheet + 'static,
122 {
123 Root::update(self, cx, move |root, window, cx| {
124 root.open_sheet_at(placement, build, window, cx);
125 })
126 }
127
128 #[inline]
129 fn has_active_sheet(&mut self, cx: &mut App) -> bool {
130 Root::read(self, cx).active_sheet.is_some()
131 }
132
133 #[inline]
134 fn close_sheet(&mut self, cx: &mut App) {
135 Root::update(self, cx, |root, window, cx| {
136 root.close_sheet(window, cx);
137 })
138 }
139
140 #[inline]
141 fn open_dialog<F>(&mut self, cx: &mut App, build: F)
142 where
143 F: Fn(Dialog, &mut Window, &mut App) -> Dialog + 'static,
144 {
145 Root::update(self, cx, move |root, window, cx| {
146 root.open_dialog(build, window, cx);
147 })
148 }
149
150 #[inline]
151 fn open_alert_dialog<F>(&mut self, cx: &mut App, build: F)
152 where
153 F: Fn(AlertDialog, &mut Window, &mut App) -> AlertDialog + 'static,
154 {
155 self.open_dialog(cx, move |_, window, cx| {
156 build(AlertDialog::new(cx), window, cx).build_surface(window, cx)
157 })
158 }
159
160 #[inline]
161 fn has_active_dialog(&mut self, cx: &mut App) -> bool {
162 Root::read(self, cx).active_dialogs.len() > 0
163 }
164
165 #[inline]
166 fn close_dialog(&mut self, cx: &mut App) {
167 Root::update(self, cx, |root, window, cx| {
168 root.close_dialog(window, cx);
169 })
170 }
171
172 #[inline]
173 fn close_all_dialogs(&mut self, cx: &mut App) {
174 Root::update(self, cx, |root, window, cx| {
175 root.close_all_dialogs(window, cx);
176 })
177 }
178
179 #[inline]
180 fn push_notification(&mut self, note: impl Into<Notification>, cx: &mut App) {
181 let note = note.into();
182 Root::update(self, cx, |root, window, cx| {
183 root.push_notification(note, window, cx);
184 })
185 }
186
187 #[inline]
188 fn remove_notification<T: Sized + 'static>(&mut self, cx: &mut App) {
189 Root::update(self, cx, |root, window, cx| {
190 root.remove_notification::<T>(window, cx);
191 })
192 }
193
194 #[inline]
195 fn remove_notification1<T: Sized + 'static>(
196 &mut self,
197 key: impl Into<ElementId>,
198 cx: &mut App,
199 ) {
200 let key = key.into();
201 Root::update(self, cx, |root, window, cx| {
202 root.remove_notification1::<T>(key, window, cx);
203 })
204 }
205
206 #[inline]
207 fn clear_notifications(&mut self, cx: &mut App) {
208 Root::update(self, cx, |root, window, cx| {
209 root.clear_notifications(window, cx);
210 })
211 }
212
213 #[inline]
214 fn notifications(&mut self, cx: &mut App) -> Rc<Vec<Entity<Notification>>> {
215 Rc::new(Root::read(self, cx).notification.read(cx).notifications())
216 }
217
218 #[inline]
219 fn has_focused_input(&mut self, cx: &mut App) -> bool {
220 self.focused_input(cx).is_some()
221 }
222
223 fn focused_input(&mut self, cx: &mut App) -> Option<AnyInputState> {
224 let state = Root::read(self, cx).focused_input.clone()?;
225 if state.focus_handle(cx).is_focused(self) {
226 return Some(state);
227 }
228
229 Root::try_update(self, cx, |root, _, cx| {
232 if root.focused_input.as_ref() == Some(&state) {
233 root.focused_input = None;
234 cx.notify();
235 }
236 });
237 None
238 }
239
240 #[inline]
241 fn selected_text(&mut self, cx: &mut App) -> String {
242 gpui_base::TextSelection::selected_text(self, cx)
243 }
244
245 #[inline]
246 fn has_text_selection(&mut self, cx: &mut App) -> bool {
247 gpui_base::TextSelection::has_selection(self, cx)
248 }
249
250 #[inline]
251 fn clear_text_selection(&mut self, cx: &mut App) {
252 gpui_base::TextSelection::clear(self, cx);
253 }
254
255 #[inline]
256 fn end_text_selection(&mut self, cx: &mut App) {
257 gpui_base::TextSelection::end(self, cx);
258 }
259}