1use std::{fmt, mem, ops};
2
3use zng_layout::unit::PxSize;
4
5use crate::{
6 render::{FrameBuilder, FrameUpdate},
7 update::{EventUpdate, 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 Event {
76 update: &'a EventUpdate,
78 },
79 Update {
94 updates: &'a WidgetUpdates,
96 },
97 Measure {
114 wm: &'a mut WidgetMeasure,
116 desired_size: &'a mut PxSize,
118 },
119 Layout {
141 wl: &'a mut WidgetLayout,
143 final_size: &'a mut PxSize,
145 },
146 Render {
156 frame: &'a mut FrameBuilder,
158 },
159 RenderUpdate {
171 update: &'a mut FrameUpdate,
173 },
174}
175impl<'a> UiNodeOp<'a> {
176 pub fn mtd(&self) -> UiNodeMethod {
178 match self {
179 UiNodeOp::Init => UiNodeMethod::Init,
180 UiNodeOp::Deinit => UiNodeMethod::Deinit,
181 UiNodeOp::Info { .. } => UiNodeMethod::Info,
182 UiNodeOp::Event { .. } => UiNodeMethod::Event,
183 UiNodeOp::Update { .. } => UiNodeMethod::Update,
184 UiNodeOp::Measure { .. } => UiNodeMethod::Measure,
185 UiNodeOp::Layout { .. } => UiNodeMethod::Layout,
186 UiNodeOp::Render { .. } => UiNodeMethod::Render,
187 UiNodeOp::RenderUpdate { .. } => UiNodeMethod::RenderUpdate,
188 }
189 }
190
191 pub fn reborrow(&mut self) -> UiNodeOp<'_> {
193 match self {
194 UiNodeOp::Init => UiNodeOp::Init,
195 UiNodeOp::Deinit => UiNodeOp::Deinit,
196 UiNodeOp::Info { info } => UiNodeOp::Info { info },
197 UiNodeOp::Event { update } => UiNodeOp::Event { update },
198 UiNodeOp::Update { updates } => UiNodeOp::Update { updates },
199 UiNodeOp::Measure { wm, desired_size } => UiNodeOp::Measure { wm, desired_size },
200 UiNodeOp::Layout { wl, final_size } => UiNodeOp::Layout { wl, final_size },
201 UiNodeOp::Render { frame } => UiNodeOp::Render { frame },
202 UiNodeOp::RenderUpdate { update } => UiNodeOp::RenderUpdate { update },
203 }
204 }
205}
206impl fmt::Debug for UiNodeOp<'_> {
207 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
208 match self {
209 Self::Event { update } => f.debug_struct("Event").field("update", update).finish(),
210 Self::Update { updates } => f.debug_struct("Update").field("updates", updates).finish(),
211 op => write!(f, "{}", op.mtd()),
212 }
213 }
214}
215
216#[derive(Clone, Copy, serde::Serialize, serde::Deserialize)]
218#[non_exhaustive]
219pub enum UiNodeMethod {
220 Init,
222 Deinit,
224 Info,
226 Event,
228 Update,
230 UpdateList,
232 Measure,
234 MeasureList,
236 Layout,
238 LayoutList,
240 Render,
242 RenderList,
244 RenderUpdate,
246 RenderUpdateList,
248}
249impl UiNodeMethod {
250 pub fn enum_name(self) -> &'static str {
252 match self {
253 UiNodeMethod::Init => "Init",
254 UiNodeMethod::Deinit => "Deinit",
255 UiNodeMethod::Info => "Info",
256 UiNodeMethod::Event => "Event",
257 UiNodeMethod::Update => "Update",
258 UiNodeMethod::UpdateList => "UpdateList",
259 UiNodeMethod::Measure => "Measure",
260 UiNodeMethod::MeasureList => "MeasureList",
261 UiNodeMethod::Layout => "Layout",
262 UiNodeMethod::LayoutList => "LayoutList",
263 UiNodeMethod::Render => "Render",
264 UiNodeMethod::RenderList => "RenderList",
265 UiNodeMethod::RenderUpdate => "RenderUpdate",
266 UiNodeMethod::RenderUpdateList => "RenderUpdateList",
267 }
268 }
269
270 pub fn mtd_name(self) -> &'static str {
272 match self {
273 UiNodeMethod::Init => "init",
274 UiNodeMethod::Deinit => "deinit",
275 UiNodeMethod::Info => "info",
276 UiNodeMethod::Event => "event",
277 UiNodeMethod::Update => "update",
278 UiNodeMethod::UpdateList => "update_list",
279 UiNodeMethod::Measure => "measure",
280 UiNodeMethod::MeasureList => "measure_list",
281 UiNodeMethod::Layout => "layout",
282 UiNodeMethod::LayoutList => "layout_list",
283 UiNodeMethod::Render => "render",
284 UiNodeMethod::RenderList => "render_list",
285 UiNodeMethod::RenderUpdate => "render_update",
286 UiNodeMethod::RenderUpdateList => "render_update_list",
287 }
288 }
289}
290impl fmt::Debug for UiNodeMethod {
291 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
292 fmt::Display::fmt(self, f)
293 }
294}
295impl fmt::Display for UiNodeMethod {
296 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
297 if f.alternate() {
298 write!(f, "{}", self.enum_name())
299 } else {
300 write!(f, "{}", self.mtd_name())
301 }
302 }
303}
304
305pub fn match_node(child: impl IntoUiNode, closure: impl FnMut(&mut MatchNodeChild, UiNodeOp) + Send + 'static) -> UiNode {
360 match_node_impl(child.into_node(), closure)
361}
362
363fn match_node_impl(child: UiNode, closure: impl FnMut(&mut MatchNodeChild, UiNodeOp) + Send + 'static) -> UiNode {
364 struct MatchNode<F> {
365 child: MatchNodeChild,
366 closure: F,
367 }
368 impl<F: FnMut(&mut MatchNodeChild, UiNodeOp) + Send + 'static> UiNodeImpl for MatchNode<F> {
369 fn children_len(&self) -> usize {
370 1
371 }
372
373 fn with_child(&mut self, index: usize, visitor: &mut dyn FnMut(&mut UiNode)) {
374 if index == 0 {
375 visitor(&mut self.child.node)
376 }
377 }
378
379 fn init(&mut self) {
380 self.child.delegated = false;
381
382 (self.closure)(&mut self.child, UiNodeOp::Init);
383
384 if !mem::take(&mut self.child.delegated) {
385 self.child.node.0.init();
386 }
387 }
388
389 fn deinit(&mut self) {
390 self.child.delegated = false;
391
392 (self.closure)(&mut self.child, UiNodeOp::Deinit);
393
394 if !mem::take(&mut self.child.delegated) {
395 self.child.node.0.deinit();
396 }
397 }
398
399 fn info(&mut self, info: &mut WidgetInfoBuilder) {
400 self.child.delegated = false;
401
402 (self.closure)(&mut self.child, UiNodeOp::Info { info });
403
404 if !mem::take(&mut self.child.delegated) {
405 self.child.node.0.info(info);
406 }
407 }
408
409 fn event(&mut self, update: &EventUpdate) {
410 self.child.delegated = false;
411
412 (self.closure)(&mut self.child, UiNodeOp::Event { update });
413
414 if !mem::take(&mut self.child.delegated) {
415 self.child.node.0.event(update);
416 }
417 }
418
419 fn update(&mut self, updates: &WidgetUpdates) {
420 self.child.delegated = false;
421
422 (self.closure)(&mut self.child, UiNodeOp::Update { updates });
423
424 if !mem::take(&mut self.child.delegated) {
425 self.child.node.0.update(updates);
426 }
427 }
428
429 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
430 self.child.delegated = false;
431
432 let mut size = PxSize::zero();
433 (self.closure)(
434 &mut self.child,
435 UiNodeOp::Measure {
436 wm,
437 desired_size: &mut size,
438 },
439 );
440
441 if !mem::take(&mut self.child.delegated) {
442 if size != PxSize::zero() {
443 tracing::error!("measure changed size without flagging delegated");
446 return size;
447 }
448
449 self.child.node.0.measure(wm)
450 } else {
451 size
452 }
453 }
454
455 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
456 self.child.delegated = false;
457
458 let mut size = PxSize::zero();
459 (self.closure)(&mut self.child, UiNodeOp::Layout { wl, final_size: &mut size });
460
461 if !mem::take(&mut self.child.delegated) {
462 if size != PxSize::zero() {
463 tracing::error!("layout changed size without flagging delegated");
466 return size;
467 }
468
469 self.child.node.0.layout(wl)
470 } else {
471 size
472 }
473 }
474
475 fn render(&mut self, frame: &mut FrameBuilder) {
476 self.child.delegated = false;
477
478 (self.closure)(&mut self.child, UiNodeOp::Render { frame });
479
480 if !mem::take(&mut self.child.delegated) {
481 self.child.node.0.render(frame);
482 }
483 }
484
485 fn render_update(&mut self, update: &mut FrameUpdate) {
486 self.child.delegated = false;
487
488 (self.closure)(&mut self.child, UiNodeOp::RenderUpdate { update });
489
490 if !mem::take(&mut self.child.delegated) {
491 self.child.node.0.render_update(update);
492 }
493 }
494
495 fn is_list(&self) -> bool {
496 false
497 }
498
499 fn for_each_child(&mut self, visitor: &mut dyn FnMut(usize, &mut UiNode)) {
500 visitor(0, &mut self.child.node)
501 }
502
503 fn try_for_each_child(
504 &mut self,
505 visitor: &mut dyn FnMut(usize, &mut UiNode) -> ControlFlow<BoxAnyVarValue>,
506 ) -> ControlFlow<BoxAnyVarValue> {
507 visitor(0, &mut self.child.node)
508 }
509
510 fn par_each_child(&mut self, visitor: &(dyn Fn(usize, &mut UiNode) + Sync)) {
511 visitor(0, &mut self.child.node)
512 }
513
514 fn par_fold_reduce(
515 &mut self,
516 identity: BoxAnyVarValue,
517 fold: &(dyn Fn(BoxAnyVarValue, usize, &mut UiNode) -> BoxAnyVarValue + Sync),
518 _: &(dyn Fn(BoxAnyVarValue, BoxAnyVarValue) -> BoxAnyVarValue + Sync),
519 ) -> BoxAnyVarValue {
520 fold(identity, 0, &mut self.child.node)
521 }
522
523 fn update_list(&mut self, updates: &WidgetUpdates, _: &mut dyn UiNodeListObserver) {
524 self.update(updates);
525 }
526
527 fn measure_list(
528 &mut self,
529 wm: &mut WidgetMeasure,
530 _: &(dyn Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync),
531 _: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
532 ) -> PxSize {
533 self.measure(wm)
534 }
535
536 fn layout_list(
537 &mut self,
538 wl: &mut WidgetLayout,
539 _: &(dyn Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync),
540 _: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
541 ) -> PxSize {
542 self.layout(wl)
543 }
544
545 fn render_list(&mut self, frame: &mut FrameBuilder, _: &(dyn Fn(usize, &mut UiNode, &mut FrameBuilder) + Sync)) {
546 self.render(frame)
547 }
548
549 fn render_update_list(&mut self, update: &mut FrameUpdate, _: &(dyn Fn(usize, &mut UiNode, &mut FrameUpdate) + Sync)) {
550 self.render_update(update);
551 }
552
553 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
554 None
555 }
556 }
557 MatchNode {
558 child: MatchNodeChild {
559 node: child,
560 delegated: false,
561 },
562 closure,
563 }
564 .into_node()
565}
566
567pub struct MatchNodeChild {
573 node: UiNode,
574 delegated: bool,
575}
576impl MatchNodeChild {
577 #[inline(always)]
581 pub fn delegated(&mut self) {
582 self.delegated = true;
583 }
584
585 #[inline(always)]
587 pub fn has_delegated(&self) -> bool {
588 self.delegated
589 }
590
591 #[inline(always)]
597 pub fn node(&mut self) -> &mut UiNode {
598 &mut self.node
599 }
600 #[inline(always)]
610 pub fn node_impl<U: UiNodeImpl>(&mut self) -> &mut U {
611 self.node.downcast_mut::<U>().unwrap()
612 }
613
614 #[inline(always)]
616 pub fn init(&mut self) {
617 self.node.0.init();
618 self.delegated = true;
619 }
620
621 #[inline(always)]
623 pub fn deinit(&mut self) {
624 self.node.0.deinit();
625 self.delegated = true;
626 }
627
628 #[inline(always)]
630 pub fn info(&mut self, info: &mut WidgetInfoBuilder) {
631 self.node.0.info(info);
632 self.delegated = true;
633 }
634
635 #[inline(always)]
637 pub fn event(&mut self, update: &EventUpdate) {
638 self.node.0.event(update);
639 self.delegated = true;
640 }
641
642 #[inline(always)]
644 pub fn update(&mut self, updates: &WidgetUpdates) {
645 self.node.0.update(updates);
646 self.delegated = true;
647 }
648
649 #[inline(always)]
651 pub fn update_list(&mut self, updates: &WidgetUpdates, observer: &mut dyn UiNodeListObserver) {
652 self.node.0.update_list(updates, observer);
653 self.delegated = true;
654 }
655
656 #[inline(always)]
658 #[must_use]
659 pub fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
660 self.delegated = true;
661 self.node.0.measure(wm)
662 }
663
664 #[inline(always)]
666 #[must_use]
667 pub fn measure_list(
668 &mut self,
669 wm: &mut WidgetMeasure,
670 measure: impl Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync,
671 fold_size: impl Fn(PxSize, PxSize) -> PxSize + Sync,
672 ) -> PxSize {
673 self.delegated = true;
674 self.node.0.measure_list(wm, &measure, &fold_size)
675 }
676
677 #[inline(always)]
679 #[must_use]
680 pub fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
681 self.delegated = true;
682 self.node.0.layout(wl)
683 }
684
685 #[inline(always)]
687 #[must_use]
688 pub fn layout_list(
689 &mut self,
690 wl: &mut WidgetLayout,
691 layout: impl Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync,
692 fold_size: impl Fn(PxSize, PxSize) -> PxSize + Sync,
693 ) -> PxSize {
694 self.delegated = true;
695 self.node.0.layout_list(wl, &layout, &fold_size)
696 }
697
698 #[inline(always)]
700 pub fn render(&mut self, frame: &mut FrameBuilder) {
701 self.node.0.render(frame);
702 self.delegated = true;
703 }
704
705 #[inline(always)]
707 pub fn render_list(&mut self, frame: &mut FrameBuilder, render: impl Fn(usize, &mut UiNode, &mut FrameBuilder) + Sync) {
708 self.node.render_list(frame, render);
709 self.delegated = true;
710 }
711
712 #[inline(always)]
714 pub fn render_update(&mut self, update: &mut FrameUpdate) {
715 self.node.0.render_update(update);
716 self.delegated = true;
717 }
718
719 #[inline(always)]
721 pub fn render_update_list(&mut self, update: &mut FrameUpdate, render_update: impl Fn(usize, &mut UiNode, &mut FrameUpdate) + Sync) {
722 self.node.render_update_list(update, render_update);
723 }
724
725 #[inline(always)]
727 pub fn op(&mut self, op: UiNodeOp) {
728 self.node.op(op);
729 self.delegated = true;
730 }
731}
732
733pub fn match_node_leaf(closure: impl FnMut(UiNodeOp) + Send + 'static) -> UiNode {
735 struct MatchNodeLeaf<F> {
736 closure: F,
737 }
738 impl<F: FnMut(UiNodeOp) + Send + 'static> UiNodeImpl for MatchNodeLeaf<F> {
739 fn children_len(&self) -> usize {
740 0
741 }
742 fn with_child(&mut self, _: usize, _: &mut dyn FnMut(&mut UiNode)) {}
743
744 fn init(&mut self) {
745 (self.closure)(UiNodeOp::Init);
746 }
747
748 fn deinit(&mut self) {
749 (self.closure)(UiNodeOp::Deinit);
750 }
751
752 fn info(&mut self, info: &mut WidgetInfoBuilder) {
753 (self.closure)(UiNodeOp::Info { info });
754 }
755
756 fn event(&mut self, update: &EventUpdate) {
757 (self.closure)(UiNodeOp::Event { update });
758 }
759
760 fn update(&mut self, updates: &WidgetUpdates) {
761 (self.closure)(UiNodeOp::Update { updates });
762 }
763
764 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
765 let mut size = PxSize::zero();
766 (self.closure)(UiNodeOp::Measure {
767 wm,
768 desired_size: &mut size,
769 });
770 size
771 }
772
773 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
774 let mut size = PxSize::zero();
775 (self.closure)(UiNodeOp::Layout { wl, final_size: &mut size });
776 size
777 }
778
779 fn render(&mut self, frame: &mut FrameBuilder) {
780 (self.closure)(UiNodeOp::Render { frame });
781 }
782
783 fn render_update(&mut self, update: &mut FrameUpdate) {
784 (self.closure)(UiNodeOp::RenderUpdate { update });
785 }
786
787 fn is_list(&self) -> bool {
788 false
789 }
790
791 fn for_each_child(&mut self, _: &mut dyn FnMut(usize, &mut UiNode)) {}
792
793 fn try_for_each_child(
794 &mut self,
795 _: &mut dyn FnMut(usize, &mut UiNode) -> ControlFlow<BoxAnyVarValue>,
796 ) -> ControlFlow<BoxAnyVarValue> {
797 ControlFlow::Continue(())
798 }
799
800 fn par_each_child(&mut self, _: &(dyn Fn(usize, &mut UiNode) + Sync)) {}
801
802 fn par_fold_reduce(
803 &mut self,
804 identity: BoxAnyVarValue,
805 _: &(dyn Fn(BoxAnyVarValue, usize, &mut UiNode) -> BoxAnyVarValue + Sync),
806 _: &(dyn Fn(BoxAnyVarValue, BoxAnyVarValue) -> BoxAnyVarValue + Sync),
807 ) -> BoxAnyVarValue {
808 identity
809 }
810
811 fn update_list(&mut self, updates: &WidgetUpdates, _: &mut dyn UiNodeListObserver) {
812 self.update(updates);
813 }
814
815 fn measure_list(
816 &mut self,
817 wm: &mut WidgetMeasure,
818 _: &(dyn Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync),
819 _: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
820 ) -> PxSize {
821 self.measure(wm)
822 }
823
824 fn layout_list(
825 &mut self,
826 wl: &mut WidgetLayout,
827 _: &(dyn Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync),
828 _: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
829 ) -> PxSize {
830 self.layout(wl)
831 }
832
833 fn render_list(&mut self, frame: &mut FrameBuilder, _: &(dyn Fn(usize, &mut UiNode, &mut FrameBuilder) + Sync)) {
834 self.render(frame);
835 }
836
837 fn render_update_list(&mut self, update: &mut FrameUpdate, _: &(dyn Fn(usize, &mut UiNode, &mut FrameUpdate) + Sync)) {
838 self.render_update(update);
839 }
840
841 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
842 None
843 }
844 }
845 UiNode::new(MatchNodeLeaf { closure })
846}
847
848pub fn match_widget(child: impl IntoUiNode, closure: impl FnMut(&mut MatchWidgetChild, UiNodeOp) + Send + 'static) -> UiNode {
854 struct MatchWidget<F> {
855 child: MatchWidgetChild,
856 closure: F,
857 }
858 impl<F: FnMut(&mut MatchWidgetChild, UiNodeOp) + Send + 'static> UiNodeImpl for MatchWidget<F> {
859 fn children_len(&self) -> usize {
860 1
861 }
862
863 fn with_child(&mut self, index: usize, visitor: &mut dyn FnMut(&mut UiNode)) {
864 if index == 0 {
865 visitor(&mut self.child.node)
866 }
867 }
868
869 fn init(&mut self) {
870 self.child.0.delegated = false;
871
872 (self.closure)(&mut self.child, UiNodeOp::Init);
873
874 if !mem::take(&mut self.child.0.delegated) {
875 self.child.0.node.0.init();
876 }
877 }
878
879 fn deinit(&mut self) {
880 self.child.0.delegated = false;
881
882 (self.closure)(&mut self.child, UiNodeOp::Deinit);
883
884 if !mem::take(&mut self.child.0.delegated) {
885 self.child.0.node.0.deinit();
886 }
887 }
888
889 fn info(&mut self, info: &mut WidgetInfoBuilder) {
890 self.child.0.delegated = false;
891
892 (self.closure)(&mut self.child, UiNodeOp::Info { info });
893
894 if !mem::take(&mut self.child.0.delegated) {
895 self.child.0.node.0.info(info);
896 } else {
897 #[cfg(debug_assertions)]
898 if self
899 .child
900 .0
901 .node
902 .as_widget()
903 .map(|mut w| {
904 w.with_context(crate::widget::WidgetUpdateMode::Ignore, || {
905 WIDGET.pending_update().contains(crate::update::UpdateFlags::INFO)
906 })
907 })
908 .unwrap_or(false)
909 {
910 tracing::warn!(target: "match_widget-pending", "pending info build after info delegated in {:?}", WIDGET.id());
912 }
913 }
914 }
915
916 fn event(&mut self, update: &EventUpdate) {
917 self.child.0.delegated = false;
918
919 (self.closure)(&mut self.child, UiNodeOp::Event { update });
920
921 if !mem::take(&mut self.child.0.delegated) {
922 self.child.0.node.0.event(update);
923 }
924 }
925
926 fn update(&mut self, updates: &WidgetUpdates) {
927 self.child.0.delegated = false;
928
929 (self.closure)(&mut self.child, UiNodeOp::Update { updates });
930
931 if !mem::take(&mut self.child.0.delegated) {
932 self.child.0.node.0.update(updates);
933 }
934 }
935
936 fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
937 self.child.0.delegated = false;
938
939 let mut size = PxSize::zero();
940 (self.closure)(
941 &mut self.child,
942 UiNodeOp::Measure {
943 wm,
944 desired_size: &mut size,
945 },
946 );
947
948 if !mem::take(&mut self.child.0.delegated) {
949 if size != PxSize::zero() {
950 tracing::error!("measure changed size without flagging delegated in {:?}", WIDGET.id());
953 return size;
954 }
955
956 self.child.0.node.0.measure(wm)
957 } else {
958 size
959 }
960 }
961
962 fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
963 self.child.0.delegated = false;
964
965 let mut size = PxSize::zero();
966 (self.closure)(&mut self.child, UiNodeOp::Layout { wl, final_size: &mut size });
967
968 if !mem::take(&mut self.child.0.delegated) {
969 if size != PxSize::zero() {
970 tracing::error!("layout changed size without flagging delegated in {:?}", WIDGET.id());
973 return size;
974 }
975
976 self.child.0.node.0.layout(wl)
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::LAYOUT)
987 })
988 })
989 .unwrap_or(false)
990 {
991 tracing::warn!(target: "match_widget-pending", "pending layout after layout delegated in {:?}", WIDGET.id());
993 }
994 size
995 }
996 }
997
998 fn render(&mut self, frame: &mut FrameBuilder) {
999 self.child.0.delegated = false;
1000
1001 (self.closure)(&mut self.child, UiNodeOp::Render { frame });
1002
1003 if !mem::take(&mut self.child.0.delegated) {
1004 self.child.0.node.0.render(frame);
1005 } else {
1006 #[cfg(debug_assertions)]
1007 if self
1008 .child
1009 .0
1010 .node
1011 .as_widget()
1012 .map(|mut w| {
1013 w.with_context(crate::widget::WidgetUpdateMode::Ignore, || {
1014 WIDGET.pending_update().contains(crate::update::UpdateFlags::RENDER)
1015 })
1016 })
1017 .unwrap_or(false)
1018 {
1019 tracing::warn!(target: "match_widget-pending", "pending render after render delegated in {:?}", WIDGET.id());
1021 }
1022 }
1023 }
1024
1025 fn render_update(&mut self, update: &mut FrameUpdate) {
1026 self.child.0.delegated = false;
1027
1028 (self.closure)(&mut self.child, UiNodeOp::RenderUpdate { update });
1029
1030 if !mem::take(&mut self.child.0.delegated) {
1031 self.child.0.node.0.render_update(update);
1032 } else {
1033 #[cfg(debug_assertions)]
1034 if self
1035 .child
1036 .0
1037 .node
1038 .as_widget()
1039 .map(|mut w| {
1040 w.with_context(crate::widget::WidgetUpdateMode::Ignore, || {
1041 WIDGET.pending_update().contains(crate::update::UpdateFlags::RENDER_UPDATE)
1042 })
1043 })
1044 .unwrap_or(false)
1045 {
1046 tracing::warn!(target: "match_widget-pending", "pending render_update after render_update delegated in {:?}", WIDGET.id());
1048 }
1049 }
1050 }
1051
1052 fn is_list(&self) -> bool {
1053 false
1054 }
1055
1056 fn for_each_child(&mut self, visitor: &mut dyn FnMut(usize, &mut UiNode)) {
1057 visitor(0, &mut self.child.node)
1058 }
1059
1060 fn try_for_each_child(
1061 &mut self,
1062 visitor: &mut dyn FnMut(usize, &mut UiNode) -> ControlFlow<BoxAnyVarValue>,
1063 ) -> ControlFlow<BoxAnyVarValue> {
1064 visitor(0, &mut self.child.node)
1065 }
1066
1067 fn par_each_child(&mut self, visitor: &(dyn Fn(usize, &mut UiNode) + Sync)) {
1068 visitor(0, &mut self.child.node)
1069 }
1070
1071 fn par_fold_reduce(
1072 &mut self,
1073 identity: BoxAnyVarValue,
1074 fold: &(dyn Fn(BoxAnyVarValue, usize, &mut UiNode) -> BoxAnyVarValue + Sync),
1075 _: &(dyn Fn(BoxAnyVarValue, BoxAnyVarValue) -> BoxAnyVarValue + Sync),
1076 ) -> BoxAnyVarValue {
1077 fold(identity, 0, &mut self.child.node)
1078 }
1079
1080 fn update_list(&mut self, updates: &WidgetUpdates, _: &mut dyn UiNodeListObserver) {
1081 self.update(updates);
1082 }
1083
1084 fn measure_list(
1085 &mut self,
1086 wm: &mut WidgetMeasure,
1087 _: &(dyn Fn(usize, &mut UiNode, &mut WidgetMeasure) -> PxSize + Sync),
1088 _: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
1089 ) -> PxSize {
1090 self.measure(wm)
1091 }
1092
1093 fn layout_list(
1094 &mut self,
1095 wl: &mut WidgetLayout,
1096 _: &(dyn Fn(usize, &mut UiNode, &mut WidgetLayout) -> PxSize + Sync),
1097 _: &(dyn Fn(PxSize, PxSize) -> PxSize + Sync),
1098 ) -> PxSize {
1099 self.layout(wl)
1100 }
1101
1102 fn render_list(&mut self, frame: &mut FrameBuilder, _: &(dyn Fn(usize, &mut UiNode, &mut FrameBuilder) + Sync)) {
1103 self.render(frame);
1104 }
1105
1106 fn render_update_list(&mut self, update: &mut FrameUpdate, _: &(dyn Fn(usize, &mut UiNode, &mut FrameUpdate) + Sync)) {
1107 self.render_update(update);
1108 }
1109
1110 fn as_widget(&mut self) -> Option<&mut dyn WidgetUiNodeImpl> {
1111 self.child.node.0.as_widget()
1112 }
1113 }
1114 MatchWidget {
1115 child: MatchWidgetChild(MatchNodeChild {
1116 node: child.into_node(),
1117 delegated: false,
1118 }),
1119 closure,
1120 }
1121 .into_node()
1122}
1123
1124pub struct MatchWidgetChild(MatchNodeChild);
1130impl ops::Deref for MatchWidgetChild {
1131 type Target = MatchNodeChild;
1132
1133 fn deref(&self) -> &Self::Target {
1134 &self.0
1135 }
1136}
1137impl ops::DerefMut for MatchWidgetChild {
1138 fn deref_mut(&mut self) -> &mut Self::Target {
1139 &mut self.0
1140 }
1141}