1use std::mem;
2
3use zng_layout::unit::PxSize;
4
5use crate::{
6 render::{FrameBuilder, FrameUpdate},
7 update::{EventUpdate, WidgetUpdates},
8 widget::{
9 WidgetUpdateMode,
10 info::{WidgetInfoBuilder, WidgetLayout, WidgetMeasure},
11 ui_node,
12 },
13};
14
15use super::*;
16
17#[non_exhaustive]
21pub enum UiNodeOp<'a> {
22 Init,
33 Deinit,
43 Info {
60 info: &'a mut WidgetInfoBuilder,
62 },
63 Event {
80 update: &'a EventUpdate,
82 },
83 Update {
98 updates: &'a WidgetUpdates,
100 },
101 Measure {
118 wm: &'a mut WidgetMeasure,
120 desired_size: &'a mut PxSize,
122 },
123 Layout {
145 wl: &'a mut WidgetLayout,
147 final_size: &'a mut PxSize,
149 },
150 Render {
160 frame: &'a mut FrameBuilder,
162 },
163 RenderUpdate {
175 update: &'a mut FrameUpdate,
177 },
178}
179impl UiNodeOp<'_> {
180 pub fn mtd(&self) -> UiNodeOpMethod {
182 match self {
183 UiNodeOp::Init => UiNodeOpMethod::Init,
184 UiNodeOp::Deinit => UiNodeOpMethod::Deinit,
185 UiNodeOp::Info { .. } => UiNodeOpMethod::Info,
186 UiNodeOp::Event { .. } => UiNodeOpMethod::Event,
187 UiNodeOp::Update { .. } => UiNodeOpMethod::Update,
188 UiNodeOp::Measure { .. } => UiNodeOpMethod::Measure,
189 UiNodeOp::Layout { .. } => UiNodeOpMethod::Layout,
190 UiNodeOp::Render { .. } => UiNodeOpMethod::Render,
191 UiNodeOp::RenderUpdate { .. } => UiNodeOpMethod::RenderUpdate,
192 }
193 }
194
195 pub fn reborrow(&mut self) -> UiNodeOp {
197 match self {
198 UiNodeOp::Init => UiNodeOp::Init,
199 UiNodeOp::Deinit => UiNodeOp::Deinit,
200 UiNodeOp::Info { info } => UiNodeOp::Info { info },
201 UiNodeOp::Event { update } => UiNodeOp::Event { update },
202 UiNodeOp::Update { updates } => UiNodeOp::Update { updates },
203 UiNodeOp::Measure { wm, desired_size } => UiNodeOp::Measure { wm, desired_size },
204 UiNodeOp::Layout { wl, final_size } => UiNodeOp::Layout { wl, final_size },
205 UiNodeOp::Render { frame } => UiNodeOp::Render { frame },
206 UiNodeOp::RenderUpdate { update } => UiNodeOp::RenderUpdate { update },
207 }
208 }
209}
210impl fmt::Debug for UiNodeOp<'_> {
211 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
212 match self {
213 Self::Event { update } => f.debug_struct("Event").field("update", update).finish(),
214 Self::Update { updates } => f.debug_struct("Update").field("updates", updates).finish(),
215 op => write!(f, "{}", op.mtd()),
216 }
217 }
218}
219
220#[derive(Clone, Copy, serde::Serialize, serde::Deserialize)]
222#[non_exhaustive]
223pub enum UiNodeOpMethod {
224 Init,
226 Deinit,
228 Info,
230 Event,
232 Update,
234 Measure,
236 Layout,
238 Render,
240 RenderUpdate,
242}
243impl UiNodeOpMethod {
244 pub fn enum_name(self) -> &'static str {
246 match self {
247 UiNodeOpMethod::Init => "Init",
248 UiNodeOpMethod::Deinit => "Deinit",
249 UiNodeOpMethod::Info => "Info",
250 UiNodeOpMethod::Event => "Event",
251 UiNodeOpMethod::Update => "Update",
252 UiNodeOpMethod::Measure => "Measure",
253 UiNodeOpMethod::Layout => "Layout",
254 UiNodeOpMethod::Render => "Render",
255 UiNodeOpMethod::RenderUpdate => "RenderUpdate",
256 }
257 }
258
259 pub fn mtd_name(self) -> &'static str {
261 match self {
262 UiNodeOpMethod::Init => "init",
263 UiNodeOpMethod::Deinit => "deinit",
264 UiNodeOpMethod::Info => "info",
265 UiNodeOpMethod::Event => "event",
266 UiNodeOpMethod::Update => "update",
267 UiNodeOpMethod::Measure => "measure",
268 UiNodeOpMethod::Layout => "layout",
269 UiNodeOpMethod::Render => "render",
270 UiNodeOpMethod::RenderUpdate => "render_update",
271 }
272 }
273}
274impl fmt::Debug for UiNodeOpMethod {
275 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
276 fmt::Display::fmt(self, f)
277 }
278}
279impl fmt::Display for UiNodeOpMethod {
280 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
281 if f.alternate() {
282 write!(f, "{}", self.enum_name())
283 } else {
284 write!(f, "{}", self.mtd_name())
285 }
286 }
287}
288
289#[cfg(feature = "dyn_node")]
349pub fn match_node<C: UiNode>(child: C, closure: impl FnMut(&mut MatchNodeChild<BoxedUiNode>, UiNodeOp) + Send + 'static) -> impl UiNode {
350 #[cfg(feature = "dyn_closure")]
351 let closure: Box<dyn FnMut(&mut MatchNodeChild<BoxedUiNode>, UiNodeOp) + Send> = Box::new(closure);
352
353 match_node_impl(child.boxed(), closure)
354}
355
356#[cfg(not(feature = "dyn_node"))]
416pub fn match_node<C: UiNode>(child: C, closure: impl FnMut(&mut MatchNodeChild<C>, UiNodeOp) + Send + 'static) -> impl UiNode {
417 match_node_typed(child, closure)
418}
419
420pub fn match_node_typed<C: UiNode>(child: C, closure: impl FnMut(&mut MatchNodeChild<C>, UiNodeOp) + Send + 'static) -> impl UiNode {
424 #[cfg(feature = "dyn_closure")]
425 let closure: Box<dyn FnMut(&mut MatchNodeChild<C>, UiNodeOp) + Send> = Box::new(closure);
426
427 match_node_impl(child, closure)
428}
429
430fn match_node_impl<C: UiNode>(child: C, closure: impl FnMut(&mut MatchNodeChild<C>, UiNodeOp) + Send + 'static) -> impl UiNode {
431 #[ui_node(struct MatchNode<C: UiNode> {
432 child: MatchNodeChild<C>,
433 closure: impl FnMut(&mut MatchNodeChild<C>, UiNodeOp) + Send + 'static,
434 })]
435 impl UiNode for MatchNode {
436 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
437 fn init(&mut self) {
438 self.child.delegated = false;
439
440 (self.closure)(&mut self.child, UiNodeOp::Init);
441
442 if !mem::take(&mut self.child.delegated) {
443 self.child.child.init();
444 }
445 }
446
447 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
448 fn deinit(&mut self) {
449 self.child.delegated = false;
450
451 (self.closure)(&mut self.child, UiNodeOp::Deinit);
452
453 if !mem::take(&mut self.child.delegated) {
454 self.child.child.deinit();
455 }
456 }
457
458 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
459 fn info(&mut self, info: &mut WidgetInfoBuilder) {
460 self.child.delegated = false;
461
462 (self.closure)(&mut self.child, UiNodeOp::Info { info });
463
464 if !mem::take(&mut self.child.delegated) {
465 self.child.child.info(info);
466 }
467 }
468
469 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
470 fn event(&mut self, update: &EventUpdate) {
471 self.child.delegated = false;
472
473 (self.closure)(&mut self.child, UiNodeOp::Event { update });
474
475 if !mem::take(&mut self.child.delegated) {
476 self.child.child.event(update);
477 }
478 }
479
480 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
481 fn update(&mut self, updates: &WidgetUpdates) {
482 self.child.delegated = false;
483
484 (self.closure)(&mut self.child, UiNodeOp::Update { updates });
485
486 if !mem::take(&mut self.child.delegated) {
487 self.child.child.update(updates);
488 }
489 }
490
491 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
492 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
493 self.child.delegated = false;
494
495 let mut size = PxSize::zero();
496 (self.closure)(
497 &mut self.child,
498 UiNodeOp::Measure {
499 wm,
500 desired_size: &mut size,
501 },
502 );
503
504 if !mem::take(&mut self.child.delegated) {
505 if size != PxSize::zero() {
506 tracing::error!("measure changed size without flagging delegated");
509 return size;
510 }
511
512 self.child.child.measure(wm)
513 } else {
514 size
515 }
516 }
517
518 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
519 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
520 self.child.delegated = false;
521
522 let mut size = PxSize::zero();
523 (self.closure)(&mut self.child, UiNodeOp::Layout { wl, final_size: &mut size });
524
525 if !mem::take(&mut self.child.delegated) {
526 if size != PxSize::zero() {
527 tracing::error!("layout changed size without flagging delegated");
530 return size;
531 }
532
533 self.child.child.layout(wl)
534 } else {
535 size
536 }
537 }
538
539 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
540 fn render(&mut self, frame: &mut FrameBuilder) {
541 self.child.delegated = false;
542
543 (self.closure)(&mut self.child, UiNodeOp::Render { frame });
544
545 if !mem::take(&mut self.child.delegated) {
546 self.child.child.render(frame);
547 }
548 }
549
550 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
551 fn render_update(&mut self, update: &mut FrameUpdate) {
552 self.child.delegated = false;
553
554 (self.closure)(&mut self.child, UiNodeOp::RenderUpdate { update });
555
556 if !mem::take(&mut self.child.delegated) {
557 self.child.child.render_update(update);
558 }
559 }
560 }
561 MatchNode {
562 child: MatchNodeChild { child, delegated: false },
563 closure,
564 }
565}
566
567pub struct MatchNodeChild<C> {
573 child: C,
574 delegated: bool,
575}
576impl<C: UiNode> MatchNodeChild<C> {
577 pub fn delegated(&mut self) {
581 self.delegated = true;
582 }
583
584 pub fn has_delegated(&self) -> bool {
586 self.delegated
587 }
588
589 pub fn child(&mut self) -> &mut C {
599 &mut self.child
600 }
601}
602impl<C: UiNode> UiNode for MatchNodeChild<C> {
603 fn init(&mut self) {
604 self.child.init();
605 self.delegated = true;
606 }
607
608 fn deinit(&mut self) {
609 self.child.deinit();
610 self.delegated = true;
611 }
612
613 fn info(&mut self, info: &mut WidgetInfoBuilder) {
614 self.child.info(info);
615 self.delegated = true;
616 }
617
618 fn event(&mut self, update: &EventUpdate) {
619 self.child.event(update);
620 self.delegated = true;
621 }
622
623 fn update(&mut self, updates: &WidgetUpdates) {
624 self.child.update(updates);
625 self.delegated = true;
626 }
627
628 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
629 self.delegated = true;
630 self.child.measure(wm)
631 }
632
633 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
634 self.delegated = true;
635 self.child.layout(wl)
636 }
637
638 fn render(&mut self, frame: &mut FrameBuilder) {
639 self.child.render(frame);
640 self.delegated = true;
641 }
642
643 fn render_update(&mut self, update: &mut FrameUpdate) {
644 self.child.render_update(update);
645 self.delegated = true;
646 }
647
648 fn is_widget(&self) -> bool {
649 self.child.is_widget()
650 }
651
652 fn with_context<R, F>(&mut self, update_mode: WidgetUpdateMode, f: F) -> Option<R>
653 where
654 F: FnOnce() -> R,
655 {
656 self.child.with_context(update_mode, f)
657 }
658}
659
660pub fn match_node_leaf(closure: impl FnMut(UiNodeOp) + Send + 'static) -> impl UiNode {
662 #[ui_node(struct MatchNodeLeaf {
663 closure: impl FnMut(UiNodeOp) + Send + 'static,
664 })]
665 impl UiNode for MatchNodeLeaf {
666 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
667 fn init(&mut self) {
668 (self.closure)(UiNodeOp::Init);
669 }
670
671 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
672 fn deinit(&mut self) {
673 (self.closure)(UiNodeOp::Deinit);
674 }
675
676 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
677 fn info(&mut self, info: &mut WidgetInfoBuilder) {
678 (self.closure)(UiNodeOp::Info { info });
679 }
680
681 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
682 fn event(&mut self, update: &EventUpdate) {
683 (self.closure)(UiNodeOp::Event { update });
684 }
685
686 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
687 fn update(&mut self, updates: &WidgetUpdates) {
688 (self.closure)(UiNodeOp::Update { updates });
689 }
690
691 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
692 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
693 let mut size = PxSize::zero();
694 (self.closure)(UiNodeOp::Measure {
695 wm,
696 desired_size: &mut size,
697 });
698 size
699 }
700
701 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
702 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
703 let mut size = PxSize::zero();
704 (self.closure)(UiNodeOp::Layout { wl, final_size: &mut size });
705 size
706 }
707
708 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
709 fn render(&mut self, frame: &mut FrameBuilder) {
710 (self.closure)(UiNodeOp::Render { frame });
711 }
712
713 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
714 fn render_update(&mut self, update: &mut FrameUpdate) {
715 (self.closure)(UiNodeOp::RenderUpdate { update });
716 }
717 }
718 MatchNodeLeaf { closure }
719}
720
721pub fn match_widget<W: UiNode>(child: W, closure: impl FnMut(&mut MatchWidgetChild<W>, UiNodeOp) + Send + 'static) -> impl UiNode {
732 #[ui_node(struct MatchWidget<C: UiNode> {
733 child: MatchWidgetChild<C>,
734 closure: impl FnMut(&mut MatchWidgetChild<C>, UiNodeOp) + Send + 'static,
735 })]
736 impl UiNode for MatchWidget {
737 fn is_widget(&self) -> bool {
738 self.child.0.child.is_widget()
739 }
740
741 fn with_context<R, F: FnOnce() -> R>(&mut self, update_mode: WidgetUpdateMode, f: F) -> Option<R> {
742 self.child.0.child.with_context(update_mode, f)
743 }
744
745 fn init(&mut self) {
746 self.child.0.delegated = false;
747
748 (self.closure)(&mut self.child, UiNodeOp::Init);
749
750 if !mem::take(&mut self.child.0.delegated) {
751 self.child.0.child.init();
752 }
753 }
754
755 fn deinit(&mut self) {
756 self.child.0.delegated = false;
757
758 (self.closure)(&mut self.child, UiNodeOp::Deinit);
759
760 if !mem::take(&mut self.child.0.delegated) {
761 self.child.0.child.deinit();
762 }
763 }
764
765 fn info(&mut self, info: &mut WidgetInfoBuilder) {
766 self.child.0.delegated = false;
767
768 (self.closure)(&mut self.child, UiNodeOp::Info { info });
769
770 if !mem::take(&mut self.child.0.delegated) {
771 self.child.0.child.info(info);
772 } else {
773 #[cfg(debug_assertions)]
774 if self
775 .child
776 .0
777 .child
778 .with_context(WidgetUpdateMode::Ignore, || {
779 WIDGET.pending_update().contains(crate::update::UpdateFlags::INFO)
780 })
781 .unwrap_or(false)
782 {
783 tracing::warn!(target: "match_widget-pending", "pending info build after info delegated in {:?}", WIDGET.id());
785 }
786 }
787 }
788
789 fn event(&mut self, update: &EventUpdate) {
790 self.child.0.delegated = false;
791
792 (self.closure)(&mut self.child, UiNodeOp::Event { update });
793
794 if !mem::take(&mut self.child.0.delegated) {
795 self.child.0.child.event(update);
796 }
797 }
798
799 fn update(&mut self, updates: &WidgetUpdates) {
800 self.child.0.delegated = false;
801
802 (self.closure)(&mut self.child, UiNodeOp::Update { updates });
803
804 if !mem::take(&mut self.child.0.delegated) {
805 self.child.0.child.update(updates);
806 }
807 }
808
809 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
810 self.child.0.delegated = false;
811
812 let mut size = PxSize::zero();
813 (self.closure)(
814 &mut self.child,
815 UiNodeOp::Measure {
816 wm,
817 desired_size: &mut size,
818 },
819 );
820
821 if !mem::take(&mut self.child.0.delegated) {
822 if size != PxSize::zero() {
823 tracing::error!("measure changed size without flagging delegated in {:?}", WIDGET.id());
826 return size;
827 }
828
829 self.child.0.child.measure(wm)
830 } else {
831 size
832 }
833 }
834
835 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
836 self.child.0.delegated = false;
837
838 let mut size = PxSize::zero();
839 (self.closure)(&mut self.child, UiNodeOp::Layout { wl, final_size: &mut size });
840
841 if !mem::take(&mut self.child.0.delegated) {
842 if size != PxSize::zero() {
843 tracing::error!("layout changed size without flagging delegated in {:?}", WIDGET.id());
846 return size;
847 }
848
849 self.child.0.child.layout(wl)
850 } else {
851 #[cfg(debug_assertions)]
852 if self
853 .child
854 .0
855 .child
856 .with_context(WidgetUpdateMode::Ignore, || {
857 WIDGET.pending_update().contains(crate::update::UpdateFlags::LAYOUT)
858 })
859 .unwrap_or(false)
860 {
861 tracing::warn!(target: "match_widget-pending", "pending layout after layout delegated in {:?}", WIDGET.id());
863 }
864 size
865 }
866 }
867
868 fn render(&mut self, frame: &mut FrameBuilder) {
869 self.child.0.delegated = false;
870
871 (self.closure)(&mut self.child, UiNodeOp::Render { frame });
872
873 if !mem::take(&mut self.child.0.delegated) {
874 self.child.0.child.render(frame);
875 } else {
876 #[cfg(debug_assertions)]
877 if self
878 .child
879 .0
880 .child
881 .with_context(WidgetUpdateMode::Ignore, || {
882 WIDGET.pending_update().contains(crate::update::UpdateFlags::RENDER)
883 })
884 .unwrap_or(false)
885 {
886 tracing::warn!(target: "match_widget-pending", "pending render after render delegated in {:?}", WIDGET.id());
888 }
889 }
890 }
891
892 fn render_update(&mut self, update: &mut FrameUpdate) {
893 self.child.0.delegated = false;
894
895 (self.closure)(&mut self.child, UiNodeOp::RenderUpdate { update });
896
897 if !mem::take(&mut self.child.0.delegated) {
898 self.child.0.child.render_update(update);
899 } else {
900 #[cfg(debug_assertions)]
901 if self
902 .child
903 .0
904 .child
905 .with_context(WidgetUpdateMode::Ignore, || {
906 WIDGET.pending_update().contains(crate::update::UpdateFlags::RENDER_UPDATE)
907 })
908 .unwrap_or(false)
909 {
910 tracing::warn!(target: "match_widget-pending", "pending render_update after render_update delegated in {:?}", WIDGET.id());
912 }
913 }
914 }
915 }
916 MatchWidget {
917 child: MatchWidgetChild(MatchNodeChild { child, delegated: false }),
918 closure,
919 }
920}
921
922pub struct MatchWidgetChild<C>(MatchNodeChild<C>);
928impl<C> MatchWidgetChild<C> {
929 pub fn delegated(&mut self) {
933 self.0.delegated = true;
934 }
935
936 pub fn has_delegated(&self) -> bool {
938 self.0.delegated
939 }
940
941 pub fn child(&mut self) -> &mut C {
948 &mut self.0.child
949 }
950
951 pub fn as_match_node(&mut self) -> &mut MatchNodeChild<C> {
955 &mut self.0
956 }
957}
958#[ui_node(delegate = &mut self.0)]
959impl<C: UiNode> UiNode for MatchWidgetChild<C> {
960 fn is_widget(&self) -> bool {
961 self.0.child.is_widget()
962 }
963
964 fn with_context<R, F: FnOnce() -> R>(&mut self, update_mode: WidgetUpdateMode, f: F) -> Option<R> {
965 self.0.child.with_context(update_mode, f)
966 }
967}
968
969pub fn match_node_list<L: UiNodeList>(
974 children: L,
975 closure: impl FnMut(&mut MatchNodeChildren<L>, UiNodeOp) + Send + 'static,
976) -> impl UiNode {
977 #[ui_node(struct MatchNodeList<C: UiNodeList> {
978 children: MatchNodeChildren<C>,
979 closure: impl FnMut(&mut MatchNodeChildren<C>, UiNodeOp) + Send + 'static,
980 })]
981 #[allow_(zng::missing_delegate)] impl UiNode for MatchNodeList {
983 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
984 fn init(&mut self) {
985 self.children.delegated = false;
986
987 (self.closure)(&mut self.children, UiNodeOp::Init);
988
989 if !mem::take(&mut self.children.delegated) {
990 ui_node_list_default::init_all(&mut self.children.children);
991 }
992 }
993
994 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
995 fn deinit(&mut self) {
996 self.children.delegated = false;
997
998 (self.closure)(&mut self.children, UiNodeOp::Deinit);
999
1000 if !mem::take(&mut self.children.delegated) {
1001 ui_node_list_default::deinit_all(&mut self.children.children);
1002 }
1003 }
1004
1005 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
1006 fn info(&mut self, info: &mut WidgetInfoBuilder) {
1007 self.children.delegated = false;
1008
1009 (self.closure)(&mut self.children, UiNodeOp::Info { info });
1010
1011 if !mem::take(&mut self.children.delegated) {
1012 ui_node_list_default::info_all(&mut self.children.children, info)
1013 }
1014 }
1015
1016 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
1017 fn event(&mut self, update: &EventUpdate) {
1018 self.children.delegated = false;
1019
1020 (self.closure)(&mut self.children, UiNodeOp::Event { update });
1021
1022 if !mem::take(&mut self.children.delegated) {
1023 ui_node_list_default::event_all(&mut self.children.children, update);
1024 }
1025 }
1026
1027 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
1028 fn update(&mut self, updates: &WidgetUpdates) {
1029 self.children.delegated = false;
1030
1031 (self.closure)(&mut self.children, UiNodeOp::Update { updates });
1032
1033 if !mem::take(&mut self.children.delegated) {
1034 ui_node_list_default::update_all(&mut self.children.children, updates);
1035 }
1036 }
1037
1038 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
1039 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
1040 self.children.delegated = false;
1041
1042 let mut size = PxSize::zero();
1043 (self.closure)(
1044 &mut self.children,
1045 UiNodeOp::Measure {
1046 wm,
1047 desired_size: &mut size,
1048 },
1049 );
1050
1051 if !mem::take(&mut self.children.delegated) {
1052 if size != PxSize::zero() {
1053 tracing::error!("measure(list) changed size without flagging delegated");
1056 return size;
1057 }
1058
1059 ui_node_list_default::measure_all(&mut self.children.children, wm)
1060 } else {
1061 size
1062 }
1063 }
1064
1065 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
1066 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
1067 self.children.delegated = false;
1068
1069 let mut size = PxSize::zero();
1070 (self.closure)(&mut self.children, UiNodeOp::Layout { wl, final_size: &mut size });
1071
1072 if !mem::take(&mut self.children.delegated) {
1073 if size != PxSize::zero() {
1074 tracing::error!("layout(list) changed size without flagging delegated");
1077 return size;
1078 }
1079 ui_node_list_default::layout_all(&mut self.children.children, wl)
1080 } else {
1081 size
1082 }
1083 }
1084
1085 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
1086 fn render(&mut self, frame: &mut FrameBuilder) {
1087 self.children.delegated = false;
1088
1089 (self.closure)(&mut self.children, UiNodeOp::Render { frame });
1090
1091 if !mem::take(&mut self.children.delegated) {
1092 ui_node_list_default::render_all(&mut self.children.children, frame);
1093 }
1094 }
1095
1096 #[cfg_attr(not(feature = "dyn_closure"), inline(always))]
1097 fn render_update(&mut self, update: &mut FrameUpdate) {
1098 self.children.delegated = false;
1099
1100 (self.closure)(&mut self.children, UiNodeOp::RenderUpdate { update });
1101
1102 if !mem::take(&mut self.children.delegated) {
1103 ui_node_list_default::render_update_all(&mut self.children.children, update);
1104 }
1105 }
1106 }
1107 MatchNodeList {
1108 children: MatchNodeChildren {
1109 children,
1110 delegated: false,
1111 },
1112 closure,
1113 }
1114}
1115
1116pub struct MatchNodeChildren<L> {
1127 children: L,
1128 delegated: bool,
1129}
1130impl<L: UiNodeList> MatchNodeChildren<L> {
1131 pub fn delegated(&mut self) {
1135 self.delegated = true;
1136 }
1137
1138 pub fn has_delegated(&self) -> bool {
1140 self.delegated
1141 }
1142
1143 pub fn children(&mut self) -> &mut L {
1149 &mut self.children
1150 }
1151}
1152impl<L: UiNodeList> UiNodeList for MatchNodeChildren<L> {
1153 fn with_node<R, F>(&mut self, index: usize, f: F) -> R
1154 where
1155 F: FnOnce(&mut BoxedUiNode) -> R,
1156 {
1157 self.delegated = true;
1158 self.children.with_node(index, f)
1159 }
1160
1161 fn for_each<F>(&mut self, f: F)
1162 where
1163 F: FnMut(usize, &mut BoxedUiNode),
1164 {
1165 self.delegated = true;
1166 self.children.for_each(f)
1167 }
1168
1169 fn par_each<F>(&mut self, f: F)
1170 where
1171 F: Fn(usize, &mut BoxedUiNode) + Send + Sync,
1172 {
1173 self.delegated = true;
1174 self.children.par_each(f)
1175 }
1176
1177 fn par_fold_reduce<T, I, F, R>(&mut self, identity: I, fold: F, reduce: R) -> T
1178 where
1179 T: Send + 'static,
1180 I: Fn() -> T + Send + Sync,
1181 F: Fn(T, usize, &mut BoxedUiNode) -> T + Send + Sync,
1182 R: Fn(T, T) -> T + Send + Sync,
1183 {
1184 self.delegated = true;
1185 self.children.par_fold_reduce(identity, fold, reduce)
1186 }
1187
1188 fn len(&self) -> usize {
1189 self.children.len()
1190 }
1191
1192 fn boxed(self) -> BoxedUiNodeList {
1193 Box::new(self)
1194 }
1195
1196 fn drain_into(&mut self, vec: &mut Vec<BoxedUiNode>) {
1197 self.children.drain_into(vec)
1198 }
1199
1200 fn init_all(&mut self) {
1201 self.children.init_all();
1202 self.delegated = true;
1203 }
1204
1205 fn deinit_all(&mut self) {
1206 self.children.deinit_all();
1207 self.delegated = true;
1208 }
1209
1210 fn update_all(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
1211 self.children.update_all(updates, observer);
1212 self.delegated = true;
1213 }
1214
1215 fn info_all(&mut self, info: &mut WidgetInfoBuilder) {
1216 self.children.info_all(info);
1217 self.delegated = true;
1218 }
1219
1220 fn event_all(&mut self, update: &EventUpdate) {
1221 self.children.event_all(update);
1222 self.delegated = true;
1223 }
1224
1225 fn measure_each<F, S>(&mut self, wm: &mut WidgetMeasure, measure: F, fold_size: S) -> PxSize
1226 where
1227 F: Fn(usize, &mut BoxedUiNode, &mut WidgetMeasure) -> PxSize + Send + Sync,
1228 S: Fn(PxSize, PxSize) -> PxSize + Send + Sync,
1229 {
1230 self.delegated = true;
1231 self.children.measure_each(wm, measure, fold_size)
1232 }
1233
1234 fn layout_each<F, S>(&mut self, wl: &mut WidgetLayout, layout: F, fold_size: S) -> PxSize
1235 where
1236 F: Fn(usize, &mut BoxedUiNode, &mut WidgetLayout) -> PxSize + Send + Sync,
1237 S: Fn(PxSize, PxSize) -> PxSize + Send + Sync,
1238 {
1239 self.delegated = true;
1240 self.children.layout_each(wl, layout, fold_size)
1241 }
1242
1243 fn render_all(&mut self, frame: &mut FrameBuilder) {
1244 self.children.render_all(frame);
1245 self.delegated = true;
1246 }
1247
1248 fn render_update_all(&mut self, update: &mut FrameUpdate) {
1249 self.children.render_update_all(update);
1250 self.delegated = true;
1251 }
1252}