11use itertools:: Itertools ;
22use ratatui:: {
3- layout:: { Alignment , Constraint , Layout } ,
3+ layout:: { Alignment , Constraint , Layout , Rect , Size } ,
44 style:: { Modifier , Style } ,
55 text:: { Line , Span } ,
6- widgets:: { Block , Borders , List , ListItem , Paragraph , Widget } ,
6+ widgets:: { Block , Borders , List , ListItem , Paragraph , StatefulWidget , Widget } ,
77} ;
8+ use tui_scrollview:: { ScrollView , ScrollbarVisibility } ;
89
910use crate :: {
1011 cli:: run:: app:: { App , LogType } ,
1112 pty:: Pty ,
1213} ;
1314
1415impl Widget for & mut App {
16+ #[ allow( clippy:: indexing_slicing) ]
1517 fn render (
1618 self ,
1719 area : ratatui:: prelude:: Rect ,
@@ -28,7 +30,7 @@ impl Widget for &mut App {
2830 . title ( "'Shell-Cell'" )
2931 . title_bottom ( "Ctrl-C or Ctrl-D: exit" ) ;
3032 let inner = block. inner ( area) ;
31- Widget :: render ( block , area, buf) ;
33+ block . render ( area, buf) ;
3234
3335 let area_width = inner. width as usize ;
3436
@@ -55,9 +57,8 @@ impl Widget for &mut App {
5557 } )
5658 . collect :: < Vec < _ > > ( ) ;
5759 let logs_len = logs. len ( ) ;
58- // Calculate how many log items can fit in the available height
59- let available_height = inner. height as usize ;
60- let skip_amount = logs_len. saturating_sub ( available_height) ;
60+ let logs_height = u16:: try_from ( logs_len) . unwrap_or ( u16:: MAX ) ;
61+ let skip_amount = logs_len. saturating_sub ( logs_height. into ( ) ) ;
6162
6263 let logs = logs
6364 . iter ( )
@@ -84,18 +85,23 @@ impl Widget for &mut App {
8485 } )
8586 . skip ( skip_amount) ;
8687
87- Widget :: render ( List :: new ( logs) , inner, buf) ;
88+ let mut scroll_view = ScrollView :: new ( Size :: new ( inner. width , logs_height) )
89+ . vertical_scrollbar_visibility ( ScrollbarVisibility :: Automatic )
90+ . horizontal_scrollbar_visibility ( ScrollbarVisibility :: Never ) ;
91+
92+ scroll_view. render_widget ( List :: new ( logs) , Rect :: new ( 0 , 0 , inner. width , logs_height) ) ;
93+ scroll_view. render ( inner, buf, & mut state. scroll_view_state ) ;
8894 } else if let App :: RunningPty ( state) = self {
8995 let block = block
9096 . title ( format ! ( "'Shell-Cell' {}" , state. scell_name) )
9197 . title_bottom ( "Ctrl-D: exit" ) ;
9298 let inner = block. inner ( area) ;
93- Widget :: render ( block , area, buf) ;
94- Widget :: render ( & mut state. pty , inner, buf) ;
99+ block . render ( area, buf) ;
100+ state. pty . render ( inner, buf) ;
95101 } else if let App :: Finished = self {
96102 let block = block. title ( "'Shell-Cell'" ) ;
97103 let inner = block. inner ( area) ;
98- Widget :: render ( block , area, buf) ;
104+ block . render ( area, buf) ;
99105
100106 // Create a centered area using Layout
101107 let vertical_layout = Layout :: vertical ( [
@@ -117,8 +123,7 @@ impl Widget for &mut App {
117123 ] ;
118124
119125 let paragraph = Paragraph :: new ( text) . alignment ( Alignment :: Center ) ;
120- #[ allow( clippy:: indexing_slicing) ]
121- Widget :: render ( paragraph, vertical_layout[ 1 ] , buf) ;
126+ paragraph. render ( vertical_layout[ 1 ] , buf) ;
122127 }
123128 }
124129}
@@ -133,25 +138,6 @@ impl Widget for &mut Pty {
133138 {
134139 // set the proper size for the terminal screen
135140 self . set_size ( area. height , area. width ) ;
136- Widget :: render (
137- tui_term:: widget:: PseudoTerminal :: new ( self . screen ( ) ) ,
138- area,
139- buf,
140- ) ;
141+ tui_term:: widget:: PseudoTerminal :: new ( self . screen ( ) ) . render ( area, buf) ;
141142 }
142143}
143-
144- fn logs_list_iter < ' a > ( messages : & ' a [ & str ] ) -> impl Iterator < Item = ListItem < ' a > > {
145- messages. iter ( ) . enumerate ( ) . map ( |( i, msg) | {
146- let is_last = i == messages. len ( ) . saturating_sub ( 1 ) && i != 0 ;
147-
148- let style = Style :: default ( ) . add_modifier ( Modifier :: BOLD ) ;
149-
150- let line = if is_last {
151- Line :: from ( vec ! [ Span :: styled( format!( "{msg} ..." ) , style. yellow( ) ) ] )
152- } else {
153- Line :: from ( vec ! [ Span :: styled( format!( "✓ {msg}" ) , style. green( ) ) ] )
154- } ;
155- ListItem :: new ( line)
156- } )
157- }
0 commit comments