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