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