1use std::{
2 cmp::Ordering,
3 mem, ops,
4 sync::{
5 Arc,
6 atomic::{AtomicBool, Ordering::Relaxed},
7 },
8};
9
10use parking_lot::Mutex;
11use task::ParallelIteratorExt;
12use zng_app_context::context_local;
13use zng_layout::unit::{Factor, PxSize, PxTransform, PxVector};
14use zng_state_map::StateId;
15use zng_task::{self as task, rayon::prelude::*};
16use zng_unique_id::static_id;
17use zng_var::{animation::Transitionable, impl_from_and_into_var};
18
19use super::*;
20
21#[macro_export]
51macro_rules! ui_vec {
52 () => { $crate::widget::node::UiVec::new() };
53 ($node:expr; $n:expr) => {
54 {
55 let mut n: usize = $n;
56 let mut vec = $crate::widget::node::UiVec::with_capacity(n);
57 while n > 0 {
58 vec.push($node);
59 n -= 1;
60 }
61 vec
62 }
63 };
64 ($($nodes:tt)+) => {
65 $crate::ui_vec_items! {
66 match { $($nodes)+ }
67 result { }
68 }
69 };
70}
71#[doc(inline)]
72pub use crate::ui_vec;
73use crate::{
74 render::{FrameBuilder, FrameUpdate, FrameValueKey},
75 update::{EventUpdate, UPDATES, WidgetUpdates},
76 widget::{
77 WIDGET, WidgetUpdateMode,
78 base::{PARALLEL_VAR, Parallel},
79 info::{WidgetInfo, WidgetInfoBuilder, WidgetLayout, WidgetMeasure},
80 },
81};
82
83#[macro_export]
85#[doc(hidden)]
86macro_rules! ui_vec_items {
87 (
89 match { #[$meta:meta] $($tt:tt)* }
90 result { $($r:tt)* }
91 ) => {
92 $crate::ui_vec_items! {
93 match { $($tt)* }
94 result { $($r)* #[$meta] }
95 }
96 };
97 (
99 match { $node:expr, $($tt:tt)* }
100 result { $($r:tt)* }
101 ) => {
102 $crate::ui_vec_items! {
103 match { $($tt)* }
104 result { $($r)* $crate::widget::node::UiNode::boxed($node), }
105 }
106 };
107 (
109 match { $node:expr }
110 result { $($r:tt)* }
111 ) => {
112 $crate::ui_vec_items! {
113 match { }
114 result { $($r)* $crate::widget::node::UiNode::boxed($node) }
115 }
116 };
117 (
119 match { }
120 result { $($r:tt)* }
121 ) => {
122 $crate::widget::node::UiVec(std::vec![
123 $($r)*
124 ])
125 };
126}
127
128fn vec_for_each<F>(self_: &mut [BoxedUiNode], f: F)
129where
130 F: FnMut(usize, &mut BoxedUiNode),
131{
132 #[cfg(feature = "dyn_closure")]
133 let f: Box<dyn FnMut(usize, &mut BoxedUiNode)> = Box::new(f);
134 vec_for_each_impl(self_, f)
135}
136fn vec_for_each_impl<F>(self_: &mut [BoxedUiNode], mut f: F)
137where
138 F: FnMut(usize, &mut BoxedUiNode),
139{
140 self_.iter_mut().enumerate().for_each(|(i, n)| f(i, n))
141}
142
143fn vec_par_each<F>(self_: &mut Vec<BoxedUiNode>, f: F)
144where
145 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
146{
147 #[cfg(feature = "dyn_closure")]
148 let f: Box<dyn Fn(usize, &mut BoxedUiNode) + Send + Sync> = Box::new(f);
149 par_each_impl(self_, f)
150}
151fn par_each_impl<F>(self_: &mut Vec<BoxedUiNode>, f: F)
152where
153 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
154{
155 self_.par_iter_mut().enumerate().with_ctx().for_each(|(i, n)| f(i, n));
156}
157
158fn vec_par_fold_reduce<T, I, F, R>(self_: &mut Vec<BoxedUiNode>, identity: I, fold: F, reduce: R) -> T
159where
160 T: Send,
161 I: Fn() -> T + Send + Sync,
162 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
163 R: Fn(T, T) -> T + Send + Sync,
164{
165 #[cfg(feature = "dyn_closure")]
166 let identity: Box<dyn Fn() -> T + Send + Sync> = Box::new(identity);
167 #[cfg(feature = "dyn_closure")]
168 let fold: Box<dyn Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync> = Box::new(fold);
169 #[cfg(feature = "dyn_closure")]
170 let reduce: Box<dyn Fn(T, T) -> T + Send + Sync> = Box::new(reduce);
171
172 par_fold_reduce_impl(self_, identity, fold, reduce)
173}
174fn par_fold_reduce_impl<T, I, F, R>(self_: &mut Vec<BoxedUiNode>, identity: I, fold: F, reduce: R) -> T
175where
176 T: Send,
177 I: Fn() -> T + Send + Sync,
178 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
179 R: Fn(T, T) -> T + Send + Sync,
180{
181 self_
182 .par_iter_mut()
183 .enumerate()
184 .with_ctx()
185 .fold(&identity, move |a, (i, n)| fold(a, i, n))
186 .reduce(&identity, reduce)
187}
188
189impl UiNodeList for Vec<BoxedUiNode> {
190 fn with_node<R, F>(&mut self, index: usize, f: F) -> R
191 where
192 F: FnOnce(&mut BoxedUiNode) -> R,
193 {
194 f(&mut self[index])
195 }
196
197 fn for_each<F>(&mut self, f: F)
198 where
199 F: FnMut(usize, &mut BoxedUiNode),
200 {
201 vec_for_each(self, f)
202 }
203
204 fn par_each<F>(&mut self, f: F)
205 where
206 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
207 {
208 vec_par_each(self, f)
209 }
210
211 fn par_fold_reduce<T, I, F, R>(&mut self, identity: I, fold: F, reduce: R) -> T
212 where
213 T: Send,
214 I: Fn() -> T + Send + Sync,
215 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
216 R: Fn(T, T) -> T + Send + Sync,
217 {
218 vec_par_fold_reduce(self, identity, fold, reduce)
219 }
220
221 fn len(&self) -> usize {
222 Vec::len(self)
223 }
224
225 fn boxed(self) -> BoxedUiNodeList {
226 Box::new(self)
227 }
228
229 fn drain_into(&mut self, vec: &mut Vec<BoxedUiNode>) {
230 vec.append(self)
231 }
232}
233
234#[derive(Default)]
238pub struct UiVec(pub Vec<BoxedUiNode>);
239impl UiVec {
240 pub fn new() -> Self {
242 Self::default()
243 }
244
245 pub fn with_capacity(capacity: usize) -> Self {
249 Self(Vec::with_capacity(capacity))
250 }
251
252 pub fn push(&mut self, node: impl UiNode) {
256 self.0.push(node.boxed())
257 }
258
259 pub fn insert(&mut self, index: usize, node: impl UiNode) {
263 self.0.insert(index, node.boxed())
264 }
265}
266impl ops::Deref for UiVec {
267 type Target = Vec<BoxedUiNode>;
268
269 fn deref(&self) -> &Self::Target {
270 &self.0
271 }
272}
273impl ops::DerefMut for UiVec {
274 fn deref_mut(&mut self) -> &mut Self::Target {
275 &mut self.0
276 }
277}
278impl From<Vec<BoxedUiNode>> for UiVec {
279 fn from(vec: Vec<BoxedUiNode>) -> Self {
280 Self(vec)
281 }
282}
283impl From<UiVec> for Vec<BoxedUiNode> {
284 fn from(vec: UiVec) -> Self {
285 vec.0
286 }
287}
288impl<U: UiNode> FromIterator<U> for UiVec {
289 fn from_iter<T: IntoIterator<Item = U>>(iter: T) -> Self {
290 Self(Vec::from_iter(iter.into_iter().map(UiNode::boxed)))
291 }
292}
293impl IntoIterator for UiVec {
294 type Item = BoxedUiNode;
295
296 type IntoIter = std::vec::IntoIter<BoxedUiNode>;
297
298 fn into_iter(self) -> Self::IntoIter {
299 self.0.into_iter()
300 }
301}
302
303impl UiNodeList for UiVec {
304 fn with_node<R, F>(&mut self, index: usize, f: F) -> R
305 where
306 F: FnOnce(&mut BoxedUiNode) -> R,
307 {
308 self.0.with_node(index, f)
309 }
310
311 fn for_each<F>(&mut self, f: F)
312 where
313 F: FnMut(usize, &mut BoxedUiNode),
314 {
315 self.0.for_each(f)
316 }
317
318 fn par_each<F>(&mut self, f: F)
319 where
320 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
321 {
322 self.0.par_each(f)
323 }
324
325 fn par_fold_reduce<T, I, F, R>(&mut self, identity: I, fold: F, reduce: R) -> T
326 where
327 T: Send + 'static,
328 I: Fn() -> T + Send + Sync,
329 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
330 R: Fn(T, T) -> T + Send + Sync,
331 {
332 self.0.par_fold_reduce(identity, fold, reduce)
333 }
334
335 fn len(&self) -> usize {
336 self.0.len()
337 }
338
339 fn boxed(self) -> BoxedUiNodeList {
340 self.0.boxed()
341 }
342
343 fn drain_into(&mut self, vec: &mut Vec<BoxedUiNode>) {
344 self.0.drain_into(vec)
345 }
346}
347
348pub trait UiNodeListChain: UiNodeList {
350 fn chain<B>(self, other: B) -> UiNodeListChainImpl
354 where
355 B: UiNodeList,
356 Self: Sized;
357}
358impl<A: UiNodeList> UiNodeListChain for A {
359 fn chain<B>(self, other: B) -> UiNodeListChainImpl
360 where
361 B: UiNodeList,
362 {
363 UiNodeListChainImpl(self.boxed(), other.boxed())
364 }
365}
366
367fn chain_for_each<F>(self_: &mut UiNodeListChainImpl, f: F)
368where
369 F: FnMut(usize, &mut BoxedUiNode),
370{
371 #[cfg(feature = "dyn_closure")]
372 let f: Box<dyn FnMut(usize, &mut BoxedUiNode)> = Box::new(f);
373 chain_for_each_impl(self_, f)
374}
375fn chain_for_each_impl<F>(self_: &mut UiNodeListChainImpl, mut f: F)
376where
377 F: FnMut(usize, &mut BoxedUiNode),
378{
379 self_.0.for_each(&mut f);
380 let offset = self_.0.len();
381 self_.1.for_each(move |i, n| f(i + offset, n))
382}
383
384fn chain_par_each<F>(self_: &mut UiNodeListChainImpl, f: F)
385where
386 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
387{
388 #[cfg(feature = "dyn_closure")]
389 let f: Box<dyn Fn(usize, &mut BoxedUiNode) + Send + Sync> = Box::new(f);
390 chain_par_each_impl(self_, f)
391}
392fn chain_par_each_impl<F>(self_: &mut UiNodeListChainImpl, f: F)
393where
394 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
395{
396 let offset = self_.0.len();
397 task::join(|| self_.0.par_each(&f), || self_.1.par_each(|i, n| f(i + offset, n)));
398}
399
400fn chain_par_fold_reduce<T, I, F, R>(self_: &mut UiNodeListChainImpl, identity: I, fold: F, reduce: R) -> T
401where
402 T: Send + 'static,
403 I: Fn() -> T + Send + Sync,
404 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
405 R: Fn(T, T) -> T + Send + Sync,
406{
407 #[cfg(feature = "dyn_closure")]
408 let identity: Box<dyn Fn() -> T + Send + Sync> = Box::new(identity);
409 #[cfg(feature = "dyn_closure")]
410 let fold: Box<dyn Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync> = Box::new(fold);
411 #[cfg(feature = "dyn_closure")]
412 let reduce: Box<dyn Fn(T, T) -> T + Send + Sync> = Box::new(reduce);
413
414 chain_par_fold_reduce_impl(self_, identity, fold, reduce)
415}
416
417fn chain_par_fold_reduce_impl<T, I, F, R>(self_: &mut UiNodeListChainImpl, identity: I, fold: F, reduce: R) -> T
418where
419 T: Send + 'static,
420 I: Fn() -> T + Send + Sync,
421 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
422 R: Fn(T, T) -> T + Send + Sync,
423{
424 let offset = self_.0.len();
425 let (a, b) = task::join(
426 || self_.0.par_fold_reduce(&identity, &fold, &reduce),
427 || self_.1.par_fold_reduce(&identity, |a, i, n| fold(a, i + offset, n), &reduce),
428 );
429 reduce(a, b)
430}
431
432pub struct UiNodeListChainImpl(pub BoxedUiNodeList, pub BoxedUiNodeList);
434impl UiNodeList for UiNodeListChainImpl {
435 fn with_node<R, F>(&mut self, index: usize, f: F) -> R
436 where
437 F: FnOnce(&mut BoxedUiNode) -> R,
438 {
439 assert_bounds(self.len(), index);
440
441 if index < self.0.len() {
442 self.0.with_node(index, f)
443 } else {
444 self.1.with_node(index - self.0.len(), f)
445 }
446 }
447
448 fn for_each<F>(&mut self, f: F)
449 where
450 F: FnMut(usize, &mut BoxedUiNode),
451 {
452 chain_for_each(self, f)
453 }
454
455 fn par_each<F>(&mut self, f: F)
456 where
457 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
458 {
459 chain_par_each(self, f)
460 }
461
462 fn par_fold_reduce<T, I, F, R>(&mut self, identity: I, fold: F, reduce: R) -> T
463 where
464 T: Send + 'static,
465 I: Fn() -> T + Send + Sync,
466 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
467 R: Fn(T, T) -> T + Send + Sync,
468 {
469 chain_par_fold_reduce(self, identity, fold, reduce)
470 }
471
472 fn len(&self) -> usize {
473 self.0.len() + self.1.len()
474 }
475
476 fn boxed(self) -> BoxedUiNodeList {
477 Box::new(self)
478 }
479
480 fn drain_into(&mut self, vec: &mut Vec<BoxedUiNode>) {
481 self.0.drain_into(vec);
482 self.1.drain_into(vec);
483 }
484
485 fn init_all(&mut self) {
486 if PARALLEL_VAR.get().contains(Parallel::INIT) {
487 task::join(|| self.0.init_all(), || self.1.init_all());
488 } else {
489 self.0.init_all();
490 self.1.init_all();
491 }
492 }
493
494 fn deinit_all(&mut self) {
495 if PARALLEL_VAR.get().contains(Parallel::DEINIT) {
496 task::join(|| self.0.deinit_all(), || self.1.deinit_all());
497 } else {
498 self.0.deinit_all();
499 self.1.deinit_all();
500 }
501 }
502
503 fn info_all(&mut self, info: &mut WidgetInfoBuilder) {
504 if PARALLEL_VAR.get().contains(Parallel::INFO) {
505 let mut b = info.parallel_split();
506 task::join(|| self.0.info_all(info), || self.1.info_all(&mut b));
507 info.parallel_fold(b);
508 } else {
509 self.0.info_all(info);
510 self.1.info_all(info);
511 }
512 }
513
514 fn event_all(&mut self, update: &EventUpdate) {
515 if PARALLEL_VAR.get().contains(Parallel::EVENT) {
516 task::join(|| self.0.event_all(update), || self.1.event_all(update));
517 } else {
518 self.0.event_all(update);
519 self.1.event_all(update);
520 }
521 }
522
523 fn update_all(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
524 if observer.is_reset_only() && PARALLEL_VAR.get().contains(Parallel::UPDATE) {
525 let (r0, r1) = task::join(
526 || {
527 let mut r = false;
528 self.0.update_all(updates, &mut r);
529 r
530 },
531 || {
532 let mut r = false;
533 self.1.update_all(updates, &mut r);
534 r
535 },
536 );
537
538 if r0 || r1 {
539 observer.reset();
540 }
541 } else {
542 self.0.update_all(updates, observer);
543 self.1.update_all(updates, &mut OffsetUiListObserver(self.0.len(), observer));
544 }
545 }
546
547 fn render_all(&mut self, frame: &mut FrameBuilder) {
548 if PARALLEL_VAR.get().contains(Parallel::RENDER) {
549 let mut b = frame.parallel_split();
550 task::join(|| self.0.render_all(frame), || self.1.render_all(&mut b));
551 frame.parallel_fold(b);
552 } else {
553 self.0.render_all(frame);
554 self.1.render_all(frame);
555 }
556 }
557
558 fn render_update_all(&mut self, update: &mut FrameUpdate) {
559 if PARALLEL_VAR.get().contains(Parallel::RENDER) {
560 let mut b = update.parallel_split();
561 task::join(|| self.0.render_update_all(update), || self.1.render_update_all(&mut b));
562 update.parallel_fold(b);
563 } else {
564 self.0.render_update_all(update);
565 self.1.render_update_all(update);
566 }
567 }
568}
569
570#[expect(non_camel_case_types)]
572pub struct SORTING_LIST;
573impl SORTING_LIST {
574 pub fn is_inside_list(&self) -> bool {
576 !SORTING_LIST_PARENT.is_default()
577 }
578
579 pub fn invalidate_sort(&self) {
581 SORTING_LIST_PARENT.get().store(true, Relaxed)
582 }
583
584 fn with<R>(&self, action: impl FnOnce() -> R) -> (R, bool) {
585 SORTING_LIST_PARENT.with_context(&mut Some(Arc::new(AtomicBool::new(false))), || {
586 let r = action();
587 (r, SORTING_LIST_PARENT.get().load(Relaxed))
588 })
589 }
590}
591context_local! {
592 static SORTING_LIST_PARENT: AtomicBool = AtomicBool::new(false);
593}
594
595pub struct SortingList {
604 list: BoxedUiNodeList,
605
606 map: Vec<usize>,
607 sort: Box<dyn Fn(&mut BoxedUiNode, &mut BoxedUiNode) -> Ordering + Send + 'static>,
608}
609impl SortingList {
610 pub fn new(list: impl UiNodeList, sort: impl Fn(&mut BoxedUiNode, &mut BoxedUiNode) -> Ordering + Send + 'static) -> Self {
612 Self {
613 list: list.boxed(),
614 map: vec![],
615 sort: Box::new(sort),
616 }
617 }
618
619 fn update_map(&mut self) {
620 let map = &mut self.map;
621 let len = self.list.len();
622
623 if len == 0 {
624 map.clear();
625 } else if map.len() != len {
626 map.clear();
627 map.extend(0..len);
628 let mut taken_a = NilUiNode.boxed();
629 map.sort_by(|&a, &b| {
630 self.list.with_node(a, |a| mem::swap(a, &mut taken_a));
631 let result = self.list.with_node(b, |b| (self.sort)(&mut taken_a, b));
632 self.list.with_node(a, |a| mem::swap(a, &mut taken_a));
633
634 result
635 })
636 }
637 }
638 pub fn list(&mut self) -> &mut BoxedUiNodeList {
644 &mut self.list
645 }
646
647 pub fn invalidate_sort(&mut self) {
651 self.map.clear()
652 }
653
654 fn with_map<R>(&mut self, f: impl FnOnce(&[usize], &mut BoxedUiNodeList) -> R) -> R {
655 self.update_map();
656
657 let (r, resort) = SORTING_LIST.with(|| f(&self.map, &mut self.list));
658
659 if resort {
660 self.invalidate_sort();
661 }
662
663 r
664 }
665}
666impl UiNodeList for SortingList {
667 fn with_node<R, F>(&mut self, index: usize, f: F) -> R
668 where
669 F: FnOnce(&mut BoxedUiNode) -> R,
670 {
671 self.with_map(|map, list| list.with_node(map[index], f))
672 }
673
674 fn for_each<F>(&mut self, mut f: F)
675 where
676 F: FnMut(usize, &mut BoxedUiNode),
677 {
678 self.with_map(|map, list| {
679 for (index, map) in map.iter().enumerate() {
680 list.with_node(*map, |n| f(index, n))
681 }
682 });
683 }
684
685 fn par_each<F>(&mut self, f: F)
686 where
687 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
688 {
689 self.for_each(f)
690 }
691
692 fn par_fold_reduce<T, I, F, R>(&mut self, identity: I, fold: F, _: R) -> T
693 where
694 T: Send + 'static,
695 I: Fn() -> T + Send + Sync,
696 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
697 R: Fn(T, T) -> T + Send + Sync,
698 {
699 let mut r = Some(identity());
700 self.for_each(|i, n| {
701 r = Some(fold(r.take().unwrap(), i, n));
702 });
703 r.unwrap()
704 }
705
706 fn len(&self) -> usize {
707 self.list.len()
708 }
709
710 fn boxed(self) -> BoxedUiNodeList {
711 Box::new(self)
712 }
713
714 fn drain_into(&mut self, vec: &mut Vec<BoxedUiNode>) {
715 let start = vec.len();
716 self.with_map(|map, list| {
717 list.drain_into(vec);
718 sort_by_indices(&mut vec[start..], map.to_vec());
719 });
720 self.map.clear();
721 }
722
723 fn init_all(&mut self) {
724 let _ = SORTING_LIST.with(|| self.list.init_all());
725 self.invalidate_sort();
726 }
727
728 fn deinit_all(&mut self) {
729 let _ = SORTING_LIST.with(|| self.list.deinit_all());
730 self.invalidate_sort();
731 }
732
733 fn info_all(&mut self, info: &mut WidgetInfoBuilder) {
734 self.list.info_all(info);
735 }
736
737 fn event_all(&mut self, update: &EventUpdate) {
738 self.list.event_all(update);
739 }
740
741 fn update_all(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
742 let mut changed = false;
743 let (_, resort) = SORTING_LIST.with(|| self.list.update_all(updates, &mut (observer, &mut changed as _)));
744 if changed || resort {
745 self.invalidate_sort();
746 }
747 }
748
749 fn render_all(&mut self, frame: &mut FrameBuilder) {
750 self.for_each(|_, n| n.render(frame));
751 }
752
753 fn render_update_all(&mut self, update: &mut FrameUpdate) {
754 self.list.render_update_all(update);
755 }
756
757 fn is_empty(&self) -> bool {
758 self.len() == 0
759 }
760}
761
762fn sort_by_indices<T>(data: &mut [T], mut indices: Vec<usize>) {
764 for idx in 0..data.len() {
765 if indices[idx] != idx {
766 let mut current_idx = idx;
767 loop {
768 let target_idx = indices[current_idx];
769 indices[current_idx] = current_idx;
770 if indices[target_idx] == target_idx {
771 break;
772 }
773 data.swap(current_idx, target_idx);
774 current_idx = target_idx;
775 }
776 }
777 }
778}
779
780#[derive(Default, Debug)]
781struct ZIndexCtx {
782 panel_id: Option<WidgetId>,
784 resort: AtomicBool,
786}
787
788context_local! {
789 static Z_INDEX_CTX: ZIndexCtx = ZIndexCtx::default();
790}
791
792#[expect(non_camel_case_types)]
794pub struct Z_INDEX;
795impl Z_INDEX {
796 fn with(&self, panel_id: WidgetId, action: impl FnOnce()) -> bool {
797 let ctx = ZIndexCtx {
798 panel_id: Some(panel_id),
799 resort: AtomicBool::new(false),
800 };
801 Z_INDEX_CTX.with_context(&mut Some(Arc::new(ctx)), || {
802 action();
803 Z_INDEX_CTX.get().resort.load(Relaxed)
804 })
805 }
806
807 pub fn get(&self) -> ZIndex {
811 WIDGET.get_state(*Z_INDEX_ID).unwrap_or_default()
812 }
813
814 pub fn get_wgt(&self, widget: &mut impl UiNode) -> ZIndex {
818 widget.with_context(WidgetUpdateMode::Ignore, || self.get()).unwrap_or_default()
819 }
820
821 pub fn set(&self, index: ZIndex) -> bool {
829 let z_ctx = Z_INDEX_CTX.get();
830 let valid = z_ctx.panel_id == WIDGET.parent_id() && z_ctx.panel_id.is_some();
831 if valid {
832 z_ctx.resort.store(true, Relaxed);
833 WIDGET.set_state(*Z_INDEX_ID, index);
834 }
835 valid
836 }
837}
838
839static_id! {
840 static ref Z_INDEX_ID: StateId<ZIndex>;
841}
842
843#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Transitionable)]
857pub struct ZIndex(pub u32);
858impl ZIndex {
859 pub const BACK: ZIndex = ZIndex(0);
863
864 pub const DEFAULT: ZIndex = ZIndex(u32::MAX / 2);
868
869 pub const FRONT: ZIndex = ZIndex(u32::MAX);
871
872 pub fn saturating_add(self, other: impl Into<Self>) -> Self {
878 ZIndex(self.0.saturating_add(other.into().0))
879 }
880
881 pub fn saturating_sub(self, other: impl Into<Self>) -> Self {
887 ZIndex(self.0.saturating_sub(other.into().0))
888 }
889}
890impl Default for ZIndex {
891 fn default() -> Self {
892 ZIndex::DEFAULT
893 }
894}
895impl<Z: Into<ZIndex>> ops::Add<Z> for ZIndex {
896 type Output = Self;
897
898 fn add(self, rhs: Z) -> Self::Output {
899 self.saturating_add(rhs)
900 }
901}
902impl<Z: Into<ZIndex>> ops::AddAssign<Z> for ZIndex {
903 fn add_assign(&mut self, rhs: Z) {
904 *self = *self + rhs;
905 }
906}
907impl<Z: Into<ZIndex>> ops::Sub<Z> for ZIndex {
908 type Output = Self;
909
910 fn sub(self, rhs: Z) -> Self::Output {
911 self.saturating_sub(rhs)
912 }
913}
914impl<Z: Into<ZIndex>> ops::SubAssign<Z> for ZIndex {
915 fn sub_assign(&mut self, rhs: Z) {
916 *self = *self - rhs;
917 }
918}
919impl ops::Mul<Factor> for ZIndex {
920 type Output = Self;
921
922 fn mul(self, rhs: Factor) -> Self::Output {
923 ZIndex(self.0 * rhs)
924 }
925}
926impl ops::Div<Factor> for ZIndex {
927 type Output = Self;
928
929 fn div(self, rhs: Factor) -> Self::Output {
930 ZIndex(self.0 / rhs)
931 }
932}
933impl ops::MulAssign<Factor> for ZIndex {
934 fn mul_assign(&mut self, rhs: Factor) {
935 self.0 *= rhs;
936 }
937}
938impl ops::DivAssign<Factor> for ZIndex {
939 fn div_assign(&mut self, rhs: Factor) {
940 self.0 /= rhs;
941 }
942}
943impl fmt::Debug for ZIndex {
944 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
945 let z = *self;
946 if f.alternate() {
947 write!(f, "ZIndex::")?;
948 }
949
950 if z == Self::DEFAULT {
951 write!(f, "DEFAULT")
952 } else if z == Self::BACK {
953 write!(f, "BACK")
954 } else if z == Self::FRONT {
955 write!(f, "FRONT")
956 } else if z > Self::DEFAULT {
957 if z > Self::FRONT - 10000 {
958 write!(f, "FRONT-{}", Self::FRONT.0 - z.0)
959 } else {
960 write!(f, "DEFAULT+{}", z.0 - Self::DEFAULT.0)
961 }
962 } else if z < Self::BACK + 10000 {
963 write!(f, "BACK+{}", z.0 - Self::BACK.0)
964 } else {
965 write!(f, "DEFAULT-{}", Self::DEFAULT.0 - z.0)
966 }
967 }
968}
969impl_from_and_into_var! {
970 fn from(index: u32) -> ZIndex {
971 ZIndex(index)
972 }
973}
974
975pub trait UiNodeListObserver {
984 fn inserted(&mut self, index: usize);
986 fn removed(&mut self, index: usize);
988 fn moved(&mut self, removed_index: usize, inserted_index: usize);
990 fn reset(&mut self);
992
993 fn is_reset_only(&self) -> bool;
1003}
1004impl UiNodeListObserver for () {
1006 fn is_reset_only(&self) -> bool {
1007 true
1008 }
1009
1010 fn reset(&mut self) {}
1011
1012 fn inserted(&mut self, _: usize) {}
1013
1014 fn removed(&mut self, _: usize) {}
1015
1016 fn moved(&mut self, _: usize, _: usize) {}
1017}
1018impl UiNodeListObserver for bool {
1020 fn is_reset_only(&self) -> bool {
1021 true
1022 }
1023
1024 fn reset(&mut self) {
1025 *self = true;
1026 }
1027
1028 fn inserted(&mut self, _: usize) {
1029 *self = true;
1030 }
1031
1032 fn removed(&mut self, _: usize) {
1033 *self = true;
1034 }
1035
1036 fn moved(&mut self, _: usize, _: usize) {
1037 *self = true;
1038 }
1039}
1040
1041pub struct OffsetUiListObserver<'o>(pub usize, pub &'o mut dyn UiNodeListObserver);
1045impl UiNodeListObserver for OffsetUiListObserver<'_> {
1046 fn is_reset_only(&self) -> bool {
1047 self.1.is_reset_only()
1048 }
1049
1050 fn reset(&mut self) {
1051 self.1.reset()
1052 }
1053
1054 fn inserted(&mut self, index: usize) {
1055 self.1.inserted(index + self.0)
1056 }
1057
1058 fn removed(&mut self, index: usize) {
1059 self.1.removed(index + self.0)
1060 }
1061
1062 fn moved(&mut self, removed_index: usize, inserted_index: usize) {
1063 self.1.moved(removed_index + self.0, inserted_index + self.0)
1064 }
1065}
1066
1067impl UiNodeListObserver for (&mut dyn UiNodeListObserver, &mut dyn UiNodeListObserver) {
1068 fn is_reset_only(&self) -> bool {
1069 self.0.is_reset_only() && self.1.is_reset_only()
1070 }
1071
1072 fn reset(&mut self) {
1073 self.0.reset();
1074 self.1.reset();
1075 }
1076
1077 fn inserted(&mut self, index: usize) {
1078 self.0.inserted(index);
1079 self.1.inserted(index);
1080 }
1081
1082 fn removed(&mut self, index: usize) {
1083 self.0.removed(index);
1084 self.1.removed(index);
1085 }
1086
1087 fn moved(&mut self, removed_index: usize, inserted_index: usize) {
1088 self.0.moved(removed_index, inserted_index);
1089 self.1.moved(removed_index, inserted_index);
1090 }
1091}
1092
1093pub struct EditableUiNodeList {
1095 vec: Vec<BoxedUiNode>,
1096 ctrl: EditableUiNodeListRef,
1097}
1098impl Default for EditableUiNodeList {
1099 fn default() -> Self {
1100 Self {
1101 vec: vec![],
1102 ctrl: EditableUiNodeListRef::new(true),
1103 }
1104 }
1105}
1106impl Drop for EditableUiNodeList {
1107 fn drop(&mut self) {
1108 self.ctrl.0.lock().alive = false;
1109 }
1110}
1111impl EditableUiNodeList {
1112 pub fn new() -> Self {
1114 Self::default()
1115 }
1116
1117 pub fn from_vec(vec: impl Into<Vec<BoxedUiNode>>) -> Self {
1119 let mut s = Self::new();
1120 s.vec = vec.into();
1121 s
1122 }
1123
1124 pub fn reference(&self) -> EditableUiNodeListRef {
1126 self.ctrl.clone()
1127 }
1128
1129 fn fulfill_requests(&mut self, observer: &mut dyn UiNodeListObserver) {
1130 if let Some(r) = self.ctrl.take_requests() {
1131 if r.clear {
1132 self.clear();
1134 observer.reset();
1135
1136 for (i, mut wgt) in r.insert {
1137 wgt.init();
1138 WIDGET.update_info();
1139 if i < self.len() {
1140 self.insert(i, wgt);
1141 } else {
1142 self.push(wgt);
1143 }
1144 }
1145 for mut wgt in r.push {
1146 wgt.init();
1147 WIDGET.update_info();
1148 self.push(wgt);
1149 }
1150 for (r, i) in r.move_index {
1151 if r < self.len() {
1152 let wgt = self.vec.remove(r);
1153
1154 if i < self.len() {
1155 self.vec.insert(i, wgt);
1156 } else {
1157 self.vec.push(wgt);
1158 }
1159
1160 WIDGET.update_info();
1161 }
1162 }
1163 for (id, to) in r.move_id {
1164 if let Some(r) = self
1165 .vec
1166 .iter_mut()
1167 .position(|w| w.with_context(WidgetUpdateMode::Ignore, || WIDGET.id() == id).unwrap_or(false))
1168 {
1169 let i = to(r, self.len());
1170
1171 if r != i {
1172 let wgt = self.vec.remove(r);
1173
1174 if i < self.len() {
1175 self.vec.insert(i, wgt);
1176 } else {
1177 self.vec.push(wgt);
1178 }
1179
1180 WIDGET.update_info();
1181 }
1182 }
1183 }
1184 } else {
1185 let mut removed = false;
1186 for mut retain in r.retain {
1187 let mut i = 0;
1188 self.vec.retain_mut(|n| {
1189 let r = retain(n);
1190 if !r {
1191 n.deinit();
1192 removed = true;
1193 observer.removed(i);
1194 } else {
1195 i += 1;
1196 }
1197 r
1198 });
1199 }
1200 if removed {
1201 WIDGET.update_info();
1202 }
1203
1204 for (i, mut wgt) in r.insert {
1205 wgt.init();
1206 WIDGET.update_info();
1207
1208 if i < self.len() {
1209 self.insert(i, wgt);
1210 observer.inserted(i);
1211 } else {
1212 observer.inserted(self.len());
1213 self.push(wgt);
1214 }
1215 }
1216
1217 for mut wgt in r.push {
1218 wgt.init();
1219 WIDGET.update_info();
1220
1221 observer.inserted(self.len());
1222 self.push(wgt);
1223 }
1224
1225 for (r, i) in r.move_index {
1226 if r < self.len() {
1227 let wgt = self.vec.remove(r);
1228
1229 if i < self.len() {
1230 self.vec.insert(i, wgt);
1231
1232 observer.moved(r, i);
1233 } else {
1234 let i = self.vec.len();
1235
1236 self.vec.push(wgt);
1237
1238 observer.moved(r, i);
1239 }
1240
1241 WIDGET.update_info();
1242 }
1243 }
1244
1245 for (id, to) in r.move_id {
1246 if let Some(r) = self
1247 .vec
1248 .iter_mut()
1249 .position(|w| w.with_context(WidgetUpdateMode::Ignore, || WIDGET.id() == id).unwrap_or(false))
1250 {
1251 let i = to(r, self.len());
1252
1253 if r != i {
1254 let wgt = self.vec.remove(r);
1255
1256 if i < self.len() {
1257 self.vec.insert(i, wgt);
1258 observer.moved(r, i);
1259 } else {
1260 let i = self.vec.len();
1261 self.vec.push(wgt);
1262 observer.moved(r, i);
1263 }
1264
1265 WIDGET.update_info();
1266 }
1267 }
1268 }
1269 }
1270 }
1271 }
1272}
1273impl ops::Deref for EditableUiNodeList {
1274 type Target = Vec<BoxedUiNode>;
1275
1276 fn deref(&self) -> &Self::Target {
1277 &self.vec
1278 }
1279}
1280impl ops::DerefMut for EditableUiNodeList {
1281 fn deref_mut(&mut self) -> &mut Self::Target {
1282 &mut self.vec
1283 }
1284}
1285impl UiNodeList for EditableUiNodeList {
1286 fn with_node<R, F>(&mut self, index: usize, f: F) -> R
1287 where
1288 F: FnOnce(&mut BoxedUiNode) -> R,
1289 {
1290 self.vec.with_node(index, f)
1291 }
1292
1293 fn for_each<F>(&mut self, f: F)
1294 where
1295 F: FnMut(usize, &mut BoxedUiNode),
1296 {
1297 self.vec.for_each(f)
1298 }
1299
1300 fn par_each<F>(&mut self, f: F)
1301 where
1302 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
1303 {
1304 self.vec.par_each(f)
1305 }
1306
1307 fn par_fold_reduce<T, I, F, R>(&mut self, identity: I, fold: F, reduce: R) -> T
1308 where
1309 T: Send + 'static,
1310 I: Fn() -> T + Send + Sync,
1311 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
1312 R: Fn(T, T) -> T + Send + Sync,
1313 {
1314 self.vec.par_fold_reduce(identity, fold, reduce)
1315 }
1316
1317 fn len(&self) -> usize {
1318 self.vec.len()
1319 }
1320
1321 fn boxed(self) -> BoxedUiNodeList {
1322 Box::new(self)
1323 }
1324
1325 fn drain_into(&mut self, vec: &mut Vec<BoxedUiNode>) {
1326 vec.append(&mut self.vec)
1327 }
1328
1329 fn init_all(&mut self) {
1330 self.ctrl.0.lock().target = Some(WIDGET.id());
1331 self.vec.init_all();
1332 }
1333
1334 fn deinit_all(&mut self) {
1335 self.ctrl.0.lock().target = None;
1336 self.vec.deinit_all();
1337 }
1338
1339 fn info_all(&mut self, info: &mut WidgetInfoBuilder) {
1340 self.vec.info_all(info);
1341 }
1342
1343 fn event_all(&mut self, update: &EventUpdate) {
1344 self.vec.event_all(update)
1345 }
1346
1347 fn update_all(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
1348 self.vec.update_all(updates, &mut ());
1349 self.fulfill_requests(observer);
1350 }
1351
1352 fn measure_each<F, S>(&mut self, wm: &mut WidgetMeasure, measure: F, fold_size: S) -> PxSize
1353 where
1354 F: Fn(usize, &mut BoxedUiNode, &mut WidgetMeasure) -> PxSize + Send + Sync,
1355 S: Fn(PxSize, PxSize) -> PxSize + Send + Sync,
1356 {
1357 self.vec.measure_each(wm, measure, fold_size)
1358 }
1359
1360 fn layout_each<F, S>(&mut self, wl: &mut WidgetLayout, layout: F, fold_size: S) -> PxSize
1361 where
1362 F: Fn(usize, &mut BoxedUiNode, &mut WidgetLayout) -> PxSize + Send + Sync,
1363 S: Fn(PxSize, PxSize) -> PxSize + Send + Sync,
1364 {
1365 self.vec.layout_each(wl, layout, fold_size)
1366 }
1367
1368 fn render_all(&mut self, frame: &mut FrameBuilder) {
1369 self.vec.render_all(frame)
1370 }
1371
1372 fn render_update_all(&mut self, update: &mut FrameUpdate) {
1373 self.vec.render_update_all(update)
1374 }
1375}
1376
1377type NodeMoveToFn = fn(usize, usize) -> usize;
1379
1380#[derive(Clone, Debug)]
1382pub struct EditableUiNodeListRef(Arc<Mutex<EditRequests>>);
1383struct EditRequests {
1384 target: Option<WidgetId>,
1385 insert: Vec<(usize, BoxedUiNode)>,
1386 push: Vec<BoxedUiNode>,
1387 retain: Vec<Box<dyn FnMut(&mut BoxedUiNode) -> bool + Send>>,
1388 move_index: Vec<(usize, usize)>,
1389 move_id: Vec<(WidgetId, NodeMoveToFn)>,
1390 clear: bool,
1391
1392 alive: bool,
1393}
1394impl fmt::Debug for EditRequests {
1395 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1396 f.debug_struct("EditRequests")
1397 .field("target", &self.target)
1398 .field("insert.len", &self.insert.len())
1399 .field("push.len", &self.push.len())
1400 .field("retain.len", &self.retain.len())
1401 .field("move_index", &self.move_index)
1402 .field("move_id", &self.move_id)
1403 .field("clear", &self.clear)
1404 .field("alive", &self.alive)
1405 .finish()
1406 }
1407}
1408impl EditableUiNodeListRef {
1409 fn new(alive: bool) -> Self {
1410 Self(Arc::new(Mutex::new(EditRequests {
1411 target: None,
1412 insert: vec![],
1413 push: vec![],
1414 retain: vec![],
1415 move_index: vec![],
1416 move_id: vec![],
1417 clear: false,
1418 alive,
1419 })))
1420 }
1421
1422 pub fn dummy() -> Self {
1428 Self::new(false)
1429 }
1430
1431 pub fn alive(&self) -> bool {
1433 self.0.lock().alive
1434 }
1435
1436 pub fn insert(&self, index: usize, widget: impl UiNode) {
1444 let mut s = self.0.lock();
1445 if !s.alive {
1446 return;
1447 }
1448 s.insert.push((index, widget.boxed()));
1449 UPDATES.update(s.target);
1450 }
1451
1452 pub fn push(&self, widget: impl UiNode) {
1460 let mut s = self.0.lock();
1461 if !s.alive {
1462 return;
1463 }
1464 s.push.push(widget.boxed());
1465 UPDATES.update(s.target);
1466 }
1467
1468 pub fn remove(&self, id: impl Into<WidgetId>) {
1473 fn remove_impl(id: WidgetId) -> impl FnMut(&mut BoxedUiNode) -> bool + Send + 'static {
1474 move |node| node.with_context(WidgetUpdateMode::Ignore, || WIDGET.id() != id).unwrap_or(true)
1475 }
1476 self.retain(remove_impl(id.into()))
1477 }
1478
1479 pub fn retain(&self, predicate: impl FnMut(&mut BoxedUiNode) -> bool + Send + 'static) {
1485 let mut s = self.0.lock();
1486 if !s.alive {
1487 return;
1488 }
1489 s.retain.push(Box::new(predicate));
1490 UPDATES.update(s.target);
1491 }
1492
1493 pub fn move_index(&self, remove_index: usize, insert_index: usize) {
1500 if remove_index != insert_index {
1501 let mut s = self.0.lock();
1502 if !s.alive {
1503 return;
1504 }
1505 s.move_index.push((remove_index, insert_index));
1506 UPDATES.update(s.target);
1507 }
1508 }
1509
1510 pub fn move_id(&self, id: impl Into<WidgetId>, get_move_to: NodeMoveToFn) {
1550 let mut s = self.0.lock();
1551 if !s.alive {
1552 return;
1553 }
1554 s.move_id.push((id.into(), get_move_to));
1555 UPDATES.update(s.target);
1556 }
1557
1558 pub fn clear(&self) {
1562 let mut s = self.0.lock();
1563 s.clear = true;
1564 UPDATES.update(s.target);
1565 }
1566
1567 fn take_requests(&self) -> Option<EditRequests> {
1568 let mut s = self.0.lock();
1569
1570 if s.clear
1571 || !s.insert.is_empty()
1572 || !s.push.is_empty()
1573 || !s.retain.is_empty()
1574 || !s.move_index.is_empty()
1575 || !s.move_id.is_empty()
1576 {
1577 let empty = EditRequests {
1578 target: s.target,
1579 alive: s.alive,
1580
1581 insert: vec![],
1582 push: vec![],
1583 retain: vec![],
1584 move_index: vec![],
1585 move_id: vec![],
1586 clear: false,
1587 };
1588 Some(mem::replace(&mut *s, empty))
1589 } else {
1590 None
1591 }
1592 }
1593}
1594
1595fn many_list_index(lists: &Vec<BoxedUiNodeList>, index: usize) -> (usize, usize) {
1596 let mut offset = 0;
1597
1598 for (li, list) in lists.iter().enumerate() {
1599 let i = index - offset;
1600 let len = list.len();
1601
1602 if i < len {
1603 return (li, i);
1604 }
1605
1606 offset += len;
1607 }
1608
1609 panic!(
1610 "'index out of bounds: the len is {} but the index is {}",
1611 UiNodeList::len(lists),
1612 index
1613 );
1614}
1615
1616fn vec_list_for_each<F>(self_: &mut Vec<BoxedUiNodeList>, f: F)
1617where
1618 F: FnMut(usize, &mut BoxedUiNode),
1619{
1620 #[cfg(feature = "dyn_closure")]
1621 let f: Box<dyn FnMut(usize, &mut BoxedUiNode)> = Box::new(f);
1622
1623 vec_list_for_each_impl(self_, f)
1624}
1625fn vec_list_for_each_impl<F>(self_: &mut Vec<BoxedUiNodeList>, mut f: F)
1626where
1627 F: FnMut(usize, &mut BoxedUiNode),
1628{
1629 let mut offset = 0;
1630 for list in self_ {
1631 list.for_each(|i, n| f(i + offset, n));
1632 offset += list.len();
1633 }
1634}
1635
1636fn vec_list_par_each<F>(self_: &mut Vec<BoxedUiNodeList>, f: F)
1637where
1638 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
1639{
1640 #[cfg(feature = "dyn_closure")]
1641 let f: Box<dyn Fn(usize, &mut BoxedUiNode) + Send + Sync> = Box::new(f);
1642 vec_list_par_each_impl(self_, f)
1643}
1644fn vec_list_par_each_impl<F>(self_: &mut Vec<BoxedUiNodeList>, f: F)
1645where
1646 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
1647{
1648 task::scope(|s| {
1649 let f = &f;
1650 let mut offset = 0;
1651 for list in self_ {
1652 let len = list.len();
1653 s.spawn(move |_| {
1654 list.par_each(move |i, n| f(i + offset, n));
1655 });
1656 offset += len;
1657 }
1658 });
1659}
1660
1661fn vec_list_par_fold_reduce<T, I, F, R>(self_: &mut [BoxedUiNodeList], identity: I, fold: F, reduce: R) -> T
1662where
1663 T: Send + 'static,
1664 I: Fn() -> T + Send + Sync,
1665 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
1666 R: Fn(T, T) -> T + Send + Sync,
1667{
1668 #[cfg(feature = "dyn_closure")]
1669 let identity: Box<dyn Fn() -> T + Send + Sync> = Box::new(identity);
1670 #[cfg(feature = "dyn_closure")]
1671 let fold: Box<dyn Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync> = Box::new(fold);
1672 #[cfg(feature = "dyn_closure")]
1673 let reduce: Box<dyn Fn(T, T) -> T + Send + Sync> = Box::new(reduce);
1674
1675 vec_list_par_fold_reduce_impl(self_, identity, fold, reduce)
1676}
1677fn vec_list_par_fold_reduce_impl<T, I, F, R>(self_: &mut [BoxedUiNodeList], identity: I, fold: F, reduce: R) -> T
1678where
1679 T: Send + 'static,
1680 I: Fn() -> T + Send + Sync,
1681 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
1682 R: Fn(T, T) -> T + Send + Sync,
1683{
1684 let mut offset = 0;
1685 let mut r = Some(identity());
1686 for list in self_.chunks_mut(2) {
1687 let b = if list.len() == 2 {
1688 let mut pair = list.iter_mut();
1689 let a = pair.next().unwrap();
1690 let b = pair.next().unwrap();
1691 let offset_b = offset + a.len();
1692
1693 let (a, b) = task::join(
1694 || a.par_fold_reduce(&identity, |a, i, n| fold(a, i + offset, n), &reduce),
1695 || b.par_fold_reduce(&identity, |a, i, n| fold(a, i + offset_b, n), &reduce),
1696 );
1697
1698 reduce(a, b)
1699 } else {
1700 list[0].par_fold_reduce(&identity, |a, i, n| fold(a, i + offset, n), &reduce)
1701 };
1702
1703 let a = r.take().unwrap();
1704 r = Some(reduce(a, b));
1705
1706 offset += list.iter().map(|l| l.len()).sum::<usize>();
1707 }
1708 r.unwrap()
1709}
1710
1711impl UiNodeList for Vec<BoxedUiNodeList> {
1712 fn with_node<R, F>(&mut self, index: usize, f: F) -> R
1713 where
1714 F: FnOnce(&mut BoxedUiNode) -> R,
1715 {
1716 let (l, i) = many_list_index(self, index);
1717 self[l].with_node(i, f)
1718 }
1719
1720 fn for_each<F>(&mut self, f: F)
1721 where
1722 F: FnMut(usize, &mut BoxedUiNode),
1723 {
1724 vec_list_for_each(self, f)
1725 }
1726
1727 fn par_each<F>(&mut self, f: F)
1728 where
1729 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
1730 {
1731 vec_list_par_each(self, f)
1732 }
1733
1734 fn par_fold_reduce<T, I, F, R>(&mut self, identity: I, fold: F, reduce: R) -> T
1735 where
1736 T: Send + 'static,
1737 I: Fn() -> T + Send + Sync,
1738 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
1739 R: Fn(T, T) -> T + Send + Sync,
1740 {
1741 vec_list_par_fold_reduce(self, identity, fold, reduce)
1742 }
1743
1744 fn len(&self) -> usize {
1745 self.iter().map(|l| l.len()).sum()
1746 }
1747
1748 fn boxed(self) -> BoxedUiNodeList {
1749 Box::new(self)
1750 }
1751
1752 fn drain_into(&mut self, vec: &mut Vec<BoxedUiNode>) {
1753 for mut list in self.drain(..) {
1754 list.drain_into(vec);
1755 }
1756 }
1757
1758 fn is_empty(&self) -> bool {
1759 self.iter().all(|l| l.is_empty())
1760 }
1761
1762 fn init_all(&mut self) {
1763 if self.len() > 1 && PARALLEL_VAR.get().contains(Parallel::INIT) {
1764 self.par_iter_mut().with_ctx().for_each(|l| l.init_all());
1765 } else {
1766 for l in self {
1767 l.init_all();
1768 }
1769 }
1770 }
1771
1772 fn deinit_all(&mut self) {
1773 if self.len() > 1 && PARALLEL_VAR.get().contains(Parallel::DEINIT) {
1774 self.par_iter_mut().with_ctx().for_each(|l| l.deinit_all());
1775 } else {
1776 for list in self {
1777 list.deinit_all();
1778 }
1779 }
1780 }
1781
1782 fn update_all(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
1783 if self.len() > 1 && observer.is_reset_only() && PARALLEL_VAR.get().contains(Parallel::UPDATE) {
1784 let r = self
1785 .par_iter_mut()
1786 .with_ctx()
1787 .map(|l| {
1788 let mut r = false;
1789 l.update_all(updates, &mut r);
1790 r
1791 })
1792 .any(std::convert::identity);
1793 if r {
1794 observer.reset();
1795 }
1796 } else {
1797 let mut offset = 0;
1798 for list in self {
1799 list.update_all(updates, &mut OffsetUiListObserver(offset, observer));
1800 offset += list.len();
1801 }
1802 }
1803 }
1804
1805 fn info_all(&mut self, info: &mut WidgetInfoBuilder) {
1806 if self.len() > 1 && PARALLEL_VAR.get().contains(Parallel::INFO) {
1807 let b = self
1808 .par_iter_mut()
1809 .with_ctx()
1810 .fold(
1811 || info.parallel_split(),
1812 |mut info, list| {
1813 list.info_all(&mut info);
1814 info
1815 },
1816 )
1817 .reduce(
1818 || info.parallel_split(),
1819 |mut a, b| {
1820 a.parallel_fold(b);
1821 a
1822 },
1823 );
1824 info.parallel_fold(b);
1825 } else {
1826 for list in self {
1827 list.info_all(info);
1828 }
1829 }
1830 }
1831
1832 fn event_all(&mut self, update: &EventUpdate) {
1833 if self.len() > 1 && PARALLEL_VAR.get().contains(Parallel::EVENT) {
1834 self.par_iter_mut().with_ctx().for_each(|l| l.event_all(update));
1835 } else {
1836 for list in self {
1837 list.event_all(update);
1838 }
1839 }
1840 }
1841
1842 fn render_all(&mut self, frame: &mut FrameBuilder) {
1847 if self.len() > 1 && PARALLEL_VAR.get().contains(Parallel::RENDER) {
1848 let b = self
1849 .par_iter_mut()
1850 .with_ctx()
1851 .fold(
1852 || frame.parallel_split(),
1853 |mut frame, list| {
1854 list.render_all(&mut frame);
1855 frame
1856 },
1857 )
1858 .reduce(
1859 || frame.parallel_split(),
1860 |mut a, b| {
1861 a.parallel_fold(b);
1862 a
1863 },
1864 );
1865 frame.parallel_fold(b);
1866 } else {
1867 for list in self {
1868 list.render_all(frame);
1869 }
1870 }
1871 }
1872
1873 fn render_update_all(&mut self, update: &mut FrameUpdate) {
1874 if self.len() > 1 && PARALLEL_VAR.get().contains(Parallel::RENDER) {
1875 let b = self
1876 .par_iter_mut()
1877 .with_ctx()
1878 .fold(
1879 || update.parallel_split(),
1880 |mut update, list| {
1881 list.render_update_all(&mut update);
1882 update
1883 },
1884 )
1885 .reduce(
1886 || update.parallel_split(),
1887 |mut a, b| {
1888 a.parallel_fold(b);
1889 a
1890 },
1891 );
1892 update.parallel_fold(b);
1893 } else {
1894 for list in self {
1895 list.render_update_all(update);
1896 }
1897 }
1898 }
1899}
1900
1901#[derive(Debug, Clone)]
1903pub struct PanelListRange {
1904 range: Option<(WidgetId, WidgetId)>,
1906 version: u8,
1907}
1908impl PanelListRange {
1909 pub fn update(
1914 parent: &WidgetInfo,
1915 panel_id: impl Into<StateId<Self>>,
1916 last_version: &mut Option<u8>,
1917 ) -> Option<crate::widget::info::iter::Children> {
1918 let range = parent.meta().get_clone(panel_id);
1919 if let Some(Self { range, version }) = range {
1920 let version = Some(version);
1921 if *last_version != version {
1922 *last_version = version;
1923
1924 if let Some((s, e)) = range {
1925 let tree = parent.tree();
1926 if let (Some(s), Some(e)) = (tree.get(s), tree.get(e)) {
1927 let parent = Some(parent);
1928 if s.parent().as_ref() == parent && e.parent().as_ref() == parent {
1929 return Some(crate::widget::info::iter::Children::new_range(s, e));
1930 }
1931 }
1932 }
1933 }
1934 }
1935 None
1936 }
1937
1938 pub fn get(parent: &WidgetInfo, panel_id: impl Into<StateId<Self>>) -> Option<crate::widget::info::iter::Children> {
1940 let range = parent.meta().get_clone(panel_id);
1941 if let Some(Self { range: Some((s, e)), .. }) = range {
1942 let tree = parent.tree();
1943 if let (Some(s), Some(e)) = (tree.get(s), tree.get(e)) {
1944 let parent = Some(parent);
1945 if s.parent().as_ref() == parent && e.parent().as_ref() == parent {
1946 return Some(crate::widget::info::iter::Children::new_range(s, e));
1947 }
1948 }
1949 }
1950 None
1951 }
1952}
1953
1954pub struct PanelList<D = DefaultPanelListData>
1969where
1970 D: PanelListData,
1971{
1972 list: BoxedUiNodeList,
1973 data: Vec<Mutex<D>>, offset_key: FrameValueKey<PxTransform>,
1976 info_id: Option<(StateId<PanelListRange>, u8, bool)>,
1977
1978 z_map: Vec<u64>,
1979 z_naturally_sorted: bool,
1980}
1981impl PanelList<DefaultPanelListData> {
1982 pub fn new(list: impl UiNodeList) -> Self {
1984 Self::new_custom(list)
1985 }
1986}
1987
1988impl<D> PanelList<D>
1989where
1990 D: PanelListData,
1991{
1992 pub fn new_custom(list: impl UiNodeList) -> Self {
1994 Self {
1995 data: {
1996 let mut d = vec![];
1997 d.resize_with(list.len(), Default::default);
1998 d
1999 },
2000 list: list.boxed(),
2001 offset_key: FrameValueKey::new_unique(),
2002 info_id: None,
2003 z_map: vec![],
2004 z_naturally_sorted: false,
2005 }
2006 }
2007
2008 pub fn track_info_range(mut self, info_id: impl Into<StateId<PanelListRange>>) -> Self {
2014 self.info_id = Some((info_id.into(), 0, true));
2015 self
2016 }
2017
2018 pub fn into_parts(
2020 self,
2021 ) -> (
2022 BoxedUiNodeList,
2023 Vec<Mutex<D>>,
2024 FrameValueKey<PxTransform>,
2025 Option<StateId<PanelListRange>>,
2026 ) {
2027 (self.list, self.data, self.offset_key, self.info_id.map(|t| t.0))
2028 }
2029
2030 pub fn from_parts(
2036 list: BoxedUiNodeList,
2037 data: Vec<Mutex<D>>,
2038 offset_key: FrameValueKey<PxTransform>,
2039 info_id: Option<StateId<PanelListRange>>,
2040 ) -> Self {
2041 assert_eq!(list.len(), data.len());
2042 Self {
2043 list,
2044 data,
2045 offset_key,
2046 info_id: info_id.map(|i| (i, 0, true)),
2047 z_map: vec![],
2048 z_naturally_sorted: false,
2049 }
2050 }
2051
2052 pub fn info_id(&self) -> Option<StateId<PanelListRange>> {
2056 self.info_id.as_ref().map(|t| t.0)
2057 }
2058
2059 pub fn with_node<R, F>(&mut self, index: usize, f: F) -> R
2061 where
2062 F: FnOnce(&mut BoxedUiNode, &mut D) -> R,
2063 {
2064 #[cfg(feature = "dyn_closure")]
2065 let f: Box<dyn FnOnce(&mut BoxedUiNode, &mut D) -> R> = Box::new(f);
2066 self.with_node_impl(index, f)
2067 }
2068 fn with_node_impl<R, F>(&mut self, index: usize, f: F) -> R
2069 where
2070 F: FnOnce(&mut BoxedUiNode, &mut D) -> R,
2071 {
2072 let data = self.data[index].get_mut();
2073 self.list.with_node(index, move |n| f(n, data))
2074 }
2075
2076 pub fn for_each<F>(&mut self, f: F)
2078 where
2079 F: FnMut(usize, &mut BoxedUiNode, &mut D),
2080 {
2081 #[cfg(feature = "dyn_closure")]
2082 let f: Box<dyn FnMut(usize, &mut BoxedUiNode, &mut D)> = Box::new(f);
2083 self.for_each_impl(f)
2084 }
2085 fn for_each_impl<F>(&mut self, mut f: F)
2086 where
2087 F: FnMut(usize, &mut BoxedUiNode, &mut D),
2088 {
2089 let data = &mut self.data;
2090 self.list.for_each(move |i, n| f(i, n, data[i].get_mut()))
2091 }
2092
2093 pub fn par_each<F>(&mut self, f: F)
2095 where
2096 F: Fn(usize, &mut BoxedUiNode, &mut D) + Send + Sync,
2097 D: Sync,
2098 {
2099 #[cfg(feature = "dyn_closure")]
2100 let f: Box<dyn Fn(usize, &mut BoxedUiNode, &mut D) + Send + Sync> = Box::new(f);
2101 self.par_each_impl(f)
2102 }
2103 fn par_each_impl<F>(&mut self, f: F)
2104 where
2105 F: Fn(usize, &mut BoxedUiNode, &mut D) + Send + Sync,
2106 D: Sync,
2107 {
2108 let data = &self.data;
2109 self.list.par_each(|i, n| {
2110 f(
2111 i,
2112 n,
2113 &mut data[i].try_lock().unwrap_or_else(|| panic!("data for `{i}` is already locked")),
2114 )
2115 })
2116 }
2117
2118 pub fn par_fold_reduce<T, I, F, R>(&mut self, identity: I, fold: F, reduce: R) -> T
2122 where
2123 T: Send + 'static,
2124 I: Fn() -> T + Send + Sync,
2125 F: Fn(T, usize, &mut BoxedUiNode, &mut D) -> T + Send + Sync,
2126 R: Fn(T, T) -> T + Send + Sync,
2127 {
2128 #[cfg(feature = "dyn_closure")]
2129 let identity: Box<dyn Fn() -> T + Send + Sync> = Box::new(identity);
2130 #[cfg(feature = "dyn_closure")]
2131 let fold: Box<dyn Fn(T, usize, &mut BoxedUiNode, &mut D) -> T + Send + Sync> = Box::new(fold);
2132 #[cfg(feature = "dyn_closure")]
2133 let reduce: Box<dyn Fn(T, T) -> T + Send + Sync> = Box::new(reduce);
2134
2135 self.par_fold_reduce_impl(identity, fold, reduce)
2136 }
2137 fn par_fold_reduce_impl<T, I, F, R>(&mut self, identity: I, fold: F, reduce: R) -> T
2138 where
2139 T: Send + 'static,
2140 I: Fn() -> T + Send + Sync,
2141 F: Fn(T, usize, &mut BoxedUiNode, &mut D) -> T + Send + Sync,
2142 R: Fn(T, T) -> T + Send + Sync,
2143 {
2144 let data = &self.data;
2145 self.list.par_fold_reduce(
2146 identity,
2147 |a, i, n| {
2148 fold(
2149 a,
2150 i,
2151 n,
2152 &mut data[i].try_lock().unwrap_or_else(|| panic!("data for `{i}` is already locked")),
2153 )
2154 },
2155 reduce,
2156 )
2157 }
2158
2159 pub fn measure_each<F, S>(&mut self, wm: &mut WidgetMeasure, measure: F, fold_size: S) -> PxSize
2163 where
2164 F: Fn(usize, &mut BoxedUiNode, &mut D, &mut WidgetMeasure) -> PxSize + Send + Sync,
2165 S: Fn(PxSize, PxSize) -> PxSize + Send + Sync,
2166 {
2167 #[cfg(feature = "dyn_closure")]
2168 let measure: Box<dyn Fn(usize, &mut BoxedUiNode, &mut D, &mut WidgetMeasure) -> PxSize + Send + Sync> = Box::new(measure);
2169 #[cfg(feature = "dyn_closure")]
2170 let fold_size: Box<dyn Fn(PxSize, PxSize) -> PxSize + Send + Sync> = Box::new(fold_size);
2171
2172 self.measure_each_impl(wm, measure, fold_size)
2173 }
2174 fn measure_each_impl<F, S>(&mut self, wm: &mut WidgetMeasure, measure: F, fold_size: S) -> PxSize
2175 where
2176 F: Fn(usize, &mut BoxedUiNode, &mut D, &mut WidgetMeasure) -> PxSize + Send + Sync,
2177 S: Fn(PxSize, PxSize) -> PxSize + Send + Sync,
2178 {
2179 let data = &self.data;
2180 self.list.measure_each(
2181 wm,
2182 |i, n, wm| {
2183 measure(
2184 i,
2185 n,
2186 &mut data[i].try_lock().unwrap_or_else(|| panic!("data for `{i}` is already locked")),
2187 wm,
2188 )
2189 },
2190 fold_size,
2191 )
2192 }
2193
2194 pub fn layout_each<F, S>(&mut self, wl: &mut WidgetLayout, layout: F, fold_size: S) -> PxSize
2198 where
2199 F: Fn(usize, &mut BoxedUiNode, &mut D, &mut WidgetLayout) -> PxSize + Send + Sync,
2200 S: Fn(PxSize, PxSize) -> PxSize + Send + Sync,
2201 {
2202 #[cfg(feature = "dyn_closure")]
2203 let layout: Box<dyn Fn(usize, &mut BoxedUiNode, &mut D, &mut WidgetLayout) -> PxSize + Send + Sync> = Box::new(layout);
2204 #[cfg(feature = "dyn_closure")]
2205 let fold_size: Box<dyn Fn(PxSize, PxSize) -> PxSize + Send + Sync> = Box::new(fold_size);
2206
2207 self.layout_each_impl(wl, layout, fold_size)
2208 }
2209 fn layout_each_impl<F, S>(&mut self, wl: &mut WidgetLayout, layout: F, fold_size: S) -> PxSize
2210 where
2211 F: Fn(usize, &mut BoxedUiNode, &mut D, &mut WidgetLayout) -> PxSize + Send + Sync,
2212 S: Fn(PxSize, PxSize) -> PxSize + Send + Sync,
2213 {
2214 let data = &self.data;
2215 self.list.layout_each(
2216 wl,
2217 |i, n, wl| {
2218 layout(
2219 i,
2220 n,
2221 &mut data[i].try_lock().unwrap_or_else(|| panic!("data for `{i}` is already locked")),
2222 wl,
2223 )
2224 },
2225 fold_size,
2226 )
2227 }
2228
2229 pub fn for_each_z_sorted(&mut self, f: impl FnMut(usize, &mut BoxedUiNode, &mut D)) {
2231 #[cfg(feature = "dyn_closure")]
2232 let f: Box<dyn FnMut(usize, &mut BoxedUiNode, &mut D)> = Box::new(f);
2233 self.for_each_z_sorted_impl(f)
2234 }
2235 fn for_each_z_sorted_impl(&mut self, mut f: impl FnMut(usize, &mut BoxedUiNode, &mut D)) {
2236 if self.z_naturally_sorted {
2237 self.for_each(f)
2238 } else {
2239 if self.z_map.len() != self.list.len() {
2240 self.z_sort();
2241 }
2242
2243 if self.z_naturally_sorted {
2244 self.for_each(f);
2245 } else {
2246 for &index in self.z_map.iter() {
2247 let index = index as usize;
2248 let data = self.data[index].get_mut();
2249 self.list.with_node(index, |node| f(index, node, data));
2250 }
2251 }
2252 }
2253 }
2254
2255 fn z_sort(&mut self) {
2256 let len = self.list.len();
2270 assert!(len <= u32::MAX as usize);
2271
2272 let mut prev_z = ZIndex::BACK;
2273 let mut need_map = false;
2274 let mut z_and_i = Vec::with_capacity(len);
2275 let mut has_non_default_zs = false;
2276
2277 self.list.for_each(|i, node| {
2278 let z = Z_INDEX.get_wgt(node);
2279 z_and_i.push(((z.0 as u64) << 32) | i as u64);
2280
2281 need_map |= z < prev_z;
2282 has_non_default_zs |= z != ZIndex::DEFAULT;
2283 prev_z = z;
2284 });
2285
2286 self.z_naturally_sorted = !need_map;
2287
2288 if need_map {
2289 z_and_i.sort_unstable();
2290
2291 for z in &mut z_and_i {
2292 *z &= u32::MAX as u64;
2293 }
2294
2295 self.z_map = z_and_i;
2296 } else {
2297 self.z_map.clear();
2298 }
2299 }
2300
2301 pub fn z_map(&mut self, index: usize) -> usize {
2303 if self.z_naturally_sorted {
2304 return index;
2305 }
2306
2307 if self.z_map.len() != self.list.len() {
2308 self.z_sort();
2309 }
2310
2311 if self.z_naturally_sorted {
2312 return index;
2313 }
2314
2315 self.z_map[index] as usize
2316 }
2317
2318 pub fn data(&mut self, index: usize) -> &mut D {
2320 self.data[index].get_mut()
2321 }
2322
2323 pub fn commit_data(&mut self) -> PanelListDataChanges {
2331 let mut changes = PanelListDataChanges::empty();
2332 for data in self.data.iter_mut() {
2333 changes |= data.get_mut().commit();
2334 }
2335 changes
2336 }
2337
2338 pub fn offset_key(&self) -> FrameValueKey<PxTransform> {
2342 self.offset_key
2343 }
2344}
2345impl<D> UiNodeList for PanelList<D>
2346where
2347 D: PanelListData,
2348{
2349 fn with_node<R, F>(&mut self, index: usize, f: F) -> R
2350 where
2351 F: FnOnce(&mut BoxedUiNode) -> R,
2352 {
2353 self.list.with_node(index, f)
2354 }
2355
2356 fn for_each<F>(&mut self, f: F)
2357 where
2358 F: FnMut(usize, &mut BoxedUiNode),
2359 {
2360 self.list.for_each(f)
2361 }
2362
2363 fn par_each<F>(&mut self, f: F)
2364 where
2365 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
2366 {
2367 self.list.par_each(f)
2368 }
2369
2370 fn par_fold_reduce<T, I, F, R>(&mut self, identity: I, fold: F, reduce: R) -> T
2371 where
2372 T: Send + 'static,
2373 I: Fn() -> T + Send + Sync,
2374 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
2375 R: Fn(T, T) -> T + Send + Sync,
2376 {
2377 self.list.par_fold_reduce(identity, fold, reduce)
2378 }
2379
2380 fn len(&self) -> usize {
2381 self.list.len()
2382 }
2383
2384 fn boxed(self) -> BoxedUiNodeList {
2385 Box::new(self)
2386 }
2387
2388 fn drain_into(&mut self, vec: &mut Vec<BoxedUiNode>) {
2389 self.list.drain_into(vec);
2390 self.data.clear();
2391 self.z_map.clear();
2392 self.z_naturally_sorted = true;
2393 }
2394
2395 fn init_all(&mut self) {
2396 self.z_map.clear();
2397 let resort = Z_INDEX.with(WIDGET.id(), || self.list.init_all());
2398 self.z_naturally_sorted = !resort;
2399 self.data.resize_with(self.list.len(), Default::default);
2400 }
2401
2402 fn deinit_all(&mut self) {
2403 self.list.deinit_all();
2404 }
2405
2406 fn info_all(&mut self, info: &mut WidgetInfoBuilder) {
2407 if self.list.is_empty() {
2408 return;
2409 }
2410
2411 self.list.info_all(info);
2412
2413 if let Some((id, version, pump_update)) = &mut self.info_id {
2414 let start = self.list.with_node(0, |c| c.with_context(WidgetUpdateMode::Ignore, || WIDGET.id()));
2415 let end = self
2416 .list
2417 .with_node(self.list.len() - 1, |c| c.with_context(WidgetUpdateMode::Ignore, || WIDGET.id()));
2418 let range = match (start, end) {
2419 (Some(s), Some(e)) => Some((s, e)),
2420 _ => None,
2421 };
2422 info.set_meta(*id, PanelListRange { range, version: *version });
2423
2424 if mem::take(pump_update) {
2425 self.list.for_each(|_, c| {
2426 c.with_context(WidgetUpdateMode::Bubble, || WIDGET.update());
2427 });
2428 }
2429 }
2430 }
2431
2432 fn event_all(&mut self, update: &EventUpdate) {
2433 self.list.event_all(update);
2434 }
2435
2436 fn update_all(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
2437 let mut observer = PanelObserver {
2438 changed: false,
2439 data: &mut self.data,
2440 observer,
2441 };
2442 let resort = Z_INDEX.with(WIDGET.id(), || self.list.update_all(updates, &mut observer));
2443 let observer_changed = observer.changed;
2444 if resort || (observer.changed && self.z_naturally_sorted) {
2445 self.z_map.clear();
2446 self.z_naturally_sorted = false;
2447 WIDGET.render();
2448 }
2449 self.data.resize_with(self.list.len(), Default::default);
2450
2451 if observer_changed {
2452 if let Some((_, v, u)) = &mut self.info_id {
2453 if !*u {
2454 *v = v.wrapping_add(1);
2455 *u = true;
2456 }
2457 }
2459 }
2460 }
2461
2462 fn render_all(&mut self, frame: &mut FrameBuilder) {
2463 let offset_key = self.offset_key;
2464 if self.z_naturally_sorted && self.len() > 1 && PARALLEL_VAR.get().contains(Parallel::RENDER) {
2465 let b = self.par_fold_reduce(
2466 || frame.parallel_split(),
2467 |mut frame, i, child, data| {
2468 let offset = data.child_offset();
2469 if data.define_reference_frame() {
2470 frame.push_reference_frame(
2471 (offset_key, i as u32).into(),
2472 offset_key.bind_child(i as u32, offset.into(), false),
2473 true,
2474 true,
2475 |frame| {
2476 child.render(frame);
2477 },
2478 );
2479 } else {
2480 frame.push_child(offset, |frame| {
2481 child.render(frame);
2482 });
2483 }
2484 frame
2485 },
2486 |mut a, b| {
2487 a.parallel_fold(b);
2488 a
2489 },
2490 );
2491 frame.parallel_fold(b);
2492 } else {
2493 self.for_each_z_sorted(|i, child, data| {
2494 let offset = data.child_offset();
2495 if data.define_reference_frame() {
2496 frame.push_reference_frame(
2497 (offset_key, i as u32).into(),
2498 offset_key.bind_child(i as u32, offset.into(), false),
2499 true,
2500 true,
2501 |frame| {
2502 child.render(frame);
2503 },
2504 );
2505 } else {
2506 frame.push_child(offset, |frame| {
2507 child.render(frame);
2508 });
2509 }
2510 });
2511 }
2512 }
2513
2514 fn render_update_all(&mut self, update: &mut FrameUpdate) {
2515 let offset_key = self.offset_key;
2516
2517 if self.len() > 1 && PARALLEL_VAR.get().contains(Parallel::RENDER) {
2518 let b = self.par_fold_reduce(
2519 || update.parallel_split(),
2520 |mut update, i, child, data| {
2521 let offset = data.child_offset();
2522 if data.define_reference_frame() {
2523 update.with_transform(offset_key.update_child(i as u32, offset.into(), false), true, |update| {
2524 child.render_update(update);
2525 });
2526 } else {
2527 update.with_child(offset, |update| {
2528 child.render_update(update);
2529 });
2530 }
2531 update
2532 },
2533 |mut a, b| {
2534 a.parallel_fold(b);
2535 a
2536 },
2537 );
2538 update.parallel_fold(b);
2539 } else {
2540 self.for_each(|i, child, data| {
2541 let offset = data.child_offset();
2542 if data.define_reference_frame() {
2543 update.with_transform(offset_key.update_child(i as u32, offset.into(), false), true, |update| {
2544 child.render_update(update);
2545 });
2546 } else {
2547 update.with_child(offset, |update| {
2548 child.render_update(update);
2549 });
2550 }
2551 });
2552 }
2553 }
2554}
2555
2556bitflags::bitflags! {
2557 #[must_use = "|= with other item changes, call request_render"]
2559 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
2560 #[serde(transparent)]
2561 pub struct PanelListDataChanges: u8 {
2562 const CHILD_OFFSET = 0b01;
2564 const DEFINE_REFERENCE_FRAME = 0b10;
2566 }
2567}
2568impl PanelListDataChanges {
2569 pub fn request_render(self) {
2571 if self.contains(Self::DEFINE_REFERENCE_FRAME) {
2572 WIDGET.render();
2573 } else if self.contains(Self::CHILD_OFFSET) {
2574 WIDGET.render_update();
2575 }
2576 }
2577}
2578
2579#[derive(Clone, Debug, Default)]
2581pub struct DefaultPanelListData {
2582 pub child_offset: PxVector,
2584 pub define_reference_frame: bool,
2586
2587 prev_child_offset: PxVector,
2588 prev_define_reference_frame: bool,
2589}
2590impl PanelListData for DefaultPanelListData {
2591 fn child_offset(&self) -> PxVector {
2592 self.child_offset
2593 }
2594
2595 fn define_reference_frame(&self) -> bool {
2596 self.define_reference_frame
2597 }
2598
2599 fn commit(&mut self) -> PanelListDataChanges {
2600 let mut changes = PanelListDataChanges::empty();
2601 if self.define_reference_frame != self.prev_define_reference_frame {
2602 changes |= PanelListDataChanges::DEFINE_REFERENCE_FRAME;
2603 }
2604 if self.child_offset != self.prev_child_offset {
2605 changes |= PanelListDataChanges::CHILD_OFFSET;
2606 }
2607 self.prev_define_reference_frame = self.define_reference_frame;
2608 self.prev_child_offset = self.child_offset;
2609 changes
2610 }
2611}
2612
2613pub trait PanelListData: Default + Send + Any {
2615 fn child_offset(&self) -> PxVector;
2617
2618 fn define_reference_frame(&self) -> bool;
2620
2621 fn commit(&mut self) -> PanelListDataChanges;
2625}
2626impl PanelListData for () {
2627 fn child_offset(&self) -> PxVector {
2628 PxVector::zero()
2629 }
2630
2631 fn define_reference_frame(&self) -> bool {
2632 false
2633 }
2634
2635 fn commit(&mut self) -> PanelListDataChanges {
2636 PanelListDataChanges::empty()
2637 }
2638}
2639
2640struct PanelObserver<'d, D>
2641where
2642 D: PanelListData,
2643{
2644 changed: bool,
2645 data: &'d mut Vec<Mutex<D>>,
2646 observer: &'d mut dyn UiNodeListObserver,
2647}
2648impl<D> UiNodeListObserver for PanelObserver<'_, D>
2649where
2650 D: PanelListData,
2651{
2652 fn is_reset_only(&self) -> bool {
2653 false
2654 }
2655
2656 fn reset(&mut self) {
2657 self.changed = true;
2658 self.data.clear();
2659 self.observer.reset();
2660 }
2661
2662 fn inserted(&mut self, index: usize) {
2663 self.changed = true;
2664 self.data.insert(index, Default::default());
2665 self.observer.inserted(index);
2666 }
2667
2668 fn removed(&mut self, index: usize) {
2669 self.changed = true;
2670 self.data.remove(index);
2671 self.observer.removed(index);
2672 }
2673
2674 fn moved(&mut self, removed_index: usize, inserted_index: usize) {
2675 self.changed = true;
2676 let item = self.data.remove(removed_index);
2677 self.data.insert(inserted_index, item);
2678 self.observer.moved(removed_index, inserted_index);
2679 }
2680}