1#![deny(missing_docs)]
2
3use floem_reactive::{Scope, UpdaterEffect};
4
5use crate::{
6 context::UpdateCx,
7 view::ViewId,
8 view::{IntoView, View},
9};
10
11pub struct Container {
16 id: ViewId,
17 child_scope: Scope,
18}
19
20impl Container {
21 pub fn new(child: impl IntoView) -> Self {
30 let id = ViewId::new();
31 id.set_children([child.into_view()]);
32 Container {
33 id,
34 child_scope: Scope::current(),
35 }
36 }
37
38 pub fn derived<CF, IV>(content: CF) -> Self
55 where
56 CF: Fn() -> IV + 'static,
57 IV: IntoView + 'static,
58 {
59 let id = ViewId::new();
60 let content_fn = Box::new(Scope::current().enter_child(move |_| content().into_view()));
61
62 let (child, child_scope) = UpdaterEffect::new(
63 move || content_fn(()),
64 move |(new_view, new_scope)| {
65 let old_child = id.children();
66 id.set_children([new_view]);
67 id.update_state((old_child, new_scope));
68 },
69 );
70
71 id.set_children([child]);
72 Container { id, child_scope }
73 }
74
75 pub fn with_id(id: ViewId, child: impl IntoView) -> Self {
79 id.set_children([child.into_view()]);
80 Container {
81 id,
82 child_scope: Scope::current(),
83 }
84 }
85}
86
87#[deprecated(since = "0.2.0", note = "Use Container::new() instead")]
92pub fn container<V: IntoView + 'static>(child: V) -> Container {
93 Container::new(child)
94}
95
96impl View for Container {
97 fn id(&self) -> ViewId {
98 self.id
99 }
100
101 fn debug_name(&self) -> std::borrow::Cow<'static, str> {
102 "Container".into()
103 }
104
105 fn update(&mut self, cx: &mut UpdateCx, state: Box<dyn std::any::Any>) {
106 if let Ok(val) = state.downcast::<(Vec<ViewId>, Scope)>() {
107 let old_child_scope = self.child_scope;
108 let (old_children, child_scope) = *val;
109 self.child_scope = child_scope;
110 for child in old_children {
111 cx.window_state.remove_view(child);
112 }
113 old_child_scope.dispose();
114 self.id.request_all();
115 }
116 }
117}
118
119pub trait ContainerExt {
121 fn container(self) -> Container;
123}
124
125impl<T: IntoView + 'static> ContainerExt for T {
126 fn container(self) -> Container {
127 Container::new(self)
128 }
129}