@@ -65,6 +65,24 @@ impl<'a> Tui<'a> {
6565 height
6666 }
6767
68+ fn calc_list_coordinates ( & self ) -> ( usize , usize ) {
69+ let list_total = self . proc_list . collected . len ( ) ;
70+ let list_offset = self . stat . list_offset ;
71+ ( list_offset, list_total)
72+ }
73+
74+ fn calc_column_coordinates ( & self ) -> ( usize , usize , usize ) {
75+ let total_columns = self . proc_list . fields . len ( ) ;
76+ let horizontal_offset = self . stat . horizontal_offset ;
77+ let column_coordinate = min ( horizontal_offset, total_columns - 1 ) ;
78+ let horizontal_offset = if horizontal_offset >= total_columns {
79+ horizontal_offset - ( total_columns - 1 )
80+ } else {
81+ 0
82+ } ;
83+ ( column_coordinate, total_columns, horizontal_offset * 8 )
84+ }
85+
6886 fn render_header ( & self , area : Rect , buf : & mut Buffer ) {
6987 let constraints = vec ! [ Constraint :: Length ( 1 ) ; self . calc_header_height( ) as usize ] ;
7088 let colorful = self . stat . colorful ;
@@ -347,11 +365,32 @@ impl<'a> Tui<'a> {
347365 . render ( layout[ 0 ] , buf) ;
348366 return ;
349367 }
350- let input = Line :: from ( vec ! [
351- Span :: styled( & self . stat. input_label, Style :: default ( ) . primary( colorful) ) ,
352- Span :: raw( " " ) ,
353- Span :: raw( & self . stat. input_value) ,
354- ] ) ;
368+ let input = if !self . stat . input_label . is_empty ( ) || !self . stat . input_value . is_empty ( ) {
369+ Line :: from ( vec ! [
370+ Span :: styled( & self . stat. input_label, Style :: default ( ) . primary( colorful) ) ,
371+ Span :: raw( " " ) ,
372+ Span :: raw( & self . stat. input_value) ,
373+ ] )
374+ } else if self . stat . show_coordinates {
375+ let list_coordinates = self . calc_list_coordinates ( ) ;
376+ let column_coordinates = self . calc_column_coordinates ( ) ;
377+ Line :: from ( vec ! [
378+ Span :: raw( format!(
379+ " scroll coordinates: y = {}/{} (tasks), x = {}/{} (fields)" ,
380+ list_coordinates. 0 + 1 ,
381+ list_coordinates. 1 ,
382+ column_coordinates. 0 + 1 ,
383+ column_coordinates. 1
384+ ) ) ,
385+ Span :: raw( if column_coordinates. 2 > 0 {
386+ format!( " + {}" , column_coordinates. 2 )
387+ } else {
388+ String :: new( )
389+ } ) ,
390+ ] )
391+ } else {
392+ Line :: from ( "" )
393+ } ;
355394 input. render ( area, buf) ;
356395 }
357396
@@ -386,37 +425,57 @@ impl<'a> Tui<'a> {
386425 _ => Constraint :: Length ( 0 ) ,
387426 } ;
388427
428+ let list_coordinates = self . calc_list_coordinates ( ) ;
429+ let column_coordinates = self . calc_column_coordinates ( ) ;
430+
389431 let constraints: Vec < Constraint > = self
390432 . proc_list
391433 . fields
392434 . iter ( )
393435 . map ( |field| build_constraint ( field) )
436+ . skip ( column_coordinates. 0 )
394437 . collect ( ) ;
395438
396- self . stat . list_offset = min ( self . stat . list_offset , self . proc_list . collected . len ( ) - 1 ) ;
397-
398- let header =
399- Row :: new ( self . proc_list . fields . clone ( ) ) . style ( Style :: default ( ) . bg_secondary ( colorful) ) ;
439+ let header = Row :: new (
440+ self . proc_list
441+ . fields
442+ . clone ( )
443+ . split_off ( column_coordinates. 0 ) ,
444+ )
445+ . style ( Style :: default ( ) . bg_secondary ( colorful) ) ;
400446
401447 let rows = self . proc_list . collected . iter ( ) . map ( |item| {
402- let cells = item. iter ( ) . enumerate ( ) . map ( |( n, c) | {
403- if highlight_sorted && n == highlight_column {
404- Cell :: from ( Span :: styled (
405- c,
406- if highlight_bold {
407- Style :: default ( ) . bg_primary ( colorful)
448+ let cells = item
449+ . iter ( )
450+ . enumerate ( )
451+ . skip ( column_coordinates. 0 )
452+ . map ( |( n, c) | {
453+ let c = if column_coordinates. 2 > 0 {
454+ if c. len ( ) < column_coordinates. 2 {
455+ ""
408456 } else {
409- Style :: default ( ) . primary ( colorful)
410- } ,
411- ) )
412- } else {
413- Cell :: from ( c. as_str ( ) )
414- }
415- } ) ;
457+ & c[ column_coordinates. 2 ..]
458+ }
459+ } else {
460+ c
461+ } ;
462+ if highlight_sorted && n == highlight_column {
463+ Cell :: from ( Span :: styled (
464+ c,
465+ if highlight_bold {
466+ Style :: default ( ) . bg_primary ( colorful)
467+ } else {
468+ Style :: default ( ) . primary ( colorful)
469+ } ,
470+ ) )
471+ } else {
472+ Cell :: from ( c)
473+ }
474+ } ) ;
416475 Row :: new ( cells) . height ( 1 )
417476 } ) ;
418477
419- let mut state = TableState :: default ( ) . with_offset ( self . stat . list_offset ) ;
478+ let mut state = TableState :: default ( ) . with_offset ( list_coordinates . 0 ) ;
420479
421480 let table = Table :: new ( rows, constraints) . header ( header) ;
422481 StatefulWidget :: render ( table, area, buf, & mut state) ;
@@ -425,6 +484,7 @@ impl<'a> Tui<'a> {
425484
426485impl Widget for Tui < ' _ > {
427486 fn render ( mut self , area : Rect , buf : & mut Buffer ) {
487+ self . stat . list_offset = min ( self . stat . list_offset , self . proc_list . collected . len ( ) - 1 ) ;
428488 let layout = Layout :: new (
429489 Direction :: Vertical ,
430490 [
@@ -437,6 +497,11 @@ impl Widget for Tui<'_> {
437497
438498 self . render_header ( layout[ 0 ] , buf) ;
439499 self . render_input ( layout[ 1 ] , buf) ;
440- self . render_list ( layout[ 2 ] , buf) ;
500+ let mut list_area = layout[ 2 ] ;
501+ if self . stat . max_list_display > 0 {
502+ let list_height = min ( layout[ 2 ] . height , self . stat . max_list_display as u16 ) + 1 ; // 1 for header
503+ list_area. height = list_height;
504+ }
505+ self . render_list ( list_area, buf) ;
441506 }
442507}
0 commit comments