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::from(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(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
432#[non_exhaustive]
434pub struct UiNodeListChainImpl(pub BoxedUiNodeList, pub BoxedUiNodeList);
435impl UiNodeList for UiNodeListChainImpl {
436 fn with_node<R, F>(&mut self, index: usize, f: F) -> R
437 where
438 F: FnOnce(&mut BoxedUiNode) -> R,
439 {
440 assert_bounds(self.len(), index);
441
442 if index < self.0.len() {
443 self.0.with_node(index, f)
444 } else {
445 self.1.with_node(index - self.0.len(), f)
446 }
447 }
448
449 fn for_each<F>(&mut self, f: F)
450 where
451 F: FnMut(usize, &mut BoxedUiNode),
452 {
453 chain_for_each(self, f)
454 }
455
456 fn par_each<F>(&mut self, f: F)
457 where
458 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
459 {
460 chain_par_each(self, f)
461 }
462
463 fn par_fold_reduce<T, I, F, R>(&mut self, identity: I, fold: F, reduce: R) -> T
464 where
465 T: Send + 'static,
466 I: Fn() -> T + Send + Sync,
467 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
468 R: Fn(T, T) -> T + Send + Sync,
469 {
470 chain_par_fold_reduce(self, identity, fold, reduce)
471 }
472
473 fn len(&self) -> usize {
474 self.0.len() + self.1.len()
475 }
476
477 fn boxed(self) -> BoxedUiNodeList {
478 Box::new(self)
479 }
480
481 fn drain_into(&mut self, vec: &mut Vec<BoxedUiNode>) {
482 self.0.drain_into(vec);
483 self.1.drain_into(vec);
484 }
485
486 fn init_all(&mut self) {
487 if PARALLEL_VAR.get().contains(Parallel::INIT) {
488 task::join(|| self.0.init_all(), || self.1.init_all());
489 } else {
490 self.0.init_all();
491 self.1.init_all();
492 }
493 }
494
495 fn deinit_all(&mut self) {
496 if PARALLEL_VAR.get().contains(Parallel::DEINIT) {
497 task::join(|| self.0.deinit_all(), || self.1.deinit_all());
498 } else {
499 self.0.deinit_all();
500 self.1.deinit_all();
501 }
502 }
503
504 fn info_all(&mut self, info: &mut WidgetInfoBuilder) {
505 if PARALLEL_VAR.get().contains(Parallel::INFO) {
506 let mut b = info.parallel_split();
507 task::join(|| self.0.info_all(info), || self.1.info_all(&mut b));
508 info.parallel_fold(b);
509 } else {
510 self.0.info_all(info);
511 self.1.info_all(info);
512 }
513 }
514
515 fn event_all(&mut self, update: &EventUpdate) {
516 if PARALLEL_VAR.get().contains(Parallel::EVENT) {
517 task::join(|| self.0.event_all(update), || self.1.event_all(update));
518 } else {
519 self.0.event_all(update);
520 self.1.event_all(update);
521 }
522 }
523
524 fn update_all(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
525 if observer.is_reset_only() && PARALLEL_VAR.get().contains(Parallel::UPDATE) {
526 let (r0, r1) = task::join(
527 || {
528 let mut r = false;
529 self.0.update_all(updates, &mut r);
530 r
531 },
532 || {
533 let mut r = false;
534 self.1.update_all(updates, &mut r);
535 r
536 },
537 );
538
539 if r0 || r1 {
540 observer.reset();
541 }
542 } else {
543 self.0.update_all(updates, observer);
544 self.1.update_all(updates, &mut OffsetUiListObserver(self.0.len(), observer));
545 }
546 }
547
548 fn render_all(&mut self, frame: &mut FrameBuilder) {
549 if PARALLEL_VAR.get().contains(Parallel::RENDER) {
550 let mut b = frame.parallel_split();
551 task::join(|| self.0.render_all(frame), || self.1.render_all(&mut b));
552 frame.parallel_fold(b);
553 } else {
554 self.0.render_all(frame);
555 self.1.render_all(frame);
556 }
557 }
558
559 fn render_update_all(&mut self, update: &mut FrameUpdate) {
560 if PARALLEL_VAR.get().contains(Parallel::RENDER) {
561 let mut b = update.parallel_split();
562 task::join(|| self.0.render_update_all(update), || self.1.render_update_all(&mut b));
563 update.parallel_fold(b);
564 } else {
565 self.0.render_update_all(update);
566 self.1.render_update_all(update);
567 }
568 }
569}
570
571#[expect(non_camel_case_types)]
573pub struct SORTING_LIST;
574impl SORTING_LIST {
575 pub fn is_inside_list(&self) -> bool {
577 !SORTING_LIST_PARENT.is_default()
578 }
579
580 pub fn invalidate_sort(&self) {
582 SORTING_LIST_PARENT.get().store(true, Relaxed)
583 }
584
585 fn with<R>(&self, action: impl FnOnce() -> R) -> (R, bool) {
586 SORTING_LIST_PARENT.with_context(&mut Some(Arc::new(AtomicBool::new(false))), || {
587 let r = action();
588 (r, SORTING_LIST_PARENT.get().load(Relaxed))
589 })
590 }
591}
592context_local! {
593 static SORTING_LIST_PARENT: AtomicBool = AtomicBool::new(false);
594}
595
596pub struct SortingList {
605 list: BoxedUiNodeList,
606
607 map: Vec<usize>,
608 sort: Box<dyn Fn(&mut BoxedUiNode, &mut BoxedUiNode) -> Ordering + Send + 'static>,
609}
610impl SortingList {
611 pub fn new(list: impl UiNodeList, sort: impl Fn(&mut BoxedUiNode, &mut BoxedUiNode) -> Ordering + Send + 'static) -> Self {
613 Self {
614 list: list.boxed(),
615 map: vec![],
616 sort: Box::new(sort),
617 }
618 }
619
620 fn update_map(&mut self) {
621 let map = &mut self.map;
622 let len = self.list.len();
623
624 if len == 0 {
625 map.clear();
626 } else if map.len() != len {
627 map.clear();
628 map.extend(0..len);
629 let mut taken_a = NilUiNode.boxed();
630 map.sort_by(|&a, &b| {
631 self.list.with_node(a, |a| mem::swap(a, &mut taken_a));
632 let result = self.list.with_node(b, |b| (self.sort)(&mut taken_a, b));
633 self.list.with_node(a, |a| mem::swap(a, &mut taken_a));
634
635 result
636 })
637 }
638 }
639 pub fn list(&mut self) -> &mut BoxedUiNodeList {
645 &mut self.list
646 }
647
648 pub fn invalidate_sort(&mut self) {
652 self.map.clear()
653 }
654
655 fn with_map<R>(&mut self, f: impl FnOnce(&[usize], &mut BoxedUiNodeList) -> R) -> R {
656 self.update_map();
657
658 let (r, resort) = SORTING_LIST.with(|| f(&self.map, &mut self.list));
659
660 if resort {
661 self.invalidate_sort();
662 }
663
664 r
665 }
666}
667impl UiNodeList for SortingList {
668 fn with_node<R, F>(&mut self, index: usize, f: F) -> R
669 where
670 F: FnOnce(&mut BoxedUiNode) -> R,
671 {
672 self.with_map(|map, list| list.with_node(map[index], f))
673 }
674
675 fn for_each<F>(&mut self, mut f: F)
676 where
677 F: FnMut(usize, &mut BoxedUiNode),
678 {
679 self.with_map(|map, list| {
680 for (index, map) in map.iter().enumerate() {
681 list.with_node(*map, |n| f(index, n))
682 }
683 });
684 }
685
686 fn par_each<F>(&mut self, f: F)
687 where
688 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
689 {
690 self.for_each(f)
691 }
692
693 fn par_fold_reduce<T, I, F, R>(&mut self, identity: I, fold: F, _: R) -> T
694 where
695 T: Send + 'static,
696 I: Fn() -> T + Send + Sync,
697 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
698 R: Fn(T, T) -> T + Send + Sync,
699 {
700 let mut r = Some(identity());
701 self.for_each(|i, n| {
702 r = Some(fold(r.take().unwrap(), i, n));
703 });
704 r.unwrap()
705 }
706
707 fn len(&self) -> usize {
708 self.list.len()
709 }
710
711 fn boxed(self) -> BoxedUiNodeList {
712 Box::new(self)
713 }
714
715 fn drain_into(&mut self, vec: &mut Vec<BoxedUiNode>) {
716 let start = vec.len();
717 self.with_map(|map, list| {
718 list.drain_into(vec);
719 sort_by_indices(&mut vec[start..], map.to_vec());
720 });
721 self.map.clear();
722 }
723
724 fn init_all(&mut self) {
725 let _ = SORTING_LIST.with(|| self.list.init_all());
726 self.invalidate_sort();
727 }
728
729 fn deinit_all(&mut self) {
730 let _ = SORTING_LIST.with(|| self.list.deinit_all());
731 self.invalidate_sort();
732 }
733
734 fn info_all(&mut self, info: &mut WidgetInfoBuilder) {
735 self.list.info_all(info);
736 }
737
738 fn event_all(&mut self, update: &EventUpdate) {
739 self.list.event_all(update);
740 }
741
742 fn update_all(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
743 let mut changed = false;
744 let (_, resort) = SORTING_LIST.with(|| self.list.update_all(updates, &mut (observer, &mut changed as _)));
745 if changed || resort {
746 self.invalidate_sort();
747 }
748 }
749
750 fn render_all(&mut self, frame: &mut FrameBuilder) {
751 self.for_each(|_, n| n.render(frame));
752 }
753
754 fn render_update_all(&mut self, update: &mut FrameUpdate) {
755 self.list.render_update_all(update);
756 }
757
758 fn is_empty(&self) -> bool {
759 self.len() == 0
760 }
761}
762
763fn sort_by_indices<T>(data: &mut [T], mut indices: Vec<usize>) {
765 for idx in 0..data.len() {
766 if indices[idx] != idx {
767 let mut current_idx = idx;
768 loop {
769 let target_idx = indices[current_idx];
770 indices[current_idx] = current_idx;
771 if indices[target_idx] == target_idx {
772 break;
773 }
774 data.swap(current_idx, target_idx);
775 current_idx = target_idx;
776 }
777 }
778 }
779}
780
781#[derive(Default, Debug)]
782struct ZIndexCtx {
783 panel_id: Option<WidgetId>,
785 resort: AtomicBool,
787}
788
789context_local! {
790 static Z_INDEX_CTX: ZIndexCtx = ZIndexCtx::default();
791}
792
793#[expect(non_camel_case_types)]
795pub struct Z_INDEX;
796impl Z_INDEX {
797 fn with(&self, panel_id: WidgetId, action: impl FnOnce()) -> bool {
798 let ctx = ZIndexCtx {
799 panel_id: Some(panel_id),
800 resort: AtomicBool::new(false),
801 };
802 Z_INDEX_CTX.with_context(&mut Some(Arc::new(ctx)), || {
803 action();
804 Z_INDEX_CTX.get().resort.load(Relaxed)
805 })
806 }
807
808 pub fn get(&self) -> ZIndex {
812 WIDGET.get_state(*Z_INDEX_ID).unwrap_or_default()
813 }
814
815 pub fn get_wgt(&self, widget: &mut impl UiNode) -> ZIndex {
819 widget.with_context(WidgetUpdateMode::Ignore, || self.get()).unwrap_or_default()
820 }
821
822 pub fn set(&self, index: ZIndex) -> bool {
830 let z_ctx = Z_INDEX_CTX.get();
831 let valid = z_ctx.panel_id == WIDGET.parent_id() && z_ctx.panel_id.is_some();
832 if valid {
833 z_ctx.resort.store(true, Relaxed);
834 WIDGET.set_state(*Z_INDEX_ID, index);
835 }
836 valid
837 }
838}
839
840static_id! {
841 static ref Z_INDEX_ID: StateId<ZIndex>;
842}
843
844#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Transitionable)]
858pub struct ZIndex(u32);
859impl ZIndex {
860 pub const BACK: ZIndex = ZIndex(0);
864
865 pub const DEFAULT: ZIndex = ZIndex(u32::MAX / 2);
869
870 pub const FRONT: ZIndex = ZIndex(u32::MAX);
872
873 pub fn saturating_add(self, other: impl Into<Self>) -> Self {
879 ZIndex(self.0.saturating_add(other.into().0))
880 }
881
882 pub fn saturating_sub(self, other: impl Into<Self>) -> Self {
888 ZIndex(self.0.saturating_sub(other.into().0))
889 }
890}
891impl Default for ZIndex {
892 fn default() -> Self {
893 ZIndex::DEFAULT
894 }
895}
896impl<Z: Into<ZIndex>> ops::Add<Z> for ZIndex {
897 type Output = Self;
898
899 fn add(self, rhs: Z) -> Self::Output {
900 self.saturating_add(rhs)
901 }
902}
903impl<Z: Into<ZIndex>> ops::AddAssign<Z> for ZIndex {
904 fn add_assign(&mut self, rhs: Z) {
905 *self = *self + rhs;
906 }
907}
908impl<Z: Into<ZIndex>> ops::Sub<Z> for ZIndex {
909 type Output = Self;
910
911 fn sub(self, rhs: Z) -> Self::Output {
912 self.saturating_sub(rhs)
913 }
914}
915impl<Z: Into<ZIndex>> ops::SubAssign<Z> for ZIndex {
916 fn sub_assign(&mut self, rhs: Z) {
917 *self = *self - rhs;
918 }
919}
920impl ops::Mul<Factor> for ZIndex {
921 type Output = Self;
922
923 fn mul(self, rhs: Factor) -> Self::Output {
924 ZIndex(self.0 * rhs)
925 }
926}
927impl ops::Div<Factor> for ZIndex {
928 type Output = Self;
929
930 fn div(self, rhs: Factor) -> Self::Output {
931 ZIndex(self.0 / rhs)
932 }
933}
934impl ops::MulAssign<Factor> for ZIndex {
935 fn mul_assign(&mut self, rhs: Factor) {
936 self.0 *= rhs;
937 }
938}
939impl ops::DivAssign<Factor> for ZIndex {
940 fn div_assign(&mut self, rhs: Factor) {
941 self.0 /= rhs;
942 }
943}
944impl fmt::Debug for ZIndex {
945 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
946 let z = *self;
947 if f.alternate() {
948 write!(f, "ZIndex::")?;
949 }
950
951 if z == Self::DEFAULT {
952 write!(f, "DEFAULT")
953 } else if z == Self::BACK {
954 write!(f, "BACK")
955 } else if z == Self::FRONT {
956 write!(f, "FRONT")
957 } else if z > Self::DEFAULT {
958 if z > Self::FRONT - 10000 {
959 write!(f, "FRONT-{}", Self::FRONT.0 - z.0)
960 } else {
961 write!(f, "DEFAULT+{}", z.0 - Self::DEFAULT.0)
962 }
963 } else if z < Self::BACK + 10000 {
964 write!(f, "BACK+{}", z.0 - Self::BACK.0)
965 } else {
966 write!(f, "DEFAULT-{}", Self::DEFAULT.0 - z.0)
967 }
968 }
969}
970impl_from_and_into_var! {
971 fn from(index: u32) -> ZIndex {
972 ZIndex(index)
973 }
974 fn from(index: ZIndex) -> u32 {
975 index.0
976 }
977 fn from(index: ZIndex) -> Option<ZIndex>;
978}
979
980pub trait UiNodeListObserver {
989 fn inserted(&mut self, index: usize);
991 fn removed(&mut self, index: usize);
993 fn moved(&mut self, removed_index: usize, inserted_index: usize);
995 fn reset(&mut self);
997
998 fn is_reset_only(&self) -> bool;
1008}
1009impl UiNodeListObserver for () {
1011 fn is_reset_only(&self) -> bool {
1012 true
1013 }
1014
1015 fn reset(&mut self) {}
1016
1017 fn inserted(&mut self, _: usize) {}
1018
1019 fn removed(&mut self, _: usize) {}
1020
1021 fn moved(&mut self, _: usize, _: usize) {}
1022}
1023impl UiNodeListObserver for bool {
1025 fn is_reset_only(&self) -> bool {
1026 true
1027 }
1028
1029 fn reset(&mut self) {
1030 *self = true;
1031 }
1032
1033 fn inserted(&mut self, _: usize) {
1034 *self = true;
1035 }
1036
1037 fn removed(&mut self, _: usize) {
1038 *self = true;
1039 }
1040
1041 fn moved(&mut self, _: usize, _: usize) {
1042 *self = true;
1043 }
1044}
1045
1046pub struct OffsetUiListObserver<'o>(pub usize, pub &'o mut dyn UiNodeListObserver);
1050impl UiNodeListObserver for OffsetUiListObserver<'_> {
1051 fn is_reset_only(&self) -> bool {
1052 self.1.is_reset_only()
1053 }
1054
1055 fn reset(&mut self) {
1056 self.1.reset()
1057 }
1058
1059 fn inserted(&mut self, index: usize) {
1060 self.1.inserted(index + self.0)
1061 }
1062
1063 fn removed(&mut self, index: usize) {
1064 self.1.removed(index + self.0)
1065 }
1066
1067 fn moved(&mut self, removed_index: usize, inserted_index: usize) {
1068 self.1.moved(removed_index + self.0, inserted_index + self.0)
1069 }
1070}
1071
1072impl UiNodeListObserver for (&mut dyn UiNodeListObserver, &mut dyn UiNodeListObserver) {
1073 fn is_reset_only(&self) -> bool {
1074 self.0.is_reset_only() && self.1.is_reset_only()
1075 }
1076
1077 fn reset(&mut self) {
1078 self.0.reset();
1079 self.1.reset();
1080 }
1081
1082 fn inserted(&mut self, index: usize) {
1083 self.0.inserted(index);
1084 self.1.inserted(index);
1085 }
1086
1087 fn removed(&mut self, index: usize) {
1088 self.0.removed(index);
1089 self.1.removed(index);
1090 }
1091
1092 fn moved(&mut self, removed_index: usize, inserted_index: usize) {
1093 self.0.moved(removed_index, inserted_index);
1094 self.1.moved(removed_index, inserted_index);
1095 }
1096}
1097
1098pub struct EditableUiNodeList {
1100 vec: Vec<BoxedUiNode>,
1101 ctrl: EditableUiNodeListRef,
1102}
1103impl Default for EditableUiNodeList {
1104 fn default() -> Self {
1105 Self {
1106 vec: vec![],
1107 ctrl: EditableUiNodeListRef::new(true),
1108 }
1109 }
1110}
1111impl Drop for EditableUiNodeList {
1112 fn drop(&mut self) {
1113 self.ctrl.0.lock().alive = false;
1114 }
1115}
1116impl EditableUiNodeList {
1117 pub fn new() -> Self {
1119 Self::default()
1120 }
1121
1122 pub fn from_vec(vec: impl Into<Vec<BoxedUiNode>>) -> Self {
1124 let mut s = Self::new();
1125 s.vec = vec.into();
1126 s
1127 }
1128
1129 pub fn reference(&self) -> EditableUiNodeListRef {
1131 self.ctrl.clone()
1132 }
1133
1134 fn fulfill_requests(&mut self, observer: &mut dyn UiNodeListObserver) {
1135 if let Some(r) = self.ctrl.take_requests() {
1136 if r.clear {
1137 self.clear();
1139 observer.reset();
1140
1141 for (i, mut wgt) in r.insert {
1142 wgt.init();
1143 WIDGET.update_info();
1144 if i < self.len() {
1145 self.insert(i, wgt);
1146 } else {
1147 self.push(wgt);
1148 }
1149 }
1150 for mut wgt in r.push {
1151 wgt.init();
1152 WIDGET.update_info();
1153 self.push(wgt);
1154 }
1155 for (r, i) in r.move_index {
1156 if r < self.len() {
1157 let wgt = self.vec.remove(r);
1158
1159 if i < self.len() {
1160 self.vec.insert(i, wgt);
1161 } else {
1162 self.vec.push(wgt);
1163 }
1164
1165 WIDGET.update_info();
1166 }
1167 }
1168 for (id, to) in r.move_id {
1169 if let Some(r) = self
1170 .vec
1171 .iter_mut()
1172 .position(|w| w.with_context(WidgetUpdateMode::Ignore, || WIDGET.id() == id).unwrap_or(false))
1173 {
1174 let i = to(r, self.len());
1175
1176 if r != i {
1177 let wgt = self.vec.remove(r);
1178
1179 if i < self.len() {
1180 self.vec.insert(i, wgt);
1181 } else {
1182 self.vec.push(wgt);
1183 }
1184
1185 WIDGET.update_info();
1186 }
1187 }
1188 }
1189 } else {
1190 let mut removed = false;
1191 for mut retain in r.retain {
1192 let mut i = 0;
1193 self.vec.retain_mut(|n| {
1194 let r = retain(n);
1195 if !r {
1196 n.deinit();
1197 removed = true;
1198 observer.removed(i);
1199 } else {
1200 i += 1;
1201 }
1202 r
1203 });
1204 }
1205 if removed {
1206 WIDGET.update_info();
1207 }
1208
1209 for (i, mut wgt) in r.insert {
1210 wgt.init();
1211 WIDGET.update_info();
1212
1213 if i < self.len() {
1214 self.insert(i, wgt);
1215 observer.inserted(i);
1216 } else {
1217 observer.inserted(self.len());
1218 self.push(wgt);
1219 }
1220 }
1221
1222 for mut wgt in r.push {
1223 wgt.init();
1224 WIDGET.update_info();
1225
1226 observer.inserted(self.len());
1227 self.push(wgt);
1228 }
1229
1230 for (r, i) in r.move_index {
1231 if r < self.len() {
1232 let wgt = self.vec.remove(r);
1233
1234 if i < self.len() {
1235 self.vec.insert(i, wgt);
1236
1237 observer.moved(r, i);
1238 } else {
1239 let i = self.vec.len();
1240
1241 self.vec.push(wgt);
1242
1243 observer.moved(r, i);
1244 }
1245
1246 WIDGET.update_info();
1247 }
1248 }
1249
1250 for (id, to) in r.move_id {
1251 if let Some(r) = self
1252 .vec
1253 .iter_mut()
1254 .position(|w| w.with_context(WidgetUpdateMode::Ignore, || WIDGET.id() == id).unwrap_or(false))
1255 {
1256 let i = to(r, self.len());
1257
1258 if r != i {
1259 let wgt = self.vec.remove(r);
1260
1261 if i < self.len() {
1262 self.vec.insert(i, wgt);
1263 observer.moved(r, i);
1264 } else {
1265 let i = self.vec.len();
1266 self.vec.push(wgt);
1267 observer.moved(r, i);
1268 }
1269
1270 WIDGET.update_info();
1271 }
1272 }
1273 }
1274 }
1275 }
1276 }
1277}
1278impl ops::Deref for EditableUiNodeList {
1279 type Target = Vec<BoxedUiNode>;
1280
1281 fn deref(&self) -> &Self::Target {
1282 &self.vec
1283 }
1284}
1285impl ops::DerefMut for EditableUiNodeList {
1286 fn deref_mut(&mut self) -> &mut Self::Target {
1287 &mut self.vec
1288 }
1289}
1290impl UiNodeList for EditableUiNodeList {
1291 fn with_node<R, F>(&mut self, index: usize, f: F) -> R
1292 where
1293 F: FnOnce(&mut BoxedUiNode) -> R,
1294 {
1295 self.vec.with_node(index, f)
1296 }
1297
1298 fn for_each<F>(&mut self, f: F)
1299 where
1300 F: FnMut(usize, &mut BoxedUiNode),
1301 {
1302 self.vec.for_each(f)
1303 }
1304
1305 fn par_each<F>(&mut self, f: F)
1306 where
1307 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
1308 {
1309 self.vec.par_each(f)
1310 }
1311
1312 fn par_fold_reduce<T, I, F, R>(&mut self, identity: I, fold: F, reduce: R) -> T
1313 where
1314 T: Send + 'static,
1315 I: Fn() -> T + Send + Sync,
1316 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
1317 R: Fn(T, T) -> T + Send + Sync,
1318 {
1319 self.vec.par_fold_reduce(identity, fold, reduce)
1320 }
1321
1322 fn len(&self) -> usize {
1323 self.vec.len()
1324 }
1325
1326 fn boxed(self) -> BoxedUiNodeList {
1327 Box::new(self)
1328 }
1329
1330 fn drain_into(&mut self, vec: &mut Vec<BoxedUiNode>) {
1331 vec.append(&mut self.vec)
1332 }
1333
1334 fn init_all(&mut self) {
1335 self.ctrl.0.lock().target = Some(WIDGET.id());
1336 self.vec.init_all();
1337 }
1338
1339 fn deinit_all(&mut self) {
1340 self.ctrl.0.lock().target = None;
1341 self.vec.deinit_all();
1342 }
1343
1344 fn info_all(&mut self, info: &mut WidgetInfoBuilder) {
1345 self.vec.info_all(info);
1346 }
1347
1348 fn event_all(&mut self, update: &EventUpdate) {
1349 self.vec.event_all(update)
1350 }
1351
1352 fn update_all(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
1353 self.vec.update_all(updates, &mut ());
1354 self.fulfill_requests(observer);
1355 }
1356
1357 fn measure_each<F, S>(&mut self, wm: &mut WidgetMeasure, measure: F, fold_size: S) -> PxSize
1358 where
1359 F: Fn(usize, &mut BoxedUiNode, &mut WidgetMeasure) -> PxSize + Send + Sync,
1360 S: Fn(PxSize, PxSize) -> PxSize + Send + Sync,
1361 {
1362 self.vec.measure_each(wm, measure, fold_size)
1363 }
1364
1365 fn layout_each<F, S>(&mut self, wl: &mut WidgetLayout, layout: F, fold_size: S) -> PxSize
1366 where
1367 F: Fn(usize, &mut BoxedUiNode, &mut WidgetLayout) -> PxSize + Send + Sync,
1368 S: Fn(PxSize, PxSize) -> PxSize + Send + Sync,
1369 {
1370 self.vec.layout_each(wl, layout, fold_size)
1371 }
1372
1373 fn render_all(&mut self, frame: &mut FrameBuilder) {
1374 self.vec.render_all(frame)
1375 }
1376
1377 fn render_update_all(&mut self, update: &mut FrameUpdate) {
1378 self.vec.render_update_all(update)
1379 }
1380}
1381
1382type NodeMoveToFn = fn(usize, usize) -> usize;
1384
1385#[derive(Clone, Debug)]
1387pub struct EditableUiNodeListRef(Arc<Mutex<EditRequests>>);
1388struct EditRequests {
1389 target: Option<WidgetId>,
1390 insert: Vec<(usize, BoxedUiNode)>,
1391 push: Vec<BoxedUiNode>,
1392 retain: Vec<Box<dyn FnMut(&mut BoxedUiNode) -> bool + Send>>,
1393 move_index: Vec<(usize, usize)>,
1394 move_id: Vec<(WidgetId, NodeMoveToFn)>,
1395 clear: bool,
1396
1397 alive: bool,
1398}
1399impl fmt::Debug for EditRequests {
1400 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1401 f.debug_struct("EditRequests")
1402 .field("target", &self.target)
1403 .field("insert.len", &self.insert.len())
1404 .field("push.len", &self.push.len())
1405 .field("retain.len", &self.retain.len())
1406 .field("move_index", &self.move_index)
1407 .field("move_id", &self.move_id)
1408 .field("clear", &self.clear)
1409 .field("alive", &self.alive)
1410 .finish()
1411 }
1412}
1413impl EditableUiNodeListRef {
1414 fn new(alive: bool) -> Self {
1415 Self(Arc::new(Mutex::new(EditRequests {
1416 target: None,
1417 insert: vec![],
1418 push: vec![],
1419 retain: vec![],
1420 move_index: vec![],
1421 move_id: vec![],
1422 clear: false,
1423 alive,
1424 })))
1425 }
1426
1427 pub fn dummy() -> Self {
1433 Self::new(false)
1434 }
1435
1436 pub fn alive(&self) -> bool {
1438 self.0.lock().alive
1439 }
1440
1441 pub fn insert(&self, index: usize, widget: impl UiNode) {
1449 let mut s = self.0.lock();
1450 if !s.alive {
1451 return;
1452 }
1453 s.insert.push((index, widget.boxed()));
1454 UPDATES.update(s.target);
1455 }
1456
1457 pub fn push(&self, widget: impl UiNode) {
1465 let mut s = self.0.lock();
1466 if !s.alive {
1467 return;
1468 }
1469 s.push.push(widget.boxed());
1470 UPDATES.update(s.target);
1471 }
1472
1473 pub fn remove(&self, id: impl Into<WidgetId>) {
1478 fn remove_impl(id: WidgetId) -> impl FnMut(&mut BoxedUiNode) -> bool + Send + 'static {
1479 move |node| node.with_context(WidgetUpdateMode::Ignore, || WIDGET.id() != id).unwrap_or(true)
1480 }
1481 self.retain(remove_impl(id.into()))
1482 }
1483
1484 pub fn retain(&self, predicate: impl FnMut(&mut BoxedUiNode) -> bool + Send + 'static) {
1490 let mut s = self.0.lock();
1491 if !s.alive {
1492 return;
1493 }
1494 s.retain.push(Box::new(predicate));
1495 UPDATES.update(s.target);
1496 }
1497
1498 pub fn move_index(&self, remove_index: usize, insert_index: usize) {
1505 if remove_index != insert_index {
1506 let mut s = self.0.lock();
1507 if !s.alive {
1508 return;
1509 }
1510 s.move_index.push((remove_index, insert_index));
1511 UPDATES.update(s.target);
1512 }
1513 }
1514
1515 pub fn move_id(&self, id: impl Into<WidgetId>, get_move_to: NodeMoveToFn) {
1555 let mut s = self.0.lock();
1556 if !s.alive {
1557 return;
1558 }
1559 s.move_id.push((id.into(), get_move_to));
1560 UPDATES.update(s.target);
1561 }
1562
1563 pub fn clear(&self) {
1567 let mut s = self.0.lock();
1568 s.clear = true;
1569 UPDATES.update(s.target);
1570 }
1571
1572 fn take_requests(&self) -> Option<EditRequests> {
1573 let mut s = self.0.lock();
1574
1575 if s.clear
1576 || !s.insert.is_empty()
1577 || !s.push.is_empty()
1578 || !s.retain.is_empty()
1579 || !s.move_index.is_empty()
1580 || !s.move_id.is_empty()
1581 {
1582 let empty = EditRequests {
1583 target: s.target,
1584 alive: s.alive,
1585
1586 insert: vec![],
1587 push: vec![],
1588 retain: vec![],
1589 move_index: vec![],
1590 move_id: vec![],
1591 clear: false,
1592 };
1593 Some(mem::replace(&mut *s, empty))
1594 } else {
1595 None
1596 }
1597 }
1598}
1599
1600fn many_list_index(lists: &Vec<BoxedUiNodeList>, index: usize) -> (usize, usize) {
1601 let mut offset = 0;
1602
1603 for (li, list) in lists.iter().enumerate() {
1604 let i = index - offset;
1605 let len = list.len();
1606
1607 if i < len {
1608 return (li, i);
1609 }
1610
1611 offset += len;
1612 }
1613
1614 panic!(
1615 "'index out of bounds: the len is {} but the index is {}",
1616 UiNodeList::len(lists),
1617 index
1618 );
1619}
1620
1621fn vec_list_for_each<F>(self_: &mut Vec<BoxedUiNodeList>, f: F)
1622where
1623 F: FnMut(usize, &mut BoxedUiNode),
1624{
1625 #[cfg(feature = "dyn_closure")]
1626 let f: Box<dyn FnMut(usize, &mut BoxedUiNode)> = Box::new(f);
1627
1628 vec_list_for_each_impl(self_, f)
1629}
1630fn vec_list_for_each_impl<F>(self_: &mut Vec<BoxedUiNodeList>, mut f: F)
1631where
1632 F: FnMut(usize, &mut BoxedUiNode),
1633{
1634 let mut offset = 0;
1635 for list in self_ {
1636 list.for_each(|i, n| f(i + offset, n));
1637 offset += list.len();
1638 }
1639}
1640
1641fn vec_list_par_each<F>(self_: &mut Vec<BoxedUiNodeList>, f: F)
1642where
1643 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
1644{
1645 #[cfg(feature = "dyn_closure")]
1646 let f: Box<dyn Fn(usize, &mut BoxedUiNode) + Send + Sync> = Box::new(f);
1647 vec_list_par_each_impl(self_, f)
1648}
1649fn vec_list_par_each_impl<F>(self_: &mut Vec<BoxedUiNodeList>, f: F)
1650where
1651 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
1652{
1653 task::scope(|s| {
1654 let f = &f;
1655 let mut offset = 0;
1656 for list in self_ {
1657 let len = list.len();
1658 s.spawn(move |_| {
1659 list.par_each(move |i, n| f(i + offset, n));
1660 });
1661 offset += len;
1662 }
1663 });
1664}
1665
1666fn vec_list_par_fold_reduce<T, I, F, R>(self_: &mut [BoxedUiNodeList], identity: I, fold: F, reduce: R) -> T
1667where
1668 T: Send + 'static,
1669 I: Fn() -> T + Send + Sync,
1670 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
1671 R: Fn(T, T) -> T + Send + Sync,
1672{
1673 #[cfg(feature = "dyn_closure")]
1674 let identity: Box<dyn Fn() -> T + Send + Sync> = Box::new(identity);
1675 #[cfg(feature = "dyn_closure")]
1676 let fold: Box<dyn Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync> = Box::new(fold);
1677 #[cfg(feature = "dyn_closure")]
1678 let reduce: Box<dyn Fn(T, T) -> T + Send + Sync> = Box::new(reduce);
1679
1680 vec_list_par_fold_reduce_impl(self_, identity, fold, reduce)
1681}
1682fn vec_list_par_fold_reduce_impl<T, I, F, R>(self_: &mut [BoxedUiNodeList], identity: I, fold: F, reduce: R) -> T
1683where
1684 T: Send + 'static,
1685 I: Fn() -> T + Send + Sync,
1686 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
1687 R: Fn(T, T) -> T + Send + Sync,
1688{
1689 let mut offset = 0;
1690 let mut r = Some(identity());
1691 for list in self_.chunks_mut(2) {
1692 let b = if list.len() == 2 {
1693 let mut pair = list.iter_mut();
1694 let a = pair.next().unwrap();
1695 let b = pair.next().unwrap();
1696 let offset_b = offset + a.len();
1697
1698 let (a, b) = task::join(
1699 || a.par_fold_reduce(&identity, |a, i, n| fold(a, i + offset, n), &reduce),
1700 || b.par_fold_reduce(&identity, |a, i, n| fold(a, i + offset_b, n), &reduce),
1701 );
1702
1703 reduce(a, b)
1704 } else {
1705 list[0].par_fold_reduce(&identity, |a, i, n| fold(a, i + offset, n), &reduce)
1706 };
1707
1708 let a = r.take().unwrap();
1709 r = Some(reduce(a, b));
1710
1711 offset += list.iter().map(|l| l.len()).sum::<usize>();
1712 }
1713 r.unwrap()
1714}
1715
1716impl UiNodeList for Vec<BoxedUiNodeList> {
1717 fn with_node<R, F>(&mut self, index: usize, f: F) -> R
1718 where
1719 F: FnOnce(&mut BoxedUiNode) -> R,
1720 {
1721 let (l, i) = many_list_index(self, index);
1722 self[l].with_node(i, f)
1723 }
1724
1725 fn for_each<F>(&mut self, f: F)
1726 where
1727 F: FnMut(usize, &mut BoxedUiNode),
1728 {
1729 vec_list_for_each(self, f)
1730 }
1731
1732 fn par_each<F>(&mut self, f: F)
1733 where
1734 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
1735 {
1736 vec_list_par_each(self, f)
1737 }
1738
1739 fn par_fold_reduce<T, I, F, R>(&mut self, identity: I, fold: F, reduce: R) -> T
1740 where
1741 T: Send + 'static,
1742 I: Fn() -> T + Send + Sync,
1743 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
1744 R: Fn(T, T) -> T + Send + Sync,
1745 {
1746 vec_list_par_fold_reduce(self, identity, fold, reduce)
1747 }
1748
1749 fn len(&self) -> usize {
1750 self.iter().map(|l| l.len()).sum()
1751 }
1752
1753 fn boxed(self) -> BoxedUiNodeList {
1754 Box::new(self)
1755 }
1756
1757 fn drain_into(&mut self, vec: &mut Vec<BoxedUiNode>) {
1758 for mut list in self.drain(..) {
1759 list.drain_into(vec);
1760 }
1761 }
1762
1763 fn is_empty(&self) -> bool {
1764 self.iter().all(|l| l.is_empty())
1765 }
1766
1767 fn init_all(&mut self) {
1768 if self.len() > 1 && PARALLEL_VAR.get().contains(Parallel::INIT) {
1769 self.par_iter_mut().with_ctx().for_each(|l| l.init_all());
1770 } else {
1771 for l in self {
1772 l.init_all();
1773 }
1774 }
1775 }
1776
1777 fn deinit_all(&mut self) {
1778 if self.len() > 1 && PARALLEL_VAR.get().contains(Parallel::DEINIT) {
1779 self.par_iter_mut().with_ctx().for_each(|l| l.deinit_all());
1780 } else {
1781 for list in self {
1782 list.deinit_all();
1783 }
1784 }
1785 }
1786
1787 fn update_all(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
1788 if self.len() > 1 && observer.is_reset_only() && PARALLEL_VAR.get().contains(Parallel::UPDATE) {
1789 let r = self
1790 .par_iter_mut()
1791 .with_ctx()
1792 .map(|l| {
1793 let mut r = false;
1794 l.update_all(updates, &mut r);
1795 r
1796 })
1797 .any(std::convert::identity);
1798 if r {
1799 observer.reset();
1800 }
1801 } else {
1802 let mut offset = 0;
1803 for list in self {
1804 list.update_all(updates, &mut OffsetUiListObserver(offset, observer));
1805 offset += list.len();
1806 }
1807 }
1808 }
1809
1810 fn info_all(&mut self, info: &mut WidgetInfoBuilder) {
1811 if self.len() > 1 && PARALLEL_VAR.get().contains(Parallel::INFO) {
1812 let b = self
1813 .par_iter_mut()
1814 .with_ctx()
1815 .fold(
1816 || info.parallel_split(),
1817 |mut info, list| {
1818 list.info_all(&mut info);
1819 info
1820 },
1821 )
1822 .reduce(
1823 || info.parallel_split(),
1824 |mut a, b| {
1825 a.parallel_fold(b);
1826 a
1827 },
1828 );
1829 info.parallel_fold(b);
1830 } else {
1831 for list in self {
1832 list.info_all(info);
1833 }
1834 }
1835 }
1836
1837 fn event_all(&mut self, update: &EventUpdate) {
1838 if self.len() > 1 && PARALLEL_VAR.get().contains(Parallel::EVENT) {
1839 self.par_iter_mut().with_ctx().for_each(|l| l.event_all(update));
1840 } else {
1841 for list in self {
1842 list.event_all(update);
1843 }
1844 }
1845 }
1846
1847 fn render_all(&mut self, frame: &mut FrameBuilder) {
1852 if self.len() > 1 && PARALLEL_VAR.get().contains(Parallel::RENDER) {
1853 let b = self
1854 .par_iter_mut()
1855 .with_ctx()
1856 .fold(
1857 || frame.parallel_split(),
1858 |mut frame, list| {
1859 list.render_all(&mut frame);
1860 frame
1861 },
1862 )
1863 .reduce(
1864 || frame.parallel_split(),
1865 |mut a, b| {
1866 a.parallel_fold(b);
1867 a
1868 },
1869 );
1870 frame.parallel_fold(b);
1871 } else {
1872 for list in self {
1873 list.render_all(frame);
1874 }
1875 }
1876 }
1877
1878 fn render_update_all(&mut self, update: &mut FrameUpdate) {
1879 if self.len() > 1 && PARALLEL_VAR.get().contains(Parallel::RENDER) {
1880 let b = self
1881 .par_iter_mut()
1882 .with_ctx()
1883 .fold(
1884 || update.parallel_split(),
1885 |mut update, list| {
1886 list.render_update_all(&mut update);
1887 update
1888 },
1889 )
1890 .reduce(
1891 || update.parallel_split(),
1892 |mut a, b| {
1893 a.parallel_fold(b);
1894 a
1895 },
1896 );
1897 update.parallel_fold(b);
1898 } else {
1899 for list in self {
1900 list.render_update_all(update);
1901 }
1902 }
1903 }
1904}
1905
1906#[derive(Debug, Clone)]
1908pub struct PanelListRange {
1909 range: Option<(WidgetId, WidgetId)>,
1911 version: u8,
1912}
1913impl PanelListRange {
1914 pub fn update(
1919 parent: &WidgetInfo,
1920 panel_id: impl Into<StateId<Self>>,
1921 last_version: &mut Option<u8>,
1922 ) -> Option<crate::widget::info::iter::Children> {
1923 let range = parent.meta().get_clone(panel_id);
1924 if let Some(Self { range, version }) = range {
1925 let version = Some(version);
1926 if *last_version != version {
1927 *last_version = version;
1928
1929 if let Some((s, e)) = range {
1930 let tree = parent.tree();
1931 if let (Some(s), Some(e)) = (tree.get(s), tree.get(e)) {
1932 let parent = Some(parent);
1933 if s.parent().as_ref() == parent && e.parent().as_ref() == parent {
1934 return Some(crate::widget::info::iter::Children::new_range(s, e));
1935 }
1936 }
1937 }
1938 }
1939 }
1940 None
1941 }
1942
1943 pub fn get(parent: &WidgetInfo, panel_id: impl Into<StateId<Self>>) -> Option<crate::widget::info::iter::Children> {
1945 let range = parent.meta().get_clone(panel_id);
1946 if let Some(Self { range: Some((s, e)), .. }) = range {
1947 let tree = parent.tree();
1948 if let (Some(s), Some(e)) = (tree.get(s), tree.get(e)) {
1949 let parent = Some(parent);
1950 if s.parent().as_ref() == parent && e.parent().as_ref() == parent {
1951 return Some(crate::widget::info::iter::Children::new_range(s, e));
1952 }
1953 }
1954 }
1955 None
1956 }
1957}
1958
1959pub struct PanelList<D = DefaultPanelListData>
1974where
1975 D: PanelListData,
1976{
1977 list: BoxedUiNodeList,
1978 data: Vec<Mutex<D>>, offset_key: FrameValueKey<PxTransform>,
1981 info_id: Option<(StateId<PanelListRange>, u8, bool)>,
1982
1983 z_map: Vec<u64>,
1984 z_naturally_sorted: bool,
1985}
1986impl PanelList<DefaultPanelListData> {
1987 pub fn new(list: impl UiNodeList) -> Self {
1989 Self::new_custom(list)
1990 }
1991}
1992
1993impl<D> PanelList<D>
1994where
1995 D: PanelListData,
1996{
1997 pub fn new_custom(list: impl UiNodeList) -> Self {
1999 Self {
2000 data: {
2001 let mut d = vec![];
2002 d.resize_with(list.len(), Default::default);
2003 d
2004 },
2005 list: list.boxed(),
2006 offset_key: FrameValueKey::new_unique(),
2007 info_id: None,
2008 z_map: vec![],
2009 z_naturally_sorted: false,
2010 }
2011 }
2012
2013 pub fn track_info_range(mut self, info_id: impl Into<StateId<PanelListRange>>) -> Self {
2019 self.info_id = Some((info_id.into(), 0, true));
2020 self
2021 }
2022
2023 pub fn into_parts(
2025 self,
2026 ) -> (
2027 BoxedUiNodeList,
2028 Vec<Mutex<D>>,
2029 FrameValueKey<PxTransform>,
2030 Option<StateId<PanelListRange>>,
2031 ) {
2032 (self.list, self.data, self.offset_key, self.info_id.map(|t| t.0))
2033 }
2034
2035 pub fn from_parts(
2041 list: BoxedUiNodeList,
2042 data: Vec<Mutex<D>>,
2043 offset_key: FrameValueKey<PxTransform>,
2044 info_id: Option<StateId<PanelListRange>>,
2045 ) -> Self {
2046 assert_eq!(list.len(), data.len());
2047 Self {
2048 list,
2049 data,
2050 offset_key,
2051 info_id: info_id.map(|i| (i, 0, true)),
2052 z_map: vec![],
2053 z_naturally_sorted: false,
2054 }
2055 }
2056
2057 pub fn info_id(&self) -> Option<StateId<PanelListRange>> {
2061 self.info_id.as_ref().map(|t| t.0)
2062 }
2063
2064 pub fn with_node<R, F>(&mut self, index: usize, f: F) -> R
2066 where
2067 F: FnOnce(&mut BoxedUiNode, &mut D) -> R,
2068 {
2069 #[cfg(feature = "dyn_closure")]
2070 let f: Box<dyn FnOnce(&mut BoxedUiNode, &mut D) -> R> = Box::new(f);
2071 self.with_node_impl(index, f)
2072 }
2073 fn with_node_impl<R, F>(&mut self, index: usize, f: F) -> R
2074 where
2075 F: FnOnce(&mut BoxedUiNode, &mut D) -> R,
2076 {
2077 let data = self.data[index].get_mut();
2078 self.list.with_node(index, move |n| f(n, data))
2079 }
2080
2081 pub fn for_each<F>(&mut self, f: F)
2083 where
2084 F: FnMut(usize, &mut BoxedUiNode, &mut D),
2085 {
2086 #[cfg(feature = "dyn_closure")]
2087 let f: Box<dyn FnMut(usize, &mut BoxedUiNode, &mut D)> = Box::new(f);
2088 self.for_each_impl(f)
2089 }
2090 fn for_each_impl<F>(&mut self, mut f: F)
2091 where
2092 F: FnMut(usize, &mut BoxedUiNode, &mut D),
2093 {
2094 let data = &mut self.data;
2095 self.list.for_each(move |i, n| f(i, n, data[i].get_mut()))
2096 }
2097
2098 pub fn par_each<F>(&mut self, f: F)
2100 where
2101 F: Fn(usize, &mut BoxedUiNode, &mut D) + Send + Sync,
2102 D: Sync,
2103 {
2104 #[cfg(feature = "dyn_closure")]
2105 let f: Box<dyn Fn(usize, &mut BoxedUiNode, &mut D) + Send + Sync> = Box::new(f);
2106 self.par_each_impl(f)
2107 }
2108 fn par_each_impl<F>(&mut self, f: F)
2109 where
2110 F: Fn(usize, &mut BoxedUiNode, &mut D) + Send + Sync,
2111 D: Sync,
2112 {
2113 let data = &self.data;
2114 self.list.par_each(|i, n| {
2115 f(
2116 i,
2117 n,
2118 &mut data[i].try_lock().unwrap_or_else(|| panic!("data for `{i}` is already locked")),
2119 )
2120 })
2121 }
2122
2123 pub fn par_fold_reduce<T, I, F, R>(&mut self, identity: I, fold: F, reduce: R) -> T
2127 where
2128 T: Send + 'static,
2129 I: Fn() -> T + Send + Sync,
2130 F: Fn(T, usize, &mut BoxedUiNode, &mut D) -> T + Send + Sync,
2131 R: Fn(T, T) -> T + Send + Sync,
2132 {
2133 #[cfg(feature = "dyn_closure")]
2134 let identity: Box<dyn Fn() -> T + Send + Sync> = Box::new(identity);
2135 #[cfg(feature = "dyn_closure")]
2136 let fold: Box<dyn Fn(T, usize, &mut BoxedUiNode, &mut D) -> T + Send + Sync> = Box::new(fold);
2137 #[cfg(feature = "dyn_closure")]
2138 let reduce: Box<dyn Fn(T, T) -> T + Send + Sync> = Box::new(reduce);
2139
2140 self.par_fold_reduce_impl(identity, fold, reduce)
2141 }
2142 fn par_fold_reduce_impl<T, I, F, R>(&mut self, identity: I, fold: F, reduce: R) -> T
2143 where
2144 T: Send + 'static,
2145 I: Fn() -> T + Send + Sync,
2146 F: Fn(T, usize, &mut BoxedUiNode, &mut D) -> T + Send + Sync,
2147 R: Fn(T, T) -> T + Send + Sync,
2148 {
2149 let data = &self.data;
2150 self.list.par_fold_reduce(
2151 identity,
2152 |a, i, n| {
2153 fold(
2154 a,
2155 i,
2156 n,
2157 &mut data[i].try_lock().unwrap_or_else(|| panic!("data for `{i}` is already locked")),
2158 )
2159 },
2160 reduce,
2161 )
2162 }
2163
2164 pub fn measure_each<F, S>(&mut self, wm: &mut WidgetMeasure, measure: F, fold_size: S) -> PxSize
2168 where
2169 F: Fn(usize, &mut BoxedUiNode, &mut D, &mut WidgetMeasure) -> PxSize + Send + Sync,
2170 S: Fn(PxSize, PxSize) -> PxSize + Send + Sync,
2171 {
2172 #[cfg(feature = "dyn_closure")]
2173 let measure: Box<dyn Fn(usize, &mut BoxedUiNode, &mut D, &mut WidgetMeasure) -> PxSize + Send + Sync> = Box::new(measure);
2174 #[cfg(feature = "dyn_closure")]
2175 let fold_size: Box<dyn Fn(PxSize, PxSize) -> PxSize + Send + Sync> = Box::new(fold_size);
2176
2177 self.measure_each_impl(wm, measure, fold_size)
2178 }
2179 fn measure_each_impl<F, S>(&mut self, wm: &mut WidgetMeasure, measure: F, fold_size: S) -> PxSize
2180 where
2181 F: Fn(usize, &mut BoxedUiNode, &mut D, &mut WidgetMeasure) -> PxSize + Send + Sync,
2182 S: Fn(PxSize, PxSize) -> PxSize + Send + Sync,
2183 {
2184 let data = &self.data;
2185 self.list.measure_each(
2186 wm,
2187 |i, n, wm| {
2188 measure(
2189 i,
2190 n,
2191 &mut data[i].try_lock().unwrap_or_else(|| panic!("data for `{i}` is already locked")),
2192 wm,
2193 )
2194 },
2195 fold_size,
2196 )
2197 }
2198
2199 pub fn layout_each<F, S>(&mut self, wl: &mut WidgetLayout, layout: F, fold_size: S) -> PxSize
2203 where
2204 F: Fn(usize, &mut BoxedUiNode, &mut D, &mut WidgetLayout) -> PxSize + Send + Sync,
2205 S: Fn(PxSize, PxSize) -> PxSize + Send + Sync,
2206 {
2207 #[cfg(feature = "dyn_closure")]
2208 let layout: Box<dyn Fn(usize, &mut BoxedUiNode, &mut D, &mut WidgetLayout) -> PxSize + Send + Sync> = Box::new(layout);
2209 #[cfg(feature = "dyn_closure")]
2210 let fold_size: Box<dyn Fn(PxSize, PxSize) -> PxSize + Send + Sync> = Box::new(fold_size);
2211
2212 self.layout_each_impl(wl, layout, fold_size)
2213 }
2214 fn layout_each_impl<F, S>(&mut self, wl: &mut WidgetLayout, layout: F, fold_size: S) -> PxSize
2215 where
2216 F: Fn(usize, &mut BoxedUiNode, &mut D, &mut WidgetLayout) -> PxSize + Send + Sync,
2217 S: Fn(PxSize, PxSize) -> PxSize + Send + Sync,
2218 {
2219 let data = &self.data;
2220 self.list.layout_each(
2221 wl,
2222 |i, n, wl| {
2223 layout(
2224 i,
2225 n,
2226 &mut data[i].try_lock().unwrap_or_else(|| panic!("data for `{i}` is already locked")),
2227 wl,
2228 )
2229 },
2230 fold_size,
2231 )
2232 }
2233
2234 pub fn for_each_z_sorted(&mut self, f: impl FnMut(usize, &mut BoxedUiNode, &mut D)) {
2236 #[cfg(feature = "dyn_closure")]
2237 let f: Box<dyn FnMut(usize, &mut BoxedUiNode, &mut D)> = Box::new(f);
2238 self.for_each_z_sorted_impl(f)
2239 }
2240 fn for_each_z_sorted_impl(&mut self, mut f: impl FnMut(usize, &mut BoxedUiNode, &mut D)) {
2241 if self.z_naturally_sorted {
2242 self.for_each(f)
2243 } else {
2244 if self.z_map.len() != self.list.len() {
2245 self.z_sort();
2246 }
2247
2248 if self.z_naturally_sorted {
2249 self.for_each(f);
2250 } else {
2251 for &index in self.z_map.iter() {
2252 let index = index as usize;
2253 let data = self.data[index].get_mut();
2254 self.list.with_node(index, |node| f(index, node, data));
2255 }
2256 }
2257 }
2258 }
2259
2260 fn z_sort(&mut self) {
2261 let len = self.list.len();
2275 assert!(len <= u32::MAX as usize);
2276
2277 let mut prev_z = ZIndex::BACK;
2278 let mut need_map = false;
2279 let mut z_and_i = Vec::with_capacity(len);
2280 let mut has_non_default_zs = false;
2281
2282 self.list.for_each(|i, node| {
2283 let z = Z_INDEX.get_wgt(node);
2284 z_and_i.push(((z.0 as u64) << 32) | i as u64);
2285
2286 need_map |= z < prev_z;
2287 has_non_default_zs |= z != ZIndex::DEFAULT;
2288 prev_z = z;
2289 });
2290
2291 self.z_naturally_sorted = !need_map;
2292
2293 if need_map {
2294 z_and_i.sort_unstable();
2295
2296 for z in &mut z_and_i {
2297 *z &= u32::MAX as u64;
2298 }
2299
2300 self.z_map = z_and_i;
2301 } else {
2302 self.z_map.clear();
2303 }
2304 }
2305
2306 pub fn z_map(&mut self, index: usize) -> usize {
2308 if self.z_naturally_sorted {
2309 return index;
2310 }
2311
2312 if self.z_map.len() != self.list.len() {
2313 self.z_sort();
2314 }
2315
2316 if self.z_naturally_sorted {
2317 return index;
2318 }
2319
2320 self.z_map[index] as usize
2321 }
2322
2323 pub fn data(&mut self, index: usize) -> &mut D {
2325 self.data[index].get_mut()
2326 }
2327
2328 pub fn commit_data(&mut self) -> PanelListDataChanges {
2336 let mut changes = PanelListDataChanges::empty();
2337 for data in self.data.iter_mut() {
2338 changes |= data.get_mut().commit();
2339 }
2340 changes
2341 }
2342
2343 pub fn offset_key(&self) -> FrameValueKey<PxTransform> {
2347 self.offset_key
2348 }
2349}
2350impl<D> UiNodeList for PanelList<D>
2351where
2352 D: PanelListData,
2353{
2354 fn with_node<R, F>(&mut self, index: usize, f: F) -> R
2355 where
2356 F: FnOnce(&mut BoxedUiNode) -> R,
2357 {
2358 self.list.with_node(index, f)
2359 }
2360
2361 fn for_each<F>(&mut self, f: F)
2362 where
2363 F: FnMut(usize, &mut BoxedUiNode),
2364 {
2365 self.list.for_each(f)
2366 }
2367
2368 fn par_each<F>(&mut self, f: F)
2369 where
2370 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
2371 {
2372 self.list.par_each(f)
2373 }
2374
2375 fn par_fold_reduce<T, I, F, R>(&mut self, identity: I, fold: F, reduce: R) -> T
2376 where
2377 T: Send + 'static,
2378 I: Fn() -> T + Send + Sync,
2379 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
2380 R: Fn(T, T) -> T + Send + Sync,
2381 {
2382 self.list.par_fold_reduce(identity, fold, reduce)
2383 }
2384
2385 fn len(&self) -> usize {
2386 self.list.len()
2387 }
2388
2389 fn boxed(self) -> BoxedUiNodeList {
2390 Box::new(self)
2391 }
2392
2393 fn drain_into(&mut self, vec: &mut Vec<BoxedUiNode>) {
2394 self.list.drain_into(vec);
2395 self.data.clear();
2396 self.z_map.clear();
2397 self.z_naturally_sorted = true;
2398 }
2399
2400 fn init_all(&mut self) {
2401 self.z_map.clear();
2402 let resort = Z_INDEX.with(WIDGET.id(), || self.list.init_all());
2403 self.z_naturally_sorted = !resort;
2404 self.data.resize_with(self.list.len(), Default::default);
2405 }
2406
2407 fn deinit_all(&mut self) {
2408 self.list.deinit_all();
2409 }
2410
2411 fn info_all(&mut self, info: &mut WidgetInfoBuilder) {
2412 if self.list.is_empty() {
2413 return;
2414 }
2415
2416 self.list.info_all(info);
2417
2418 if let Some((id, version, pump_update)) = &mut self.info_id {
2419 let start = self.list.with_node(0, |c| c.with_context(WidgetUpdateMode::Ignore, || WIDGET.id()));
2420 let end = self
2421 .list
2422 .with_node(self.list.len() - 1, |c| c.with_context(WidgetUpdateMode::Ignore, || WIDGET.id()));
2423 let range = match (start, end) {
2424 (Some(s), Some(e)) => Some((s, e)),
2425 _ => None,
2426 };
2427 info.set_meta(*id, PanelListRange { range, version: *version });
2428
2429 if mem::take(pump_update) {
2430 self.list.for_each(|_, c| {
2431 c.with_context(WidgetUpdateMode::Bubble, || WIDGET.update());
2432 });
2433 }
2434 }
2435 }
2436
2437 fn event_all(&mut self, update: &EventUpdate) {
2438 self.list.event_all(update);
2439 }
2440
2441 fn update_all(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
2442 let mut observer = PanelObserver {
2443 changed: false,
2444 data: &mut self.data,
2445 observer,
2446 };
2447 let resort = Z_INDEX.with(WIDGET.id(), || self.list.update_all(updates, &mut observer));
2448 let observer_changed = observer.changed;
2449 if resort || (observer.changed && self.z_naturally_sorted) {
2450 self.z_map.clear();
2451 self.z_naturally_sorted = false;
2452 WIDGET.render();
2453 }
2454 self.data.resize_with(self.list.len(), Default::default);
2455
2456 if observer_changed {
2457 if let Some((_, v, u)) = &mut self.info_id {
2458 if !*u {
2459 *v = v.wrapping_add(1);
2460 *u = true;
2461 }
2462 }
2464 }
2465 }
2466
2467 fn render_all(&mut self, frame: &mut FrameBuilder) {
2468 let offset_key = self.offset_key;
2469 if self.z_naturally_sorted && self.len() > 1 && PARALLEL_VAR.get().contains(Parallel::RENDER) {
2470 let b = self.par_fold_reduce(
2471 || frame.parallel_split(),
2472 |mut frame, i, child, data| {
2473 let offset = data.child_offset();
2474 if data.define_reference_frame() {
2475 frame.push_reference_frame(
2476 (offset_key, i as u32).into(),
2477 offset_key.bind_child(i as u32, offset.into(), false),
2478 true,
2479 true,
2480 |frame| {
2481 child.render(frame);
2482 },
2483 );
2484 } else {
2485 frame.push_child(offset, |frame| {
2486 child.render(frame);
2487 });
2488 }
2489 frame
2490 },
2491 |mut a, b| {
2492 a.parallel_fold(b);
2493 a
2494 },
2495 );
2496 frame.parallel_fold(b);
2497 } else {
2498 self.for_each_z_sorted(|i, child, data| {
2499 let offset = data.child_offset();
2500 if data.define_reference_frame() {
2501 frame.push_reference_frame(
2502 (offset_key, i as u32).into(),
2503 offset_key.bind_child(i as u32, offset.into(), false),
2504 true,
2505 true,
2506 |frame| {
2507 child.render(frame);
2508 },
2509 );
2510 } else {
2511 frame.push_child(offset, |frame| {
2512 child.render(frame);
2513 });
2514 }
2515 });
2516 }
2517 }
2518
2519 fn render_update_all(&mut self, update: &mut FrameUpdate) {
2520 let offset_key = self.offset_key;
2521
2522 if self.len() > 1 && PARALLEL_VAR.get().contains(Parallel::RENDER) {
2523 let b = self.par_fold_reduce(
2524 || update.parallel_split(),
2525 |mut update, i, child, data| {
2526 let offset = data.child_offset();
2527 if data.define_reference_frame() {
2528 update.with_transform(offset_key.update_child(i as u32, offset.into(), false), true, |update| {
2529 child.render_update(update);
2530 });
2531 } else {
2532 update.with_child(offset, |update| {
2533 child.render_update(update);
2534 });
2535 }
2536 update
2537 },
2538 |mut a, b| {
2539 a.parallel_fold(b);
2540 a
2541 },
2542 );
2543 update.parallel_fold(b);
2544 } else {
2545 self.for_each(|i, child, data| {
2546 let offset = data.child_offset();
2547 if data.define_reference_frame() {
2548 update.with_transform(offset_key.update_child(i as u32, offset.into(), false), true, |update| {
2549 child.render_update(update);
2550 });
2551 } else {
2552 update.with_child(offset, |update| {
2553 child.render_update(update);
2554 });
2555 }
2556 });
2557 }
2558 }
2559}
2560
2561bitflags::bitflags! {
2562 #[must_use = "|= with other item changes, call request_render"]
2564 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
2565 #[serde(transparent)]
2566 pub struct PanelListDataChanges: u8 {
2567 const CHILD_OFFSET = 0b01;
2569 const DEFINE_REFERENCE_FRAME = 0b10;
2571 }
2572}
2573impl PanelListDataChanges {
2574 pub fn request_render(self) {
2576 if self.contains(Self::DEFINE_REFERENCE_FRAME) {
2577 WIDGET.render();
2578 } else if self.contains(Self::CHILD_OFFSET) {
2579 WIDGET.render_update();
2580 }
2581 }
2582}
2583
2584#[derive(Clone, Debug, Default)]
2586pub struct DefaultPanelListData {
2587 pub child_offset: PxVector,
2589 pub define_reference_frame: bool,
2591
2592 prev_child_offset: PxVector,
2593 prev_define_reference_frame: bool,
2594}
2595impl PanelListData for DefaultPanelListData {
2596 fn child_offset(&self) -> PxVector {
2597 self.child_offset
2598 }
2599
2600 fn define_reference_frame(&self) -> bool {
2601 self.define_reference_frame
2602 }
2603
2604 fn commit(&mut self) -> PanelListDataChanges {
2605 let mut changes = PanelListDataChanges::empty();
2606 if self.define_reference_frame != self.prev_define_reference_frame {
2607 changes |= PanelListDataChanges::DEFINE_REFERENCE_FRAME;
2608 }
2609 if self.child_offset != self.prev_child_offset {
2610 changes |= PanelListDataChanges::CHILD_OFFSET;
2611 }
2612 self.prev_define_reference_frame = self.define_reference_frame;
2613 self.prev_child_offset = self.child_offset;
2614 changes
2615 }
2616}
2617
2618pub trait PanelListData: Default + Send + Any {
2620 fn child_offset(&self) -> PxVector;
2622
2623 fn define_reference_frame(&self) -> bool;
2625
2626 fn commit(&mut self) -> PanelListDataChanges;
2630}
2631impl PanelListData for () {
2632 fn child_offset(&self) -> PxVector {
2633 PxVector::zero()
2634 }
2635
2636 fn define_reference_frame(&self) -> bool {
2637 false
2638 }
2639
2640 fn commit(&mut self) -> PanelListDataChanges {
2641 PanelListDataChanges::empty()
2642 }
2643}
2644
2645struct PanelObserver<'d, D>
2646where
2647 D: PanelListData,
2648{
2649 changed: bool,
2650 data: &'d mut Vec<Mutex<D>>,
2651 observer: &'d mut dyn UiNodeListObserver,
2652}
2653impl<D> UiNodeListObserver for PanelObserver<'_, D>
2654where
2655 D: PanelListData,
2656{
2657 fn is_reset_only(&self) -> bool {
2658 false
2659 }
2660
2661 fn reset(&mut self) {
2662 self.changed = true;
2663 self.data.clear();
2664 self.observer.reset();
2665 }
2666
2667 fn inserted(&mut self, index: usize) {
2668 self.changed = true;
2669 self.data.insert(index, Default::default());
2670 self.observer.inserted(index);
2671 }
2672
2673 fn removed(&mut self, index: usize) {
2674 self.changed = true;
2675 self.data.remove(index);
2676 self.observer.removed(index);
2677 }
2678
2679 fn moved(&mut self, removed_index: usize, inserted_index: usize) {
2680 self.changed = true;
2681 let item = self.data.remove(removed_index);
2682 self.data.insert(inserted_index, item);
2683 self.observer.moved(removed_index, inserted_index);
2684 }
2685}