Skip to content

Commit 859a941

Browse files
committed
Allow tab to have no active tabs.
* this is a common scenario when using a tabbed interface with one-tab per document without any documents having yet been loaded.
1 parent b9bcd24 commit 859a941

File tree

2 files changed

+37
-22
lines changed

2 files changed

+37
-22
lines changed

src/inspector.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1111,7 +1111,7 @@ pub fn capture(window_id: WindowId) {
11111111
.style(|s| s.background(Color::WHITE));
11121112

11131113
let tab = tab(
1114-
move || selected.get(),
1114+
move || Some(selected.get()),
11151115
move || [0, 1].into_iter(),
11161116
|it| *it,
11171117
move |it| match it {

src/views/tab.rs

+36-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::{hash::Hash, marker::PhantomData};
2-
32
use floem_reactive::{as_child_of_current_scope, create_effect, Scope};
43
use smallvec::SmallVec;
54
use taffy::style::Display;
@@ -18,21 +17,22 @@ type ViewFn<T> = Box<dyn Fn(T) -> (Box<dyn View>, Scope)>;
1817
enum TabState<V> {
1918
Diff(Box<Diff<V>>),
2019
Active(usize),
20+
None
2121
}
2222

2323
pub struct Tab<T>
2424
where
2525
T: 'static,
2626
{
2727
id: ViewId,
28-
active: usize,
28+
active: Option<usize>,
2929
children: Vec<Option<(ViewId, Scope)>>,
3030
view_fn: ViewFn<T>,
3131
phatom: PhantomData<T>,
3232
}
3333

3434
pub fn tab<IF, I, T, KF, K, VF, V>(
35-
active_fn: impl Fn() -> usize + 'static,
35+
active_fn: impl Fn() -> Option<usize> + 'static,
3636
each_fn: IF,
3737
key_fn: KF,
3838
view_fn: VF,
@@ -72,20 +72,23 @@ where
7272
}
7373
diff
7474
};
75-
id.update_state(TabState::Diff(Box::new(diff)));
75+
id.update_state(TabState::<T>::Diff(Box::new(diff)));
7676
HashRun(hashed_items)
7777
});
7878

7979
create_effect(move |_| {
80-
let active = active_fn();
81-
id.update_state(TabState::Active::<T>(active));
80+
let active_key = active_fn();
81+
match active_key {
82+
Some(key) => id.update_state(TabState::Active::<T>(key)),
83+
None => id.update_state(TabState::None::<T>),
84+
}
8285
});
8386

8487
let view_fn = Box::new(as_child_of_current_scope(move |e| view_fn(e).into_any()));
8588

8689
Tab {
8790
id,
88-
active: 0,
91+
active: None,
8992
children: Vec::new(),
9093
view_fn,
9194
phatom: PhantomData,
@@ -98,7 +101,7 @@ impl<T> View for Tab<T> {
98101
}
99102

100103
fn debug_name(&self) -> std::borrow::Cow<'static, str> {
101-
format!("Tab: {}", self.active).into()
104+
format!("Tab: {:?}", self.active).into()
102105
}
103106

104107
fn update(&mut self, cx: &mut UpdateCx, state: Box<dyn std::any::Any>) {
@@ -114,7 +117,10 @@ impl<T> View for Tab<T> {
114117
);
115118
}
116119
TabState::Active(active) => {
117-
self.active = active;
120+
self.active.replace(active);
121+
}
122+
TabState::None => {
123+
self.active.take();
118124
}
119125
}
120126
self.id.request_all();
@@ -131,23 +137,32 @@ impl<T> View for Tab<T> {
131137
let mut child_view = child_view.borrow_mut();
132138
child_view.combined_style = child_view.combined_style.clone().set(
133139
DisplayProp,
134-
if i != self.active {
135-
// set display to none for non active child
136-
Display::None
137-
} else {
138-
Display::Flex
139-
},
140+
141+
match self.active {
142+
None => {
143+
Display::None
144+
}
145+
Some(active_index) if active_index == i => {
146+
Display::Flex
147+
}
148+
Some(_active_index) => {
149+
// set display to none for non-active child
150+
Display::None
151+
}
152+
}
140153
);
141154
}
142155
}
143156

144157
fn paint(&mut self, cx: &mut crate::context::PaintCx) {
145-
if let Some(Some((active, _))) = self
146-
.children
147-
.get(self.active)
148-
.or_else(|| self.children.first())
149-
{
150-
cx.paint_view(*active);
158+
if let Some(active_index) = self.active {
159+
if let Some(Some((active, _))) = self
160+
.children
161+
.get(active_index)
162+
.or_else(|| self.children.first())
163+
{
164+
cx.paint_view(*active);
165+
}
151166
}
152167
}
153168
}

0 commit comments

Comments
 (0)