1use std::{fmt, mem, ops};
2
3use zng_layout::unit::PxSize;
4
5use crate::{
6 render::{FrameBuilder, FrameUpdate},
7 update::WidgetUpdates,
8 widget::info::{WidgetInfoBuilder, WidgetLayout, WidgetMeasure},
9};
10
11use super::*;
12
13#[non_exhaustive]
17pub enum UiNodeOp<'a> {
18 Init,
29 Deinit,
39 Info {
56 info: &'a mut WidgetInfoBuilder,
58 },
59 Update {
77 updates: &'a WidgetUpdates,
79 },
80 Measure {
97 wm: &'a mut WidgetMeasure,
99 desired_size: &'a mut PxSize,
101 },
102 Layout {
124 wl: &'a mut WidgetLayout,
126 final_size: &'a mut PxSize,
128 },
129 Render {
139 frame: &'a mut FrameBuilder,
141 },
142 RenderUpdate {
154 update: &'a mut FrameUpdate,
156 },
157}
158impl<'a> UiNodeOp<'a> {
159 pub fn mtd(&self) -> UiNodeMethod {
161 match self {
162 UiNodeOp::Init => UiNodeMethod::Init,
163 UiNodeOp::Deinit => UiNodeMethod::Deinit,
164 UiNodeOp::Info { .. } => UiNodeMethod::Info,
165 UiNodeOp::Update { .. } => UiNodeMethod::Update,
166 UiNodeOp::Measure { .. } => UiNodeMethod::Measure,
167 UiNodeOp::Layout { .. } => UiNodeMethod::Layout,
168 UiNodeOp::Render { .. } => UiNodeMethod::Render,
169 UiNodeOp::RenderUpdate { .. } => UiNodeMethod::RenderUpdate,
170 }
171 }
172
173 pub fn reborrow(&mut self) -> UiNodeOp<'_> {
175 match self {
176 UiNodeOp::Init => UiNodeOp::Init,
177 UiNodeOp::Deinit => UiNodeOp::Deinit,
178 UiNodeOp::Info { info } => UiNodeOp::Info { info },
179 UiNodeOp::Update { updates } => UiNodeOp::Update { updates },
180 UiNodeOp::Measure { wm, desired_size } => UiNodeOp::Measure { wm, desired_size },
181 UiNodeOp::Layout { wl, final_size } => UiNodeOp::Layout { wl, final_size },
182 UiNodeOp::Render { frame } => UiNodeOp::Render { frame },
183 UiNodeOp::RenderUpdate { update } => UiNodeOp::RenderUpdate { update },
184 }
185 }
186}
187impl fmt::Debug for UiNodeOp<'_> {
188 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
189 match self {
190 Self::Update { updates } => f.debug_struct("Update").field("updates", updates).finish(),
191 op => write!(f, "{}", op.mtd()),
192 }
193 }
194}
195
196#[derive(Clone, Copy, serde::Serialize, serde::Deserialize)]
198#[non_exhaustive]
199pub enum UiNodeMethod {
200 Init,
202 Deinit,
204 Info,
206 Update,
208 UpdateList,
210 Measure,
212 MeasureList,
214 Layout,
216 LayoutList,
218 Render,
220 RenderList,
222 RenderUpdate,
224 RenderUpdateList,
226}
227impl UiNodeMethod {
228 pub fn enum_name(self) -> &'static str {
230 match self {
231 UiNodeMethod::Init => "Init",
232 UiNodeMethod::Deinit => "Deinit",
233 UiNodeMethod::Info => "Info",
234 UiNodeMethod::Update => "Update",
235 UiNodeMethod::UpdateList => "UpdateList",
236 UiNodeMethod::Measure => "Measure",
237 UiNodeMethod::MeasureList => "MeasureList",
238 UiNodeMethod::Layout => "Layout",
239 UiNodeMethod::LayoutList => "LayoutList",
240 UiNodeMethod::Render => "Render",
241 UiNodeMethod::RenderList => "RenderList",
242 UiNodeMethod::RenderUpdate => "RenderUpdate",
243 UiNodeMethod::RenderUpdateList => "RenderUpdateList",
244 }
245 }
246
247 pub fn mtd_name(self) -> &'static str {
249 match self {
250 UiNodeMethod::Init => "init",
251 UiNodeMethod::Deinit => "deinit",
252 UiNodeMethod::Info => "info",
253 UiNodeMethod::Update => "update",
254 UiNodeMethod::UpdateList => "update_list",
255 UiNodeMethod::Measure => "measure",
256 UiNodeMethod::MeasureList => "measure_list",
257 UiNodeMethod::Layout => "layout",
258 UiNodeMethod::LayoutList => "layout_list",
259 UiNodeMethod::Render => "render",
260 UiNodeMethod::RenderList => "render_list",
261 UiNodeMethod::RenderUpdate => "render_update",
262 UiNodeMethod::RenderUpdateList => "render_update_list",
263 }
264 }
265}
266impl fmt::Debug for UiNodeMethod {
267 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
268 fmt::Display::fmt(self, f)
269 }
270}
271impl fmt::Display for UiNodeMethod {
272 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
273 if f.alternate() {
274 write!(f, "{}", self.enum_name())
275 } else {
276 write!(f, "{}", self.mtd_name())
277 }
278 }
279}
280
281pub fn match_node(child: impl IntoUiNode, closure: impl FnMut(&mut MatchNodeChild, UiNodeOp) + Send + 'static) -> UiNode {
336 match_node_impl(child.into_node(), closure)
337}
338
339fn match_node_impl(child: UiNode, closure: impl FnMut(&mut MatchNodeChild, UiNodeOp) + Send + 'static) -> UiNode {
340 struct MatchNode<F> {
341 child: MatchNodeChild,
342 closure: F,
343 }
344 impl<F: FnMut(&mut MatchNodeChild, UiNodeOp) + Send + 'static> UiNodeImpl for MatchNode<F> {
345 fn children_len(&self) -> usize {
346 1
347 }
348
349 fn with_child(&mut self, index: usize, visitor: &mut dyn FnMut(&mut UiNode)) {
350 if index == 0 {
351 visitor(&mut self.child.node)
352 }
353 }
354
355 fn init(&mut self) {
356 self.child.delegated = false;
357
358 (self.closure)(&mut self.child, UiNodeOp::Init);
359
360 if !mem::take(&mut self.child.delegated) {
361 self.child.node.0.init();
362 }
363 }
364
365 fn deinit(&mut self) {
366 self.child.delegated = false;
367
368 (self.closure)(&mut self.child, UiNodeOp::Deinit);
369
370 if !mem::take(&mut self.child.delegated) {
371 self.child.node.0.deinit();
372 }
373 }
374
375 fn info(&mut self, info: &mut WidgetInfoBuilder) {
376 self.child.delegated = false;
377
378 (self.closure)(&mut self.child, UiNodeOp::Info { info });
379
380 if !mem::take(&mut self.child.delegated) {
381 self.child.node.0.info(info);
382 }
383 }
384
385 fn update(&mut self, updates: &WidgetUpdates) {
386 self.child.delegated = false;
387
388 (self.closure)(&mut self.child, UiNodeOp::Update { updates });
389
390 if !mem::take(&mut self.child.delegated) {
391 self.child.node.0.update(updates);
392 }
393 }
394
395 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
396 self.child.delegated = false;
397
398 let mut size = PxSize::zero();
399 (self.closure)(
400 &mut self.child,
401 UiNodeOp::Measure {
402 wm,
403 desired_size: &mut size,
404 },
405 );
406
407 if !mem::take(&mut self.child.delegated) {
408 if size != PxSize::zero() {
409 tracing::error!("measure changed size without flagging delegated");
412 return size;
413 }
414
415 self.child.node.0.measure(wm)
416 } else {
417 size
418 }
419 }
420
421 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
422 self.child.delegated = false;
423
424 let mut size = PxSize::zero();
425 (self.closure)(&mut self.child, UiNodeOp::Layout { wl, final_size: &mut size });
426
427 if !mem::take(&mut self.child.delegated) {
428 if size != PxSize::zero() {
429 tracing::error!("layout changed size without flagging delegated");
432 return size;
433 }
434
435 self.child.node.0.layout(wl)
436 } else {
437 size
438 }
439 }
440
441 fn render(&mut self, frame: &mut FrameBuilder) {
442 self.child.delegated = false;
443
444 (self.closure)(&mut self.child, UiNodeOp::Render { frame });
445
446 if !mem::take(&mut self.child.delegated) {
447 self.child.node.0.render(frame);
448 }
449 }
450
451 fn render_update(&mut self, update: &mut FrameUpdate) {
452 self.child.delegated = false;
453
454 (self.closure)(&mut self.child, UiNodeOp::RenderUpdate { update });
455
456 if !mem::take(&mut self.child.delegated) {
457 self.child.node.0.render_update(update);
458 }
459 }
460
461 fn is_list(&self) -> bool {
462 false
463 }
464
465 fn for_each_child(&mut self, visitor: &mut dyn FnMut(usize, &mut UiNode)) {
466 visitor(0, &mut self.child.node)
467 }
468
469 fn try_for_each_child(
470 &mut self,
471 visitor: &mut dyn FnMut(usize, &mut UiNode) -> ControlFlow<BoxAnyVarValue>,
472 ) -> ControlFlow<BoxAnyVarValue> {
473 visitor(0, &mut self.child.node)
474 }
475
476 fn par_each_child(&mut self, visitor: &(dyn Fn(usize, &mut UiNode) + Sync)) {
477 visitor(0, &mut self.child.node)
478 }
479
480 fn par_fold_reduce(
481 &mut self,
482 identity: BoxAnyVarValue,
483 fold: &(dyn Fn(BoxAnyVarValue, usize, &mut UiNode) -> BoxAnyVarValue + Sync),
484 _: &(dyn Fn(BoxAnyVarValue, BoxAnyVarValue) -> BoxAnyVarValue + Sync),
485 ) -> BoxAnyVarValue {
486 fold(identity, 0, &mut self.child.node)
487 }
488
489 fn update_list(&mut self, updates: &WidgetUpdates, _: &mut dyn UiNodeListObserver) {
490 self.update(updates);
491 }
492
493 fn measure_list(
494 &mut self,
495 wm: &mut WidgetMeasure,
496 _: &(dyn Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync),
497 _: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
498 ) -> PxSize {
499 self.measure(wm)
500 }
501
502 fn layout_list(
503 &mut self,
504 wl: &mut WidgetLayout,
505 _: &(dyn Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync),
506 _: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
507 ) -> PxSize {
508 self.layout(wl)
509 }
510
511 fn render_list(&mut self, frame: &mut FrameBuilder, _: &(dyn Fn(usize, &mut UiNode, &mut FrameBuilder) + Sync)) {
512 self.render(frame)
513 }
514
515 fn render_update_list(&mut self, update: &mut FrameUpdate, _: &(dyn Fn(usize, &mut UiNode, &mut FrameUpdate) + Sync)) {
516 self.render_update(update);
517 }
518
519 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
520 None
521 }
522 }
523 MatchNode {
524 child: MatchNodeChild {
525 node: child,
526 delegated: false,
527 },
528 closure,
529 }
530 .into_node()
531}
532
533pub struct MatchNodeChild {
539 node: UiNode,
540 delegated: bool,
541}
542impl MatchNodeChild {
543 #[inline(always)]
547 pub fn delegated(&mut self) {
548 self.delegated = true;
549 }
550
551 #[inline(always)]
553 pub fn has_delegated(&self) -> bool {
554 self.delegated
555 }
556
557 #[inline(always)]
563 pub fn node(&mut self) -> &mut UiNode {
564 &mut self.node
565 }
566 #[inline(always)]
576 pub fn node_impl<U: UiNodeImpl>(&mut self) -> &mut U {
577 self.node.downcast_mut::<U>().unwrap()
578 }
579
580 #[inline(always)]
582 pub fn init(&mut self) {
583 self.node.0.init();
584 self.delegated = true;
585 }
586
587 #[inline(always)]
589 pub fn deinit(&mut self) {
590 self.node.0.deinit();
591 self.delegated = true;
592 }
593
594 #[inline(always)]
596 pub fn info(&mut self, info: &mut WidgetInfoBuilder) {
597 self.node.0.info(info);
598 self.delegated = true;
599 }
600
601 #[inline(always)]
603 pub fn update(&mut self, updates: &WidgetUpdates) {
604 self.node.0.update(updates);
605 self.delegated = true;
606 }
607
608 #[inline(always)]
610 pub fn update_list(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
611 self.node.0.update_list(updates, observer);
612 self.delegated = true;
613 }
614
615 #[inline(always)]
617 #[must_use]
618 pub fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
619 self.delegated = true;
620 self.node.0.measure(wm)
621 }
622
623 #[inline(always)]
625 #[must_use]
626 pub fn measure_list(
627 &mut self,
628 wm: &mut WidgetMeasure,
629 measure: impl Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync,
630 fold_size: impl Fn(PxSize, PxSize) -> PxSize + Sync,
631 ) -> PxSize {
632 self.delegated = true;
633 self.node.0.measure_list(wm, &measure, &fold_size)
634 }
635
636 #[inline(always)]
638 #[must_use]
639 pub fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
640 self.delegated = true;
641 self.node.0.layout(wl)
642 }
643
644 #[inline(always)]
646 #[must_use]
647 pub fn layout_list(
648 &mut self,
649 wl: &mut WidgetLayout,
650 layout: impl Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync,
651 fold_size: impl Fn(PxSize, PxSize) -> PxSize + Sync,
652 ) -> PxSize {
653 self.delegated = true;
654 self.node.0.layout_list(wl, &layout, &fold_size)
655 }
656
657 #[inline(always)]
659 pub fn render(&mut self, frame: &mut FrameBuilder) {
660 self.node.0.render(frame);
661 self.delegated = true;
662 }
663
664 #[inline(always)]
666 pub fn render_list(&mut self, frame: &mut FrameBuilder, render: impl Fn(usize, &mut UiNode, &mut FrameBuilder) + Sync) {
667 self.node.render_list(frame, render);
668 self.delegated = true;
669 }
670
671 #[inline(always)]
673 pub fn render_update(&mut self, update: &mut FrameUpdate) {
674 self.node.0.render_update(update);
675 self.delegated = true;
676 }
677
678 #[inline(always)]
680 pub fn render_update_list(&mut self, update: &mut FrameUpdate, render_update: impl Fn(usize, &mut UiNode, &mut FrameUpdate) + Sync) {
681 self.node.render_update_list(update, render_update);
682 }
683
684 #[inline(always)]
686 pub fn op(&mut self, op: UiNodeOp) {
687 self.node.op(op);
688 self.delegated = true;
689 }
690}
691
692pub fn match_node_leaf(closure: impl FnMut(UiNodeOp) + Send + 'static) -> UiNode {
694 struct MatchNodeLeaf<F> {
695 closure: F,
696 }
697 impl<F: FnMut(UiNodeOp) + Send + 'static> UiNodeImpl for MatchNodeLeaf<F> {
698 fn children_len(&self) -> usize {
699 0
700 }
701 fn with_child(&mut self, _: usize, _: &mut dyn FnMut(&mut UiNode)) {}
702
703 fn init(&mut self) {
704 (self.closure)(UiNodeOp::Init);
705 }
706
707 fn deinit(&mut self) {
708 (self.closure)(UiNodeOp::Deinit);
709 }
710
711 fn info(&mut self, info: &mut WidgetInfoBuilder) {
712 (self.closure)(UiNodeOp::Info { info });
713 }
714
715 fn update(&mut self, updates: &WidgetUpdates) {
716 (self.closure)(UiNodeOp::Update { updates });
717 }
718
719 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
720 let mut size = PxSize::zero();
721 (self.closure)(UiNodeOp::Measure {
722 wm,
723 desired_size: &mut size,
724 });
725 size
726 }
727
728 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
729 let mut size = PxSize::zero();
730 (self.closure)(UiNodeOp::Layout { wl, final_size: &mut size });
731 size
732 }
733
734 fn render(&mut self, frame: &mut FrameBuilder) {
735 (self.closure)(UiNodeOp::Render { frame });
736 }
737
738 fn render_update(&mut self, update: &mut FrameUpdate) {
739 (self.closure)(UiNodeOp::RenderUpdate { update });
740 }
741
742 fn is_list(&self) -> bool {
743 false
744 }
745
746 fn for_each_child(&mut self, _: &mut dyn FnMut(usize, &mut UiNode)) {}
747
748 fn try_for_each_child(
749 &mut self,
750 _: &mut dyn FnMut(usize, &mut UiNode) -> ControlFlow<BoxAnyVarValue>,
751 ) -> ControlFlow<BoxAnyVarValue> {
752 ControlFlow::Continue(())
753 }
754
755 fn par_each_child(&mut self, _: &(dyn Fn(usize, &mut UiNode) + Sync)) {}
756
757 fn par_fold_reduce(
758 &mut self,
759 identity: BoxAnyVarValue,
760 _: &(dyn Fn(BoxAnyVarValue, usize, &mut UiNode) -> BoxAnyVarValue + Sync),
761 _: &(dyn Fn(BoxAnyVarValue, BoxAnyVarValue) -> BoxAnyVarValue + Sync),
762 ) -> BoxAnyVarValue {
763 identity
764 }
765
766 fn update_list(&mut self, updates: &WidgetUpdates, _: &mut dyn UiNodeListObserver) {
767 self.update(updates);
768 }
769
770 fn measure_list(
771 &mut self,
772 wm: &mut WidgetMeasure,
773 _: &(dyn Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync),
774 _: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
775 ) -> PxSize {
776 self.measure(wm)
777 }
778
779 fn layout_list(
780 &mut self,
781 wl: &mut WidgetLayout,
782 _: &(dyn Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync),
783 _: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
784 ) -> PxSize {
785 self.layout(wl)
786 }
787
788 fn render_list(&mut self, frame: &mut FrameBuilder, _: &(dyn Fn(usize, &mut UiNode, &mut FrameBuilder) + Sync)) {
789 self.render(frame);
790 }
791
792 fn render_update_list(&mut self, update: &mut FrameUpdate, _: &(dyn Fn(usize, &mut UiNode, &mut FrameUpdate) + Sync)) {
793 self.render_update(update);
794 }
795
796 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
797 None
798 }
799 }
800 UiNode::new(MatchNodeLeaf { closure })
801}
802
803pub fn match_widget(child: impl IntoUiNode, closure: impl FnMut(&mut MatchWidgetChild, UiNodeOp) + Send + 'static) -> UiNode {
809 struct MatchWidget<F> {
810 child: MatchWidgetChild,
811 closure: F,
812 }
813 impl<F: FnMut(&mut MatchWidgetChild, UiNodeOp) + Send + 'static> UiNodeImpl for MatchWidget<F> {
814 fn children_len(&self) -> usize {
815 1
816 }
817
818 fn with_child(&mut self, index: usize, visitor: &mut dyn FnMut(&mut UiNode)) {
819 if index == 0 {
820 visitor(&mut self.child.node)
821 }
822 }
823
824 fn init(&mut self) {
825 self.child.0.delegated = false;
826
827 (self.closure)(&mut self.child, UiNodeOp::Init);
828
829 if !mem::take(&mut self.child.0.delegated) {
830 self.child.0.node.0.init();
831 }
832 }
833
834 fn deinit(&mut self) {
835 self.child.0.delegated = false;
836
837 (self.closure)(&mut self.child, UiNodeOp::Deinit);
838
839 if !mem::take(&mut self.child.0.delegated) {
840 self.child.0.node.0.deinit();
841 }
842 }
843
844 fn info(&mut self, info: &mut WidgetInfoBuilder) {
845 self.child.0.delegated = false;
846
847 (self.closure)(&mut self.child, UiNodeOp::Info { info });
848
849 if !mem::take(&mut self.child.0.delegated) {
850 self.child.0.node.0.info(info);
851 } else {
852 #[cfg(debug_assertions)]
853 if self
854 .child
855 .0
856 .node
857 .as_widget()
858 .map(|mut w| {
859 w.with_context(crate::widget::WidgetUpdateMode::Ignore, || {
860 WIDGET.pending_update().contains(crate::update::UpdateFlags::INFO)
861 })
862 })
863 .unwrap_or(false)
864 {
865 tracing::warn!(target: "match_widget-pending", "pending info build after info delegated in {:?}", WIDGET.id());
867 }
868 }
869 }
870
871 fn update(&mut self, updates: &WidgetUpdates) {
872 self.child.0.delegated = false;
873
874 (self.closure)(&mut self.child, UiNodeOp::Update { updates });
875
876 if !mem::take(&mut self.child.0.delegated) {
877 self.child.0.node.0.update(updates);
878 }
879 }
880
881 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
882 self.child.0.delegated = false;
883
884 let mut size = PxSize::zero();
885 (self.closure)(
886 &mut self.child,
887 UiNodeOp::Measure {
888 wm,
889 desired_size: &mut size,
890 },
891 );
892
893 if !mem::take(&mut self.child.0.delegated) {
894 if size != PxSize::zero() {
895 tracing::error!("measure changed size without flagging delegated in {:?}", WIDGET.id());
898 return size;
899 }
900
901 self.child.0.node.0.measure(wm)
902 } else {
903 size
904 }
905 }
906
907 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
908 self.child.0.delegated = false;
909
910 let mut size = PxSize::zero();
911 (self.closure)(&mut self.child, UiNodeOp::Layout { wl, final_size: &mut size });
912
913 if !mem::take(&mut self.child.0.delegated) {
914 if size != PxSize::zero() {
915 tracing::error!("layout changed size without flagging delegated in {:?}", WIDGET.id());
918 return size;
919 }
920
921 self.child.0.node.0.layout(wl)
922 } else {
923 #[cfg(debug_assertions)]
924 if self
925 .child
926 .0
927 .node
928 .as_widget()
929 .map(|mut w| {
930 w.with_context(crate::widget::WidgetUpdateMode::Ignore, || {
931 WIDGET.pending_update().contains(crate::update::UpdateFlags::LAYOUT)
932 })
933 })
934 .unwrap_or(false)
935 {
936 tracing::warn!(target: "match_widget-pending", "pending layout after layout delegated in {:?}", WIDGET.id());
938 }
939 size
940 }
941 }
942
943 fn render(&mut self, frame: &mut FrameBuilder) {
944 self.child.0.delegated = false;
945
946 (self.closure)(&mut self.child, UiNodeOp::Render { frame });
947
948 if !mem::take(&mut self.child.0.delegated) {
949 self.child.0.node.0.render(frame);
950 } else {
951 #[cfg(debug_assertions)]
952 if self
953 .child
954 .0
955 .node
956 .as_widget()
957 .map(|mut w| {
958 w.with_context(crate::widget::WidgetUpdateMode::Ignore, || {
959 WIDGET.pending_update().contains(crate::update::UpdateFlags::RENDER)
960 })
961 })
962 .unwrap_or(false)
963 {
964 tracing::warn!(target: "match_widget-pending", "pending render after render delegated in {:?}", WIDGET.id());
966 }
967 }
968 }
969
970 fn render_update(&mut self, update: &mut FrameUpdate) {
971 self.child.0.delegated = false;
972
973 (self.closure)(&mut self.child, UiNodeOp::RenderUpdate { update });
974
975 if !mem::take(&mut self.child.0.delegated) {
976 self.child.0.node.0.render_update(update);
977 } else {
978 #[cfg(debug_assertions)]
979 if self
980 .child
981 .0
982 .node
983 .as_widget()
984 .map(|mut w| {
985 w.with_context(crate::widget::WidgetUpdateMode::Ignore, || {
986 WIDGET.pending_update().contains(crate::update::UpdateFlags::RENDER_UPDATE)
987 })
988 })
989 .unwrap_or(false)
990 {
991 tracing::warn!(target: "match_widget-pending", "pending render_update after render_update delegated in {:?}", WIDGET.id());
993 }
994 }
995 }
996
997 fn is_list(&self) -> bool {
998 false
999 }
1000
1001 fn for_each_child(&mut self, visitor: &mut dyn FnMut(usize, &mut UiNode)) {
1002 visitor(0, &mut self.child.node)
1003 }
1004
1005 fn try_for_each_child(
1006 &mut self,
1007 visitor: &mut dyn FnMut(usize, &mut UiNode) -> ControlFlow<BoxAnyVarValue>,
1008 ) -> ControlFlow<BoxAnyVarValue> {
1009 visitor(0, &mut self.child.node)
1010 }
1011
1012 fn par_each_child(&mut self, visitor: &(dyn Fn(usize, &mut UiNode) + Sync)) {
1013 visitor(0, &mut self.child.node)
1014 }
1015
1016 fn par_fold_reduce(
1017 &mut self,
1018 identity: BoxAnyVarValue,
1019 fold: &(dyn Fn(BoxAnyVarValue, usize, &mut UiNode) -> BoxAnyVarValue + Sync),
1020 _: &(dyn Fn(BoxAnyVarValue, BoxAnyVarValue) -> BoxAnyVarValue + Sync),
1021 ) -> BoxAnyVarValue {
1022 fold(identity, 0, &mut self.child.node)
1023 }
1024
1025 fn update_list(&mut self, updates: &WidgetUpdates, _: &mut dyn UiNodeListObserver) {
1026 self.update(updates);
1027 }
1028
1029 fn measure_list(
1030 &mut self,
1031 wm: &mut WidgetMeasure,
1032 _: &(dyn Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync),
1033 _: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
1034 ) -> PxSize {
1035 self.measure(wm)
1036 }
1037
1038 fn layout_list(
1039 &mut self,
1040 wl: &mut WidgetLayout,
1041 _: &(dyn Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync),
1042 _: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
1043 ) -> PxSize {
1044 self.layout(wl)
1045 }
1046
1047 fn render_list(&mut self, frame: &mut FrameBuilder, _: &(dyn Fn(usize, &mut UiNode, &mut FrameBuilder) + Sync)) {
1048 self.render(frame);
1049 }
1050
1051 fn render_update_list(&mut self, update: &mut FrameUpdate, _: &(dyn Fn(usize, &mut UiNode, &mut FrameUpdate) + Sync)) {
1052 self.render_update(update);
1053 }
1054
1055 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
1056 self.child.node.0.as_widget()
1057 }
1058 }
1059 MatchWidget {
1060 child: MatchWidgetChild(MatchNodeChild {
1061 node: child.into_node(),
1062 delegated: false,
1063 }),
1064 closure,
1065 }
1066 .into_node()
1067}
1068
1069pub struct MatchWidgetChild(MatchNodeChild);
1075impl ops::Deref for MatchWidgetChild {
1076 type Target = MatchNodeChild;
1077
1078 fn deref(&self) -> &Self::Target {
1079 &self.0
1080 }
1081}
1082impl ops::DerefMut for MatchWidgetChild {
1083 fn deref_mut(&mut self) -> &mut Self::Target {
1084 &mut self.0
1085 }
1086}