1use std::{
2 cmp::Ordering,
3 fmt, mem,
4 ops::{self, ControlFlow},
5 sync::{
6 Arc,
7 atomic::{AtomicBool, Ordering::Relaxed},
8 },
9};
10
11use crate::{
12 render::{FrameBuilder, FrameUpdate, FrameValueKey},
13 update::{UPDATES, WidgetUpdates},
14 widget::{
15 WIDGET, WidgetUpdateMode,
16 base::{PARALLEL_VAR, Parallel},
17 info::{WidgetInfo, WidgetInfoBuilder, WidgetLayout, WidgetMeasure},
18 },
19};
20use zng_app_context::context_local;
21use zng_layout::unit::{Factor, PxSize, PxTransform, PxVector};
22use zng_state_map::StateId;
23use zng_task::parking_lot::Mutex;
24use zng_task::rayon::prelude::*;
25use zng_unique_id::static_id;
26use zng_var::{animation::Transitionable, impl_from_and_into_var};
27
28use super::*;
29
30#[macro_export]
57macro_rules! ui_vec {
58 () => { $crate::widget::node::UiVec::new() };
59 ($node:expr; $n:expr) => {
60 {
61 let mut n: usize = $n;
62 let mut vec = $crate::widget::node::UiVec::with_capacity(n);
63 while n > 0 {
64 vec.push($node);
65 n -= 1;
66 }
67 vec
68 }
69 };
70 ($($nodes:tt)+) => {
71 $crate::ui_vec_items! {
72 match { $($nodes)+ }
73 result { }
74 }
75 };
76}
77#[doc(inline)]
78pub use crate::ui_vec;
79
80#[macro_export]
82#[doc(hidden)]
83macro_rules! ui_vec_items {
84 (
86 match { #[$meta:meta] $($tt:tt)* }
87 result { $($r:tt)* }
88 ) => {
89 $crate::ui_vec_items! {
90 match { $($tt)* }
91 result { $($r)* #[$meta] }
92 }
93 };
94 (
96 match { $node:expr, $($tt:tt)* }
97 result { $($r:tt)* }
98 ) => {
99 $crate::ui_vec_items! {
100 match { $($tt)* }
101 result { $($r)* $crate::widget::node::IntoUiNode::into_node($node), }
102 }
103 };
104 (
106 match { $node:expr }
107 result { $($r:tt)* }
108 ) => {
109 $crate::ui_vec_items! {
110 match { }
111 result { $($r)* $crate::widget::node::IntoUiNode::into_node($node) }
112 }
113 };
114 (
116 match { }
117 result { $($r:tt)* }
118 ) => {
119 $crate::widget::node::UiVec::from(std::vec![
120 $($r)*
121 ])
122 };
123}
124
125#[derive(Default)]
129pub struct UiVec(Vec<UiNode>);
130impl UiVec {
131 pub fn new() -> Self {
133 Self::default()
134 }
135
136 pub fn with_capacity(capacity: usize) -> Self {
140 Self(Vec::with_capacity(capacity))
141 }
142
143 pub fn push(&mut self, node: impl IntoUiNode) {
147 self.0.push(node.into_node())
148 }
149
150 pub fn insert(&mut self, index: usize, node: impl IntoUiNode) {
154 self.0.insert(index, node.into_node())
155 }
156
157 pub fn chain(self, other: impl IntoUiNode) -> UiNode {
161 UiNode::new(self).chain(other)
162 }
163}
164impl ops::Deref for UiVec {
165 type Target = Vec<UiNode>;
166
167 fn deref(&self) -> &Self::Target {
168 &self.0
169 }
170}
171impl ops::DerefMut for UiVec {
172 fn deref_mut(&mut self) -> &mut Self::Target {
173 &mut self.0
174 }
175}
176impl From<Vec<UiNode>> for UiVec {
177 fn from(vec: Vec<UiNode>) -> Self {
178 Self(vec)
179 }
180}
181impl From<UiVec> for Vec<UiNode> {
182 fn from(vec: UiVec) -> Self {
183 vec.0
184 }
185}
186impl<U: IntoUiNode> FromIterator<U> for UiVec {
187 fn from_iter<T: IntoIterator<Item = U>>(iter: T) -> Self {
188 Self(Vec::from_iter(iter.into_iter().map(IntoUiNode::into_node)))
189 }
190}
191impl IntoIterator for UiVec {
192 type Item = UiNode;
193
194 type IntoIter = std::vec::IntoIter<UiNode>;
195
196 fn into_iter(self) -> Self::IntoIter {
197 self.0.into_iter()
198 }
199}
200impl IntoUiNode for Vec<UiNode> {
201 fn into_node(self) -> UiNode {
202 UiNode::new(UiVec(self))
203 }
204}
205impl IntoUiNode for Box<[UiNode]> {
206 fn into_node(self) -> UiNode {
207 UiNode::new(UiVec(self.into()))
208 }
209}
210impl UiNodeImpl for UiVec {
211 fn children_len(&self) -> usize {
212 self.len()
213 }
214
215 fn with_child(&mut self, index: usize, visitor: &mut dyn FnMut(&mut UiNode)) {
216 if index < self.len() {
217 visitor(&mut self[index])
218 }
219 }
220
221 fn is_list(&self) -> bool {
222 true
223 }
224
225 fn for_each_child(&mut self, visitor: &mut dyn FnMut(usize, &mut UiNode)) {
226 for (i, n) in self.0.iter_mut().enumerate() {
227 visitor(i, n)
228 }
229 }
230
231 fn try_for_each_child(
232 &mut self,
233 visitor: &mut dyn FnMut(usize, &mut UiNode) -> ControlFlow<BoxAnyVarValue>,
234 ) -> ControlFlow<BoxAnyVarValue> {
235 for (i, n) in self.0.iter_mut().enumerate() {
236 visitor(i, n)?;
237 }
238 ControlFlow::Continue(())
239 }
240
241 fn par_each_child(&mut self, visitor: &(dyn Fn(usize, &mut UiNode) + Sync)) {
242 if self.len() >= MIN_PARALLEL {
243 self.par_iter_mut().enumerate().with_ctx().for_each(|(i, n)| visitor(i, n))
244 } else {
245 self.iter_mut().enumerate().for_each(|(i, n)| visitor(i, n))
246 }
247 }
248
249 fn par_fold_reduce(
250 &mut self,
251 identity: BoxAnyVarValue,
252 fold: &(dyn Fn(BoxAnyVarValue, usize, &mut UiNode) -> BoxAnyVarValue + Sync),
253 reduce: &(dyn Fn(BoxAnyVarValue, BoxAnyVarValue) -> BoxAnyVarValue + Sync),
254 ) -> BoxAnyVarValue {
255 self.par_iter_mut()
256 .enumerate()
257 .with_ctx()
258 .fold(|| identity.clone(), move |a, (i, n)| fold(a, i, n))
259 .reduce(|| identity.clone(), reduce)
260 }
261
262 fn init(&mut self) {
263 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::INIT) {
264 self.par_iter_mut().with_ctx().for_each(|n| n.init());
265 } else {
266 self.iter_mut().for_each(|n| n.init());
267 }
268 }
269
270 fn deinit(&mut self) {
271 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::DEINIT) {
272 self.par_iter_mut().with_ctx().for_each(|n| n.deinit());
273 } else {
274 self.iter_mut().for_each(|n| n.deinit());
275 }
276 }
277
278 fn info(&mut self, info: &mut WidgetInfoBuilder) {
279 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::INFO) {
280 let b = self
281 .par_iter_mut()
282 .with_ctx()
283 .fold(
284 || info.parallel_split(),
285 |mut info, c| {
286 c.info(&mut info);
287 info
288 },
289 )
290 .reduce(
291 || info.parallel_split(),
292 |mut a, b| {
293 a.parallel_fold(b);
294 a
295 },
296 );
297 info.parallel_fold(b);
298 } else {
299 self.iter_mut().for_each(|n| n.info(info));
300 }
301 }
302
303 fn update(&mut self, updates: &WidgetUpdates) {
304 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::UPDATE) {
305 self.par_iter_mut().with_ctx().for_each(|n| n.update(updates));
306 } else {
307 self.iter_mut().for_each(|n| n.update(updates));
308 }
309 }
310 fn update_list(&mut self, updates: &WidgetUpdates, _: &mut dyn UiNodeListObserver) {
311 self.update(updates);
312 }
313
314 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
315 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::LAYOUT) {
316 let (b, desired_size) = self
317 .par_iter_mut()
318 .with_ctx()
319 .fold(
320 || (wm.parallel_split(), PxSize::zero()),
321 |(mut wm, desired_size), n| {
322 let n_ds = n.measure(&mut wm);
323 (wm, desired_size.max(n_ds))
324 },
325 )
326 .reduce(
327 || (wm.parallel_split(), PxSize::zero()),
328 |(mut wm, desired_size), (b_wm, b_ds)| {
329 wm.parallel_fold(b_wm);
330 (wm, desired_size.max(b_ds))
331 },
332 );
333 wm.parallel_fold(b);
334 desired_size
335 } else {
336 let mut desired_size = PxSize::zero();
337 self.iter_mut().for_each(|n| desired_size = desired_size.max(n.measure(wm)));
338 desired_size
339 }
340 }
341
342 fn measure_list(
343 &mut self,
344 wm: &mut WidgetMeasure,
345 measure: &(dyn Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync),
346 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
347 ) -> PxSize {
348 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::LAYOUT) {
349 let (b, desired_size) = self
350 .par_iter_mut()
351 .enumerate()
352 .with_ctx()
353 .fold(
354 || (wm.parallel_split(), PxSize::zero()),
355 |(mut wm, desired_size), (i, n)| {
356 let n_ds = measure(i, n, &mut wm);
357 (wm, fold_size(desired_size, n_ds))
358 },
359 )
360 .reduce(
361 || (wm.parallel_split(), PxSize::zero()),
362 |(mut wm, desired_size), (b_wm, b_ds)| {
363 wm.parallel_fold(b_wm);
364 (wm, fold_size(desired_size, b_ds))
365 },
366 );
367 wm.parallel_fold(b);
368 desired_size
369 } else {
370 let mut desired_size = PxSize::zero();
371 self.iter_mut()
372 .enumerate()
373 .for_each(|(i, n)| desired_size = fold_size(desired_size, measure(i, n, wm)));
374 desired_size
375 }
376 }
377
378 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
379 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::LAYOUT) {
380 let (b, final_size) = self
381 .par_iter_mut()
382 .with_ctx()
383 .fold(
384 || (wl.parallel_split(), PxSize::zero()),
385 |(mut wl, final_size), n| {
386 let n_ds = n.layout(&mut wl);
387 (wl, final_size.max(n_ds))
388 },
389 )
390 .reduce(
391 || (wl.parallel_split(), PxSize::zero()),
392 |(mut wl, desired_size), (b_wl, b_ds)| {
393 wl.parallel_fold(b_wl);
394 (wl, desired_size.max(b_ds))
395 },
396 );
397 wl.parallel_fold(b);
398 final_size
399 } else {
400 let mut final_size = PxSize::zero();
401 self.iter_mut().for_each(|n| final_size = final_size.max(n.layout(wl)));
402 final_size
403 }
404 }
405
406 fn layout_list(
407 &mut self,
408 wl: &mut WidgetLayout,
409 layout: &(dyn Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync),
410 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
411 ) -> PxSize {
412 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::LAYOUT) {
413 let (b, desired_size) = self
414 .par_iter_mut()
415 .enumerate()
416 .with_ctx()
417 .fold(
418 || (wl.parallel_split(), PxSize::zero()),
419 |(mut wl, desired_size), (i, n)| {
420 let n_ds = layout(i, n, &mut wl);
421 (wl, fold_size(desired_size, n_ds))
422 },
423 )
424 .reduce(
425 || (wl.parallel_split(), PxSize::zero()),
426 |(mut wl, desired_size), (b_wm, b_ds)| {
427 wl.parallel_fold(b_wm);
428 (wl, fold_size(desired_size, b_ds))
429 },
430 );
431 wl.parallel_fold(b);
432 desired_size
433 } else {
434 let mut desired_size = PxSize::zero();
435 self.iter_mut()
436 .enumerate()
437 .for_each(|(i, n)| desired_size = fold_size(desired_size, layout(i, n, wl)));
438 desired_size
439 }
440 }
441
442 fn render(&mut self, frame: &mut FrameBuilder) {
443 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::RENDER) {
444 let mut par_start = 0;
445 while frame.is_outer() && par_start < self.len() {
446 self[par_start].render(frame);
448 par_start += 1;
449 }
450 let b = self[par_start..]
451 .par_iter_mut()
452 .with_ctx()
453 .fold(
454 || frame.parallel_split(),
455 |mut frame, c| {
456 c.render(&mut frame);
457 frame
458 },
459 )
460 .reduce(
461 || frame.parallel_split(),
462 |mut a, b| {
463 a.parallel_fold(b);
464 a
465 },
466 );
467 frame.parallel_fold(b);
468 } else {
469 self.iter_mut().for_each(|n| n.render(frame));
470 }
471 }
472
473 fn render_list(&mut self, frame: &mut FrameBuilder, render: &(dyn Fn(usize, &mut UiNode, &mut FrameBuilder) + Sync)) {
474 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::RENDER) {
475 let mut par_start = 0;
476 while frame.is_outer() && par_start < self.len() {
477 self[par_start].render(frame);
479 par_start += 1;
480 }
481 let b = self[par_start..]
482 .par_iter_mut()
483 .enumerate()
484 .with_ctx()
485 .fold(
486 || frame.parallel_split(),
487 |mut frame, (i, c)| {
488 render(i, c, &mut frame);
489 frame
490 },
491 )
492 .reduce(
493 || frame.parallel_split(),
494 |mut a, b| {
495 a.parallel_fold(b);
496 a
497 },
498 );
499 frame.parallel_fold(b);
500 } else {
501 self.iter_mut().enumerate().for_each(|(i, n)| render(i, n, frame));
502 }
503 }
504
505 fn render_update(&mut self, update: &mut FrameUpdate) {
506 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::RENDER) {
507 let mut par_start = 0;
508 while update.is_outer() && par_start < self.len() {
509 self[par_start].render_update(update);
511 par_start += 1;
512 }
513 let b = self[par_start..]
514 .par_iter_mut()
515 .with_ctx()
516 .fold(
517 || update.parallel_split(),
518 |mut update, c| {
519 c.render_update(&mut update);
520 update
521 },
522 )
523 .reduce(
524 || update.parallel_split(),
525 |mut a, b| {
526 a.parallel_fold(b);
527 a
528 },
529 );
530 update.parallel_fold(b);
531 } else {
532 self.iter_mut().for_each(|n| n.render_update(update));
533 }
534 }
535
536 fn render_update_list(&mut self, update: &mut FrameUpdate, render_update: &(dyn Fn(usize, &mut UiNode, &mut FrameUpdate) + Sync)) {
537 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::RENDER) {
538 let mut par_start = 0;
539 while update.is_outer() && par_start < self.len() {
540 self[par_start].render_update(update);
542 par_start += 1;
543 }
544 let b = self[par_start..]
545 .par_iter_mut()
546 .enumerate()
547 .with_ctx()
548 .fold(
549 || update.parallel_split(),
550 |mut update, (i, c)| {
551 render_update(i, c, &mut update);
552 update
553 },
554 )
555 .reduce(
556 || update.parallel_split(),
557 |mut a, b| {
558 a.parallel_fold(b);
559 a
560 },
561 );
562 update.parallel_fold(b);
563 } else {
564 self.iter_mut().enumerate().for_each(|(i, n)| render_update(i, n, update));
565 }
566 }
567
568 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
569 None
570 }
571}
572
573impl UiNode {
575 pub fn chain(self, other: impl IntoUiNode) -> UiNode {
582 self.chain_impl(other.into_node())
583 }
584 fn chain_impl(mut self, mut other: UiNode) -> UiNode {
585 if self.is_nil() {
586 return other;
587 }
588 if other.is_nil() {
589 return self;
590 }
591
592 if let Some(chain) = self.downcast_mut::<ChainList>() {
593 if let Some(other_too) = other.downcast_mut::<ChainList>() {
594 chain.0.append(&mut other_too.0);
595 } else {
596 chain.0.push(other);
597 }
598 self
599 } else {
600 ChainList(ui_vec![self, other]).into_node()
601 }
602 }
603
604 pub fn sorting_by(mut self, sort: impl Fn(&mut UiNode, &mut UiNode) -> Ordering + Send + 'static) -> UiNode {
610 if let Some(already) = self.downcast_mut::<SortingList>() {
611 already.sort = Box::new(sort);
612 already.invalidate_sort();
613 self
614 } else {
615 SortingList::new(self, sort).into_node()
616 }
617 }
618}
619
620pub struct ChainList(pub UiVec);
622impl ChainList {
623 pub fn chain(self, other: impl IntoUiNode) -> UiNode {
627 self.into_node().chain(other)
628 }
629}
630impl UiNodeImpl for ChainList {
631 fn children_len(&self) -> usize {
632 let mut len = 0;
633 for c in self.0.iter() {
634 if c.is_list() {
635 len += c.children_len();
636 } else {
637 len += 1;
638 }
639 }
640 len
641 }
642
643 fn with_child(&mut self, index: usize, visitor: &mut dyn FnMut(&mut UiNode)) {
644 let mut offset = 0;
645 for c in self.0.iter_mut() {
646 let next_offset = offset + if c.is_list() { c.children_len() } else { 1 };
647 if next_offset > index {
648 c.with_child(index - offset, visitor);
649 break;
650 }
651 offset = next_offset;
652 }
653 }
654
655 fn is_list(&self) -> bool {
656 true
657 }
658
659 fn for_each_child(&mut self, visitor: &mut dyn FnMut(usize, &mut UiNode)) {
660 let mut offset = 0;
661 for c in self.0.iter_mut() {
662 if c.is_list() {
663 c.for_each_child(|i, n| visitor(offset + i, n));
664 offset += c.children_len();
665 } else {
666 visitor(offset, c);
667 offset += 1;
668 }
669 }
670 }
671
672 fn try_for_each_child(
673 &mut self,
674 visitor: &mut dyn FnMut(usize, &mut UiNode) -> ControlFlow<BoxAnyVarValue>,
675 ) -> ControlFlow<BoxAnyVarValue> {
676 let mut offset = 0;
677 for c in self.0.iter_mut() {
678 if c.is_list() {
679 let mut cf = ControlFlow::Continue(());
680 c.for_each_child(|i, n| cf = visitor(offset + i, n));
681 cf?;
682 offset += c.children_len();
683 } else {
684 visitor(offset, c)?;
685 offset += 1;
686 }
687 }
688 ControlFlow::Continue(())
689 }
690
691 fn par_each_child(&mut self, visitor: &(dyn Fn(usize, &mut UiNode) + Sync)) {
692 let mut offset = 0;
693 for c in self.0.iter_mut() {
694 if c.is_list() {
695 c.par_each_child(|i, n| visitor(offset + i, n));
696 offset += c.children_len();
697 } else {
698 visitor(offset, c);
699 offset += 1;
700 }
701 }
702 }
703
704 fn par_fold_reduce(
705 &mut self,
706 identity: BoxAnyVarValue,
707 fold: &(dyn Fn(BoxAnyVarValue, usize, &mut UiNode) -> BoxAnyVarValue + Sync),
708 reduce: &(dyn Fn(BoxAnyVarValue, BoxAnyVarValue) -> BoxAnyVarValue + Sync),
709 ) -> BoxAnyVarValue {
710 let mut offset = 0;
711 let mut accumulator = identity.clone();
712 for c in self.0.iter_mut() {
713 if c.is_list() {
714 accumulator = c.0.par_fold_reduce(identity.clone(), &|acc, i, n| fold(acc, offset + i, n), reduce);
715 offset += c.children_len();
716 } else {
717 accumulator = fold(accumulator, offset, c);
718 offset += 1;
719 }
720 }
721 accumulator
722 }
723
724 fn init(&mut self) {
725 self.0.init();
726 }
727
728 fn deinit(&mut self) {
729 self.0.deinit();
730 }
731
732 fn info(&mut self, info: &mut WidgetInfoBuilder) {
733 self.0.info(info);
734 }
735
736 fn update(&mut self, updates: &WidgetUpdates) {
737 self.0.update(updates);
738 }
739
740 fn update_list(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
741 if observer.is_reset_only() {
742 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::UPDATE) {
743 let changed = self
744 .0
745 .par_iter_mut()
746 .with_ctx()
747 .map(|n| {
748 let mut changed = false;
749 n.update_list(updates, &mut changed);
750 changed
751 })
752 .reduce(|| false, |a, b| a || b);
753 if changed {
754 observer.reset();
755 }
756 } else {
757 let mut changed = false;
758 for c in self.0.iter_mut() {
759 c.update_list(updates, &mut changed);
760 }
761 if changed {
762 observer.reset();
763 }
764 }
765 } else {
766 let mut offset = 0;
767 for c in self.0.iter_mut() {
768 if c.is_list() {
769 c.0.update_list(updates, &mut OffsetUiListObserver(offset, observer));
770 offset += c.children_len();
771 } else {
772 c.update(updates);
773 offset += 1;
774 }
775 }
776 }
777 }
778
779 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
780 self.0.measure(wm)
781 }
782
783 fn measure_list(
784 &mut self,
785 wm: &mut WidgetMeasure,
786 measure: &(dyn Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync),
787 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
788 ) -> PxSize {
789 let mut offset = 0;
790 let mut accumulator = PxSize::zero();
791 for c in self.0.iter_mut() {
792 if c.is_list() {
793 let s = c.0.measure_list(wm, &|i, n, wm| measure(offset + i, n, wm), fold_size);
794 accumulator = fold_size(accumulator, s);
795 offset += c.children_len();
796 } else {
797 let s = measure(offset, c, wm);
798 accumulator = fold_size(accumulator, s);
799 offset += 1;
800 }
801 }
802 accumulator
803 }
804
805 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
806 self.0.layout(wl)
807 }
808
809 fn layout_list(
810 &mut self,
811 wl: &mut WidgetLayout,
812 layout: &(dyn Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync),
813 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
814 ) -> PxSize {
815 let mut offset = 0;
816 let mut accumulator = PxSize::zero();
817 for c in self.0.iter_mut() {
818 if c.is_list() {
819 let s = c.0.layout_list(wl, &|i, n, wl| layout(offset + i, n, wl), fold_size);
820 accumulator = fold_size(accumulator, s);
821 offset += c.children_len();
822 } else {
823 let s = layout(offset, c, wl);
824 accumulator = fold_size(accumulator, s);
825 offset += 1;
826 }
827 }
828 accumulator
829 }
830
831 fn render(&mut self, frame: &mut FrameBuilder) {
832 self.0.render(frame);
833 }
834
835 fn render_list(&mut self, frame: &mut FrameBuilder, render: &(dyn Fn(usize, &mut UiNode, &mut FrameBuilder) + Sync)) {
836 let mut offset = 0;
837 for c in self.0.iter_mut() {
838 if c.is_list() {
839 c.0.render_list(frame, &|i, n, frame| render(offset + i, n, frame));
840 offset += c.children_len();
841 } else {
842 render(offset, c, frame);
843 offset += 1;
844 }
845 }
846 }
847
848 fn render_update(&mut self, update: &mut FrameUpdate) {
849 self.0.render_update(update);
850 }
851
852 fn render_update_list(&mut self, update: &mut FrameUpdate, render_update: &(dyn Fn(usize, &mut UiNode, &mut FrameUpdate) + Sync)) {
853 let mut offset = 0;
854 for c in self.0.iter_mut() {
855 if c.is_list() {
856 c.0.render_update_list(update, &|i, n, update| render_update(offset + i, n, update));
857 offset += c.children_len();
858 } else {
859 render_update(offset, c, update);
860 offset += 1;
861 }
862 }
863 }
864
865 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
866 None
867 }
868}
869
870#[expect(non_camel_case_types)]
872pub struct SORTING_LIST;
873impl SORTING_LIST {
874 pub fn is_inside_list(&self) -> bool {
876 !SORTING_LIST_PARENT.is_default()
877 }
878
879 pub fn invalidate_sort(&self) {
881 SORTING_LIST_PARENT.get().store(true, Relaxed)
882 }
883
884 fn with<R>(&self, action: impl FnOnce() -> R) -> (R, bool) {
885 SORTING_LIST_PARENT.with_context(&mut Some(Arc::new(AtomicBool::new(false))), || {
886 let r = action();
887 (r, SORTING_LIST_PARENT.get().load(Relaxed))
888 })
889 }
890}
891context_local! {
892 static SORTING_LIST_PARENT: AtomicBool = AtomicBool::new(false);
893}
894
895pub struct SortingList {
907 list: UiNode,
908
909 map: Vec<usize>,
910 sort: Box<dyn Fn(&mut UiNode, &mut UiNode) -> Ordering + Send + 'static>,
911}
912impl SortingList {
913 pub fn new(list: impl IntoUiNode, sort: impl Fn(&mut UiNode, &mut UiNode) -> Ordering + Send + 'static) -> Self {
915 Self {
916 list: list.into_node().into_list(),
917 map: vec![],
918 sort: Box::new(sort),
919 }
920 }
921
922 fn update_map(&mut self) {
923 let map = &mut self.map;
924 let len = self.list.children_len();
925
926 if len == 0 {
927 map.clear();
928 } else if map.len() != len {
929 map.clear();
930 map.extend(0..len);
931 let mut taken_a = UiNode::nil();
932 map.sort_by(|&a, &b| {
933 self.list.with_child(a, |a| mem::swap(a, &mut taken_a));
934 let result = self.list.with_child(b, |b| (self.sort)(&mut taken_a, b));
935 self.list.with_child(a, |a| mem::swap(a, &mut taken_a));
936
937 result
938 })
939 }
940 }
941 pub fn list(&mut self) -> &mut UiNode {
947 &mut self.list
948 }
949
950 pub fn invalidate_sort(&mut self) {
954 self.map.clear()
955 }
956
957 fn with_map<R>(&mut self, f: impl FnOnce(&[usize], &mut UiNode) -> R) -> R {
958 self.update_map();
959
960 let (r, resort) = SORTING_LIST.with(|| f(&self.map, &mut self.list));
961
962 if resort {
963 self.invalidate_sort();
964 }
965
966 r
967 }
968
969 pub fn chain(self, other: impl IntoUiNode) -> UiNode {
973 self.into_node().chain(other)
974 }
975}
976impl UiNodeImpl for SortingList {
977 fn children_len(&self) -> usize {
978 self.list.children_len()
979 }
980
981 fn with_child(&mut self, index: usize, visitor: &mut dyn FnMut(&mut UiNode)) {
982 self.with_map(|map, list| {
983 if let Some(index) = map.get(index) {
984 list.0.with_child(*index, visitor)
985 }
986 })
987 }
988
989 fn is_list(&self) -> bool {
990 true
991 }
992
993 fn for_each_child(&mut self, visitor: &mut dyn FnMut(usize, &mut UiNode)) {
994 self.with_map(|map, list| {
995 for (i, &actual_i) in map.iter().enumerate() {
996 list.with_child(actual_i, |n| visitor(i, n));
997 }
998 })
999 }
1000
1001 fn try_for_each_child(
1002 &mut self,
1003 visitor: &mut dyn FnMut(usize, &mut UiNode) -> ControlFlow<BoxAnyVarValue>,
1004 ) -> ControlFlow<BoxAnyVarValue> {
1005 self.with_map(|map, list| {
1006 for (i, &actual_i) in map.iter().enumerate() {
1007 let mut cf = ControlFlow::Continue(());
1008 list.with_child(actual_i, |n| cf = visitor(i, n));
1009 cf?;
1010 }
1011 ControlFlow::Continue(())
1012 })
1013 }
1014
1015 fn par_each_child(&mut self, visitor: &(dyn Fn(usize, &mut UiNode) + Sync)) {
1016 self.for_each_child(&mut |i, n| visitor(i, n));
1017 }
1018
1019 fn par_fold_reduce(
1020 &mut self,
1021 identity: BoxAnyVarValue,
1022 fold: &(dyn Fn(BoxAnyVarValue, usize, &mut UiNode) -> BoxAnyVarValue + Sync),
1023 _: &(dyn Fn(BoxAnyVarValue, BoxAnyVarValue) -> BoxAnyVarValue + Sync),
1024 ) -> BoxAnyVarValue {
1025 let mut acc = Some(identity);
1026 self.for_each_child(&mut |i, n| {
1027 acc = Some(fold(acc.take().unwrap(), i, n));
1028 });
1029 acc.unwrap()
1030 }
1031
1032 fn init(&mut self) {
1033 let _ = SORTING_LIST.with(|| self.list.0.init());
1034 self.invalidate_sort();
1035 }
1036
1037 fn deinit(&mut self) {
1038 let _ = SORTING_LIST.with(|| self.list.0.deinit());
1039 self.invalidate_sort();
1040 }
1041
1042 fn info(&mut self, info: &mut WidgetInfoBuilder) {
1043 self.list.0.info(info);
1044 }
1045
1046 fn update(&mut self, updates: &WidgetUpdates) {
1047 self.list.0.update(updates);
1048 }
1049
1050 fn update_list(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
1051 let mut changed = false;
1052 let (_, resort) = SORTING_LIST.with(|| self.list.0.update_list(updates, &mut changed));
1053 if changed || resort {
1054 self.invalidate_sort();
1055 observer.reset();
1056 }
1057 }
1058
1059 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
1060 self.list.0.measure(wm)
1061 }
1062
1063 fn measure_list(
1064 &mut self,
1065 wm: &mut WidgetMeasure,
1066 measure: &(dyn Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync),
1067 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
1068 ) -> PxSize {
1069 let mut acc = PxSize::zero();
1070 self.for_each_child(&mut |i, n| {
1071 let s = measure(i, n, wm);
1072 acc = fold_size(acc, s);
1073 });
1074 acc
1075 }
1076
1077 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
1078 self.list.0.layout(wl)
1079 }
1080
1081 fn layout_list(
1082 &mut self,
1083 wl: &mut WidgetLayout,
1084 layout: &(dyn Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync),
1085 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
1086 ) -> PxSize {
1087 let mut acc = PxSize::zero();
1088 self.for_each_child(&mut |i, n| {
1089 let s = layout(i, n, wl);
1090 acc = fold_size(acc, s);
1091 });
1092 acc
1093 }
1094
1095 fn render(&mut self, frame: &mut FrameBuilder) {
1096 self.for_each_child(&mut |_, n| n.render(frame));
1097 }
1098
1099 fn render_list(&mut self, frame: &mut FrameBuilder, render: &(dyn Fn(usize, &mut UiNode, &mut FrameBuilder) + Sync)) {
1100 self.for_each_child(&mut |i, n| render(i, n, frame));
1101 }
1102
1103 fn render_update(&mut self, update: &mut FrameUpdate) {
1104 self.list.0.render_update(update);
1105 }
1106
1107 fn render_update_list(&mut self, update: &mut FrameUpdate, render_update: &(dyn Fn(usize, &mut UiNode, &mut FrameUpdate) + Sync)) {
1108 self.list.0.render_update_list(update, render_update);
1109 }
1110
1111 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
1112 None
1113 }
1114}
1115
1116pub trait UiNodeListObserver {
1125 fn inserted(&mut self, index: usize);
1127 fn removed(&mut self, index: usize);
1129 fn moved(&mut self, removed_index: usize, inserted_index: usize);
1131 fn reset(&mut self);
1133
1134 fn is_reset_only(&self) -> bool;
1144}
1145impl UiNodeListObserver for () {
1147 fn is_reset_only(&self) -> bool {
1148 true
1149 }
1150
1151 fn reset(&mut self) {}
1152
1153 fn inserted(&mut self, _: usize) {}
1154
1155 fn removed(&mut self, _: usize) {}
1156
1157 fn moved(&mut self, _: usize, _: usize) {}
1158}
1159impl UiNodeListObserver for bool {
1161 fn is_reset_only(&self) -> bool {
1162 true
1163 }
1164
1165 fn reset(&mut self) {
1166 *self = true;
1167 }
1168
1169 fn inserted(&mut self, _: usize) {
1170 *self = true;
1171 }
1172
1173 fn removed(&mut self, _: usize) {
1174 *self = true;
1175 }
1176
1177 fn moved(&mut self, _: usize, _: usize) {
1178 *self = true;
1179 }
1180}
1181
1182pub struct OffsetUiListObserver<'o>(pub usize, pub &'o mut dyn UiNodeListObserver);
1186impl UiNodeListObserver for OffsetUiListObserver<'_> {
1187 fn is_reset_only(&self) -> bool {
1188 self.1.is_reset_only()
1189 }
1190
1191 fn reset(&mut self) {
1192 self.1.reset()
1193 }
1194
1195 fn inserted(&mut self, index: usize) {
1196 self.1.inserted(index + self.0)
1197 }
1198
1199 fn removed(&mut self, index: usize) {
1200 self.1.removed(index + self.0)
1201 }
1202
1203 fn moved(&mut self, removed_index: usize, inserted_index: usize) {
1204 self.1.moved(removed_index + self.0, inserted_index + self.0)
1205 }
1206}
1207
1208impl UiNodeListObserver for (&mut dyn UiNodeListObserver, &mut dyn UiNodeListObserver) {
1209 fn is_reset_only(&self) -> bool {
1210 self.0.is_reset_only() && self.1.is_reset_only()
1211 }
1212
1213 fn reset(&mut self) {
1214 self.0.reset();
1215 self.1.reset();
1216 }
1217
1218 fn inserted(&mut self, index: usize) {
1219 self.0.inserted(index);
1220 self.1.inserted(index);
1221 }
1222
1223 fn removed(&mut self, index: usize) {
1224 self.0.removed(index);
1225 self.1.removed(index);
1226 }
1227
1228 fn moved(&mut self, removed_index: usize, inserted_index: usize) {
1229 self.0.moved(removed_index, inserted_index);
1230 self.1.moved(removed_index, inserted_index);
1231 }
1232}
1233
1234pub struct EditableUiVec {
1236 vec: UiVec,
1237 ctrl: EditableUiVecRef,
1238}
1239impl Default for EditableUiVec {
1240 fn default() -> Self {
1241 Self {
1242 vec: ui_vec![],
1243 ctrl: EditableUiVecRef::new(true),
1244 }
1245 }
1246}
1247impl Drop for EditableUiVec {
1248 fn drop(&mut self) {
1249 self.ctrl.0.lock().alive = false;
1250 }
1251}
1252impl EditableUiVec {
1253 pub fn new() -> Self {
1255 Self::default()
1256 }
1257
1258 pub fn from_vec(vec: impl Into<UiVec>) -> Self {
1260 let mut s = Self::new();
1261 s.vec = vec.into();
1262 s
1263 }
1264
1265 pub fn reference(&self) -> EditableUiVecRef {
1267 self.ctrl.clone()
1268 }
1269
1270 pub fn chain(self, other: impl IntoUiNode) -> UiNode {
1274 self.into_node().chain(other)
1275 }
1276
1277 fn fulfill_requests(&mut self, observer: &mut dyn UiNodeListObserver) {
1278 if let Some(r) = self.ctrl.take_requests() {
1279 if r.clear {
1280 self.clear();
1282 observer.reset();
1283
1284 for (i, mut wgt) in r.insert {
1285 wgt.init();
1286 WIDGET.update_info();
1287 if i < self.len() {
1288 self.insert(i, wgt);
1289 } else {
1290 self.push(wgt);
1291 }
1292 }
1293 for mut wgt in r.push {
1294 wgt.init();
1295 WIDGET.update_info();
1296 self.push(wgt);
1297 }
1298 for (r, i) in r.move_index {
1299 if r < self.len() {
1300 let wgt = self.vec.remove(r);
1301
1302 if i < self.len() {
1303 self.vec.insert(i, wgt);
1304 } else {
1305 self.vec.push(wgt);
1306 }
1307
1308 WIDGET.update_info();
1309 }
1310 }
1311 for (id, to) in r.move_id {
1312 if let Some(r) = self.vec.iter_mut().position(|n| n.as_widget().map(|mut w| w.id()) == Some(id)) {
1313 let i = to(r, self.len());
1314
1315 if r != i {
1316 let wgt = self.vec.remove(r);
1317
1318 if i < self.len() {
1319 self.vec.insert(i, wgt);
1320 } else {
1321 self.vec.push(wgt);
1322 }
1323
1324 WIDGET.update_info();
1325 }
1326 }
1327 }
1328 } else {
1329 let mut removed = false;
1330 for mut retain in r.retain {
1331 let mut i = 0;
1332 self.vec.retain_mut(|n| {
1333 let r = retain(n);
1334 if !r {
1335 n.deinit();
1336 removed = true;
1337 observer.removed(i);
1338 } else {
1339 i += 1;
1340 }
1341 r
1342 });
1343 }
1344 if removed {
1345 WIDGET.update_info();
1346 }
1347
1348 for (i, mut wgt) in r.insert {
1349 wgt.init();
1350 WIDGET.update_info();
1351
1352 if i < self.len() {
1353 self.insert(i, wgt);
1354 observer.inserted(i);
1355 } else {
1356 observer.inserted(self.len());
1357 self.push(wgt);
1358 }
1359 }
1360
1361 for mut wgt in r.push {
1362 wgt.init();
1363 WIDGET.update_info();
1364
1365 observer.inserted(self.len());
1366 self.push(wgt);
1367 }
1368
1369 for (r, i) in r.move_index {
1370 if r < self.len() {
1371 let wgt = self.vec.remove(r);
1372
1373 if i < self.len() {
1374 self.vec.insert(i, wgt);
1375
1376 observer.moved(r, i);
1377 } else {
1378 let i = self.vec.len();
1379
1380 self.vec.push(wgt);
1381
1382 observer.moved(r, i);
1383 }
1384
1385 WIDGET.update_info();
1386 }
1387 }
1388
1389 for (id, to) in r.move_id {
1390 if let Some(r) = self.vec.iter_mut().position(|n| n.as_widget().map(|mut w| w.id()) == Some(id)) {
1391 let i = to(r, self.len());
1392
1393 if r != i {
1394 let wgt = self.vec.remove(r);
1395
1396 if i < self.len() {
1397 self.vec.insert(i, wgt);
1398 observer.moved(r, i);
1399 } else {
1400 let i = self.vec.len();
1401 self.vec.push(wgt);
1402 observer.moved(r, i);
1403 }
1404
1405 WIDGET.update_info();
1406 }
1407 }
1408 }
1409 }
1410 }
1411 }
1412}
1413impl ops::Deref for EditableUiVec {
1414 type Target = UiVec;
1415
1416 fn deref(&self) -> &Self::Target {
1417 &self.vec
1418 }
1419}
1420impl ops::DerefMut for EditableUiVec {
1421 fn deref_mut(&mut self) -> &mut Self::Target {
1422 &mut self.vec
1423 }
1424}
1425impl UiNodeImpl for EditableUiVec {
1426 fn children_len(&self) -> usize {
1427 self.vec.children_len()
1428 }
1429
1430 fn with_child(&mut self, index: usize, visitor: &mut dyn FnMut(&mut UiNode)) {
1431 self.vec.with_child(index, visitor);
1432 }
1433
1434 fn is_list(&self) -> bool {
1435 true
1436 }
1437
1438 fn for_each_child(&mut self, visitor: &mut dyn FnMut(usize, &mut UiNode)) {
1439 self.vec.for_each_child(visitor);
1440 }
1441
1442 fn try_for_each_child(
1443 &mut self,
1444 visitor: &mut dyn FnMut(usize, &mut UiNode) -> ControlFlow<BoxAnyVarValue>,
1445 ) -> ControlFlow<BoxAnyVarValue> {
1446 self.vec.try_for_each_child(visitor)
1447 }
1448
1449 fn par_each_child(&mut self, visitor: &(dyn Fn(usize, &mut UiNode) + Sync)) {
1450 self.vec.par_each_child(visitor);
1451 }
1452
1453 fn par_fold_reduce(
1454 &mut self,
1455 identity: BoxAnyVarValue,
1456 fold: &(dyn Fn(BoxAnyVarValue, usize, &mut UiNode) -> BoxAnyVarValue + Sync),
1457 reduce: &(dyn Fn(BoxAnyVarValue, BoxAnyVarValue) -> BoxAnyVarValue + Sync),
1458 ) -> BoxAnyVarValue {
1459 self.vec.par_fold_reduce(identity, fold, reduce)
1460 }
1461
1462 fn init(&mut self) {
1463 self.ctrl.0.lock().target = Some(WIDGET.id());
1464 self.vec.init();
1465 }
1466
1467 fn deinit(&mut self) {
1468 self.ctrl.0.lock().target = None;
1469 self.vec.deinit();
1470 }
1471
1472 fn info(&mut self, info: &mut WidgetInfoBuilder) {
1473 self.vec.info(info);
1474 }
1475
1476 fn update(&mut self, updates: &WidgetUpdates) {
1477 self.vec.update(updates);
1478 self.fulfill_requests(&mut ());
1479 }
1480
1481 fn update_list(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
1482 self.vec.update(updates);
1483 self.fulfill_requests(observer);
1484 }
1485
1486 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
1487 self.vec.measure(wm)
1488 }
1489
1490 fn measure_list(
1491 &mut self,
1492 wm: &mut WidgetMeasure,
1493 measure: &(dyn Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync),
1494 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
1495 ) -> PxSize {
1496 self.vec.measure_list(wm, measure, fold_size)
1497 }
1498
1499 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
1500 self.vec.layout(wl)
1501 }
1502
1503 fn layout_list(
1504 &mut self,
1505 wl: &mut WidgetLayout,
1506 layout: &(dyn Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync),
1507 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
1508 ) -> PxSize {
1509 self.vec.layout_list(wl, layout, fold_size)
1510 }
1511
1512 fn render(&mut self, frame: &mut FrameBuilder) {
1513 self.vec.render(frame);
1514 }
1515
1516 fn render_list(&mut self, frame: &mut FrameBuilder, render: &(dyn Fn(usize, &mut UiNode, &mut FrameBuilder) + Sync)) {
1517 self.vec.render_list(frame, render);
1518 }
1519
1520 fn render_update(&mut self, update: &mut FrameUpdate) {
1521 self.vec.render_update(update);
1522 }
1523
1524 fn render_update_list(&mut self, update: &mut FrameUpdate, render_update: &(dyn Fn(usize, &mut UiNode, &mut FrameUpdate) + Sync)) {
1525 self.vec.render_update_list(update, render_update);
1526 }
1527
1528 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
1529 None
1530 }
1531}
1532
1533type NodeMoveToFn = fn(usize, usize) -> usize;
1535
1536#[derive(Clone, Debug)]
1538pub struct EditableUiVecRef(Arc<Mutex<EditRequests>>);
1539struct EditRequests {
1540 target: Option<WidgetId>,
1541 insert: Vec<(usize, UiNode)>,
1542 push: Vec<UiNode>,
1543 retain: Vec<Box<dyn FnMut(&mut UiNode) -> bool + Send>>,
1544 move_index: Vec<(usize, usize)>,
1545 move_id: Vec<(WidgetId, NodeMoveToFn)>,
1546 clear: bool,
1547
1548 alive: bool,
1549}
1550impl fmt::Debug for EditRequests {
1551 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1552 f.debug_struct("EditRequests")
1553 .field("target", &self.target)
1554 .field("insert.len", &self.insert.len())
1555 .field("push.len", &self.push.len())
1556 .field("retain.len", &self.retain.len())
1557 .field("move_index", &self.move_index)
1558 .field("move_id", &self.move_id)
1559 .field("clear", &self.clear)
1560 .field("alive", &self.alive)
1561 .finish()
1562 }
1563}
1564impl EditableUiVecRef {
1565 fn new(alive: bool) -> Self {
1566 Self(Arc::new(Mutex::new(EditRequests {
1567 target: None,
1568 insert: vec![],
1569 push: vec![],
1570 retain: vec![],
1571 move_index: vec![],
1572 move_id: vec![],
1573 clear: false,
1574 alive,
1575 })))
1576 }
1577
1578 pub fn dummy() -> Self {
1584 Self::new(false)
1585 }
1586
1587 pub fn alive(&self) -> bool {
1589 self.0.lock().alive
1590 }
1591
1592 pub fn insert(&self, index: usize, widget: impl IntoUiNode) {
1600 self.insert_impl(index, widget.into_node());
1601 }
1602 fn insert_impl(&self, index: usize, widget: UiNode) {
1603 let mut s = self.0.lock();
1604 if !s.alive {
1605 return;
1606 }
1607 s.insert.push((index, widget));
1608 if let Some(id) = s.target {
1609 UPDATES.update(id);
1610 }
1611 }
1612
1613 pub fn push(&self, widget: impl IntoUiNode) {
1621 self.push_impl(widget.into_node());
1622 }
1623 fn push_impl(&self, widget: UiNode) {
1624 let mut s = self.0.lock();
1625 if !s.alive {
1626 return;
1627 }
1628 s.push.push(widget);
1629 if let Some(id) = s.target {
1630 UPDATES.update(id);
1631 }
1632 }
1633
1634 pub fn remove(&self, id: impl Into<WidgetId>) {
1639 fn rmv_retain(id: WidgetId) -> impl FnMut(&mut UiNode) -> bool + Send + 'static {
1640 move |node| {
1641 match node.as_widget() {
1642 Some(mut wgt) => wgt.id() != id,
1643 None => true, }
1645 }
1646 }
1647 self.retain(rmv_retain(id.into()))
1648 }
1649
1650 pub fn retain(&self, predicate: impl FnMut(&mut UiNode) -> bool + Send + 'static) {
1656 let mut s = self.0.lock();
1657 if !s.alive {
1658 return;
1659 }
1660 s.retain.push(Box::new(predicate));
1661 if let Some(id) = s.target {
1662 UPDATES.update(id);
1663 }
1664 }
1665
1666 pub fn move_index(&self, remove_index: usize, insert_index: usize) {
1673 if remove_index != insert_index {
1674 let mut s = self.0.lock();
1675 if !s.alive {
1676 return;
1677 }
1678 s.move_index.push((remove_index, insert_index));
1679 if let Some(id) = s.target {
1680 UPDATES.update(id);
1681 }
1682 }
1683 }
1684
1685 pub fn move_id(&self, id: impl Into<WidgetId>, get_move_to: NodeMoveToFn) {
1725 let mut s = self.0.lock();
1726 if !s.alive {
1727 return;
1728 }
1729 s.move_id.push((id.into(), get_move_to));
1730 if let Some(id) = s.target {
1731 UPDATES.update(id);
1732 }
1733 }
1734
1735 pub fn clear(&self) {
1739 let mut s = self.0.lock();
1740 s.clear = true;
1741 if let Some(id) = s.target {
1742 UPDATES.update(id);
1743 }
1744 }
1745
1746 fn take_requests(&self) -> Option<EditRequests> {
1747 let mut s = self.0.lock();
1748
1749 if s.clear
1750 || !s.insert.is_empty()
1751 || !s.push.is_empty()
1752 || !s.retain.is_empty()
1753 || !s.move_index.is_empty()
1754 || !s.move_id.is_empty()
1755 {
1756 let empty = EditRequests {
1757 target: s.target,
1758 alive: s.alive,
1759
1760 insert: vec![],
1761 push: vec![],
1762 retain: vec![],
1763 move_index: vec![],
1764 move_id: vec![],
1765 clear: false,
1766 };
1767 Some(mem::replace(&mut *s, empty))
1768 } else {
1769 None
1770 }
1771 }
1772}
1773
1774static_id! {
1775 static ref Z_INDEX_ID: StateId<ZIndex>;
1776}
1777
1778#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Transitionable)]
1792pub struct ZIndex(u32);
1793impl ZIndex {
1794 pub const BACK: ZIndex = ZIndex(0);
1798
1799 pub const DEFAULT: ZIndex = ZIndex(u32::MAX / 2);
1803
1804 pub const FRONT: ZIndex = ZIndex(u32::MAX);
1806
1807 pub fn saturating_add(self, other: impl Into<Self>) -> Self {
1813 ZIndex(self.0.saturating_add(other.into().0))
1814 }
1815
1816 pub fn saturating_sub(self, other: impl Into<Self>) -> Self {
1822 ZIndex(self.0.saturating_sub(other.into().0))
1823 }
1824}
1825impl Default for ZIndex {
1826 fn default() -> Self {
1827 ZIndex::DEFAULT
1828 }
1829}
1830impl<Z: Into<ZIndex>> ops::Add<Z> for ZIndex {
1831 type Output = Self;
1832
1833 fn add(self, rhs: Z) -> Self::Output {
1834 self.saturating_add(rhs)
1835 }
1836}
1837impl<Z: Into<ZIndex>> ops::AddAssign<Z> for ZIndex {
1838 fn add_assign(&mut self, rhs: Z) {
1839 *self = *self + rhs;
1840 }
1841}
1842impl<Z: Into<ZIndex>> ops::Sub<Z> for ZIndex {
1843 type Output = Self;
1844
1845 fn sub(self, rhs: Z) -> Self::Output {
1846 self.saturating_sub(rhs)
1847 }
1848}
1849impl<Z: Into<ZIndex>> ops::SubAssign<Z> for ZIndex {
1850 fn sub_assign(&mut self, rhs: Z) {
1851 *self = *self - rhs;
1852 }
1853}
1854impl ops::Mul<Factor> for ZIndex {
1855 type Output = Self;
1856
1857 fn mul(self, rhs: Factor) -> Self::Output {
1858 ZIndex(self.0 * rhs)
1859 }
1860}
1861impl ops::Div<Factor> for ZIndex {
1862 type Output = Self;
1863
1864 fn div(self, rhs: Factor) -> Self::Output {
1865 ZIndex(self.0 / rhs)
1866 }
1867}
1868impl ops::MulAssign<Factor> for ZIndex {
1869 fn mul_assign(&mut self, rhs: Factor) {
1870 self.0 *= rhs;
1871 }
1872}
1873impl ops::DivAssign<Factor> for ZIndex {
1874 fn div_assign(&mut self, rhs: Factor) {
1875 self.0 /= rhs;
1876 }
1877}
1878impl fmt::Debug for ZIndex {
1879 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1880 let z = *self;
1881 if f.alternate() {
1882 write!(f, "ZIndex::")?;
1883 }
1884
1885 if z == Self::DEFAULT {
1886 write!(f, "DEFAULT")
1887 } else if z == Self::BACK {
1888 write!(f, "BACK")
1889 } else if z == Self::FRONT {
1890 write!(f, "FRONT")
1891 } else if z > Self::DEFAULT {
1892 if z > Self::FRONT - 10000 {
1893 write!(f, "FRONT-{}", Self::FRONT.0 - z.0)
1894 } else {
1895 write!(f, "DEFAULT+{}", z.0 - Self::DEFAULT.0)
1896 }
1897 } else if z < Self::BACK + 10000 {
1898 write!(f, "BACK+{}", z.0 - Self::BACK.0)
1899 } else {
1900 write!(f, "DEFAULT-{}", Self::DEFAULT.0 - z.0)
1901 }
1902 }
1903}
1904impl_from_and_into_var! {
1905 fn from(index: u32) -> ZIndex {
1906 ZIndex(index)
1907 }
1908 fn from(index: ZIndex) -> u32 {
1909 index.0
1910 }
1911 fn from(index: ZIndex) -> Option<ZIndex>;
1912}
1913#[derive(Default, Debug)]
1914struct ZIndexCtx {
1915 panel_id: Option<WidgetId>,
1917 resort: AtomicBool,
1919}
1920context_local! {
1921 static Z_INDEX_CTX: ZIndexCtx = ZIndexCtx::default();
1922}
1923#[expect(non_camel_case_types)]
1925pub struct Z_INDEX;
1926impl Z_INDEX {
1927 fn with(&self, panel_id: WidgetId, action: impl FnOnce()) -> bool {
1928 let ctx = ZIndexCtx {
1929 panel_id: Some(panel_id),
1930 resort: AtomicBool::new(false),
1931 };
1932 Z_INDEX_CTX.with_context(&mut Some(Arc::new(ctx)), || {
1933 action();
1934 Z_INDEX_CTX.get().resort.load(Relaxed)
1935 })
1936 }
1937
1938 pub fn get(&self) -> ZIndex {
1942 WIDGET.get_state(*Z_INDEX_ID).unwrap_or_default()
1943 }
1944
1945 pub fn get_wgt(&self, widget: &mut UiNode) -> ZIndex {
1949 match widget.as_widget() {
1950 Some(mut w) => w.with_context(WidgetUpdateMode::Ignore, || self.get()),
1951 None => ZIndex::DEFAULT,
1952 }
1953 }
1954
1955 pub fn set(&self, index: ZIndex) -> bool {
1963 let z_ctx = Z_INDEX_CTX.get();
1964 let valid = z_ctx.panel_id == WIDGET.parent_id() && z_ctx.panel_id.is_some();
1965 if valid {
1966 z_ctx.resort.store(true, Relaxed);
1967 WIDGET.set_state(*Z_INDEX_ID, index);
1968 }
1969 valid
1970 }
1971}
1972
1973#[derive(Debug, Clone)]
1975pub struct PanelListRange {
1976 range: Option<(WidgetId, WidgetId)>,
1978 version: u8,
1979}
1980impl PanelListRange {
1981 pub fn update(
1986 parent: &WidgetInfo,
1987 panel_id: impl Into<StateId<Self>>,
1988 last_version: &mut Option<u8>,
1989 ) -> Option<crate::widget::info::iter::Children> {
1990 let range = parent.meta().get_clone(panel_id);
1991 if let Some(Self { range, version }) = range {
1992 let version = Some(version);
1993 if *last_version != version {
1994 *last_version = version;
1995
1996 if let Some((s, e)) = range {
1997 let tree = parent.tree();
1998 if let Some(s) = tree.get(s)
1999 && let Some(e) = tree.get(e)
2000 {
2001 let parent = Some(parent);
2002 if s.parent().as_ref() == parent && e.parent().as_ref() == parent {
2003 return Some(crate::widget::info::iter::Children::new_range(s, e));
2004 }
2005 }
2006 }
2007 }
2008 }
2009 None
2010 }
2011
2012 pub fn get(parent: &WidgetInfo, panel_id: impl Into<StateId<Self>>) -> Option<crate::widget::info::iter::Children> {
2014 let range = parent.meta().get_clone(panel_id);
2015 if let Some(Self { range: Some((s, e)), .. }) = range {
2016 let tree = parent.tree();
2017 if let Some(s) = tree.get(s)
2018 && let Some(e) = tree.get(e)
2019 {
2020 let parent = Some(parent);
2021 if s.parent().as_ref() == parent && e.parent().as_ref() == parent {
2022 return Some(crate::widget::info::iter::Children::new_range(s, e));
2023 }
2024 }
2025 }
2026 None
2027 }
2028}
2029
2030pub struct PanelList<D = DefaultPanelListData>
2045where
2046 D: PanelListData,
2047{
2048 list: UiNode,
2049 data: Vec<Mutex<D>>, offset_key: FrameValueKey<PxTransform>,
2052 info_id: Option<(StateId<PanelListRange>, u8, bool)>,
2053
2054 z_map: Vec<u64>,
2055 z_naturally_sorted: bool,
2056}
2057impl PanelList<DefaultPanelListData> {
2058 pub fn new(list: impl IntoUiNode) -> Self {
2060 Self::new_custom(list)
2061 }
2062}
2063
2064impl<D> PanelList<D>
2065where
2066 D: PanelListData,
2067{
2068 pub fn new_custom(list: impl IntoUiNode) -> Self {
2070 Self::new_custom_impl(list.into_node())
2071 }
2072 fn new_custom_impl(list: UiNode) -> Self {
2073 let list = list.into_list();
2074 Self {
2075 data: {
2076 let mut d = vec![];
2077 d.resize_with(list.children_len(), Default::default);
2078 d
2079 },
2080 list,
2081 offset_key: FrameValueKey::new_unique(),
2082 info_id: None,
2083 z_map: vec![],
2084 z_naturally_sorted: false,
2085 }
2086 }
2087
2088 pub fn track_info_range(mut self, info_id: impl Into<StateId<PanelListRange>>) -> Self {
2094 self.info_id = Some((info_id.into(), 0, true));
2095 self
2096 }
2097
2098 pub fn into_parts(self) -> (UiNode, Vec<Mutex<D>>, FrameValueKey<PxTransform>, Option<StateId<PanelListRange>>) {
2100 (self.list, self.data, self.offset_key, self.info_id.map(|t| t.0))
2101 }
2102
2103 pub fn from_parts(
2109 list: UiNode,
2110 data: Vec<Mutex<D>>,
2111 offset_key: FrameValueKey<PxTransform>,
2112 info_id: Option<StateId<PanelListRange>>,
2113 ) -> Self {
2114 assert!(list.is_list());
2115 assert_eq!(list.children_len(), data.len());
2116 Self {
2117 list,
2118 data,
2119 offset_key,
2120 info_id: info_id.map(|i| (i, 0, true)),
2121 z_map: vec![],
2122 z_naturally_sorted: false,
2123 }
2124 }
2125
2126 pub fn info_id(&self) -> Option<StateId<PanelListRange>> {
2130 self.info_id.as_ref().map(|t| t.0)
2131 }
2132
2133 pub fn with_child<R>(&mut self, index: usize, visitor: impl FnOnce(&mut UiNode, &mut D) -> R) -> R {
2137 let data = self.data[index].get_mut();
2138 self.list.with_child(index, |u| visitor(u, data))
2139 }
2140
2141 pub fn for_each_child(&mut self, mut visitor: impl FnMut(usize, &mut UiNode, &mut D)) {
2145 let data = &mut self.data;
2146 self.list.for_each_child(|i, u| visitor(i, u, data[i].get_mut()));
2147 }
2148
2149 pub fn try_for_each_child<B: zng_var::VarValue>(
2153 &mut self,
2154 visitor: &mut dyn FnMut(usize, &mut UiNode, &mut D) -> ControlFlow<B>,
2155 ) -> ControlFlow<B> {
2156 let data = &mut self.data;
2157 self.list.try_for_each_child(|i, u| visitor(i, u, data[i].get_mut()))
2158 }
2159
2160 pub fn par_each_child(&mut self, visitor: impl Fn(usize, &mut UiNode, &mut D) + Sync)
2164 where
2165 D: Sync,
2166 {
2167 let data = &self.data;
2168 self.list.par_each_child(|i, u| {
2169 visitor(
2170 i,
2171 u,
2172 &mut *data[i].try_lock().expect("par_each_child called visitor twice on same index"),
2173 )
2174 });
2175 }
2176
2177 pub fn par_fold_reduce<T>(
2184 &mut self,
2185 identity: T,
2186 fold: impl Fn(T, usize, &mut UiNode, &mut D) -> T + Sync,
2187 reduce: impl Fn(T, T) -> T + Send + Sync,
2188 ) -> T
2189 where
2190 T: zng_var::VarValue,
2191 {
2192 let data = &self.data;
2193 self.list.par_fold_reduce(
2194 identity,
2195 |acc, i, n| {
2196 fold(
2197 acc,
2198 i,
2199 n,
2200 &mut *data[i].try_lock().expect("par_fold_reduce called visitor twice on same index"),
2201 )
2202 },
2203 reduce,
2204 )
2205 }
2206
2207 pub fn measure_list(
2209 &mut self,
2210 wm: &mut WidgetMeasure,
2211 measure: impl Fn(usize, &mut UiNode, &mut D, &mut WidgetMeasure) -> PxSize + Sync,
2212 fold_size: impl Fn(PxSize, PxSize) -> PxSize + Sync,
2213 ) -> PxSize {
2214 let data = &self.data;
2215 self.list.measure_list(
2216 wm,
2217 |i, n, wm| {
2218 measure(
2219 i,
2220 n,
2221 &mut *data[i].try_lock().expect("measure_list called visitor twice on same index"),
2222 wm,
2223 )
2224 },
2225 fold_size,
2226 )
2227 }
2228
2229 pub fn layout_list(
2231 &mut self,
2232 wl: &mut WidgetLayout,
2233 layout: impl Fn(usize, &mut UiNode, &mut D, &mut WidgetLayout) -> PxSize + Sync,
2234 fold_size: impl Fn(PxSize, PxSize) -> PxSize + Sync,
2235 ) -> PxSize {
2236 let data = &self.data;
2237 self.list.layout_list(
2238 wl,
2239 |i, n, wl| {
2240 layout(
2241 i,
2242 n,
2243 &mut *data[i].try_lock().expect("layout_list called visitor twice on same index"),
2244 wl,
2245 )
2246 },
2247 fold_size,
2248 )
2249 }
2250
2251 pub fn render_list(&mut self, frame: &mut FrameBuilder, render: impl Fn(usize, &mut UiNode, &mut D, &mut FrameBuilder) + Sync) {
2255 let offset_key = self.offset_key;
2256
2257 if self.z_naturally_sorted {
2258 let data = &self.data;
2259 self.list.render_list(frame, |i, child, frame| {
2260 let mut data = data[i].try_lock().expect("render_list called visitor twice on same index");
2261 let offset = data.child_offset();
2262 if data.define_reference_frame() {
2263 frame.push_reference_frame(
2264 (offset_key, i as u32).into(),
2265 offset_key.bind_child(i as u32, offset.into(), false),
2266 true,
2267 true,
2268 |frame| render(i, child, &mut *data, frame),
2269 );
2270 } else {
2271 frame.push_child(offset, |frame| render(i, child, &mut *data, frame));
2272 }
2273 });
2274 } else {
2275 self.for_each_z_sorted(|i, child, data| {
2276 let offset = data.child_offset();
2277 if data.define_reference_frame() {
2278 frame.push_reference_frame(
2279 (offset_key, i as u32).into(),
2280 offset_key.bind_child(i as u32, offset.into(), false),
2281 true,
2282 true,
2283 |frame| render(i, child, data, frame),
2284 );
2285 } else {
2286 frame.push_child(offset, |frame| render(i, child, data, frame));
2287 }
2288 });
2289 }
2290 }
2291
2292 pub fn render_update_list(
2296 &mut self,
2297 update: &mut FrameUpdate,
2298 render_update: impl Fn(usize, &mut UiNode, &mut D, &mut FrameUpdate) + Sync,
2299 ) {
2300 let offset_key = self.offset_key;
2301 let data = &self.data;
2302 self.list.render_update_list(update, |i, n, update| {
2303 let mut data = data[i].try_lock().expect("render_update_list called visitor twice on same index");
2304
2305 let offset = data.child_offset();
2306 if data.define_reference_frame() {
2307 update.with_transform(offset_key.update_child(i as u32, offset.into(), false), true, |update| {
2308 render_update(i, n, &mut *data, update);
2309 });
2310 } else {
2311 update.with_child(offset, |update| {
2312 render_update(i, n, &mut *data, update);
2313 });
2314 }
2315 });
2316 }
2317
2318 pub fn for_each_z_sorted(&mut self, mut visitor: impl FnMut(usize, &mut UiNode, &mut D)) {
2320 if self.z_naturally_sorted {
2321 self.for_each_child(visitor)
2322 } else {
2323 if self.z_map.len() != self.list.children_len() {
2324 self.z_sort();
2325 }
2326
2327 if self.z_naturally_sorted {
2328 self.for_each_child(visitor);
2329 } else {
2330 for &index in self.z_map.iter() {
2331 let index = index as usize;
2332 let data = self.data[index].get_mut();
2333 self.list.with_child(index, |node| visitor(index, node, data));
2334 }
2335 }
2336 }
2337 }
2338
2339 fn z_sort(&mut self) {
2340 let len = self.list.children_len();
2354 assert!(len <= u32::MAX as usize);
2355
2356 let mut prev_z = ZIndex::BACK;
2357 let mut need_map = false;
2358 let mut z_and_i = Vec::with_capacity(len);
2359 let mut has_non_default_zs = false;
2360
2361 self.list.for_each_child(|i, node| {
2362 let z = Z_INDEX.get_wgt(node);
2363 z_and_i.push(((z.0 as u64) << 32) | i as u64);
2364
2365 need_map |= z < prev_z;
2366 has_non_default_zs |= z != ZIndex::DEFAULT;
2367 prev_z = z;
2368 });
2369
2370 self.z_naturally_sorted = !need_map;
2371
2372 if need_map {
2373 z_and_i.sort_unstable();
2374
2375 for z in &mut z_and_i {
2376 *z &= u32::MAX as u64;
2377 }
2378
2379 self.z_map = z_and_i;
2380 } else {
2381 self.z_map.clear();
2382 }
2383 }
2384
2385 pub fn z_map(&mut self, index: usize) -> usize {
2387 if self.z_naturally_sorted {
2388 return index;
2389 }
2390
2391 if self.z_map.len() != self.list.children_len() {
2392 self.z_sort();
2393 }
2394
2395 if self.z_naturally_sorted {
2396 return index;
2397 }
2398
2399 self.z_map[index] as usize
2400 }
2401
2402 pub fn data(&mut self, index: usize) -> &mut D {
2404 self.data[index].get_mut()
2405 }
2406
2407 pub fn commit_data(&mut self) -> PanelListDataChanges {
2415 let mut changes = PanelListDataChanges::empty();
2416 for data in self.data.iter_mut() {
2417 changes |= data.get_mut().commit();
2418 }
2419 changes
2420 }
2421
2422 pub fn offset_key(&self) -> FrameValueKey<PxTransform> {
2426 self.offset_key
2427 }
2428}
2429impl<D> UiNodeImpl for PanelList<D>
2430where
2431 D: PanelListData,
2432{
2433 fn children_len(&self) -> usize {
2434 self.list.0.children_len()
2435 }
2436
2437 fn with_child(&mut self, index: usize, visitor: &mut dyn FnMut(&mut UiNode)) {
2438 self.list.0.with_child(index, visitor)
2439 }
2440
2441 fn is_list(&self) -> bool {
2442 true
2443 }
2444
2445 fn for_each_child(&mut self, visitor: &mut dyn FnMut(usize, &mut UiNode)) {
2446 self.list.0.for_each_child(visitor);
2447 }
2448
2449 fn try_for_each_child(
2450 &mut self,
2451 visitor: &mut dyn FnMut(usize, &mut UiNode) -> ControlFlow<BoxAnyVarValue>,
2452 ) -> ControlFlow<BoxAnyVarValue> {
2453 self.list.0.try_for_each_child(visitor)
2454 }
2455
2456 fn par_each_child(&mut self, visitor: &(dyn Fn(usize, &mut UiNode) + Sync)) {
2457 self.list.0.par_each_child(visitor);
2458 }
2459
2460 fn par_fold_reduce(
2461 &mut self,
2462 identity: BoxAnyVarValue,
2463 fold: &(dyn Fn(BoxAnyVarValue, usize, &mut UiNode) -> BoxAnyVarValue + Sync),
2464 reduce: &(dyn Fn(BoxAnyVarValue, BoxAnyVarValue) -> BoxAnyVarValue + Sync),
2465 ) -> BoxAnyVarValue {
2466 self.list.0.par_fold_reduce(identity, fold, reduce)
2467 }
2468
2469 fn init(&mut self) {
2470 fn init_impl(z_map: &mut Vec<u64>, list: &mut UiNode) -> bool {
2471 z_map.clear();
2472 Z_INDEX.with(WIDGET.id(), || list.0.init())
2473 }
2474 let resort = init_impl(&mut self.z_map, &mut self.list);
2475 self.z_naturally_sorted = !resort;
2476 self.data.resize_with(self.list.0.children_len(), Default::default);
2477 }
2478
2479 fn deinit(&mut self) {
2480 self.list.deinit();
2481 }
2482
2483 fn info(&mut self, info: &mut WidgetInfoBuilder) {
2484 fn info_impl(list: &mut UiNode, info_id: &mut Option<(StateId<PanelListRange>, u8, bool)>, info: &mut WidgetInfoBuilder) {
2485 let len = list.0.children_len();
2486 if len == 0 {
2487 return;
2488 }
2489
2490 list.0.info(info);
2491
2492 if let Some((id, version, pump_update)) = info_id {
2493 let start = list.with_child(0, |c| c.as_widget().map(|mut w| w.id()));
2494 let end = list.with_child(len - 1, |c| c.as_widget().map(|mut w| w.id()));
2495 let range = match (start, end) {
2496 (Some(s), Some(e)) => Some((s, e)),
2497 _ => None,
2498 };
2499 info.set_meta(*id, PanelListRange { range, version: *version });
2500
2501 if mem::take(pump_update) {
2502 list.for_each_child(|_, c| {
2503 if let Some(mut w) = c.as_widget() {
2504 w.with_context(WidgetUpdateMode::Bubble, || WIDGET.update());
2505 }
2506 });
2507 }
2508 }
2509 }
2510 info_impl(&mut self.list, &mut self.info_id, info);
2511 }
2512
2513 fn update(&mut self, updates: &WidgetUpdates) {
2514 self.update_list(updates, &mut ());
2515 }
2516
2517 fn update_list(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
2518 let mut observer = PanelObserver {
2519 changed: false,
2520 data: &mut self.data,
2521 observer,
2522 };
2523 fn update_list_impl(list: &mut UiNode, observer: &mut dyn UiNodeListObserver, updates: &WidgetUpdates) -> bool {
2524 Z_INDEX.with(WIDGET.id(), || list.0.update_list(updates, observer))
2525 }
2526 let resort = update_list_impl(&mut self.list, &mut observer, updates);
2527
2528 fn update_list_after(
2529 observer_changed: bool,
2530 resort: bool,
2531 z_naturally_sorted: &mut bool,
2532 info_id: &mut Option<(StateId<PanelListRange>, u8, bool)>,
2533 z_map: &mut Vec<u64>,
2534 ) {
2535 if resort || (observer_changed && *z_naturally_sorted) {
2536 z_map.clear();
2537 *z_naturally_sorted = false;
2538 WIDGET.render();
2539 }
2540
2541 if observer_changed && let Some((_, v, u)) = info_id {
2542 if !*u {
2543 *v = v.wrapping_add(1);
2544 *u = true;
2545 }
2546 WIDGET.update_info();
2547 }
2548 }
2549 update_list_after(
2550 observer.changed,
2551 resort,
2552 &mut self.z_naturally_sorted,
2553 &mut self.info_id,
2554 &mut self.z_map,
2555 );
2556
2557 self.data.resize_with(self.list.children_len(), Default::default);
2558 }
2559
2560 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
2561 self.list.measure(wm)
2562 }
2563
2564 fn measure_list(
2565 &mut self,
2566 wm: &mut WidgetMeasure,
2567 measure: &(dyn Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync),
2568 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
2569 ) -> PxSize {
2570 self.list.measure_list(wm, measure, fold_size)
2571 }
2572
2573 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
2574 self.list.layout(wl)
2575 }
2576
2577 fn layout_list(
2578 &mut self,
2579 wl: &mut WidgetLayout,
2580 layout: &(dyn Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync),
2581 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
2582 ) -> PxSize {
2583 self.list.layout_list(wl, layout, fold_size)
2584 }
2585
2586 fn render(&mut self, frame: &mut FrameBuilder) {
2587 self.render_list(frame, |_, n, _, frame| n.render(frame));
2588 }
2589
2590 fn render_update(&mut self, update: &mut FrameUpdate) {
2591 self.render_update_list(update, |_, n, _, update| n.render_update(update));
2592 }
2593
2594 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
2595 self.list.0.as_widget()
2596 }
2597}
2598
2599bitflags::bitflags! {
2600 #[must_use = "|= with other item changes, call request_render"]
2602 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
2603 #[serde(transparent)]
2604 pub struct PanelListDataChanges: u8 {
2605 const CHILD_OFFSET = 0b01;
2607 const DEFINE_REFERENCE_FRAME = 0b10;
2609 }
2610}
2611impl PanelListDataChanges {
2612 pub fn request_render(self) {
2614 if self.contains(Self::DEFINE_REFERENCE_FRAME) {
2615 WIDGET.render();
2616 } else if self.contains(Self::CHILD_OFFSET) {
2617 WIDGET.render_update();
2618 }
2619 }
2620}
2621
2622#[derive(Clone, Debug, Default)]
2624pub struct DefaultPanelListData {
2625 pub child_offset: PxVector,
2627 pub define_reference_frame: bool,
2629
2630 prev_child_offset: PxVector,
2631 prev_define_reference_frame: bool,
2632}
2633impl PanelListData for DefaultPanelListData {
2634 fn child_offset(&self) -> PxVector {
2635 self.child_offset
2636 }
2637
2638 fn define_reference_frame(&self) -> bool {
2639 self.define_reference_frame
2640 }
2641
2642 fn commit(&mut self) -> PanelListDataChanges {
2643 let mut changes = PanelListDataChanges::empty();
2644 if self.define_reference_frame != self.prev_define_reference_frame {
2645 changes |= PanelListDataChanges::DEFINE_REFERENCE_FRAME;
2646 }
2647 if self.child_offset != self.prev_child_offset {
2648 changes |= PanelListDataChanges::CHILD_OFFSET;
2649 }
2650 self.prev_define_reference_frame = self.define_reference_frame;
2651 self.prev_child_offset = self.child_offset;
2652 changes
2653 }
2654}
2655
2656pub trait PanelListData: Default + Send + Any {
2658 fn child_offset(&self) -> PxVector;
2660
2661 fn define_reference_frame(&self) -> bool;
2663
2664 fn commit(&mut self) -> PanelListDataChanges;
2668}
2669impl PanelListData for () {
2670 fn child_offset(&self) -> PxVector {
2671 PxVector::zero()
2672 }
2673
2674 fn define_reference_frame(&self) -> bool {
2675 false
2676 }
2677
2678 fn commit(&mut self) -> PanelListDataChanges {
2679 PanelListDataChanges::empty()
2680 }
2681}
2682
2683struct PanelObserver<'d, D>
2684where
2685 D: PanelListData,
2686{
2687 changed: bool,
2688 data: &'d mut Vec<Mutex<D>>,
2689 observer: &'d mut dyn UiNodeListObserver,
2690}
2691impl<D> UiNodeListObserver for PanelObserver<'_, D>
2692where
2693 D: PanelListData,
2694{
2695 fn is_reset_only(&self) -> bool {
2696 false
2697 }
2698
2699 fn reset(&mut self) {
2700 self.changed = true;
2701 self.data.clear();
2702 self.observer.reset();
2703 }
2704
2705 fn inserted(&mut self, index: usize) {
2706 self.changed = true;
2707 self.data.insert(index, Default::default());
2708 self.observer.inserted(index);
2709 }
2710
2711 fn removed(&mut self, index: usize) {
2712 self.changed = true;
2713 self.data.remove(index);
2714 self.observer.removed(index);
2715 }
2716
2717 fn moved(&mut self, removed_index: usize, inserted_index: usize) {
2718 self.changed = true;
2719 let item = self.data.remove(removed_index);
2720 self.data.insert(inserted_index, item);
2721 self.observer.moved(removed_index, inserted_index);
2722 }
2723}