1use std::{
13 any::type_name,
14 iter::Chain,
15 sync::{Arc, Mutex},
16};
17
18use super::{Node, Widget, layout::Layout};
19use crate::{
20 buffer::{Buffer, PathKind},
21 context::{self, Cache, Handle},
22 data::{Pass, RwData},
23 hook::{self, BufferClosed, WidgetCreated, WindowCreated},
24 mode,
25 opts::PrintOpts,
26 session::UiMouseEvent,
27 text::{SpawnId, Text, txt},
28 ui::{DynSpawnSpecs, PushSpecs, RwArea, Ui},
29};
30
31pub struct Windows {
33 inner: RwData<InnerWindows>,
34 spawns_to_remove: Mutex<Vec<SpawnId>>,
35 ui: Ui,
36}
37
38struct InnerWindows {
40 layout: Box<Mutex<dyn Layout>>,
41 list: Vec<Window>,
42 new_additions: Arc<Mutex<Option<Vec<(usize, Node)>>>>,
43 cur_buffer: RwData<Handle>,
44 cur_widget: RwData<Node>,
45 cur_win: usize,
46 buffer_history: BufferHistory,
47}
48
49impl Windows {
50 pub(crate) fn initialize(
53 pa: &mut Pass,
54 buffer: Buffer,
55 layout: Box<Mutex<dyn Layout>>,
56 ui: Ui,
57 ) {
58 let new_additions = Arc::new(Mutex::default());
59 let (window, node) = Window::new(0, pa, ui, buffer, new_additions.clone());
60
61 context::set_windows(Self {
62 inner: RwData::new(InnerWindows {
63 layout,
64 list: vec![window.clone()],
65 new_additions,
66 cur_buffer: RwData::new(node.try_downcast().unwrap()),
67 cur_widget: RwData::new(node.clone()),
68 cur_win: 0,
69 buffer_history: BufferHistory::default(),
70 }),
71 spawns_to_remove: Mutex::new(Vec::new()),
72 ui,
73 });
74
75 hook::trigger(
76 pa,
77 WidgetCreated(node.handle().try_downcast::<Buffer>().unwrap()),
78 );
79 hook::trigger(pa, WindowCreated(window));
80 }
81
82 pub(crate) fn new_window(&self, pa: &mut Pass, buffer: Buffer) -> Node {
87 let win = self.inner.read(pa).list.len();
88 let new_additions = self.inner.read(pa).new_additions.clone();
89 let (window, node) = Window::new(win, pa, self.ui, buffer, new_additions);
90
91 let inner = self.inner.write(pa);
92 inner.list.push(window);
93
94 hook::trigger(
95 pa,
96 WidgetCreated(node.handle().try_downcast::<Buffer>().unwrap()),
97 );
98 hook::trigger(pa, WindowCreated(self.inner.read(pa).list[win].clone()));
99
100 node
101 }
102
103 pub(crate) fn push_widget<W: Widget>(
105 &self,
106 pa: &mut Pass,
107 (target, on_buffers, specs): (&RwArea, Option<bool>, PushSpecs),
108 widget: W,
109 master: Option<&RwArea>,
110 ) -> Option<Handle<W>> {
111 self.push(pa, (target, on_buffers, specs), widget, master)?
112 .handle()
113 .try_downcast()
114 }
115
116 pub(crate) fn spawn_on_widget<W: Widget>(
120 &self,
121 pa: &mut Pass,
122 (target, specs): (&RwArea, DynSpawnSpecs),
123 widget: W,
124 ) -> Option<Handle<W>> {
125 let (win, cluster_master, master) =
126 self.inner
127 .read(pa)
128 .list
129 .iter()
130 .enumerate()
131 .find_map(|(win, window)| {
132 let inner = window.0.read(pa);
133 let master = window.nodes(pa).find_map(|node| {
134 node.area()
135 .area_is_eq(pa, target)
136 .then(|| node.handle().clone())
137 });
138
139 if inner.master_area.is_master_of(pa, target) {
140 Some((win, None, master))
141 } else if let Some((_, node)) = inner
142 .spawned
143 .iter()
144 .find(|(_, node)| node.area().is_master_of(pa, target))
145 {
146 Some((win, node.area().get_cluster_master(pa), master))
147 } else {
148 None
149 }
150 })?;
151
152 let widget = RwData::new(widget);
153 let id = SpawnId::new();
154
155 let path = widget
156 .read_as::<Buffer>(pa)
157 .and_then(|buffer| buffer.path_set());
158 let spawned = cluster_master.as_ref().unwrap_or(target).spawn(
159 pa,
160 path.as_ref().map(|p| p.as_ref()),
161 id,
162 specs,
163 )?;
164
165 let node = Node::new(widget, spawned, master);
166
167 let window = self.inner.write(pa).list.remove(win);
168 window.add(pa, node.clone(), None, Location::Spawned(id));
169 self.inner.write(pa).list.insert(win, window);
170
171 hook::trigger(
172 pa,
173 WidgetCreated(node.handle().try_downcast::<W>().unwrap()),
174 );
175
176 node.handle().try_downcast()
177 }
178
179 pub(crate) fn spawn_on_text<W: Widget>(
181 &self,
182 pa: &mut Pass,
183 (id, specs): (SpawnId, DynSpawnSpecs),
184 widget: W,
185 win: usize,
186 master: Handle<dyn Widget>,
187 ) -> Handle<W> {
188 let widget = RwData::new(widget);
189 let path = widget
190 .read_as::<Buffer>(pa)
191 .and_then(|buffer| buffer.path_set());
192 let spawned = self
193 .ui
194 .new_spawned(path.as_ref().map(|p| p.as_ref()), id, specs, win);
195
196 let node = Node::new(widget, spawned, Some(master));
197
198 let window = self.inner.write(pa).list.remove(win);
199 window.add(pa, node.clone(), None, Location::Spawned(id));
200 self.inner.write(pa).list.insert(win, window);
201
202 hook::trigger(
203 pa,
204 WidgetCreated(node.handle().try_downcast::<W>().unwrap()),
205 );
206
207 node.handle().try_downcast().unwrap()
208 }
209
210 pub(crate) fn new_buffer(&self, pa: &mut Pass, buffer: Buffer) -> Node {
217 let inner = self.inner.read(pa);
218 let (handle, specs) = inner.layout.lock().unwrap().new_buffer(pa, &inner.list);
219
220 let specs = PushSpecs { cluster: false, ..specs };
221
222 if let Some(master) = handle.area().get_cluster_master(pa) {
223 self.push(pa, (&master, Some(true), specs), buffer, None)
224 .unwrap()
225 } else {
226 self.push(pa, (&handle.area, Some(true), specs), buffer, None)
227 .unwrap()
228 }
229 }
230
231 fn push<W: Widget>(
235 &self,
236 pa: &mut Pass,
237 (target, on_buffers, mut specs): (&RwArea, Option<bool>, PushSpecs),
238 widget: W,
239 master: Option<&RwArea>,
240 ) -> Option<Node> {
241 let inner = self.inner.read(pa);
242 let win = inner
243 .list
244 .iter()
245 .position(|window| {
246 window.0.read(pa).master_area.is_master_of(pa, target)
247 || window
248 .nodes(pa)
249 .any(|node| node.area().is_master_of(pa, target))
250 })
251 .unwrap();
252
253 let inner_window = inner.list[win].0.read(pa);
254 let target_is_on_buffers = inner_window.buffers_area.is_master_of(pa, target);
255
256 let on_buffers = on_buffers.unwrap_or(target_is_on_buffers) && target_is_on_buffers;
257
258 if target_is_on_buffers && !on_buffers {
259 specs.cluster = false;
260 }
261
262 let location = if on_buffers {
263 Location::OnBuffers
264 } else if let Some((id, _)) = inner_window
265 .spawned
266 .iter()
267 .find(|(_, node)| node.area().area_is_eq(pa, target))
268 {
269 Location::Spawned(*id)
270 } else {
271 Location::Regular
272 };
273
274 let widget = RwData::new(widget);
275 let path = widget
276 .read_as::<Buffer>(pa)
277 .and_then(|buffer| buffer.path_set());
278 let (pushed, parent) =
279 target.push(pa, path.as_ref().map(|p| p.as_ref()), specs, on_buffers)?;
280
281 let master = master.and_then(|area| {
282 self.entries(pa).find_map(|(.., node)| {
283 node.area()
284 .area_is_eq(pa, area)
285 .then(|| node.handle().clone())
286 })
287 });
288
289 let node = Node::new(widget, pushed, master);
290
291 let window = self.inner.write(pa).list.remove(win);
292 window.add(pa, node.clone(), parent, location);
293 self.inner.write(pa).list.insert(win, window);
294
295 hook::trigger(
296 pa,
297 WidgetCreated(node.handle().try_downcast::<W>().unwrap()),
298 );
299
300 Some(node)
301 }
302
303 pub(crate) fn close<W: Widget + ?Sized, S>(
307 &self,
308 pa: &mut Pass,
309 handle: &Handle<W, S>,
310 ) -> Result<(), Text> {
311 let win = self.handle_window(pa, handle)?;
312
313 if let Some(buf_handle) = handle.try_downcast::<Buffer>() {
316 hook::trigger(pa, BufferClosed((buf_handle.clone(), Cache::new())));
317
318 let buffers_ahead: Vec<Node> = self.inner.read(pa).list[win]
319 .nodes(pa)
320 .filter(|node| {
321 node.handle().read_as::<Buffer>(pa).is_some_and(|buffer| {
322 buffer.layout_order > buf_handle.read(pa).layout_order
323 })
324 })
325 .cloned()
326 .collect();
327
328 for buffer_ahead in buffers_ahead {
329 self.swap(pa, handle, buffer_ahead.handle())?;
330 }
331 }
332
333 let mut list = std::mem::take(&mut self.inner.write(pa).list);
335
336 if list[win].close(pa, handle) {
337 list.remove(win);
338 self.ui.remove_window(win);
339 let cur_win = context::current_win_index(pa);
340 if cur_win > win {
341 self.inner.write(pa).cur_win -= 1;
342 }
343 }
344
345 let inner = self.inner.write(pa);
346 inner.list = list;
347 inner.new_additions.lock().unwrap().get_or_insert_default();
348
349 let inner = self.inner.read(pa);
351 if handle == inner.cur_widget.read(pa).handle() || handle == inner.cur_buffer.read(pa) {
352 if let Some(handle) = handle.try_downcast::<Buffer>() {
353 self.inner.write(pa).buffer_history.remove(&handle);
354
355 let entry = self
356 .inner
357 .write(pa)
358 .buffer_history
359 .jump_by(handle.clone(), -1)
360 .or_else(|| self.buffers(pa).next())
361 .and_then(|handle| {
362 self.entries(pa).find_map(|(win, node)| {
363 (*node.handle() == handle).then(|| (win, node.clone()))
364 })
365 });
366
367 if let Some((_, node)) = entry {
368 crate::mode::reset_to(node.handle().clone());
369 } else {
370 context::sender()
372 .send(crate::session::DuatEvent::Quit)
373 .unwrap();
374 return Ok(());
375 }
376 } else {
377 crate::mode::reset_to(inner.cur_buffer.read(pa).to_dyn());
378 }
379 }
380
381 Ok(())
382 }
383
384 pub(crate) fn swap<W1: Widget + ?Sized, S1, W2: Widget + ?Sized, S2>(
386 &self,
387 pa: &mut Pass,
388 lhs: &Handle<W1, S1>,
389 rhs: &Handle<W2, S2>,
390 ) -> Result<(), Text> {
391 let lhs_win = self.handle_window(pa, lhs)?;
392 let rhs_win = self.handle_window(pa, rhs)?;
393
394 let [lhs_buffer, rhs_buffer] = [lhs.try_downcast::<Buffer>(), rhs.try_downcast()];
395
396 if let [Some(lhs), Some(rhs)] = [lhs_buffer, rhs_buffer] {
397 let lhs_lo = lhs.read(pa).layout_order;
398 let rhs_lo = std::mem::replace(&mut rhs.write(pa).layout_order, lhs_lo);
399 lhs.write(pa).layout_order = rhs_lo
400 }
401
402 let windows = std::mem::take(&mut self.inner.write(pa).list);
403
404 let lhs_nodes = windows[lhs_win].take_with_related_nodes(pa, lhs);
405 windows[rhs_win].insert_nodes(pa, lhs_nodes);
406
407 let rhs_nodes = windows[rhs_win].take_with_related_nodes(pa, rhs);
408 windows[lhs_win].insert_nodes(pa, rhs_nodes);
409
410 let wins = self.inner.write(pa);
411 wins.list = windows;
412 wins.new_additions.lock().unwrap().get_or_insert_default();
413
414 lhs.area().swap(pa, rhs.area());
415
416 let cur_buffer = context::current_buffer(pa);
417 if lhs_win != rhs_win {
418 if lhs == cur_buffer {
419 self.inner.write(pa).cur_win = lhs_win;
420 self.ui.switch_window(lhs_win);
421 } else if rhs == cur_buffer {
422 self.inner.write(pa).cur_win = rhs_win;
423 self.ui.switch_window(rhs_win);
424 }
425 }
426
427 Ok(())
428 }
429
430 pub(crate) fn open_or_move_to_new_window(
433 &self,
434 pa: &mut Pass,
435 pk: PathKind,
436 default_buffer_cfg: PrintOpts,
437 ) -> Node {
438 let node = match self.buffer_entry(pa, pk.clone()) {
439 Ok((win, handle)) if self.get(pa, win).unwrap().buffers(pa).len() > 1 => {
440 handle.write(pa).layout_order = 0;
442
443 let nodes = {
444 let old_window = self.inner.write(pa).list.remove(win);
445 let nodes = old_window.take_with_related_nodes(pa, &handle.to_dyn());
446 self.inner.write(pa).list.insert(win, old_window);
447
448 nodes
449 };
450
451 let path = handle.read(pa).path_set();
453 let new_root = self.ui.new_root(path.as_ref().map(|p| p.as_ref()));
454 handle.area().swap(pa, &new_root);
455 let window = Window::new_from_raw(
456 pa,
457 win,
458 handle.area.clone(),
459 nodes,
460 self.inner.read(pa).new_additions.clone(),
461 );
462
463 self.inner.write(pa).list.push(window.clone());
464
465 hook::trigger(pa, WindowCreated(window));
466
467 let lo = handle.read(pa).layout_order;
469
470 for handle in &self.inner.read(pa).list[win].buffers(pa)[lo..] {
471 new_root.swap(pa, handle.area());
472 }
473
474 new_root.delete(pa);
477
478 self.inner
479 .write(pa)
480 .new_additions
481 .lock()
482 .unwrap()
483 .get_or_insert_default();
484
485 Node::from_handle(handle)
486 }
487 Ok((.., handle)) => Node::from_handle(handle),
490 Err(_) => self.new_window(pa, Buffer::new(pk.as_path(), default_buffer_cfg)),
491 };
492
493 if context::current_buffer(pa).read(pa).path_kind() != pk {
494 mode::reset_to(node.handle().clone());
495 }
496
497 node
498 }
499
500 pub(crate) fn set_current_node(&self, pa: &mut Pass, node: Node) -> Result<(), Text> {
502 let internal_pass = &mut unsafe { Pass::new() };
505
506 let win = self.handle_window(pa, node.handle())?;
507 let inner = self.inner.write(pa);
508
509 if let Some(handle) = node.try_downcast::<Buffer>() {
510 let current = std::mem::replace(inner.cur_buffer.write(internal_pass), handle.clone());
511 inner.buffer_history.insert(current, handle);
512 }
513 *inner.cur_widget.write(internal_pass) = node.clone();
514 inner.cur_win = win;
515 self.ui.switch_window(win);
516
517 Ok(())
518 }
519
520 pub(crate) fn queue_close_spawned(&self, id: SpawnId) {
524 let mut spawns_to_remove = self.spawns_to_remove.lock().unwrap();
525 if !spawns_to_remove.contains(&id) {
526 spawns_to_remove.push(id)
527 }
528 }
529
530 pub(crate) fn cleanup_despawned(&self, pa: &mut Pass) {
533 let spawns_to_remove = std::mem::take(&mut *self.spawns_to_remove.lock().unwrap());
534 for id in spawns_to_remove {
535 if let Some((_, node)) = self
536 .iter(pa)
537 .flat_map(|window| &window.0.read(pa).spawned)
538 .find(|(other, _)| *other == id)
539 {
540 self.close(pa, &node.handle().clone()).unwrap();
541 }
542 }
543 }
544
545 pub(crate) fn handle_window<W: Widget + ?Sized, S>(
549 &self,
550 pa: &Pass,
551 handle: &Handle<W, S>,
552 ) -> Result<usize, Text> {
553 self.entries(pa)
554 .find_map(|(win, node)| (node.handle() == handle).then_some(win))
555 .ok_or_else(|| txt!("The Handle was already closed"))
556 }
557
558 pub(crate) fn buffer_entry(&self, pa: &Pass, pk: PathKind) -> Result<(usize, Handle), Text> {
560 self.entries(pa)
561 .find_map(|(win, node)| {
562 (node.read_as(pa).filter(|f: &&Buffer| f.path_kind() == pk))
563 .and_then(|_| node.try_downcast().map(|handle| (win, handle)))
564 })
565 .ok_or_else(|| txt!("Buffer {pk} not found"))
566 }
567
568 pub(crate) fn named_buffer_entry(
570 &self,
571 pa: &Pass,
572 name: &str,
573 ) -> Result<(usize, Handle), Text> {
574 self.entries(pa)
575 .find_map(|(win, node)| {
576 (node.read_as(pa).filter(|f: &&Buffer| f.name() == name))
577 .and_then(|_| node.try_downcast().map(|handle| (win, handle)))
578 })
579 .ok_or_else(|| txt!("Buffer [buffer]{name}[] not found"))
580 }
581
582 pub(crate) fn node_of<'a, W: Widget>(&'a self, pa: &'a Pass) -> Result<&'a Node, Text> {
587 let handle = context::current_buffer(pa);
588
589 if let Some((handle, _)) = handle.get_related::<W>(pa).next() {
590 self.entries(pa)
591 .find_map(|(.., node)| node.ptr_eq(handle.widget()).then_some(node))
592 } else {
593 let cur_win = self.inner.read(pa).cur_win;
594 let list = &self.inner.read(pa).list;
595 list[cur_win]
596 .nodes(pa)
597 .chain(list[cur_win + 1..].iter().flat_map(|win| win.nodes(pa)))
598 .chain(list[..cur_win].iter().flat_map(|win| win.nodes(pa)))
599 .find(|node| node.data_is::<W>())
600 }
601 .ok_or(txt!("No widget of type [a]{}[] found", type_name::<W>()))
602 }
603
604 pub(crate) fn entries<'a>(&'a self, pa: &'a Pass) -> impl Iterator<Item = (usize, &'a Node)> {
608 self.inner
609 .read(pa)
610 .list
611 .iter()
612 .enumerate()
613 .flat_map(|(win, window)| {
614 let inner = window.0.read(pa);
615 inner
616 .nodes
617 .iter()
618 .chain(inner.spawned.iter().map(|(_, node)| node))
619 .map(move |node| (win, node))
620 })
621 }
622
623 pub(crate) fn iter_around<'a>(
625 &'a self,
626 pa: &'a Pass,
627 win: usize,
628 wid: usize,
629 ) -> impl Iterator<Item = (usize, &'a Node)> + 'a {
630 let window_entries =
631 |(w, window): (usize, &'a Window)| window.nodes(pa).map(move |node| (w, node));
632
633 let windows = &self.inner.read(pa).list;
634
635 let prev_len: usize = windows
636 .iter()
637 .take(win)
638 .map(|win| win.len_widgets(pa))
639 .sum();
640
641 windows
642 .iter()
643 .enumerate()
644 .skip(win)
645 .flat_map(window_entries)
646 .skip(wid + 1)
647 .chain(
648 windows
649 .iter()
650 .enumerate()
651 .take(win + 1)
652 .flat_map(window_entries)
653 .take(prev_len + wid),
654 )
655 }
656
657 pub(crate) fn iter_around_rev<'a>(
659 &'a self,
660 pa: &'a Pass,
661 win: usize,
662 wid: usize,
663 ) -> impl Iterator<Item = (usize, &'a Node)> + 'a {
664 let entries =
665 |(w, window): (usize, &'a Window)| window.nodes(pa).map(move |node| (w, node));
666
667 let windows = &self.inner.read(pa).list;
668
669 let next_len: usize = windows
670 .iter()
671 .skip(win)
672 .map(|win| win.len_widgets(pa))
673 .sum();
674
675 windows
676 .iter()
677 .enumerate()
678 .rev()
679 .skip(windows.len() - (win + 1))
680 .flat_map(move |(w, win)| entries((w, win)).rev().skip(win.len_widgets(pa) - wid))
681 .chain(
682 windows
683 .iter()
684 .enumerate()
685 .rev()
686 .take(windows.len() - win)
687 .flat_map(move |(i, win)| entries((i, win)).rev())
688 .take(next_len - (wid + 1)),
689 )
690 }
691
692 pub fn jump_buffers_by(&self, pa: &mut Pass, jumps: i32) {
699 let current = self.inner.read(pa).cur_buffer.read(pa).clone();
700 if let Some(handle) = self.inner.write(pa).buffer_history.jump_by(current, jumps) {
701 mode::reset_to(handle.to_dyn());
702 } else {
703 context::warn!("No buffer [a]{jumps}[] jumps away from the current one");
704 }
705 }
706
707 pub fn last_buffer(&self, pa: &mut Pass) -> Result<Handle, Text> {
711 let current = self.inner.read(pa).cur_buffer.read(pa).clone();
712 if let Some(handle) = self.inner.write(pa).buffer_history.last(current) {
713 mode::reset_to(handle.to_dyn());
714 Ok(handle)
715 } else {
716 Err(txt!("No last buffer"))
717 }
718 }
719
720 pub fn len(&self, pa: &Pass) -> usize {
726 self.inner.read(pa).list.len()
727 }
728
729 pub fn get<'a>(&'a self, pa: &'a Pass, win: usize) -> Option<&'a Window> {
731 self.inner.read(pa).list.get(win)
732 }
733
734 pub fn iter<'a>(&'a self, pa: &'a Pass) -> std::slice::Iter<'a, Window> {
736 self.inner.read(pa).list.iter()
737 }
738
739 pub fn handles<'a>(&'a self, pa: &'a Pass) -> impl Iterator<Item = &'a Handle<dyn Widget>> {
741 self.inner
742 .read(pa)
743 .list
744 .iter()
745 .flat_map(|w| w.nodes(pa).map(|n| n.handle()))
746 }
747
748 pub fn handles_of<'a, W: Widget>(
750 &'a self,
751 pa: &'a Pass,
752 ) -> impl Iterator<Item = Handle<W>> + 'a {
753 self.inner
754 .read(pa)
755 .list
756 .iter()
757 .flat_map(|w| w.nodes(pa).filter_map(|n| n.handle().try_downcast()))
758 }
759
760 pub fn buffers<'a>(&'a self, pa: &'a Pass) -> impl Iterator<Item = Handle> + 'a {
762 self.inner.read(pa).list.iter().flat_map(|w| w.buffers(pa))
763 }
764
765 pub fn current_window(&self, pa: &Pass) -> usize {
767 self.inner.read(pa).cur_win
768 }
769
770 pub(crate) fn current_buffer<'a>(&'a self, pa: &'a Pass) -> &'a RwData<Handle> {
772 &self.inner.read(pa).cur_buffer
773 }
774
775 pub(crate) fn current_widget<'a>(&'a self, pa: &'a Pass) -> &'a RwData<Node> {
777 &self.inner.read(pa).cur_widget
778 }
779
780 pub(crate) fn get_additions(&self, pa: &mut Pass) -> Option<Vec<(usize, Node)>> {
782 self.inner.write(pa).new_additions.lock().unwrap().take()
783 }
784}
785
786#[derive(Clone)]
791pub struct Window(RwData<InnerWindow>);
792
793struct InnerWindow {
794 index: usize,
795 nodes: Vec<Node>,
796 spawned: Vec<(SpawnId, Node)>,
797 buffers_area: RwArea,
798 master_area: RwArea,
799 new_additions: Arc<Mutex<Option<Vec<(usize, Node)>>>>,
800}
801
802impl Window {
803 fn new<W: Widget>(
805 index: usize,
806 pa: &mut Pass,
807 ui: Ui,
808 widget: W,
809 new_additions: Arc<Mutex<Option<Vec<(usize, Node)>>>>,
810 ) -> (Self, Node) {
811 let widget = RwData::new(widget);
812 let path = if let Some(buffer) = widget.write_as::<Buffer>(pa) {
813 buffer.layout_order = get_layout_order();
814 buffer.path_set()
815 } else {
816 None
817 };
818
819 let area = ui.new_root(path.as_ref().map(|p| p.as_ref()));
820 let node = Node::new::<W>(widget, area.clone(), None);
821
822 new_additions
823 .lock()
824 .unwrap()
825 .get_or_insert_default()
826 .push((index, node.clone()));
827
828 let window = Self(RwData::new(InnerWindow {
829 index,
830 nodes: vec![node.clone()],
831 spawned: Vec::new(),
832 buffers_area: area.clone(),
833 master_area: area.clone(),
834 new_additions,
835 }));
836
837 (window, node)
838 }
839
840 pub(crate) fn new_from_raw(
842 pa: &mut Pass,
843 index: usize,
844 master_area: RwArea,
845 nodes: Vec<Node>,
846 new_additions: Arc<Mutex<Option<Vec<(usize, Node)>>>>,
847 ) -> Self {
848 let master_area = master_area
849 .get_cluster_master(pa)
850 .unwrap_or(master_area.clone());
851
852 Self(RwData::new(InnerWindow {
853 index,
854 nodes,
855 spawned: Vec::new(),
856 buffers_area: master_area.clone(),
857 master_area,
858 new_additions,
859 }))
860 }
861
862 pub fn push_inner<W: Widget>(
917 &self,
918 pa: &mut Pass,
919 widget: W,
920 mut specs: PushSpecs,
921 ) -> Handle<W> {
922 let target = self.0.read(pa).buffers_area.clone();
923
924 specs.cluster = false;
925
926 context::windows()
927 .push_widget(pa, (&target, Some(false), specs), widget, None)
928 .unwrap()
929 }
930
931 pub fn push_outer<W: Widget>(
933 &self,
934 pa: &mut Pass,
935 widget: W,
936 mut specs: PushSpecs,
937 ) -> Handle<W> {
938 let target = self.0.read(pa).master_area.clone();
939
940 specs.cluster = false;
941
942 context::windows()
943 .push_widget(pa, (&target, Some(false), specs), widget, None)
944 .unwrap()
945 }
946
947 fn add(&self, pa: &mut Pass, node: Node, parent: Option<RwArea>, location: Location) {
949 match location {
950 Location::OnBuffers => {
951 self.0.write(pa).nodes.push(node.clone());
952 if let Some(parent) = &parent
953 && parent.is_master_of(pa, &self.0.read(pa).buffers_area)
954 {
955 self.0.write(pa).buffers_area = parent.clone()
956 }
957 }
958 Location::Regular => self.0.write(pa).nodes.push(node.clone()),
959 Location::Spawned(id) => self.0.write(pa).spawned.push((id, node.clone())),
960 }
961
962 if let Some(parent) = &parent
963 && parent.is_master_of(pa, &self.0.read(pa).master_area)
964 {
965 self.0.write(pa).master_area = parent.clone()
966 }
967
968 let inner = self.0.write(pa);
969 inner
970 .new_additions
971 .lock()
972 .unwrap()
973 .get_or_insert_default()
974 .push((inner.index, node.clone()));
975 }
976
977 fn close<W: Widget + ?Sized, S>(&self, pa: &mut Pass, handle: &Handle<W, S>) -> bool {
981 let handle_eq = |node: &mut Node| node.handle() == handle;
982
983 let inner = self.0.write(pa);
984
985 let node = if let Some(node) = inner.nodes.extract_if(.., handle_eq).next() {
986 node
987 } else if let Some((_, node)) = inner.spawned.extract_if(.., |(_, n)| handle_eq(n)).next() {
988 node
989 } else {
990 unreachable!("This isn't supposed to fail");
991 };
992
993 node.handle().declare_closed(pa);
994
995 let (do_rm_window, rm_areas) = node.area().delete(pa);
996 if do_rm_window {
997 for handle in self.handles(pa).cloned().collect::<Vec<_>>() {
998 handle.declare_closed(pa);
999 }
1000 return true;
1001 }
1002
1003 let (mut nodes, mut spawned) = {
1004 let inner = self.0.write(pa);
1005 let nodes = std::mem::take(&mut inner.nodes);
1006 let spawned = std::mem::take(&mut inner.spawned);
1007 (nodes, spawned)
1008 };
1009
1010 nodes.retain(|node| {
1011 if rm_areas
1012 .iter()
1013 .any(|a| a.area_is_eq(pa, node.handle().area()))
1014 {
1015 node.handle().declare_closed(pa);
1016 false
1017 } else {
1018 true
1019 }
1020 });
1021 spawned.retain(|(_, node)| {
1022 if rm_areas
1023 .iter()
1024 .any(|a| a.area_is_eq(pa, node.handle().area()))
1025 {
1026 node.handle().declare_closed(pa);
1027 false
1028 } else {
1029 true
1030 }
1031 });
1032
1033 let inner = self.0.write(pa);
1034 inner.nodes = nodes;
1035 inner.spawned = spawned;
1036
1037 let buffers = self.buffers(pa);
1038 if buffers.len() == 1 {
1039 let handle = buffers.first().unwrap();
1040
1041 let master_area = handle
1042 .area()
1043 .get_cluster_master(pa)
1044 .unwrap_or(handle.area.clone());
1045
1046 self.0.write(pa).buffers_area = master_area;
1047 }
1048
1049 if self.buffers(pa).is_empty() {
1050 for handle in self.handles(pa).cloned().collect::<Vec<_>>() {
1051 handle.declare_closed(pa);
1052 }
1053 true
1054 } else {
1055 false
1056 }
1057 }
1058
1059 fn take_with_related_nodes<W: Widget + ?Sized, S>(
1061 &self,
1062 pa: &mut Pass,
1063 handle: &Handle<W, S>,
1064 ) -> Vec<Node> {
1065 let related = handle.related();
1066
1067 let (related, inner) = pa.read_and_write(related, &self.0);
1068
1069 inner
1070 .nodes
1071 .extract_if(.., |node| {
1072 related.iter().any(|(handle, _)| handle == node.handle()) || node.handle() == handle
1073 })
1074 .collect()
1075 }
1076
1077 fn insert_nodes(&self, pa: &mut Pass, nodes: Vec<Node>) {
1079 self.0.write(pa).nodes.extend(nodes);
1080 }
1081
1082 pub(crate) fn nodes<'a>(&'a self, pa: &'a Pass) -> Nodes<'a> {
1086 let inner = self.0.read(pa);
1087
1088 let spawned = SpawnedNodes { iter: inner.spawned.iter() };
1089
1090 Nodes {
1091 iter: inner.nodes.iter().chain(spawned),
1092 len: inner.nodes.len() + inner.spawned.len(),
1093 taken: 0,
1094 }
1095 }
1096
1097 pub fn handles<'a>(&'a self, pa: &'a Pass) -> impl Iterator<Item = &'a Handle<dyn Widget>> {
1106 self.nodes(pa).map(|node| node.handle())
1107 }
1108
1109 pub fn buffers(&self, pa: &Pass) -> Vec<Handle> {
1121 let inner = self.0.read(pa);
1122 let mut buffers: Vec<Handle> = inner
1123 .nodes
1124 .iter()
1125 .filter_map(|node| node.try_downcast())
1126 .collect();
1127
1128 buffers.sort_unstable_by_key(|buffer| buffer.read(pa).layout_order);
1129
1130 buffers.extend(
1131 inner
1132 .spawned
1133 .iter()
1134 .filter_map(|(_, node)| node.try_downcast()),
1135 );
1136
1137 buffers
1138 }
1139
1140 pub(crate) fn send_mouse_event(&self, pa: &mut Pass, mouse_event: UiMouseEvent) {
1141 let inner = self.0.read(pa);
1142 let node = inner
1143 .spawned
1144 .iter()
1145 .rev()
1146 .map(|(_, node)| node)
1147 .chain(&inner.nodes)
1148 .find(|node| {
1149 let tl = node.handle().area().top_left(pa);
1150 let br = node.handle().area().bottom_right(pa);
1151 (tl.x <= mouse_event.coord.x && tl.y <= mouse_event.coord.y)
1152 && (mouse_event.coord.x < br.x && mouse_event.coord.y < br.y)
1153 })
1154 .cloned();
1155
1156 if let Some(node) = node {
1157 node.on_mouse_event(pa, mouse_event);
1158 }
1159 }
1160
1161 pub(crate) fn len_widgets(&self, pa: &Pass) -> usize {
1163 let inner = self.0.read(pa);
1164 inner.nodes.len() + inner.spawned.len()
1165 }
1166}
1167
1168#[derive(Default)]
1169struct BufferHistory {
1170 current_i: usize,
1171 list: Vec<Handle>,
1172 last: Option<Handle>,
1173}
1174
1175impl BufferHistory {
1176 fn jump_by(&mut self, current: Handle, by: i32) -> Option<Handle> {
1178 let new_i = self
1179 .current_i
1180 .saturating_add_signed(by as isize)
1181 .min(self.list.len());
1182 let new_handle = self.list.get(new_i)?.clone();
1183
1184 self.last = Some(current);
1185 self.current_i = new_i;
1186 Some(new_handle)
1187 }
1188
1189 fn last(&mut self, current: Handle) -> Option<Handle> {
1194 if let Some(last) = self.last.as_mut() {
1195 Some(std::mem::replace(last, current))
1196 } else if let Some(last) = self.list.get(self.current_i.checked_sub(1)?) {
1197 self.last = Some(current);
1198 Some(last.clone())
1199 } else {
1200 None
1201 }
1202 }
1203
1204 fn insert(&mut self, current: Handle, handle: Handle) {
1207 if self
1208 .current_i
1209 .checked_sub(1)
1210 .is_none_or(|prev_i| self.list[prev_i] != handle)
1211 && self
1212 .list
1213 .get(self.current_i)
1214 .is_none_or(|other| *other != handle)
1215 {
1216 self.list.insert(self.current_i, handle);
1217 self.last = Some(current);
1218 self.current_i += 1;
1219 }
1220 }
1221
1222 fn remove(&mut self, handle: &Handle) {
1225 let mut i = 0;
1226 self.list.retain(|other| {
1227 if other == handle {
1228 if i < self.current_i {
1229 self.current_i -= 1;
1230 }
1231 false
1232 } else {
1233 i += 1;
1234 true
1235 }
1236 });
1237 }
1238}
1239
1240fn get_layout_order() -> usize {
1243 use std::sync::atomic::{AtomicUsize, Ordering};
1244
1245 static LAYOUT_ORDER: AtomicUsize = AtomicUsize::new(0);
1246 LAYOUT_ORDER.fetch_add(1, Ordering::Relaxed)
1247}
1248
1249enum Location {
1250 OnBuffers,
1251 Regular,
1252 Spawned(SpawnId),
1253}
1254
1255#[derive(Debug, Clone)]
1256pub(crate) struct Nodes<'a> {
1257 iter: Chain<std::slice::Iter<'a, Node>, SpawnedNodes<'a>>,
1258 len: usize,
1259 taken: usize,
1260}
1261
1262impl<'a> Iterator for Nodes<'a> {
1263 type Item = &'a Node;
1264
1265 fn next(&mut self) -> Option<Self::Item> {
1266 let next = self.iter.next();
1267 self.taken += next.is_some() as usize;
1268 next
1269 }
1270
1271 fn size_hint(&self) -> (usize, Option<usize>) {
1272 (self.len - self.taken, Some(self.len - self.taken))
1273 }
1274}
1275
1276impl<'a> DoubleEndedIterator for Nodes<'a> {
1277 fn next_back(&mut self) -> Option<Self::Item> {
1278 let next = self.iter.next_back();
1279 self.taken += next.is_some() as usize;
1280 next
1281 }
1282}
1283
1284impl ExactSizeIterator for Nodes<'_> {}
1285
1286#[derive(Debug, Clone)]
1287struct SpawnedNodes<'a> {
1288 iter: std::slice::Iter<'a, (SpawnId, Node)>,
1289}
1290
1291impl<'a> Iterator for SpawnedNodes<'a> {
1292 type Item = &'a Node;
1293
1294 fn next(&mut self) -> Option<Self::Item> {
1295 self.iter.next().map(|(_, node)| node)
1296 }
1297}
1298
1299impl DoubleEndedIterator for SpawnedNodes<'_> {
1300 fn next_back(&mut self) -> Option<Self::Item> {
1301 self.iter.next_back().map(|(_, node)| node)
1302 }
1303}