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::{EventUpdate, 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 event(&mut self, update: &EventUpdate) {
305 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::EVENT) {
306 self.par_iter_mut().with_ctx().for_each(|n| n.event(update));
307 } else {
308 self.iter_mut().for_each(|n| n.event(update));
309 }
310 }
311
312 fn update(&mut self, updates: &WidgetUpdates) {
313 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::UPDATE) {
314 self.par_iter_mut().with_ctx().for_each(|n| n.update(updates));
315 } else {
316 self.iter_mut().for_each(|n| n.update(updates));
317 }
318 }
319 fn update_list(&mut self, updates: &WidgetUpdates, _: &mut dyn UiNodeListObserver) {
320 self.update(updates);
321 }
322
323 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
324 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::LAYOUT) {
325 let (b, desired_size) = self
326 .par_iter_mut()
327 .with_ctx()
328 .fold(
329 || (wm.parallel_split(), PxSize::zero()),
330 |(mut wm, desired_size), n| {
331 let n_ds = n.measure(&mut wm);
332 (wm, desired_size.max(n_ds))
333 },
334 )
335 .reduce(
336 || (wm.parallel_split(), PxSize::zero()),
337 |(mut wm, desired_size), (b_wm, b_ds)| {
338 wm.parallel_fold(b_wm);
339 (wm, desired_size.max(b_ds))
340 },
341 );
342 wm.parallel_fold(b);
343 desired_size
344 } else {
345 let mut desired_size = PxSize::zero();
346 self.iter_mut().for_each(|n| desired_size = desired_size.max(n.measure(wm)));
347 desired_size
348 }
349 }
350
351 fn measure_list(
352 &mut self,
353 wm: &mut WidgetMeasure,
354 measure: &(dyn Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync),
355 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
356 ) -> PxSize {
357 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::LAYOUT) {
358 let (b, desired_size) = self
359 .par_iter_mut()
360 .enumerate()
361 .with_ctx()
362 .fold(
363 || (wm.parallel_split(), PxSize::zero()),
364 |(mut wm, desired_size), (i, n)| {
365 let n_ds = measure(i, n, &mut wm);
366 (wm, fold_size(desired_size, n_ds))
367 },
368 )
369 .reduce(
370 || (wm.parallel_split(), PxSize::zero()),
371 |(mut wm, desired_size), (b_wm, b_ds)| {
372 wm.parallel_fold(b_wm);
373 (wm, fold_size(desired_size, b_ds))
374 },
375 );
376 wm.parallel_fold(b);
377 desired_size
378 } else {
379 let mut desired_size = PxSize::zero();
380 self.iter_mut()
381 .enumerate()
382 .for_each(|(i, n)| desired_size = fold_size(desired_size, measure(i, n, wm)));
383 desired_size
384 }
385 }
386
387 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
388 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::LAYOUT) {
389 let (b, final_size) = self
390 .par_iter_mut()
391 .with_ctx()
392 .fold(
393 || (wl.parallel_split(), PxSize::zero()),
394 |(mut wl, final_size), n| {
395 let n_ds = n.layout(&mut wl);
396 (wl, final_size.max(n_ds))
397 },
398 )
399 .reduce(
400 || (wl.parallel_split(), PxSize::zero()),
401 |(mut wl, desired_size), (b_wl, b_ds)| {
402 wl.parallel_fold(b_wl);
403 (wl, desired_size.max(b_ds))
404 },
405 );
406 wl.parallel_fold(b);
407 final_size
408 } else {
409 let mut final_size = PxSize::zero();
410 self.iter_mut().for_each(|n| final_size = final_size.max(n.layout(wl)));
411 final_size
412 }
413 }
414
415 fn layout_list(
416 &mut self,
417 wl: &mut WidgetLayout,
418 layout: &(dyn Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync),
419 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
420 ) -> PxSize {
421 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::LAYOUT) {
422 let (b, desired_size) = self
423 .par_iter_mut()
424 .enumerate()
425 .with_ctx()
426 .fold(
427 || (wl.parallel_split(), PxSize::zero()),
428 |(mut wl, desired_size), (i, n)| {
429 let n_ds = layout(i, n, &mut wl);
430 (wl, fold_size(desired_size, n_ds))
431 },
432 )
433 .reduce(
434 || (wl.parallel_split(), PxSize::zero()),
435 |(mut wl, desired_size), (b_wm, b_ds)| {
436 wl.parallel_fold(b_wm);
437 (wl, fold_size(desired_size, b_ds))
438 },
439 );
440 wl.parallel_fold(b);
441 desired_size
442 } else {
443 let mut desired_size = PxSize::zero();
444 self.iter_mut()
445 .enumerate()
446 .for_each(|(i, n)| desired_size = fold_size(desired_size, layout(i, n, wl)));
447 desired_size
448 }
449 }
450
451 fn render(&mut self, frame: &mut FrameBuilder) {
452 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::RENDER) {
453 let mut par_start = 0;
454 while frame.is_outer() && par_start < self.len() {
455 self[par_start].render(frame);
457 par_start += 1;
458 }
459 let b = self[par_start..]
460 .par_iter_mut()
461 .with_ctx()
462 .fold(
463 || frame.parallel_split(),
464 |mut frame, c| {
465 c.render(&mut frame);
466 frame
467 },
468 )
469 .reduce(
470 || frame.parallel_split(),
471 |mut a, b| {
472 a.parallel_fold(b);
473 a
474 },
475 );
476 frame.parallel_fold(b);
477 } else {
478 self.iter_mut().for_each(|n| n.render(frame));
479 }
480 }
481
482 fn render_list(&mut self, frame: &mut FrameBuilder, render: &(dyn Fn(usize, &mut UiNode, &mut FrameBuilder) + Sync)) {
483 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::RENDER) {
484 let mut par_start = 0;
485 while frame.is_outer() && par_start < self.len() {
486 self[par_start].render(frame);
488 par_start += 1;
489 }
490 let b = self[par_start..]
491 .par_iter_mut()
492 .enumerate()
493 .with_ctx()
494 .fold(
495 || frame.parallel_split(),
496 |mut frame, (i, c)| {
497 render(i, c, &mut frame);
498 frame
499 },
500 )
501 .reduce(
502 || frame.parallel_split(),
503 |mut a, b| {
504 a.parallel_fold(b);
505 a
506 },
507 );
508 frame.parallel_fold(b);
509 } else {
510 self.iter_mut().enumerate().for_each(|(i, n)| render(i, n, frame));
511 }
512 }
513
514 fn render_update(&mut self, update: &mut FrameUpdate) {
515 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::RENDER) {
516 let mut par_start = 0;
517 while update.is_outer() && par_start < self.len() {
518 self[par_start].render_update(update);
520 par_start += 1;
521 }
522 let b = self[par_start..]
523 .par_iter_mut()
524 .with_ctx()
525 .fold(
526 || update.parallel_split(),
527 |mut update, c| {
528 c.render_update(&mut update);
529 update
530 },
531 )
532 .reduce(
533 || update.parallel_split(),
534 |mut a, b| {
535 a.parallel_fold(b);
536 a
537 },
538 );
539 update.parallel_fold(b);
540 } else {
541 self.iter_mut().for_each(|n| n.render_update(update));
542 }
543 }
544
545 fn render_update_list(&mut self, update: &mut FrameUpdate, render_update: &(dyn Fn(usize, &mut UiNode, &mut FrameUpdate) + Sync)) {
546 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::RENDER) {
547 let mut par_start = 0;
548 while update.is_outer() && par_start < self.len() {
549 self[par_start].render_update(update);
551 par_start += 1;
552 }
553 let b = self[par_start..]
554 .par_iter_mut()
555 .enumerate()
556 .with_ctx()
557 .fold(
558 || update.parallel_split(),
559 |mut update, (i, c)| {
560 render_update(i, c, &mut update);
561 update
562 },
563 )
564 .reduce(
565 || update.parallel_split(),
566 |mut a, b| {
567 a.parallel_fold(b);
568 a
569 },
570 );
571 update.parallel_fold(b);
572 } else {
573 self.iter_mut().enumerate().for_each(|(i, n)| render_update(i, n, update));
574 }
575 }
576
577 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
578 None
579 }
580}
581
582impl UiNode {
584 pub fn chain(self, other: impl IntoUiNode) -> UiNode {
591 self.chain_impl(other.into_node())
592 }
593 fn chain_impl(mut self, mut other: UiNode) -> UiNode {
594 if self.is_nil() {
595 return other;
596 }
597 if other.is_nil() {
598 return self;
599 }
600
601 if let Some(chain) = self.downcast_mut::<ChainList>() {
602 if let Some(other_too) = other.downcast_mut::<ChainList>() {
603 chain.0.append(&mut other_too.0);
604 } else {
605 chain.0.push(other);
606 }
607 self
608 } else {
609 ChainList(ui_vec![self, other]).into_node()
610 }
611 }
612
613 pub fn sorting_by(mut self, sort: impl Fn(&mut UiNode, &mut UiNode) -> Ordering + Send + 'static) -> UiNode {
619 if let Some(already) = self.downcast_mut::<SortingList>() {
620 already.sort = Box::new(sort);
621 already.invalidate_sort();
622 self
623 } else {
624 SortingList::new(self, sort).into_node()
625 }
626 }
627}
628
629pub struct ChainList(pub UiVec);
631impl ChainList {
632 pub fn chain(self, other: impl IntoUiNode) -> UiNode {
636 self.into_node().chain(other)
637 }
638}
639impl UiNodeImpl for ChainList {
640 fn children_len(&self) -> usize {
641 let mut len = 0;
642 for c in self.0.iter() {
643 if c.is_list() {
644 len += c.children_len();
645 } else {
646 len += 1;
647 }
648 }
649 len
650 }
651
652 fn with_child(&mut self, index: usize, visitor: &mut dyn FnMut(&mut UiNode)) {
653 let mut offset = 0;
654 for c in self.0.iter_mut() {
655 let next_offset = offset + if c.is_list() { c.children_len() } else { 1 };
656 if next_offset > index {
657 c.with_child(index - offset, visitor);
658 break;
659 }
660 offset = next_offset;
661 }
662 }
663
664 fn is_list(&self) -> bool {
665 true
666 }
667
668 fn for_each_child(&mut self, visitor: &mut dyn FnMut(usize, &mut UiNode)) {
669 let mut offset = 0;
670 for c in self.0.iter_mut() {
671 if c.is_list() {
672 c.for_each_child(|i, n| visitor(offset + i, n));
673 offset += c.children_len();
674 } else {
675 visitor(offset, c);
676 offset += 1;
677 }
678 }
679 }
680
681 fn try_for_each_child(
682 &mut self,
683 visitor: &mut dyn FnMut(usize, &mut UiNode) -> ControlFlow<BoxAnyVarValue>,
684 ) -> ControlFlow<BoxAnyVarValue> {
685 let mut offset = 0;
686 for c in self.0.iter_mut() {
687 if c.is_list() {
688 let mut cf = ControlFlow::Continue(());
689 c.for_each_child(|i, n| cf = visitor(offset + i, n));
690 cf?;
691 offset += c.children_len();
692 } else {
693 visitor(offset, c)?;
694 offset += 1;
695 }
696 }
697 ControlFlow::Continue(())
698 }
699
700 fn par_each_child(&mut self, visitor: &(dyn Fn(usize, &mut UiNode) + Sync)) {
701 let mut offset = 0;
702 for c in self.0.iter_mut() {
703 if c.is_list() {
704 c.par_each_child(|i, n| visitor(offset + i, n));
705 offset += c.children_len();
706 } else {
707 visitor(offset, c);
708 offset += 1;
709 }
710 }
711 }
712
713 fn par_fold_reduce(
714 &mut self,
715 identity: BoxAnyVarValue,
716 fold: &(dyn Fn(BoxAnyVarValue, usize, &mut UiNode) -> BoxAnyVarValue + Sync),
717 reduce: &(dyn Fn(BoxAnyVarValue, BoxAnyVarValue) -> BoxAnyVarValue + Sync),
718 ) -> BoxAnyVarValue {
719 let mut offset = 0;
720 let mut accumulator = identity.clone();
721 for c in self.0.iter_mut() {
722 if c.is_list() {
723 accumulator = c.0.par_fold_reduce(identity.clone(), &|acc, i, n| fold(acc, offset + i, n), reduce);
724 offset += c.children_len();
725 } else {
726 accumulator = fold(accumulator, offset, c);
727 offset += 1;
728 }
729 }
730 accumulator
731 }
732
733 fn init(&mut self) {
734 self.0.init();
735 }
736
737 fn deinit(&mut self) {
738 self.0.deinit();
739 }
740
741 fn info(&mut self, info: &mut WidgetInfoBuilder) {
742 self.0.info(info);
743 }
744
745 fn event(&mut self, update: &EventUpdate) {
746 self.0.event(update);
747 }
748
749 fn update(&mut self, updates: &WidgetUpdates) {
750 self.0.update(updates);
751 }
752
753 fn update_list(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
754 if observer.is_reset_only() {
755 if (self as &mut dyn UiNodeImpl).parallelize_hint() && PARALLEL_VAR.get().contains(Parallel::UPDATE) {
756 let changed = self
757 .0
758 .par_iter_mut()
759 .with_ctx()
760 .map(|n| {
761 let mut changed = false;
762 n.update_list(updates, &mut changed);
763 changed
764 })
765 .reduce(|| false, |a, b| a || b);
766 if changed {
767 observer.reset();
768 }
769 } else {
770 let mut changed = false;
771 for c in self.0.iter_mut() {
772 c.update_list(updates, &mut changed);
773 }
774 if changed {
775 observer.reset();
776 }
777 }
778 } else {
779 let mut offset = 0;
780 for c in self.0.iter_mut() {
781 if c.is_list() {
782 c.0.update_list(updates, &mut OffsetUiListObserver(offset, observer));
783 offset += c.children_len();
784 } else {
785 c.update(updates);
786 offset += 1;
787 }
788 }
789 }
790 }
791
792 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
793 self.0.measure(wm)
794 }
795
796 fn measure_list(
797 &mut self,
798 wm: &mut WidgetMeasure,
799 measure: &(dyn Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync),
800 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
801 ) -> PxSize {
802 let mut offset = 0;
803 let mut accumulator = PxSize::zero();
804 for c in self.0.iter_mut() {
805 if c.is_list() {
806 let s = c.0.measure_list(wm, &|i, n, wm| measure(offset + i, n, wm), fold_size);
807 accumulator = fold_size(accumulator, s);
808 offset += c.children_len();
809 } else {
810 let s = measure(offset, c, wm);
811 accumulator = fold_size(accumulator, s);
812 offset += 1;
813 }
814 }
815 accumulator
816 }
817
818 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
819 self.0.layout(wl)
820 }
821
822 fn layout_list(
823 &mut self,
824 wl: &mut WidgetLayout,
825 layout: &(dyn Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync),
826 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
827 ) -> PxSize {
828 let mut offset = 0;
829 let mut accumulator = PxSize::zero();
830 for c in self.0.iter_mut() {
831 if c.is_list() {
832 let s = c.0.layout_list(wl, &|i, n, wl| layout(offset + i, n, wl), fold_size);
833 accumulator = fold_size(accumulator, s);
834 offset += c.children_len();
835 } else {
836 let s = layout(offset, c, wl);
837 accumulator = fold_size(accumulator, s);
838 offset += 1;
839 }
840 }
841 accumulator
842 }
843
844 fn render(&mut self, frame: &mut FrameBuilder) {
845 self.0.render(frame);
846 }
847
848 fn render_list(&mut self, frame: &mut FrameBuilder, render: &(dyn Fn(usize, &mut UiNode, &mut FrameBuilder) + Sync)) {
849 let mut offset = 0;
850 for c in self.0.iter_mut() {
851 if c.is_list() {
852 c.0.render_list(frame, &|i, n, frame| render(offset + i, n, frame));
853 offset += c.children_len();
854 } else {
855 render(offset, c, frame);
856 offset += 1;
857 }
858 }
859 }
860
861 fn render_update(&mut self, update: &mut FrameUpdate) {
862 self.0.render_update(update);
863 }
864
865 fn render_update_list(&mut self, update: &mut FrameUpdate, render_update: &(dyn Fn(usize, &mut UiNode, &mut FrameUpdate) + Sync)) {
866 let mut offset = 0;
867 for c in self.0.iter_mut() {
868 if c.is_list() {
869 c.0.render_update_list(update, &|i, n, update| render_update(offset + i, n, update));
870 offset += c.children_len();
871 } else {
872 render_update(offset, c, update);
873 offset += 1;
874 }
875 }
876 }
877
878 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
879 None
880 }
881}
882
883#[expect(non_camel_case_types)]
885pub struct SORTING_LIST;
886impl SORTING_LIST {
887 pub fn is_inside_list(&self) -> bool {
889 !SORTING_LIST_PARENT.is_default()
890 }
891
892 pub fn invalidate_sort(&self) {
894 SORTING_LIST_PARENT.get().store(true, Relaxed)
895 }
896
897 fn with<R>(&self, action: impl FnOnce() -> R) -> (R, bool) {
898 SORTING_LIST_PARENT.with_context(&mut Some(Arc::new(AtomicBool::new(false))), || {
899 let r = action();
900 (r, SORTING_LIST_PARENT.get().load(Relaxed))
901 })
902 }
903}
904context_local! {
905 static SORTING_LIST_PARENT: AtomicBool = AtomicBool::new(false);
906}
907
908pub struct SortingList {
920 list: UiNode,
921
922 map: Vec<usize>,
923 sort: Box<dyn Fn(&mut UiNode, &mut UiNode) -> Ordering + Send + 'static>,
924}
925impl SortingList {
926 pub fn new(list: impl IntoUiNode, sort: impl Fn(&mut UiNode, &mut UiNode) -> Ordering + Send + 'static) -> Self {
928 Self {
929 list: list.into_node().into_list(),
930 map: vec![],
931 sort: Box::new(sort),
932 }
933 }
934
935 fn update_map(&mut self) {
936 let map = &mut self.map;
937 let len = self.list.children_len();
938
939 if len == 0 {
940 map.clear();
941 } else if map.len() != len {
942 map.clear();
943 map.extend(0..len);
944 let mut taken_a = UiNode::nil();
945 map.sort_by(|&a, &b| {
946 self.list.with_child(a, |a| mem::swap(a, &mut taken_a));
947 let result = self.list.with_child(b, |b| (self.sort)(&mut taken_a, b));
948 self.list.with_child(a, |a| mem::swap(a, &mut taken_a));
949
950 result
951 })
952 }
953 }
954 pub fn list(&mut self) -> &mut UiNode {
960 &mut self.list
961 }
962
963 pub fn invalidate_sort(&mut self) {
967 self.map.clear()
968 }
969
970 fn with_map<R>(&mut self, f: impl FnOnce(&[usize], &mut UiNode) -> R) -> R {
971 self.update_map();
972
973 let (r, resort) = SORTING_LIST.with(|| f(&self.map, &mut self.list));
974
975 if resort {
976 self.invalidate_sort();
977 }
978
979 r
980 }
981
982 pub fn chain(self, other: impl IntoUiNode) -> UiNode {
986 self.into_node().chain(other)
987 }
988}
989impl UiNodeImpl for SortingList {
990 fn children_len(&self) -> usize {
991 self.list.children_len()
992 }
993
994 fn with_child(&mut self, index: usize, visitor: &mut dyn FnMut(&mut UiNode)) {
995 self.with_map(|map, list| {
996 if let Some(index) = map.get(index) {
997 list.0.with_child(*index, visitor)
998 }
999 })
1000 }
1001
1002 fn is_list(&self) -> bool {
1003 true
1004 }
1005
1006 fn for_each_child(&mut self, visitor: &mut dyn FnMut(usize, &mut UiNode)) {
1007 self.with_map(|map, list| {
1008 for (i, &actual_i) in map.iter().enumerate() {
1009 list.with_child(actual_i, |n| visitor(i, n));
1010 }
1011 })
1012 }
1013
1014 fn try_for_each_child(
1015 &mut self,
1016 visitor: &mut dyn FnMut(usize, &mut UiNode) -> ControlFlow<BoxAnyVarValue>,
1017 ) -> ControlFlow<BoxAnyVarValue> {
1018 self.with_map(|map, list| {
1019 for (i, &actual_i) in map.iter().enumerate() {
1020 let mut cf = ControlFlow::Continue(());
1021 list.with_child(actual_i, |n| cf = visitor(i, n));
1022 cf?;
1023 }
1024 ControlFlow::Continue(())
1025 })
1026 }
1027
1028 fn par_each_child(&mut self, visitor: &(dyn Fn(usize, &mut UiNode) + Sync)) {
1029 self.for_each_child(&mut |i, n| visitor(i, n));
1030 }
1031
1032 fn par_fold_reduce(
1033 &mut self,
1034 identity: BoxAnyVarValue,
1035 fold: &(dyn Fn(BoxAnyVarValue, usize, &mut UiNode) -> BoxAnyVarValue + Sync),
1036 _: &(dyn Fn(BoxAnyVarValue, BoxAnyVarValue) -> BoxAnyVarValue + Sync),
1037 ) -> BoxAnyVarValue {
1038 let mut acc = Some(identity);
1039 self.for_each_child(&mut |i, n| {
1040 acc = Some(fold(acc.take().unwrap(), i, n));
1041 });
1042 acc.unwrap()
1043 }
1044
1045 fn init(&mut self) {
1046 let _ = SORTING_LIST.with(|| self.list.0.init());
1047 self.invalidate_sort();
1048 }
1049
1050 fn deinit(&mut self) {
1051 let _ = SORTING_LIST.with(|| self.list.0.deinit());
1052 self.invalidate_sort();
1053 }
1054
1055 fn info(&mut self, info: &mut WidgetInfoBuilder) {
1056 self.list.0.info(info);
1057 }
1058
1059 fn event(&mut self, update: &EventUpdate) {
1060 self.list.0.event(update);
1061 }
1062
1063 fn update(&mut self, updates: &WidgetUpdates) {
1064 self.list.0.update(updates);
1065 }
1066
1067 fn update_list(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
1068 let mut changed = false;
1069 let (_, resort) = SORTING_LIST.with(|| self.list.0.update_list(updates, &mut changed));
1070 if changed || resort {
1071 self.invalidate_sort();
1072 observer.reset();
1073 }
1074 }
1075
1076 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
1077 self.list.0.measure(wm)
1078 }
1079
1080 fn measure_list(
1081 &mut self,
1082 wm: &mut WidgetMeasure,
1083 measure: &(dyn Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync),
1084 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
1085 ) -> PxSize {
1086 let mut acc = PxSize::zero();
1087 self.for_each_child(&mut |i, n| {
1088 let s = measure(i, n, wm);
1089 acc = fold_size(acc, s);
1090 });
1091 acc
1092 }
1093
1094 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
1095 self.list.0.layout(wl)
1096 }
1097
1098 fn layout_list(
1099 &mut self,
1100 wl: &mut WidgetLayout,
1101 layout: &(dyn Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync),
1102 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
1103 ) -> PxSize {
1104 let mut acc = PxSize::zero();
1105 self.for_each_child(&mut |i, n| {
1106 let s = layout(i, n, wl);
1107 acc = fold_size(acc, s);
1108 });
1109 acc
1110 }
1111
1112 fn render(&mut self, frame: &mut FrameBuilder) {
1113 self.for_each_child(&mut |_, n| n.render(frame));
1114 }
1115
1116 fn render_list(&mut self, frame: &mut FrameBuilder, render: &(dyn Fn(usize, &mut UiNode, &mut FrameBuilder) + Sync)) {
1117 self.for_each_child(&mut |i, n| render(i, n, frame));
1118 }
1119
1120 fn render_update(&mut self, update: &mut FrameUpdate) {
1121 self.list.0.render_update(update);
1122 }
1123
1124 fn render_update_list(&mut self, update: &mut FrameUpdate, render_update: &(dyn Fn(usize, &mut UiNode, &mut FrameUpdate) + Sync)) {
1125 self.list.0.render_update_list(update, render_update);
1126 }
1127
1128 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
1129 None
1130 }
1131}
1132
1133pub trait UiNodeListObserver {
1142 fn inserted(&mut self, index: usize);
1144 fn removed(&mut self, index: usize);
1146 fn moved(&mut self, removed_index: usize, inserted_index: usize);
1148 fn reset(&mut self);
1150
1151 fn is_reset_only(&self) -> bool;
1161}
1162impl UiNodeListObserver for () {
1164 fn is_reset_only(&self) -> bool {
1165 true
1166 }
1167
1168 fn reset(&mut self) {}
1169
1170 fn inserted(&mut self, _: usize) {}
1171
1172 fn removed(&mut self, _: usize) {}
1173
1174 fn moved(&mut self, _: usize, _: usize) {}
1175}
1176impl UiNodeListObserver for bool {
1178 fn is_reset_only(&self) -> bool {
1179 true
1180 }
1181
1182 fn reset(&mut self) {
1183 *self = true;
1184 }
1185
1186 fn inserted(&mut self, _: usize) {
1187 *self = true;
1188 }
1189
1190 fn removed(&mut self, _: usize) {
1191 *self = true;
1192 }
1193
1194 fn moved(&mut self, _: usize, _: usize) {
1195 *self = true;
1196 }
1197}
1198
1199pub struct OffsetUiListObserver<'o>(pub usize, pub &'o mut dyn UiNodeListObserver);
1203impl UiNodeListObserver for OffsetUiListObserver<'_> {
1204 fn is_reset_only(&self) -> bool {
1205 self.1.is_reset_only()
1206 }
1207
1208 fn reset(&mut self) {
1209 self.1.reset()
1210 }
1211
1212 fn inserted(&mut self, index: usize) {
1213 self.1.inserted(index + self.0)
1214 }
1215
1216 fn removed(&mut self, index: usize) {
1217 self.1.removed(index + self.0)
1218 }
1219
1220 fn moved(&mut self, removed_index: usize, inserted_index: usize) {
1221 self.1.moved(removed_index + self.0, inserted_index + self.0)
1222 }
1223}
1224
1225impl UiNodeListObserver for (&mut dyn UiNodeListObserver, &mut dyn UiNodeListObserver) {
1226 fn is_reset_only(&self) -> bool {
1227 self.0.is_reset_only() && self.1.is_reset_only()
1228 }
1229
1230 fn reset(&mut self) {
1231 self.0.reset();
1232 self.1.reset();
1233 }
1234
1235 fn inserted(&mut self, index: usize) {
1236 self.0.inserted(index);
1237 self.1.inserted(index);
1238 }
1239
1240 fn removed(&mut self, index: usize) {
1241 self.0.removed(index);
1242 self.1.removed(index);
1243 }
1244
1245 fn moved(&mut self, removed_index: usize, inserted_index: usize) {
1246 self.0.moved(removed_index, inserted_index);
1247 self.1.moved(removed_index, inserted_index);
1248 }
1249}
1250
1251pub struct EditableUiVec {
1253 vec: UiVec,
1254 ctrl: EditableUiVecRef,
1255}
1256impl Default for EditableUiVec {
1257 fn default() -> Self {
1258 Self {
1259 vec: ui_vec![],
1260 ctrl: EditableUiVecRef::new(true),
1261 }
1262 }
1263}
1264impl Drop for EditableUiVec {
1265 fn drop(&mut self) {
1266 self.ctrl.0.lock().alive = false;
1267 }
1268}
1269impl EditableUiVec {
1270 pub fn new() -> Self {
1272 Self::default()
1273 }
1274
1275 pub fn from_vec(vec: impl Into<UiVec>) -> Self {
1277 let mut s = Self::new();
1278 s.vec = vec.into();
1279 s
1280 }
1281
1282 pub fn reference(&self) -> EditableUiVecRef {
1284 self.ctrl.clone()
1285 }
1286
1287 pub fn chain(self, other: impl IntoUiNode) -> UiNode {
1291 self.into_node().chain(other)
1292 }
1293
1294 fn fulfill_requests(&mut self, observer: &mut dyn UiNodeListObserver) {
1295 if let Some(r) = self.ctrl.take_requests() {
1296 if r.clear {
1297 self.clear();
1299 observer.reset();
1300
1301 for (i, mut wgt) in r.insert {
1302 wgt.init();
1303 WIDGET.update_info();
1304 if i < self.len() {
1305 self.insert(i, wgt);
1306 } else {
1307 self.push(wgt);
1308 }
1309 }
1310 for mut wgt in r.push {
1311 wgt.init();
1312 WIDGET.update_info();
1313 self.push(wgt);
1314 }
1315 for (r, i) in r.move_index {
1316 if r < self.len() {
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 for (id, to) in r.move_id {
1329 if let Some(r) = self.vec.iter_mut().position(|n| n.as_widget().map(|mut w| w.id()) == Some(id)) {
1330 let i = to(r, self.len());
1331
1332 if r != i {
1333 let wgt = self.vec.remove(r);
1334
1335 if i < self.len() {
1336 self.vec.insert(i, wgt);
1337 } else {
1338 self.vec.push(wgt);
1339 }
1340
1341 WIDGET.update_info();
1342 }
1343 }
1344 }
1345 } else {
1346 let mut removed = false;
1347 for mut retain in r.retain {
1348 let mut i = 0;
1349 self.vec.retain_mut(|n| {
1350 let r = retain(n);
1351 if !r {
1352 n.deinit();
1353 removed = true;
1354 observer.removed(i);
1355 } else {
1356 i += 1;
1357 }
1358 r
1359 });
1360 }
1361 if removed {
1362 WIDGET.update_info();
1363 }
1364
1365 for (i, mut wgt) in r.insert {
1366 wgt.init();
1367 WIDGET.update_info();
1368
1369 if i < self.len() {
1370 self.insert(i, wgt);
1371 observer.inserted(i);
1372 } else {
1373 observer.inserted(self.len());
1374 self.push(wgt);
1375 }
1376 }
1377
1378 for mut wgt in r.push {
1379 wgt.init();
1380 WIDGET.update_info();
1381
1382 observer.inserted(self.len());
1383 self.push(wgt);
1384 }
1385
1386 for (r, i) in r.move_index {
1387 if r < self.len() {
1388 let wgt = self.vec.remove(r);
1389
1390 if i < self.len() {
1391 self.vec.insert(i, wgt);
1392
1393 observer.moved(r, i);
1394 } else {
1395 let i = self.vec.len();
1396
1397 self.vec.push(wgt);
1398
1399 observer.moved(r, i);
1400 }
1401
1402 WIDGET.update_info();
1403 }
1404 }
1405
1406 for (id, to) in r.move_id {
1407 if let Some(r) = self.vec.iter_mut().position(|n| n.as_widget().map(|mut w| w.id()) == Some(id)) {
1408 let i = to(r, self.len());
1409
1410 if r != i {
1411 let wgt = self.vec.remove(r);
1412
1413 if i < self.len() {
1414 self.vec.insert(i, wgt);
1415 observer.moved(r, i);
1416 } else {
1417 let i = self.vec.len();
1418 self.vec.push(wgt);
1419 observer.moved(r, i);
1420 }
1421
1422 WIDGET.update_info();
1423 }
1424 }
1425 }
1426 }
1427 }
1428 }
1429}
1430impl ops::Deref for EditableUiVec {
1431 type Target = UiVec;
1432
1433 fn deref(&self) -> &Self::Target {
1434 &self.vec
1435 }
1436}
1437impl ops::DerefMut for EditableUiVec {
1438 fn deref_mut(&mut self) -> &mut Self::Target {
1439 &mut self.vec
1440 }
1441}
1442impl UiNodeImpl for EditableUiVec {
1443 fn children_len(&self) -> usize {
1444 self.vec.children_len()
1445 }
1446
1447 fn with_child(&mut self, index: usize, visitor: &mut dyn FnMut(&mut UiNode)) {
1448 self.vec.with_child(index, visitor);
1449 }
1450
1451 fn is_list(&self) -> bool {
1452 true
1453 }
1454
1455 fn for_each_child(&mut self, visitor: &mut dyn FnMut(usize, &mut UiNode)) {
1456 self.vec.for_each_child(visitor);
1457 }
1458
1459 fn try_for_each_child(
1460 &mut self,
1461 visitor: &mut dyn FnMut(usize, &mut UiNode) -> ControlFlow<BoxAnyVarValue>,
1462 ) -> ControlFlow<BoxAnyVarValue> {
1463 self.vec.try_for_each_child(visitor)
1464 }
1465
1466 fn par_each_child(&mut self, visitor: &(dyn Fn(usize, &mut UiNode) + Sync)) {
1467 self.vec.par_each_child(visitor);
1468 }
1469
1470 fn par_fold_reduce(
1471 &mut self,
1472 identity: BoxAnyVarValue,
1473 fold: &(dyn Fn(BoxAnyVarValue, usize, &mut UiNode) -> BoxAnyVarValue + Sync),
1474 reduce: &(dyn Fn(BoxAnyVarValue, BoxAnyVarValue) -> BoxAnyVarValue + Sync),
1475 ) -> BoxAnyVarValue {
1476 self.vec.par_fold_reduce(identity, fold, reduce)
1477 }
1478
1479 fn init(&mut self) {
1480 self.ctrl.0.lock().target = Some(WIDGET.id());
1481 self.vec.init();
1482 }
1483
1484 fn deinit(&mut self) {
1485 self.ctrl.0.lock().target = None;
1486 self.vec.deinit();
1487 }
1488
1489 fn info(&mut self, info: &mut WidgetInfoBuilder) {
1490 self.vec.info(info);
1491 }
1492
1493 fn event(&mut self, update: &EventUpdate) {
1494 self.vec.event(update);
1495 }
1496
1497 fn update(&mut self, updates: &WidgetUpdates) {
1498 self.vec.update(updates);
1499 self.fulfill_requests(&mut ());
1500 }
1501
1502 fn update_list(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
1503 self.vec.update(updates);
1504 self.fulfill_requests(observer);
1505 }
1506
1507 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
1508 self.vec.measure(wm)
1509 }
1510
1511 fn measure_list(
1512 &mut self,
1513 wm: &mut WidgetMeasure,
1514 measure: &(dyn Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync),
1515 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
1516 ) -> PxSize {
1517 self.vec.measure_list(wm, measure, fold_size)
1518 }
1519
1520 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
1521 self.vec.layout(wl)
1522 }
1523
1524 fn layout_list(
1525 &mut self,
1526 wl: &mut WidgetLayout,
1527 layout: &(dyn Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync),
1528 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
1529 ) -> PxSize {
1530 self.vec.layout_list(wl, layout, fold_size)
1531 }
1532
1533 fn render(&mut self, frame: &mut FrameBuilder) {
1534 self.vec.render(frame);
1535 }
1536
1537 fn render_list(&mut self, frame: &mut FrameBuilder, render: &(dyn Fn(usize, &mut UiNode, &mut FrameBuilder) + Sync)) {
1538 self.vec.render_list(frame, render);
1539 }
1540
1541 fn render_update(&mut self, update: &mut FrameUpdate) {
1542 self.vec.render_update(update);
1543 }
1544
1545 fn render_update_list(&mut self, update: &mut FrameUpdate, render_update: &(dyn Fn(usize, &mut UiNode, &mut FrameUpdate) + Sync)) {
1546 self.vec.render_update_list(update, render_update);
1547 }
1548
1549 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
1550 None
1551 }
1552}
1553
1554type NodeMoveToFn = fn(usize, usize) -> usize;
1556
1557#[derive(Clone, Debug)]
1559pub struct EditableUiVecRef(Arc<Mutex<EditRequests>>);
1560struct EditRequests {
1561 target: Option<WidgetId>,
1562 insert: Vec<(usize, UiNode)>,
1563 push: Vec<UiNode>,
1564 retain: Vec<Box<dyn FnMut(&mut UiNode) -> bool + Send>>,
1565 move_index: Vec<(usize, usize)>,
1566 move_id: Vec<(WidgetId, NodeMoveToFn)>,
1567 clear: bool,
1568
1569 alive: bool,
1570}
1571impl fmt::Debug for EditRequests {
1572 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1573 f.debug_struct("EditRequests")
1574 .field("target", &self.target)
1575 .field("insert.len", &self.insert.len())
1576 .field("push.len", &self.push.len())
1577 .field("retain.len", &self.retain.len())
1578 .field("move_index", &self.move_index)
1579 .field("move_id", &self.move_id)
1580 .field("clear", &self.clear)
1581 .field("alive", &self.alive)
1582 .finish()
1583 }
1584}
1585impl EditableUiVecRef {
1586 fn new(alive: bool) -> Self {
1587 Self(Arc::new(Mutex::new(EditRequests {
1588 target: None,
1589 insert: vec![],
1590 push: vec![],
1591 retain: vec![],
1592 move_index: vec![],
1593 move_id: vec![],
1594 clear: false,
1595 alive,
1596 })))
1597 }
1598
1599 pub fn dummy() -> Self {
1605 Self::new(false)
1606 }
1607
1608 pub fn alive(&self) -> bool {
1610 self.0.lock().alive
1611 }
1612
1613 pub fn insert(&self, index: usize, widget: impl IntoUiNode) {
1621 self.insert_impl(index, widget.into_node());
1622 }
1623 fn insert_impl(&self, index: usize, widget: UiNode) {
1624 let mut s = self.0.lock();
1625 if !s.alive {
1626 return;
1627 }
1628 s.insert.push((index, widget));
1629 UPDATES.update(s.target);
1630 }
1631
1632 pub fn push(&self, widget: impl IntoUiNode) {
1640 self.push_impl(widget.into_node());
1641 }
1642 fn push_impl(&self, widget: UiNode) {
1643 let mut s = self.0.lock();
1644 if !s.alive {
1645 return;
1646 }
1647 s.push.push(widget);
1648 UPDATES.update(s.target);
1649 }
1650
1651 pub fn remove(&self, id: impl Into<WidgetId>) {
1656 fn rmv_retain(id: WidgetId) -> impl FnMut(&mut UiNode) -> bool + Send + 'static {
1657 move |node| {
1658 match node.as_widget() {
1659 Some(mut wgt) => wgt.id() != id,
1660 None => true, }
1662 }
1663 }
1664 self.retain(rmv_retain(id.into()))
1665 }
1666
1667 pub fn retain(&self, predicate: impl FnMut(&mut UiNode) -> bool + Send + 'static) {
1673 let mut s = self.0.lock();
1674 if !s.alive {
1675 return;
1676 }
1677 s.retain.push(Box::new(predicate));
1678 UPDATES.update(s.target);
1679 }
1680
1681 pub fn move_index(&self, remove_index: usize, insert_index: usize) {
1688 if remove_index != insert_index {
1689 let mut s = self.0.lock();
1690 if !s.alive {
1691 return;
1692 }
1693 s.move_index.push((remove_index, insert_index));
1694 UPDATES.update(s.target);
1695 }
1696 }
1697
1698 pub fn move_id(&self, id: impl Into<WidgetId>, get_move_to: NodeMoveToFn) {
1738 let mut s = self.0.lock();
1739 if !s.alive {
1740 return;
1741 }
1742 s.move_id.push((id.into(), get_move_to));
1743 UPDATES.update(s.target);
1744 }
1745
1746 pub fn clear(&self) {
1750 let mut s = self.0.lock();
1751 s.clear = true;
1752 UPDATES.update(s.target);
1753 }
1754
1755 fn take_requests(&self) -> Option<EditRequests> {
1756 let mut s = self.0.lock();
1757
1758 if s.clear
1759 || !s.insert.is_empty()
1760 || !s.push.is_empty()
1761 || !s.retain.is_empty()
1762 || !s.move_index.is_empty()
1763 || !s.move_id.is_empty()
1764 {
1765 let empty = EditRequests {
1766 target: s.target,
1767 alive: s.alive,
1768
1769 insert: vec![],
1770 push: vec![],
1771 retain: vec![],
1772 move_index: vec![],
1773 move_id: vec![],
1774 clear: false,
1775 };
1776 Some(mem::replace(&mut *s, empty))
1777 } else {
1778 None
1779 }
1780 }
1781}
1782
1783static_id! {
1784 static ref Z_INDEX_ID: StateId<ZIndex>;
1785}
1786
1787#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Transitionable)]
1801pub struct ZIndex(u32);
1802impl ZIndex {
1803 pub const BACK: ZIndex = ZIndex(0);
1807
1808 pub const DEFAULT: ZIndex = ZIndex(u32::MAX / 2);
1812
1813 pub const FRONT: ZIndex = ZIndex(u32::MAX);
1815
1816 pub fn saturating_add(self, other: impl Into<Self>) -> Self {
1822 ZIndex(self.0.saturating_add(other.into().0))
1823 }
1824
1825 pub fn saturating_sub(self, other: impl Into<Self>) -> Self {
1831 ZIndex(self.0.saturating_sub(other.into().0))
1832 }
1833}
1834impl Default for ZIndex {
1835 fn default() -> Self {
1836 ZIndex::DEFAULT
1837 }
1838}
1839impl<Z: Into<ZIndex>> ops::Add<Z> for ZIndex {
1840 type Output = Self;
1841
1842 fn add(self, rhs: Z) -> Self::Output {
1843 self.saturating_add(rhs)
1844 }
1845}
1846impl<Z: Into<ZIndex>> ops::AddAssign<Z> for ZIndex {
1847 fn add_assign(&mut self, rhs: Z) {
1848 *self = *self + rhs;
1849 }
1850}
1851impl<Z: Into<ZIndex>> ops::Sub<Z> for ZIndex {
1852 type Output = Self;
1853
1854 fn sub(self, rhs: Z) -> Self::Output {
1855 self.saturating_sub(rhs)
1856 }
1857}
1858impl<Z: Into<ZIndex>> ops::SubAssign<Z> for ZIndex {
1859 fn sub_assign(&mut self, rhs: Z) {
1860 *self = *self - rhs;
1861 }
1862}
1863impl ops::Mul<Factor> for ZIndex {
1864 type Output = Self;
1865
1866 fn mul(self, rhs: Factor) -> Self::Output {
1867 ZIndex(self.0 * rhs)
1868 }
1869}
1870impl ops::Div<Factor> for ZIndex {
1871 type Output = Self;
1872
1873 fn div(self, rhs: Factor) -> Self::Output {
1874 ZIndex(self.0 / rhs)
1875 }
1876}
1877impl ops::MulAssign<Factor> for ZIndex {
1878 fn mul_assign(&mut self, rhs: Factor) {
1879 self.0 *= rhs;
1880 }
1881}
1882impl ops::DivAssign<Factor> for ZIndex {
1883 fn div_assign(&mut self, rhs: Factor) {
1884 self.0 /= rhs;
1885 }
1886}
1887impl fmt::Debug for ZIndex {
1888 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1889 let z = *self;
1890 if f.alternate() {
1891 write!(f, "ZIndex::")?;
1892 }
1893
1894 if z == Self::DEFAULT {
1895 write!(f, "DEFAULT")
1896 } else if z == Self::BACK {
1897 write!(f, "BACK")
1898 } else if z == Self::FRONT {
1899 write!(f, "FRONT")
1900 } else if z > Self::DEFAULT {
1901 if z > Self::FRONT - 10000 {
1902 write!(f, "FRONT-{}", Self::FRONT.0 - z.0)
1903 } else {
1904 write!(f, "DEFAULT+{}", z.0 - Self::DEFAULT.0)
1905 }
1906 } else if z < Self::BACK + 10000 {
1907 write!(f, "BACK+{}", z.0 - Self::BACK.0)
1908 } else {
1909 write!(f, "DEFAULT-{}", Self::DEFAULT.0 - z.0)
1910 }
1911 }
1912}
1913impl_from_and_into_var! {
1914 fn from(index: u32) -> ZIndex {
1915 ZIndex(index)
1916 }
1917 fn from(index: ZIndex) -> u32 {
1918 index.0
1919 }
1920 fn from(index: ZIndex) -> Option<ZIndex>;
1921}
1922#[derive(Default, Debug)]
1923struct ZIndexCtx {
1924 panel_id: Option<WidgetId>,
1926 resort: AtomicBool,
1928}
1929context_local! {
1930 static Z_INDEX_CTX: ZIndexCtx = ZIndexCtx::default();
1931}
1932#[expect(non_camel_case_types)]
1934pub struct Z_INDEX;
1935impl Z_INDEX {
1936 fn with(&self, panel_id: WidgetId, action: impl FnOnce()) -> bool {
1937 let ctx = ZIndexCtx {
1938 panel_id: Some(panel_id),
1939 resort: AtomicBool::new(false),
1940 };
1941 Z_INDEX_CTX.with_context(&mut Some(Arc::new(ctx)), || {
1942 action();
1943 Z_INDEX_CTX.get().resort.load(Relaxed)
1944 })
1945 }
1946
1947 pub fn get(&self) -> ZIndex {
1951 WIDGET.get_state(*Z_INDEX_ID).unwrap_or_default()
1952 }
1953
1954 pub fn get_wgt(&self, widget: &mut UiNode) -> ZIndex {
1958 match widget.as_widget() {
1959 Some(mut w) => w.with_context(WidgetUpdateMode::Ignore, || self.get()),
1960 None => ZIndex::DEFAULT,
1961 }
1962 }
1963
1964 pub fn set(&self, index: ZIndex) -> bool {
1972 let z_ctx = Z_INDEX_CTX.get();
1973 let valid = z_ctx.panel_id == WIDGET.parent_id() && z_ctx.panel_id.is_some();
1974 if valid {
1975 z_ctx.resort.store(true, Relaxed);
1976 WIDGET.set_state(*Z_INDEX_ID, index);
1977 }
1978 valid
1979 }
1980}
1981
1982#[derive(Debug, Clone)]
1984pub struct PanelListRange {
1985 range: Option<(WidgetId, WidgetId)>,
1987 version: u8,
1988}
1989impl PanelListRange {
1990 pub fn update(
1995 parent: &WidgetInfo,
1996 panel_id: impl Into<StateId<Self>>,
1997 last_version: &mut Option<u8>,
1998 ) -> Option<crate::widget::info::iter::Children> {
1999 let range = parent.meta().get_clone(panel_id);
2000 if let Some(Self { range, version }) = range {
2001 let version = Some(version);
2002 if *last_version != version {
2003 *last_version = version;
2004
2005 if let Some((s, e)) = range {
2006 let tree = parent.tree();
2007 if let Some(s) = tree.get(s)
2008 && let Some(e) = tree.get(e)
2009 {
2010 let parent = Some(parent);
2011 if s.parent().as_ref() == parent && e.parent().as_ref() == parent {
2012 return Some(crate::widget::info::iter::Children::new_range(s, e));
2013 }
2014 }
2015 }
2016 }
2017 }
2018 None
2019 }
2020
2021 pub fn get(parent: &WidgetInfo, panel_id: impl Into<StateId<Self>>) -> Option<crate::widget::info::iter::Children> {
2023 let range = parent.meta().get_clone(panel_id);
2024 if let Some(Self { range: Some((s, e)), .. }) = range {
2025 let tree = parent.tree();
2026 if let Some(s) = tree.get(s)
2027 && let Some(e) = tree.get(e)
2028 {
2029 let parent = Some(parent);
2030 if s.parent().as_ref() == parent && e.parent().as_ref() == parent {
2031 return Some(crate::widget::info::iter::Children::new_range(s, e));
2032 }
2033 }
2034 }
2035 None
2036 }
2037}
2038
2039pub struct PanelList<D = DefaultPanelListData>
2054where
2055 D: PanelListData,
2056{
2057 list: UiNode,
2058 data: Vec<Mutex<D>>, offset_key: FrameValueKey<PxTransform>,
2061 info_id: Option<(StateId<PanelListRange>, u8, bool)>,
2062
2063 z_map: Vec<u64>,
2064 z_naturally_sorted: bool,
2065}
2066impl PanelList<DefaultPanelListData> {
2067 pub fn new(list: impl IntoUiNode) -> Self {
2069 Self::new_custom(list)
2070 }
2071}
2072
2073impl<D> PanelList<D>
2074where
2075 D: PanelListData,
2076{
2077 pub fn new_custom(list: impl IntoUiNode) -> Self {
2079 Self::new_custom_impl(list.into_node())
2080 }
2081 fn new_custom_impl(list: UiNode) -> Self {
2082 let list = list.into_list();
2083 Self {
2084 data: {
2085 let mut d = vec![];
2086 d.resize_with(list.children_len(), Default::default);
2087 d
2088 },
2089 list,
2090 offset_key: FrameValueKey::new_unique(),
2091 info_id: None,
2092 z_map: vec![],
2093 z_naturally_sorted: false,
2094 }
2095 }
2096
2097 pub fn track_info_range(mut self, info_id: impl Into<StateId<PanelListRange>>) -> Self {
2103 self.info_id = Some((info_id.into(), 0, true));
2104 self
2105 }
2106
2107 pub fn into_parts(self) -> (UiNode, Vec<Mutex<D>>, FrameValueKey<PxTransform>, Option<StateId<PanelListRange>>) {
2109 (self.list, self.data, self.offset_key, self.info_id.map(|t| t.0))
2110 }
2111
2112 pub fn from_parts(
2118 list: UiNode,
2119 data: Vec<Mutex<D>>,
2120 offset_key: FrameValueKey<PxTransform>,
2121 info_id: Option<StateId<PanelListRange>>,
2122 ) -> Self {
2123 assert!(list.is_list());
2124 assert_eq!(list.children_len(), data.len());
2125 Self {
2126 list,
2127 data,
2128 offset_key,
2129 info_id: info_id.map(|i| (i, 0, true)),
2130 z_map: vec![],
2131 z_naturally_sorted: false,
2132 }
2133 }
2134
2135 pub fn info_id(&self) -> Option<StateId<PanelListRange>> {
2139 self.info_id.as_ref().map(|t| t.0)
2140 }
2141
2142 pub fn with_child<R>(&mut self, index: usize, visitor: impl FnOnce(&mut UiNode, &mut D) -> R) -> R {
2146 let data = self.data[index].get_mut();
2147 self.list.with_child(index, |u| visitor(u, data))
2148 }
2149
2150 pub fn for_each_child(&mut self, mut visitor: impl FnMut(usize, &mut UiNode, &mut D)) {
2154 let data = &mut self.data;
2155 self.list.for_each_child(|i, u| visitor(i, u, data[i].get_mut()));
2156 }
2157
2158 pub fn try_for_each_child<B: zng_var::VarValue>(
2162 &mut self,
2163 visitor: &mut dyn FnMut(usize, &mut UiNode, &mut D) -> ControlFlow<B>,
2164 ) -> ControlFlow<B> {
2165 let data = &mut self.data;
2166 self.list.try_for_each_child(|i, u| visitor(i, u, data[i].get_mut()))
2167 }
2168
2169 pub fn par_each_child(&mut self, visitor: impl Fn(usize, &mut UiNode, &mut D) + Sync)
2173 where
2174 D: Sync,
2175 {
2176 let data = &self.data;
2177 self.list.par_each_child(|i, u| {
2178 visitor(
2179 i,
2180 u,
2181 &mut *data[i].try_lock().expect("par_each_child called visitor twice on same index"),
2182 )
2183 });
2184 }
2185
2186 pub fn par_fold_reduce<T>(
2193 &mut self,
2194 identity: T,
2195 fold: impl Fn(T, usize, &mut UiNode, &mut D) -> T + Sync,
2196 reduce: impl Fn(T, T) -> T + Send + Sync,
2197 ) -> T
2198 where
2199 T: zng_var::VarValue,
2200 {
2201 let data = &self.data;
2202 self.list.par_fold_reduce(
2203 identity,
2204 |acc, i, n| {
2205 fold(
2206 acc,
2207 i,
2208 n,
2209 &mut *data[i].try_lock().expect("par_fold_reduce called visitor twice on same index"),
2210 )
2211 },
2212 reduce,
2213 )
2214 }
2215
2216 pub fn measure_list(
2218 &mut self,
2219 wm: &mut WidgetMeasure,
2220 measure: impl Fn(usize, &mut UiNode, &mut D, &mut WidgetMeasure) -> PxSize + Sync,
2221 fold_size: impl Fn(PxSize, PxSize) -> PxSize + Sync,
2222 ) -> PxSize {
2223 let data = &self.data;
2224 self.list.measure_list(
2225 wm,
2226 |i, n, wm| {
2227 measure(
2228 i,
2229 n,
2230 &mut *data[i].try_lock().expect("measure_list called visitor twice on same index"),
2231 wm,
2232 )
2233 },
2234 fold_size,
2235 )
2236 }
2237
2238 pub fn layout_list(
2240 &mut self,
2241 wl: &mut WidgetLayout,
2242 layout: impl Fn(usize, &mut UiNode, &mut D, &mut WidgetLayout) -> PxSize + Sync,
2243 fold_size: impl Fn(PxSize, PxSize) -> PxSize + Sync,
2244 ) -> PxSize {
2245 let data = &self.data;
2246 self.list.layout_list(
2247 wl,
2248 |i, n, wl| {
2249 layout(
2250 i,
2251 n,
2252 &mut *data[i].try_lock().expect("layout_list called visitor twice on same index"),
2253 wl,
2254 )
2255 },
2256 fold_size,
2257 )
2258 }
2259
2260 pub fn render_list(&mut self, frame: &mut FrameBuilder, render: impl Fn(usize, &mut UiNode, &mut D, &mut FrameBuilder) + Sync) {
2264 let offset_key = self.offset_key;
2265
2266 if self.z_naturally_sorted {
2267 let data = &self.data;
2268 self.list.render_list(frame, |i, child, frame| {
2269 let mut data = data[i].try_lock().expect("render_list called visitor twice on same index");
2270 let offset = data.child_offset();
2271 if data.define_reference_frame() {
2272 frame.push_reference_frame(
2273 (offset_key, i as u32).into(),
2274 offset_key.bind_child(i as u32, offset.into(), false),
2275 true,
2276 true,
2277 |frame| render(i, child, &mut *data, frame),
2278 );
2279 } else {
2280 frame.push_child(offset, |frame| render(i, child, &mut *data, frame));
2281 }
2282 });
2283 } else {
2284 self.for_each_z_sorted(|i, child, data| {
2285 let offset = data.child_offset();
2286 if data.define_reference_frame() {
2287 frame.push_reference_frame(
2288 (offset_key, i as u32).into(),
2289 offset_key.bind_child(i as u32, offset.into(), false),
2290 true,
2291 true,
2292 |frame| render(i, child, data, frame),
2293 );
2294 } else {
2295 frame.push_child(offset, |frame| render(i, child, data, frame));
2296 }
2297 });
2298 }
2299 }
2300
2301 pub fn render_update_list(
2305 &mut self,
2306 update: &mut FrameUpdate,
2307 render_update: impl Fn(usize, &mut UiNode, &mut D, &mut FrameUpdate) + Sync,
2308 ) {
2309 let offset_key = self.offset_key;
2310 let data = &self.data;
2311 self.list.render_update_list(update, |i, n, update| {
2312 let mut data = data[i].try_lock().expect("render_update_list called visitor twice on same index");
2313
2314 let offset = data.child_offset();
2315 if data.define_reference_frame() {
2316 update.with_transform(offset_key.update_child(i as u32, offset.into(), false), true, |update| {
2317 render_update(i, n, &mut *data, update);
2318 });
2319 } else {
2320 update.with_child(offset, |update| {
2321 render_update(i, n, &mut *data, update);
2322 });
2323 }
2324 });
2325 }
2326
2327 pub fn for_each_z_sorted(&mut self, mut visitor: impl FnMut(usize, &mut UiNode, &mut D)) {
2329 if self.z_naturally_sorted {
2330 self.for_each_child(visitor)
2331 } else {
2332 if self.z_map.len() != self.list.children_len() {
2333 self.z_sort();
2334 }
2335
2336 if self.z_naturally_sorted {
2337 self.for_each_child(visitor);
2338 } else {
2339 for &index in self.z_map.iter() {
2340 let index = index as usize;
2341 let data = self.data[index].get_mut();
2342 self.list.with_child(index, |node| visitor(index, node, data));
2343 }
2344 }
2345 }
2346 }
2347
2348 fn z_sort(&mut self) {
2349 let len = self.list.children_len();
2363 assert!(len <= u32::MAX as usize);
2364
2365 let mut prev_z = ZIndex::BACK;
2366 let mut need_map = false;
2367 let mut z_and_i = Vec::with_capacity(len);
2368 let mut has_non_default_zs = false;
2369
2370 self.list.for_each_child(|i, node| {
2371 let z = Z_INDEX.get_wgt(node);
2372 z_and_i.push(((z.0 as u64) << 32) | i as u64);
2373
2374 need_map |= z < prev_z;
2375 has_non_default_zs |= z != ZIndex::DEFAULT;
2376 prev_z = z;
2377 });
2378
2379 self.z_naturally_sorted = !need_map;
2380
2381 if need_map {
2382 z_and_i.sort_unstable();
2383
2384 for z in &mut z_and_i {
2385 *z &= u32::MAX as u64;
2386 }
2387
2388 self.z_map = z_and_i;
2389 } else {
2390 self.z_map.clear();
2391 }
2392 }
2393
2394 pub fn z_map(&mut self, index: usize) -> usize {
2396 if self.z_naturally_sorted {
2397 return index;
2398 }
2399
2400 if self.z_map.len() != self.list.children_len() {
2401 self.z_sort();
2402 }
2403
2404 if self.z_naturally_sorted {
2405 return index;
2406 }
2407
2408 self.z_map[index] as usize
2409 }
2410
2411 pub fn data(&mut self, index: usize) -> &mut D {
2413 self.data[index].get_mut()
2414 }
2415
2416 pub fn commit_data(&mut self) -> PanelListDataChanges {
2424 let mut changes = PanelListDataChanges::empty();
2425 for data in self.data.iter_mut() {
2426 changes |= data.get_mut().commit();
2427 }
2428 changes
2429 }
2430
2431 pub fn offset_key(&self) -> FrameValueKey<PxTransform> {
2435 self.offset_key
2436 }
2437}
2438impl<D> UiNodeImpl for PanelList<D>
2439where
2440 D: PanelListData,
2441{
2442 fn children_len(&self) -> usize {
2443 self.list.0.children_len()
2444 }
2445
2446 fn with_child(&mut self, index: usize, visitor: &mut dyn FnMut(&mut UiNode)) {
2447 self.list.0.with_child(index, visitor)
2448 }
2449
2450 fn is_list(&self) -> bool {
2451 true
2452 }
2453
2454 fn for_each_child(&mut self, visitor: &mut dyn FnMut(usize, &mut UiNode)) {
2455 self.list.0.for_each_child(visitor);
2456 }
2457
2458 fn try_for_each_child(
2459 &mut self,
2460 visitor: &mut dyn FnMut(usize, &mut UiNode) -> ControlFlow<BoxAnyVarValue>,
2461 ) -> ControlFlow<BoxAnyVarValue> {
2462 self.list.0.try_for_each_child(visitor)
2463 }
2464
2465 fn par_each_child(&mut self, visitor: &(dyn Fn(usize, &mut UiNode) + Sync)) {
2466 self.list.0.par_each_child(visitor);
2467 }
2468
2469 fn par_fold_reduce(
2470 &mut self,
2471 identity: BoxAnyVarValue,
2472 fold: &(dyn Fn(BoxAnyVarValue, usize, &mut UiNode) -> BoxAnyVarValue + Sync),
2473 reduce: &(dyn Fn(BoxAnyVarValue, BoxAnyVarValue) -> BoxAnyVarValue + Sync),
2474 ) -> BoxAnyVarValue {
2475 self.list.0.par_fold_reduce(identity, fold, reduce)
2476 }
2477
2478 fn init(&mut self) {
2479 self.z_map.clear();
2480 let resort = Z_INDEX.with(WIDGET.id(), || self.list.0.init());
2481 self.z_naturally_sorted = !resort;
2482 self.data.resize_with(self.list.0.children_len(), Default::default);
2483 }
2484
2485 fn deinit(&mut self) {
2486 self.list.deinit();
2487 }
2488
2489 fn info(&mut self, info: &mut WidgetInfoBuilder) {
2490 let len = self.list.0.children_len();
2491 if len == 0 {
2492 return;
2493 }
2494
2495 self.list.0.info(info);
2496
2497 if let Some((id, version, pump_update)) = &mut self.info_id {
2498 let start = self.list.with_child(0, |c| c.as_widget().map(|mut w| w.id()));
2499 let end = self.list.with_child(len - 1, |c| c.as_widget().map(|mut w| w.id()));
2500 let range = match (start, end) {
2501 (Some(s), Some(e)) => Some((s, e)),
2502 _ => None,
2503 };
2504 info.set_meta(*id, PanelListRange { range, version: *version });
2505
2506 if mem::take(pump_update) {
2507 self.list.for_each_child(|_, c| {
2508 if let Some(mut w) = c.as_widget() {
2509 w.with_context(WidgetUpdateMode::Bubble, || WIDGET.update());
2510 }
2511 });
2512 }
2513 }
2514 }
2515
2516 fn event(&mut self, update: &EventUpdate) {
2517 self.list.event(update);
2518 }
2519
2520 fn update(&mut self, updates: &WidgetUpdates) {
2521 self.update_list(updates, &mut ());
2522 }
2523
2524 fn update_list(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
2525 let mut observer = PanelObserver {
2526 changed: false,
2527 data: &mut self.data,
2528 observer,
2529 };
2530 let resort = Z_INDEX.with(WIDGET.id(), || self.list.update_list(updates, &mut observer));
2531 let observer_changed = observer.changed;
2532 if resort || (observer.changed && self.z_naturally_sorted) {
2533 self.z_map.clear();
2534 self.z_naturally_sorted = false;
2535 WIDGET.render();
2536 }
2537 self.data.resize_with(self.list.children_len(), Default::default);
2538
2539 if observer_changed && let Some((_, v, u)) = &mut self.info_id {
2540 if !*u {
2541 *v = v.wrapping_add(1);
2542 *u = true;
2543 }
2544 WIDGET.info();
2545 }
2546 }
2547
2548 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
2549 self.list.measure(wm)
2550 }
2551
2552 fn measure_list(
2553 &mut self,
2554 wm: &mut WidgetMeasure,
2555 measure: &(dyn Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync),
2556 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
2557 ) -> PxSize {
2558 self.list.measure_list(wm, measure, fold_size)
2559 }
2560
2561 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
2562 self.list.layout(wl)
2563 }
2564
2565 fn layout_list(
2566 &mut self,
2567 wl: &mut WidgetLayout,
2568 layout: &(dyn Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync),
2569 fold_size: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
2570 ) -> PxSize {
2571 self.list.layout_list(wl, layout, fold_size)
2572 }
2573
2574 fn render(&mut self, frame: &mut FrameBuilder) {
2575 self.render_list(frame, |_, n, _, frame| n.render(frame));
2576 }
2577
2578 fn render_update(&mut self, update: &mut FrameUpdate) {
2579 self.render_update_list(update, |_, n, _, update| n.render_update(update));
2580 }
2581
2582 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
2583 self.list.0.as_widget()
2584 }
2585}
2586
2587bitflags::bitflags! {
2588 #[must_use = "|= with other item changes, call request_render"]
2590 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
2591 #[serde(transparent)]
2592 pub struct PanelListDataChanges: u8 {
2593 const CHILD_OFFSET = 0b01;
2595 const DEFINE_REFERENCE_FRAME = 0b10;
2597 }
2598}
2599impl PanelListDataChanges {
2600 pub fn request_render(self) {
2602 if self.contains(Self::DEFINE_REFERENCE_FRAME) {
2603 WIDGET.render();
2604 } else if self.contains(Self::CHILD_OFFSET) {
2605 WIDGET.render_update();
2606 }
2607 }
2608}
2609
2610#[derive(Clone, Debug, Default)]
2612pub struct DefaultPanelListData {
2613 pub child_offset: PxVector,
2615 pub define_reference_frame: bool,
2617
2618 prev_child_offset: PxVector,
2619 prev_define_reference_frame: bool,
2620}
2621impl PanelListData for DefaultPanelListData {
2622 fn child_offset(&self) -> PxVector {
2623 self.child_offset
2624 }
2625
2626 fn define_reference_frame(&self) -> bool {
2627 self.define_reference_frame
2628 }
2629
2630 fn commit(&mut self) -> PanelListDataChanges {
2631 let mut changes = PanelListDataChanges::empty();
2632 if self.define_reference_frame != self.prev_define_reference_frame {
2633 changes |= PanelListDataChanges::DEFINE_REFERENCE_FRAME;
2634 }
2635 if self.child_offset != self.prev_child_offset {
2636 changes |= PanelListDataChanges::CHILD_OFFSET;
2637 }
2638 self.prev_define_reference_frame = self.define_reference_frame;
2639 self.prev_child_offset = self.child_offset;
2640 changes
2641 }
2642}
2643
2644pub trait PanelListData: Default + Send + Any {
2646 fn child_offset(&self) -> PxVector;
2648
2649 fn define_reference_frame(&self) -> bool;
2651
2652 fn commit(&mut self) -> PanelListDataChanges;
2656}
2657impl PanelListData for () {
2658 fn child_offset(&self) -> PxVector {
2659 PxVector::zero()
2660 }
2661
2662 fn define_reference_frame(&self) -> bool {
2663 false
2664 }
2665
2666 fn commit(&mut self) -> PanelListDataChanges {
2667 PanelListDataChanges::empty()
2668 }
2669}
2670
2671struct PanelObserver<'d, D>
2672where
2673 D: PanelListData,
2674{
2675 changed: bool,
2676 data: &'d mut Vec<Mutex<D>>,
2677 observer: &'d mut dyn UiNodeListObserver,
2678}
2679impl<D> UiNodeListObserver for PanelObserver<'_, D>
2680where
2681 D: PanelListData,
2682{
2683 fn is_reset_only(&self) -> bool {
2684 false
2685 }
2686
2687 fn reset(&mut self) {
2688 self.changed = true;
2689 self.data.clear();
2690 self.observer.reset();
2691 }
2692
2693 fn inserted(&mut self, index: usize) {
2694 self.changed = true;
2695 self.data.insert(index, Default::default());
2696 self.observer.inserted(index);
2697 }
2698
2699 fn removed(&mut self, index: usize) {
2700 self.changed = true;
2701 self.data.remove(index);
2702 self.observer.removed(index);
2703 }
2704
2705 fn moved(&mut self, removed_index: usize, inserted_index: usize) {
2706 self.changed = true;
2707 let item = self.data.remove(removed_index);
2708 self.data.insert(inserted_index, item);
2709 self.observer.moved(removed_index, inserted_index);
2710 }
2711}