1- use crate :: {
2- interactive:: react:: Component ,
3- interactive:: {
4- react:: { BlockProps , ReactList , ReactListProps } ,
5- widgets:: { fill_background_to_right, ListState } ,
6- DisplayOptions , EntryDataBundle ,
7- } ,
1+ use crate :: interactive:: {
2+ react:: { fill_background_to_right, BlockProps , ReactList , ReactListProps } ,
3+ DisplayOptions , EntryDataBundle ,
84} ;
95use dua:: traverse:: { Tree , TreeIndex } ;
106use itertools:: Itertools ;
@@ -16,20 +12,19 @@ use tui::{
1612 widgets:: { Borders , Text , Widget } ,
1713} ;
1814
19- pub struct Entries < ' a , ' b > {
15+ pub struct Entries < ' a > {
2016 pub tree : & ' a Tree ,
2117 pub root : TreeIndex ,
2218 pub display : DisplayOptions ,
2319 pub selected : Option < TreeIndex > ,
24- pub list_state : & ' b mut ListState ,
2520 pub entries : & ' a [ EntryDataBundle ] ,
2621 pub border_style : Style ,
2722 pub is_focussed : bool ,
2823
2924 pub list : ReactList ,
3025}
3126
32- impl < ' a , ' b > Widget for Entries < ' a , ' b > {
27+ impl < ' a , ' b > Widget for Entries < ' a > {
3328 fn draw ( & mut self , area : Rect , buf : & mut Buffer ) {
3429 let Self {
3530 tree,
@@ -38,7 +33,6 @@ impl<'a, 'b> Widget for Entries<'a, 'b> {
3833 entries,
3934 selected,
4035 border_style,
41- list_state,
4236 is_focussed,
4337 list,
4438 } = self ;
@@ -63,105 +57,97 @@ impl<'a, 'b> Widget for Entries<'a, 'b> {
6357 title : Some ( & title) ,
6458 ..Default :: default ( )
6559 } ;
66-
67- let offset = list_state
68- . update (
69- selected. map ( |selected| {
70- entries
71- . iter ( )
72- . find_position ( |b| b. index == selected)
73- . map ( |( idx, _) | idx)
74- . unwrap_or ( 0 )
75- } ) ,
76- block. inner ( area) . height as usize ,
77- )
78- . start_index ;
60+ let entry_in_view = selected. map ( |selected| {
61+ entries
62+ . iter ( )
63+ . find_position ( |b| b. index == selected)
64+ . map ( |( idx, _) | idx)
65+ . unwrap_or ( 0 )
66+ } ) ;
7967
8068 let props = ReactListProps {
8169 block : Some ( block) ,
82- items : entries
83- . iter ( )
84- . skip ( offset)
85- . map (
86- |EntryDataBundle {
87- index : node_idx,
88- data : w,
89- is_dir,
90- exists,
91- } | {
92- let ( is_selected, style) = match selected {
93- Some ( idx) if * idx == * node_idx => (
94- true ,
95- Style {
96- fg : Color :: Black ,
97- bg : if * is_focussed {
98- Color :: White
99- } else {
100- Color :: DarkGray
101- } ,
102- ..Default :: default ( )
103- } ,
104- ) ,
105- _ => (
106- false ,
107- Style {
108- fg : Color :: White ,
109- bg : Color :: Reset ,
110- ..Default :: default ( )
111- } ,
112- ) ,
113- } ;
114-
115- let bytes = Text :: Styled (
116- format ! (
117- "{:>byte_column_width$}" ,
118- display. byte_format. display( w. size) . to_string( ) , // we would have to impl alignment/padding ourselves otherwise...
119- byte_column_width = display. byte_format. width( )
120- )
121- . into ( ) ,
122- Style {
123- fg : match ( is_selected, * is_focussed) {
124- ( true , true ) => Color :: DarkGray ,
125- ( true , false ) => Color :: Black ,
126- _ => Color :: Green ,
127- } ,
128- ..style
129- } ,
130- ) ;
131- let percentage = Text :: Styled (
132- format ! (
133- " |{}| " ,
134- display. byte_vis. display( w. size as f32 / total as f32 )
135- )
136- . into ( ) ,
137- style,
138- ) ;
139- let name = Text :: Styled (
140- fill_background_to_right (
141- format ! (
142- "{prefix}{}" ,
143- w. name. to_string_lossy( ) ,
144- prefix = if * is_dir && !is_top( * root) { "/" } else { " " }
145- ) ,
146- area. width ,
147- )
148- . into ( ) ,
149- Style {
150- fg : match ( !is_dir, exists) {
151- ( true , true ) if !is_selected => Color :: DarkGray ,
152- ( true , true ) => style. fg ,
153- ( _, false ) => Color :: Red ,
154- ( false , true ) => style. fg ,
155- } ,
156- ..style
70+ entry_in_view,
71+ } ;
72+ let lines = entries. iter ( ) . map (
73+ |EntryDataBundle {
74+ index : node_idx,
75+ data : w,
76+ is_dir,
77+ exists,
78+ } | {
79+ let ( is_selected, style) = match selected {
80+ Some ( idx) if * idx == * node_idx => (
81+ true ,
82+ Style {
83+ fg : Color :: Black ,
84+ bg : if * is_focussed {
85+ Color :: White
86+ } else {
87+ Color :: DarkGray
15788 } ,
158- ) ;
159- let column_segments = vec ! [ bytes, percentage, name] ;
160- column_segments
89+ ..Default :: default ( )
90+ } ,
91+ ) ,
92+ _ => (
93+ false ,
94+ Style {
95+ fg : Color :: White ,
96+ bg : Color :: Reset ,
97+ ..Default :: default ( )
98+ } ,
99+ ) ,
100+ } ;
101+
102+ let bytes = Text :: Styled (
103+ format ! (
104+ "{:>byte_column_width$}" ,
105+ display. byte_format. display( w. size) . to_string( ) , // we would have to impl alignment/padding ourselves otherwise...
106+ byte_column_width = display. byte_format. width( )
107+ )
108+ . into ( ) ,
109+ Style {
110+ fg : match ( is_selected, * is_focussed) {
111+ ( true , true ) => Color :: DarkGray ,
112+ ( true , false ) => Color :: Black ,
113+ _ => Color :: Green ,
114+ } ,
115+ ..style
161116 } ,
162- )
163- . collect ( ) ,
164- } ;
165- list. render ( props, area, buf) ;
117+ ) ;
118+ let percentage = Text :: Styled (
119+ format ! (
120+ " |{}| " ,
121+ display. byte_vis. display( w. size as f32 / total as f32 )
122+ )
123+ . into ( ) ,
124+ style,
125+ ) ;
126+ let name = Text :: Styled (
127+ fill_background_to_right (
128+ format ! (
129+ "{prefix}{}" ,
130+ w. name. to_string_lossy( ) ,
131+ prefix = if * is_dir && !is_top( * root) { "/" } else { " " }
132+ ) ,
133+ area. width ,
134+ )
135+ . into ( ) ,
136+ Style {
137+ fg : match ( !is_dir, exists) {
138+ ( true , true ) if !is_selected => Color :: DarkGray ,
139+ ( true , true ) => style. fg ,
140+ ( _, false ) => Color :: Red ,
141+ ( false , true ) => style. fg ,
142+ } ,
143+ ..style
144+ } ,
145+ ) ;
146+ let column_segments = vec ! [ bytes, percentage, name] ;
147+ column_segments
148+ } ,
149+ ) ;
150+
151+ list. render ( props, lines, area, buf) ;
166152 }
167153}
0 commit comments