ratatui_kit/render/
updater.rs1use std::{
2 any::Any,
3 cell::{Ref, RefMut},
4};
5
6use crate::{
7 ElementKey,
8 component::{Components, InstantiatedComponent},
9 context::{Context, ContextStack},
10 element::ElementExt,
11 layout_style::LayoutStyle,
12 multimap::AppendOnlyMultimap,
13 terminal::Terminal,
14};
15
16pub struct ComponentUpdater<'a, 'c: 'a> {
17 key: ElementKey,
18 component_context_stack: &'a mut ContextStack<'c>,
19 terminal: &'a mut Terminal,
20 components: &'a mut Components,
21 transparent_layout: bool,
22 layout_style: &'a mut LayoutStyle,
23}
24
25impl<'a, 'c: 'a> ComponentUpdater<'a, 'c> {
26 pub(crate) fn new(
27 key: ElementKey,
28 component_context_stack: &'a mut ContextStack<'c>,
29 terminal: &'a mut Terminal,
30 components: &'a mut Components,
31 layout_style: &'a mut LayoutStyle,
32 ) -> ComponentUpdater<'a, 'c> {
33 ComponentUpdater {
34 key,
35 component_context_stack,
36 terminal,
37 components,
38 transparent_layout: false,
39 layout_style,
40 }
41 }
42
43 pub fn component_context_stack(&self) -> &ContextStack<'c> {
44 self.component_context_stack
45 }
46
47 pub fn key(&self) -> &ElementKey {
48 &self.key
49 }
50
51 pub fn get_context<T: Any>(&'_ self) -> Option<Ref<'_, T>> {
52 self.component_context_stack.get_context()
53 }
54
55 pub fn get_context_mut<T: Any>(&'_ self) -> Option<RefMut<'_, T>> {
56 self.component_context_stack.get_context_mut()
57 }
58
59 pub fn terminal(&mut self) -> &mut Terminal {
60 self.terminal
61 }
62
63 pub fn set_transparent_layout(&mut self, transparent: bool) {
64 self.transparent_layout = transparent;
65 }
66
67 pub(crate) fn has_transparent_layout(&self) -> bool {
68 self.transparent_layout
69 }
70
71 pub fn set_layout_style(&mut self, layout_style: LayoutStyle) {
72 *self.layout_style = layout_style;
73 }
74
75 pub fn update_children<I, T>(&mut self, elements: I, context: Option<Context>)
76 where
77 I: IntoIterator<Item = T>,
78 T: ElementExt,
79 {
80 self.component_context_stack
81 .with_context(context, |context_stack| {
82 let mut used_components = AppendOnlyMultimap::default();
83
84 for mut child in elements {
85 let mut component = match self.components.pop_front(child.key()) {
86 Some(component)
87 if component.component().type_id()
88 == child.helper().component_type_id() =>
89 {
90 component
91 }
92 _ => {
93 let h = child.helper();
94 InstantiatedComponent::new(child.key().clone(), child.props_mut(), h)
95 }
96 };
97
98 component.update(self.terminal, context_stack, child.props_mut());
99 used_components.push_back(child.key().clone(), component);
100 }
101
102 self.components.components = used_components.into();
103 });
104 }
105}