11use ratatui:: { buffer:: Buffer , layout, layout:: { Constraint , Direction , Rect } , widgets:: { Block , Widget } } ;
22use yazi_config:: THEME ;
33
4- use super :: Side ;
4+ use super :: Cand ;
55use crate :: { widgets, Ctx } ;
66
7+ const PADDING_X : u16 = 1 ;
8+ const PADDING_Y : u16 = 1 ;
9+
710pub ( crate ) struct Which < ' a > {
811 cx : & ' a Ctx ,
912}
@@ -15,31 +18,42 @@ impl<'a> Which<'a> {
1518impl Widget for Which < ' _ > {
1619 fn render ( self , area : Rect , buf : & mut Buffer ) {
1720 let which = & self . cx . which ;
18- let mut cands: ( Vec < _ > , Vec < _ > , Vec < _ > ) = Default :: default ( ) ;
19- for ( i, & c) in which. cands . iter ( ) . enumerate ( ) {
20- match i % 3 {
21- 0 => cands. 0 . push ( c) ,
22- 1 => cands. 1 . push ( c) ,
23- 2 => cands. 2 . push ( c) ,
24- _ => unreachable ! ( ) ,
25- }
26- }
21+ let cols = THEME . which . cols as usize ;
2722
28- let height = area. height . min ( cands. 0 . len ( ) as u16 + 2 ) ;
29- let y = area. height . saturating_sub ( height + 2 ) ;
30- let area = Rect { x : area. width . min ( 1 ) , y, width : area. width . saturating_sub ( 2 ) , height } ;
23+ let height = area. height . min ( which. cands . len ( ) . div_ceil ( cols) as u16 + PADDING_Y * 2 ) ;
24+ let area = Rect {
25+ x : PADDING_X . min ( area. width ) ,
26+ y : area. height . saturating_sub ( height + PADDING_Y * 2 ) ,
27+ width : area. width . saturating_sub ( PADDING_X * 2 ) ,
28+ height,
29+ } ;
30+
31+ // Don't render if there's no space
32+ if area. height <= PADDING_Y * 2 {
33+ return ;
34+ }
3135
32- let chunks = layout:: Layout :: new ( Direction :: Horizontal , [
33- Constraint :: Ratio ( 1 , 3 ) ,
34- Constraint :: Ratio ( 1 , 3 ) ,
35- Constraint :: Ratio ( 1 , 3 ) ,
36- ] )
37- . split ( area) ;
36+ let chunks = {
37+ use Constraint :: * ;
38+ layout:: Layout :: new ( Direction :: Horizontal , match cols {
39+ 1 => & [ Ratio ( 1 , 1 ) ] as & [ Constraint ] ,
40+ 2 => & [ Ratio ( 1 , 2 ) , Ratio ( 1 , 2 ) ] ,
41+ _ => & [ Ratio ( 1 , 3 ) , Ratio ( 1 , 3 ) , Ratio ( 1 , 3 ) ] ,
42+ } )
43+ . split ( area)
44+ } ;
3845
3946 widgets:: Clear . render ( area, buf) ;
4047 Block :: new ( ) . style ( THEME . which . mask . into ( ) ) . render ( area, buf) ;
41- Side :: new ( which. times , cands. 0 ) . render ( chunks[ 0 ] , buf) ;
42- Side :: new ( which. times , cands. 1 ) . render ( chunks[ 1 ] , buf) ;
43- Side :: new ( which. times , cands. 2 ) . render ( chunks[ 2 ] , buf) ;
48+
49+ for y in 0 ..area. height {
50+ for ( x, chunk) in chunks. iter ( ) . enumerate ( ) {
51+ let Some ( & cand) = which. cands . get ( y as usize * cols + x) else {
52+ break ;
53+ } ;
54+
55+ Cand :: new ( cand, which. times ) . render ( Rect { y : chunk. y + y + 1 , height : 1 , ..* chunk } , buf) ;
56+ }
57+ }
4458 }
4559}
0 commit comments