1
1
use std:: { hash:: Hash , marker:: PhantomData } ;
2
-
3
2
use floem_reactive:: { as_child_of_current_scope, create_effect, Scope } ;
4
3
use smallvec:: SmallVec ;
5
4
use taffy:: style:: Display ;
@@ -18,21 +17,22 @@ type ViewFn<T> = Box<dyn Fn(T) -> (Box<dyn View>, Scope)>;
18
17
enum TabState < V > {
19
18
Diff ( Box < Diff < V > > ) ,
20
19
Active ( usize ) ,
20
+ None
21
21
}
22
22
23
23
pub struct Tab < T >
24
24
where
25
25
T : ' static ,
26
26
{
27
27
id : ViewId ,
28
- active : usize ,
28
+ active : Option < usize > ,
29
29
children : Vec < Option < ( ViewId , Scope ) > > ,
30
30
view_fn : ViewFn < T > ,
31
31
phatom : PhantomData < T > ,
32
32
}
33
33
34
34
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 ,
36
36
each_fn : IF ,
37
37
key_fn : KF ,
38
38
view_fn : VF ,
@@ -72,20 +72,23 @@ where
72
72
}
73
73
diff
74
74
} ;
75
- id. update_state ( TabState :: Diff ( Box :: new ( diff) ) ) ;
75
+ id. update_state ( TabState :: < T > :: Diff ( Box :: new ( diff) ) ) ;
76
76
HashRun ( hashed_items)
77
77
} ) ;
78
78
79
79
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
+ }
82
85
} ) ;
83
86
84
87
let view_fn = Box :: new ( as_child_of_current_scope ( move |e| view_fn ( e) . into_any ( ) ) ) ;
85
88
86
89
Tab {
87
90
id,
88
- active : 0 ,
91
+ active : None ,
89
92
children : Vec :: new ( ) ,
90
93
view_fn,
91
94
phatom : PhantomData ,
@@ -98,7 +101,7 @@ impl<T> View for Tab<T> {
98
101
}
99
102
100
103
fn debug_name ( & self ) -> std:: borrow:: Cow < ' static , str > {
101
- format ! ( "Tab: {}" , self . active) . into ( )
104
+ format ! ( "Tab: {:? }" , self . active) . into ( )
102
105
}
103
106
104
107
fn update ( & mut self , cx : & mut UpdateCx , state : Box < dyn std:: any:: Any > ) {
@@ -114,7 +117,10 @@ impl<T> View for Tab<T> {
114
117
) ;
115
118
}
116
119
TabState :: Active ( active) => {
117
- self . active = active;
120
+ self . active . replace ( active) ;
121
+ }
122
+ TabState :: None => {
123
+ self . active . take ( ) ;
118
124
}
119
125
}
120
126
self . id . request_all ( ) ;
@@ -131,23 +137,32 @@ impl<T> View for Tab<T> {
131
137
let mut child_view = child_view. borrow_mut ( ) ;
132
138
child_view. combined_style = child_view. combined_style . clone ( ) . set (
133
139
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
+ }
140
153
) ;
141
154
}
142
155
}
143
156
144
157
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
+ }
151
166
}
152
167
}
153
168
}
0 commit comments