1use std::cell::{Cell, Ref, RefCell, RefMut};
2use std::collections::HashMap;
3use std::rc::Rc;
4
5use cranpose_core::{
6 Composer, NodeError, NodeId, Phase, SlotBackend, SlotId, SlotsHost, SubcomposeState,
7};
8use indexmap::IndexSet;
9
10use crate::modifier::{
11 collect_modifier_slices_into, Modifier, ModifierChainHandle, ModifierNodeSlices, Point,
12 ResolvedModifiers, Size,
13};
14use crate::widgets::nodes::{
15 allocate_virtual_node_id, is_virtual_node, register_layout_node, LayoutNode, LayoutState,
16};
17
18use cranpose_foundation::{InvalidationKind, ModifierInvalidation, NodeCapabilities};
19
20pub use cranpose_ui_layout::{Constraints, MeasureResult, Placement};
21
22#[derive(Clone, Copy, Debug)]
27pub struct SubcomposeChild {
28 node_id: NodeId,
29 measured_size: Option<Size>,
32}
33
34impl SubcomposeChild {
35 pub fn new(node_id: NodeId) -> Self {
36 Self {
37 node_id,
38 measured_size: None,
39 }
40 }
41
42 pub fn with_size(node_id: NodeId, size: Size) -> Self {
44 Self {
45 node_id,
46 measured_size: Some(size),
47 }
48 }
49
50 pub fn node_id(&self) -> NodeId {
51 self.node_id
52 }
53
54 pub fn size(&self) -> Size {
59 self.measured_size.unwrap_or(Size {
60 width: 0.0,
61 height: 0.0,
62 })
63 }
64
65 pub fn width(&self) -> f32 {
67 self.size().width
68 }
69
70 pub fn height(&self) -> f32 {
72 self.size().height
73 }
74
75 pub fn set_size(&mut self, size: Size) {
77 self.measured_size = Some(size);
78 }
79}
80
81impl PartialEq for SubcomposeChild {
82 fn eq(&self, other: &Self) -> bool {
83 self.node_id == other.node_id
84 }
85}
86
87#[derive(Clone, Copy, Debug)]
89pub struct SubcomposePlaceable {
90 node_id: NodeId,
91 size: Size,
92}
93
94impl SubcomposePlaceable {
95 pub fn new(node_id: NodeId, size: Size) -> Self {
96 Self { node_id, size }
97 }
98}
99
100impl cranpose_ui_layout::Placeable for SubcomposePlaceable {
101 fn place(&self, _x: f32, _y: f32) {
102 }
104
105 fn width(&self) -> f32 {
106 self.size.width
107 }
108
109 fn height(&self) -> f32 {
110 self.size.height
111 }
112
113 fn node_id(&self) -> NodeId {
114 self.node_id
115 }
116}
117
118pub trait SubcomposeLayoutScope {
120 fn constraints(&self) -> Constraints;
121
122 fn layout<I>(&mut self, width: f32, height: f32, placements: I) -> MeasureResult
123 where
124 I: IntoIterator<Item = Placement>,
125 {
126 MeasureResult::new(Size { width, height }, placements.into_iter().collect())
127 }
128}
129
130pub trait SubcomposeMeasureScope: SubcomposeLayoutScope {
132 fn subcompose<Content>(&mut self, slot_id: SlotId, content: Content) -> Vec<SubcomposeChild>
133 where
134 Content: FnOnce();
135
136 fn measure(&mut self, child: SubcomposeChild, constraints: Constraints) -> SubcomposePlaceable;
138
139 fn node_has_no_parent(&self, node_id: NodeId) -> bool;
142}
143
144pub struct SubcomposeMeasureScopeImpl<'a> {
146 composer: Composer,
147 state: &'a mut SubcomposeState,
148 constraints: Constraints,
149 measurer: Box<dyn FnMut(NodeId, Constraints) -> Size + 'a>,
150 error: Rc<RefCell<Option<NodeError>>>,
151 parent_handle: SubcomposeLayoutNodeHandle,
152 root_id: NodeId,
153}
154
155impl<'a> SubcomposeMeasureScopeImpl<'a> {
156 pub fn new(
157 composer: Composer,
158 state: &'a mut SubcomposeState,
159 constraints: Constraints,
160 measurer: Box<dyn FnMut(NodeId, Constraints) -> Size + 'a>,
161 error: Rc<RefCell<Option<NodeError>>>,
162
163 parent_handle: SubcomposeLayoutNodeHandle,
164 root_id: NodeId,
165 ) -> Self {
166 Self {
167 composer,
168 state,
169 constraints,
170 measurer,
171 error,
172 parent_handle,
173 root_id,
174 }
175 }
176
177 fn record_error(&self, err: NodeError) {
178 let mut slot = self.error.borrow_mut();
179 if slot.is_none() {
180 eprintln!("[SubcomposeLayout] Error suppressed: {:?}", err);
181 *slot = Some(err);
182 }
183 }
184
185 fn perform_subcompose<Content>(&mut self, slot_id: SlotId, content: Content) -> Vec<NodeId>
186 where
187 Content: FnOnce(),
188 {
189 let mut inner = self.parent_handle.inner.borrow_mut();
190
191 let (virtual_node_id, is_reused) =
193 if let Some(node_id) = self.state.take_node_from_reusables(slot_id) {
194 (node_id, true)
195 } else {
196 let id = allocate_virtual_node_id();
197 let node = LayoutNode::new_virtual();
198 if let Err(e) = self
202 .composer
203 .register_virtual_node(id, Box::new(node.clone()))
204 {
205 eprintln!(
206 "[Subcompose] Failed to register virtual node {}: {:?}",
207 id, e
208 );
209 }
210 register_layout_node(id, &node);
211
212 inner.virtual_nodes.insert(id, Rc::new(node));
213 inner.children.insert(id);
214 (id, false)
215 };
216
217 if let Some(v_node) = inner.virtual_nodes.get(&virtual_node_id) {
219 v_node.set_parent(self.root_id);
220 }
221
222 drop(inner);
223
224 if is_reused {
228 self.composer.clear_node_children(virtual_node_id);
229 }
230
231 let slot_host = self.state.get_or_create_slots(slot_id);
232 let _ = self
233 .composer
234 .subcompose_slot(&slot_host, Some(virtual_node_id), |_| content());
235
236 self.state.register_active(slot_id, &[virtual_node_id], &[]);
237
238 self.composer.get_node_children(virtual_node_id)
242 }
243}
244
245impl<'a> SubcomposeLayoutScope for SubcomposeMeasureScopeImpl<'a> {
246 fn constraints(&self) -> Constraints {
247 self.constraints
248 }
249}
250
251impl<'a> SubcomposeMeasureScope for SubcomposeMeasureScopeImpl<'a> {
252 fn subcompose<Content>(&mut self, slot_id: SlotId, content: Content) -> Vec<SubcomposeChild>
253 where
254 Content: FnOnce(),
255 {
256 let nodes = self.perform_subcompose(slot_id, content);
257 nodes.into_iter().map(SubcomposeChild::new).collect()
258 }
259
260 fn measure(&mut self, child: SubcomposeChild, constraints: Constraints) -> SubcomposePlaceable {
261 if self.error.borrow().is_some() {
262 return SubcomposePlaceable::new(child.node_id, Size::default());
264 }
265
266 if let Err(err) = self.composer.apply_pending_commands() {
267 self.record_error(err);
268 return SubcomposePlaceable::new(child.node_id, Size::default());
269 }
270
271 let size = (self.measurer)(child.node_id, constraints);
272 SubcomposePlaceable::new(child.node_id, size)
273 }
274
275 fn node_has_no_parent(&self, node_id: NodeId) -> bool {
276 self.composer.node_has_no_parent(node_id)
277 }
278}
279
280impl<'a> SubcomposeMeasureScopeImpl<'a> {
281 pub fn subcompose_with_size<Content, F>(
286 &mut self,
287 slot_id: SlotId,
288 content: Content,
289 estimate_size: F,
290 ) -> Vec<SubcomposeChild>
291 where
292 Content: FnOnce(),
293 F: Fn(usize) -> Size,
294 {
295 let nodes = self.perform_subcompose(slot_id, content);
296 nodes
297 .into_iter()
298 .enumerate()
299 .map(|(i, node_id)| SubcomposeChild::with_size(node_id, estimate_size(i)))
300 .collect()
301 }
302
303 pub fn active_slots_count(&self) -> usize {
307 self.state.active_slots_count()
308 }
309
310 pub fn reusable_slots_count(&self) -> usize {
314 self.state.reusable_slots_count()
315 }
316
317 pub fn register_content_type(&mut self, slot_id: SlotId, content_type: u64) {
323 self.state.register_content_type(slot_id, content_type);
324 }
325
326 pub fn update_content_type(&mut self, slot_id: SlotId, content_type: Option<u64>) {
332 self.state.update_content_type(slot_id, content_type);
333 }
334
335 pub fn was_last_slot_reused(&self) -> Option<bool> {
343 self.state.was_last_slot_reused()
344 }
345}
346
347pub type MeasurePolicy =
349 dyn for<'scope> Fn(&mut SubcomposeMeasureScopeImpl<'scope>, Constraints) -> MeasureResult;
350
351pub struct SubcomposeLayoutNode {
353 inner: Rc<RefCell<SubcomposeLayoutNodeInner>>,
354 parent: Cell<Option<NodeId>>,
356 id: Cell<Option<NodeId>>,
358 needs_measure: Cell<bool>,
360 needs_layout: Cell<bool>,
361 needs_semantics: Cell<bool>,
362 needs_redraw: Cell<bool>,
363 needs_pointer_pass: Cell<bool>,
364 needs_focus_sync: Cell<bool>,
365 virtual_children_count: Cell<usize>,
366 layout_state: Rc<RefCell<LayoutState>>,
368 modifier_slices_buffer: RefCell<ModifierNodeSlices>,
370 modifier_slices_snapshot: RefCell<Rc<ModifierNodeSlices>>,
371}
372
373impl SubcomposeLayoutNode {
374 pub fn new(modifier: Modifier, measure_policy: Rc<MeasurePolicy>) -> Self {
375 let inner = Rc::new(RefCell::new(SubcomposeLayoutNodeInner::new(measure_policy)));
376 let node = Self {
377 inner,
378 parent: Cell::new(None),
379 id: Cell::new(None),
380 needs_measure: Cell::new(true),
381 needs_layout: Cell::new(true),
382 needs_semantics: Cell::new(true),
383 needs_redraw: Cell::new(true),
384 needs_pointer_pass: Cell::new(false),
385 needs_focus_sync: Cell::new(false),
386 virtual_children_count: Cell::new(0),
387 layout_state: Rc::new(RefCell::new(LayoutState::default())),
388 modifier_slices_buffer: RefCell::new(ModifierNodeSlices::default()),
389 modifier_slices_snapshot: RefCell::new(Rc::default()),
390 };
391 let (invalidations, _) = node.inner.borrow_mut().set_modifier_collect(modifier);
394 node.dispatch_modifier_invalidations(&invalidations, NodeCapabilities::empty());
395 node.update_modifier_slices_cache();
396 node
397 }
398
399 pub fn with_content_type_policy(modifier: Modifier, measure_policy: Rc<MeasurePolicy>) -> Self {
405 let mut inner_data = SubcomposeLayoutNodeInner::new(measure_policy);
406 inner_data
407 .state
408 .set_policy(Box::new(cranpose_core::ContentTypeReusePolicy::new()));
409 let inner = Rc::new(RefCell::new(inner_data));
410 let node = Self {
411 inner,
412 parent: Cell::new(None),
413 id: Cell::new(None),
414 needs_measure: Cell::new(true),
415 needs_layout: Cell::new(true),
416 needs_semantics: Cell::new(true),
417 needs_redraw: Cell::new(true),
418 needs_pointer_pass: Cell::new(false),
419 needs_focus_sync: Cell::new(false),
420 virtual_children_count: Cell::new(0),
421 layout_state: Rc::new(RefCell::new(LayoutState::default())),
422 modifier_slices_buffer: RefCell::new(ModifierNodeSlices::default()),
423 modifier_slices_snapshot: RefCell::new(Rc::default()),
424 };
425 let (invalidations, _) = node.inner.borrow_mut().set_modifier_collect(modifier);
428 node.dispatch_modifier_invalidations(&invalidations, NodeCapabilities::empty());
429 node.update_modifier_slices_cache();
430 node
431 }
432
433 pub fn handle(&self) -> SubcomposeLayoutNodeHandle {
434 SubcomposeLayoutNodeHandle {
435 inner: Rc::clone(&self.inner),
436 }
437 }
438
439 pub fn set_measure_policy(&mut self, policy: Rc<MeasurePolicy>) {
440 self.inner.borrow_mut().set_measure_policy(policy);
441 }
442
443 pub fn set_modifier(&mut self, modifier: Modifier) {
444 let prev_caps = self.modifier_capabilities();
446 let (invalidations, modifier_changed) = {
448 let mut inner = self.inner.borrow_mut();
449 inner.set_modifier_collect(modifier)
450 };
451 self.dispatch_modifier_invalidations(&invalidations, prev_caps);
454 if modifier_changed {
455 self.update_modifier_slices_cache();
456 self.mark_needs_measure();
457 self.request_semantics_update();
458 }
459 }
460
461 fn update_modifier_slices_cache(&self) {
463 let inner = self.inner.borrow();
464 let mut buffer = self.modifier_slices_buffer.borrow_mut();
465 collect_modifier_slices_into(inner.modifier_chain.chain(), &mut buffer);
466 *self.modifier_slices_snapshot.borrow_mut() = Rc::new(buffer.clone());
467 }
468
469 pub fn set_debug_modifiers(&mut self, enabled: bool) {
470 self.inner.borrow_mut().set_debug_modifiers(enabled);
471 }
472
473 pub fn modifier(&self) -> Modifier {
474 self.handle().modifier()
475 }
476
477 pub fn resolved_modifiers(&self) -> ResolvedModifiers {
478 self.inner.borrow().resolved_modifiers
479 }
480
481 pub fn layout_state(&self) -> LayoutState {
483 self.layout_state.borrow().clone()
484 }
485
486 pub fn set_position(&self, position: Point) {
488 let mut state = self.layout_state.borrow_mut();
489 state.position = position;
490 state.is_placed = true;
491 }
492
493 pub fn set_measured_size(&self, size: Size) {
495 let mut state = self.layout_state.borrow_mut();
496 state.size = size;
497 }
498
499 pub fn clear_placed(&self) {
501 self.layout_state.borrow_mut().is_placed = false;
502 }
503
504 pub fn modifier_slices_snapshot(&self) -> Rc<ModifierNodeSlices> {
506 self.modifier_slices_snapshot.borrow().clone()
507 }
508
509 pub fn state(&self) -> Ref<'_, SubcomposeState> {
510 Ref::map(self.inner.borrow(), |inner| &inner.state)
511 }
512
513 pub fn state_mut(&self) -> RefMut<'_, SubcomposeState> {
514 RefMut::map(self.inner.borrow_mut(), |inner| &mut inner.state)
515 }
516
517 pub fn active_children(&self) -> Vec<NodeId> {
518 self.inner.borrow().children.iter().copied().collect()
519 }
520
521 pub fn mark_needs_measure(&self) {
523 self.needs_measure.set(true);
524 self.needs_layout.set(true);
525 }
526
527 pub fn mark_needs_layout_flag(&self) {
529 self.needs_layout.set(true);
530 }
531
532 pub fn mark_needs_redraw(&self) {
534 self.needs_redraw.set(true);
535 if let Some(id) = self.id.get() {
536 crate::schedule_draw_repass(id);
537 }
538 crate::request_render_invalidation();
539 }
540
541 pub fn needs_measure(&self) -> bool {
543 self.needs_measure.get()
544 }
545
546 pub fn mark_needs_semantics(&self) {
548 self.needs_semantics.set(true);
549 }
550
551 pub fn needs_semantics_flag(&self) -> bool {
553 self.needs_semantics.get()
554 }
555
556 pub fn needs_redraw(&self) -> bool {
558 self.needs_redraw.get()
559 }
560
561 pub fn clear_needs_redraw(&self) {
562 self.needs_redraw.set(false);
563 }
564
565 pub fn mark_needs_pointer_pass(&self) {
567 self.needs_pointer_pass.set(true);
568 }
569
570 pub fn needs_pointer_pass(&self) -> bool {
572 self.needs_pointer_pass.get()
573 }
574
575 pub fn clear_needs_pointer_pass(&self) {
577 self.needs_pointer_pass.set(false);
578 }
579
580 pub fn mark_needs_focus_sync(&self) {
582 self.needs_focus_sync.set(true);
583 }
584
585 pub fn needs_focus_sync(&self) -> bool {
587 self.needs_focus_sync.get()
588 }
589
590 pub fn clear_needs_focus_sync(&self) {
592 self.needs_focus_sync.set(false);
593 }
594
595 fn request_semantics_update(&self) {
596 let already_dirty = self.needs_semantics.replace(true);
597 if already_dirty {
598 return;
599 }
600
601 if let Some(id) = self.id.get() {
602 cranpose_core::queue_semantics_invalidation(id);
603 }
604 }
605
606 pub fn modifier_capabilities(&self) -> NodeCapabilities {
608 self.inner.borrow().modifier_capabilities
609 }
610
611 pub fn has_layout_modifier_nodes(&self) -> bool {
612 self.modifier_capabilities()
613 .contains(NodeCapabilities::LAYOUT)
614 }
615
616 pub fn has_draw_modifier_nodes(&self) -> bool {
617 self.modifier_capabilities()
618 .contains(NodeCapabilities::DRAW)
619 }
620
621 pub fn has_pointer_input_modifier_nodes(&self) -> bool {
622 self.modifier_capabilities()
623 .contains(NodeCapabilities::POINTER_INPUT)
624 }
625
626 pub fn has_semantics_modifier_nodes(&self) -> bool {
627 self.modifier_capabilities()
628 .contains(NodeCapabilities::SEMANTICS)
629 }
630
631 pub fn has_focus_modifier_nodes(&self) -> bool {
632 self.modifier_capabilities()
633 .contains(NodeCapabilities::FOCUS)
634 }
635
636 fn dispatch_modifier_invalidations(
643 &self,
644 invalidations: &[ModifierInvalidation],
645 prev_caps: NodeCapabilities,
646 ) {
647 let curr_caps = self.modifier_capabilities();
648 for invalidation in invalidations {
649 match invalidation.kind() {
650 InvalidationKind::Layout => {
651 if curr_caps.contains(NodeCapabilities::LAYOUT)
652 || prev_caps.contains(NodeCapabilities::LAYOUT)
653 {
654 self.mark_needs_measure();
655 }
656 }
657 InvalidationKind::Draw => {
658 if curr_caps.contains(NodeCapabilities::DRAW)
659 || prev_caps.contains(NodeCapabilities::DRAW)
660 {
661 self.mark_needs_redraw();
662 }
663 }
664 InvalidationKind::PointerInput => {
665 if curr_caps.contains(NodeCapabilities::POINTER_INPUT)
666 || prev_caps.contains(NodeCapabilities::POINTER_INPUT)
667 {
668 self.mark_needs_pointer_pass();
669 crate::request_pointer_invalidation();
670 if let Some(id) = self.id.get() {
672 crate::schedule_pointer_repass(id);
673 }
674 }
675 }
676 InvalidationKind::Semantics => {
677 self.request_semantics_update();
678 }
679 InvalidationKind::Focus => {
680 if curr_caps.contains(NodeCapabilities::FOCUS)
681 || prev_caps.contains(NodeCapabilities::FOCUS)
682 {
683 self.mark_needs_focus_sync();
684 crate::request_focus_invalidation();
685 if let Some(id) = self.id.get() {
687 crate::schedule_focus_invalidation(id);
688 }
689 }
690 }
691 }
692 }
693 }
694}
695
696impl cranpose_core::Node for SubcomposeLayoutNode {
697 fn mount(&mut self) {
698 let mut inner = self.inner.borrow_mut();
699 let (chain, mut context) = inner.modifier_chain.chain_and_context_mut();
700 chain.repair_chain();
701 chain.attach_nodes(&mut *context);
702 }
703
704 fn unmount(&mut self) {
705 self.inner
706 .borrow_mut()
707 .modifier_chain
708 .chain_mut()
709 .detach_nodes();
710 }
711
712 fn insert_child(&mut self, child: NodeId) {
713 if is_virtual_node(child) {
714 let count = self.virtual_children_count.get();
715 self.virtual_children_count.set(count + 1);
716 }
717 self.inner.borrow_mut().children.insert(child);
718 }
719
720 fn remove_child(&mut self, child: NodeId) {
721 if self.inner.borrow_mut().children.shift_remove(&child) && is_virtual_node(child) {
722 let count = self.virtual_children_count.get();
723 if count > 0 {
724 self.virtual_children_count.set(count - 1);
725 }
726 }
727 }
728
729 fn move_child(&mut self, from: usize, to: usize) {
730 let mut inner = self.inner.borrow_mut();
731 if from == to || from >= inner.children.len() {
732 return;
733 }
734 let mut ordered: Vec<NodeId> = inner.children.iter().copied().collect();
735 let child = ordered.remove(from);
736 let target = to.min(ordered.len());
737 ordered.insert(target, child);
738 inner.children.clear();
739 for id in ordered {
740 inner.children.insert(id);
741 }
742 }
743
744 fn update_children(&mut self, children: &[NodeId]) {
745 let mut inner = self.inner.borrow_mut();
746 inner.children.clear();
747 for &child in children {
748 inner.children.insert(child);
749 }
750 }
751
752 fn children(&self) -> Vec<NodeId> {
753 let inner = self.inner.borrow();
754 if !inner.last_placements.is_empty() {
757 inner.last_placements.clone()
758 } else {
759 inner.children.iter().copied().collect()
760 }
761 }
762
763 fn set_node_id(&mut self, id: NodeId) {
764 self.id.set(Some(id));
765 self.inner.borrow_mut().modifier_chain.set_node_id(Some(id));
766 }
767
768 fn on_attached_to_parent(&mut self, parent: NodeId) {
769 self.parent.set(Some(parent));
770 }
771
772 fn on_removed_from_parent(&mut self) {
773 self.parent.set(None);
774 }
775
776 fn parent(&self) -> Option<NodeId> {
777 self.parent.get()
778 }
779
780 fn mark_needs_layout(&self) {
781 self.needs_layout.set(true);
782 }
783
784 fn needs_layout(&self) -> bool {
785 self.needs_layout.get()
786 }
787
788 fn mark_needs_measure(&self) {
789 self.needs_measure.set(true);
790 self.needs_layout.set(true); }
792
793 fn needs_measure(&self) -> bool {
794 self.needs_measure.get()
795 }
796
797 fn mark_needs_semantics(&self) {
798 self.needs_semantics.set(true);
799 }
800
801 fn needs_semantics(&self) -> bool {
802 self.needs_semantics.get()
803 }
804
805 fn set_parent_for_bubbling(&mut self, parent: NodeId) {
807 self.parent.set(Some(parent));
808 }
809}
810
811#[derive(Clone)]
812pub struct SubcomposeLayoutNodeHandle {
813 inner: Rc<RefCell<SubcomposeLayoutNodeInner>>,
814}
815
816impl SubcomposeLayoutNodeHandle {
817 pub fn modifier(&self) -> Modifier {
818 self.inner.borrow().modifier.clone()
819 }
820
821 pub fn layout_properties(&self) -> crate::modifier::LayoutProperties {
822 self.resolved_modifiers().layout_properties()
823 }
824
825 pub fn resolved_modifiers(&self) -> ResolvedModifiers {
826 self.inner.borrow().resolved_modifiers
827 }
828
829 pub fn total_offset(&self) -> Point {
830 self.resolved_modifiers().offset()
831 }
832
833 pub fn modifier_capabilities(&self) -> NodeCapabilities {
834 self.inner.borrow().modifier_capabilities
835 }
836
837 pub fn has_layout_modifier_nodes(&self) -> bool {
838 self.modifier_capabilities()
839 .contains(NodeCapabilities::LAYOUT)
840 }
841
842 pub fn has_draw_modifier_nodes(&self) -> bool {
843 self.modifier_capabilities()
844 .contains(NodeCapabilities::DRAW)
845 }
846
847 pub fn has_pointer_input_modifier_nodes(&self) -> bool {
848 self.modifier_capabilities()
849 .contains(NodeCapabilities::POINTER_INPUT)
850 }
851
852 pub fn has_semantics_modifier_nodes(&self) -> bool {
853 self.modifier_capabilities()
854 .contains(NodeCapabilities::SEMANTICS)
855 }
856
857 pub fn has_focus_modifier_nodes(&self) -> bool {
858 self.modifier_capabilities()
859 .contains(NodeCapabilities::FOCUS)
860 }
861
862 pub fn set_debug_modifiers(&self, enabled: bool) {
863 self.inner.borrow_mut().set_debug_modifiers(enabled);
864 }
865
866 pub fn measure<'a>(
867 &self,
868 composer: &Composer,
869 node_id: NodeId,
870 constraints: Constraints,
871 measurer: Box<dyn FnMut(NodeId, Constraints) -> Size + 'a>,
872 error: Rc<RefCell<Option<NodeError>>>,
873 ) -> Result<MeasureResult, NodeError> {
874 let (policy, mut state, slots) = {
875 let mut inner = self.inner.borrow_mut();
876 let policy = Rc::clone(&inner.measure_policy);
877 let state = std::mem::take(&mut inner.state);
878 let slots = std::mem::take(&mut inner.slots);
879 (policy, state, slots)
880 };
881 state.begin_pass();
882
883 let previous = composer.phase();
884 if !matches!(previous, Phase::Measure | Phase::Layout) {
885 composer.enter_phase(Phase::Measure);
886 }
887
888 let slots_host = Rc::new(SlotsHost::new(slots));
889 let constraints_copy = constraints;
890 let result = composer.subcompose_slot(&slots_host, Some(node_id), |inner_composer| {
899 let mut scope = SubcomposeMeasureScopeImpl::new(
900 inner_composer.clone(),
901 &mut state,
902 constraints_copy,
903 measurer,
904 Rc::clone(&error),
905 self.clone(), node_id, );
908 (policy)(&mut scope, constraints_copy)
909 })?;
910
911 state.finish_pass();
912
913 if previous != composer.phase() {
914 composer.enter_phase(previous);
915 }
916
917 {
918 let mut inner = self.inner.borrow_mut();
919 inner.slots = slots_host.take();
920 inner.state = state;
921
922 inner.last_placements = result.placements.iter().map(|p| p.node_id).collect();
927 }
928
929 Ok(result)
930 }
931
932 pub fn set_active_children<I>(&self, children: I)
933 where
934 I: IntoIterator<Item = NodeId>,
935 {
936 let mut inner = self.inner.borrow_mut();
937 inner.children.clear();
938 for child in children {
939 inner.children.insert(child);
940 }
941 }
942}
943
944struct SubcomposeLayoutNodeInner {
945 modifier: Modifier,
946 modifier_chain: ModifierChainHandle,
947 resolved_modifiers: ResolvedModifiers,
948 modifier_capabilities: NodeCapabilities,
949 state: SubcomposeState,
950 measure_policy: Rc<MeasurePolicy>,
951 children: IndexSet<NodeId>,
952 slots: SlotBackend,
953 debug_modifiers: bool,
954 virtual_nodes: HashMap<NodeId, Rc<LayoutNode>>,
956 last_placements: Vec<NodeId>,
959}
960
961impl SubcomposeLayoutNodeInner {
962 fn new(measure_policy: Rc<MeasurePolicy>) -> Self {
963 Self {
964 modifier: Modifier::empty(),
965 modifier_chain: ModifierChainHandle::new(),
966 resolved_modifiers: ResolvedModifiers::default(),
967 modifier_capabilities: NodeCapabilities::default(),
968 state: SubcomposeState::default(),
969 measure_policy,
970 children: IndexSet::new(),
971 slots: SlotBackend::default(),
972 debug_modifiers: false,
973 virtual_nodes: HashMap::new(),
974 last_placements: Vec::new(),
975 }
976 }
977
978 fn set_measure_policy(&mut self, policy: Rc<MeasurePolicy>) {
979 self.measure_policy = policy;
980 }
981
982 fn set_modifier_collect(&mut self, modifier: Modifier) -> (Vec<ModifierInvalidation>, bool) {
985 let modifier_changed = !self.modifier.structural_eq(&modifier);
986 self.modifier = modifier;
987 self.modifier_chain.set_debug_logging(self.debug_modifiers);
988 let modifier_local_invalidations = self.modifier_chain.update(&self.modifier);
989 self.resolved_modifiers = self.modifier_chain.resolved_modifiers();
990 self.modifier_capabilities = self.modifier_chain.capabilities();
991
992 let mut invalidations = self.modifier_chain.take_invalidations();
994 invalidations.extend(modifier_local_invalidations);
995
996 (invalidations, modifier_changed)
997 }
998
999 fn set_debug_modifiers(&mut self, enabled: bool) {
1000 self.debug_modifiers = enabled;
1001 self.modifier_chain.set_debug_logging(enabled);
1002 }
1003}
1004
1005#[cfg(test)]
1006#[path = "tests/subcompose_layout_tests.rs"]
1007mod tests;