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