@@ -22,7 +22,7 @@ use crate::{
22
22
Action , InternalEvent , NeedsUpdate , Queue , StackablePopupOpen ,
23
23
} ,
24
24
setup_popups,
25
- strings:: { self , order} ,
25
+ strings:: { self , ellipsis_trim_start , order} ,
26
26
tabs:: { FilesTab , Revlog , StashList , Stashing , Status } ,
27
27
ui:: style:: { SharedTheme , Theme } ,
28
28
AsyncAppNotification , AsyncNotification ,
@@ -41,11 +41,14 @@ use std::{
41
41
} ;
42
42
use tui:: {
43
43
backend:: Backend ,
44
- layout:: { Constraint , Direction , Layout , Margin , Rect } ,
44
+ layout:: {
45
+ Alignment , Constraint , Direction , Layout , Margin , Rect ,
46
+ } ,
45
47
text:: { Span , Spans } ,
46
- widgets:: { Block , Borders , Tabs } ,
48
+ widgets:: { Block , Borders , Paragraph , Tabs } ,
47
49
Frame ,
48
50
} ;
51
+ use unicode_width:: UnicodeWidthStr ;
49
52
50
53
#[ derive( Clone ) ]
51
54
pub enum QuitState {
@@ -94,6 +97,7 @@ pub struct App {
94
97
input : Input ,
95
98
popup_stack : PopupStack ,
96
99
options : SharedOptions ,
100
+ repo_path_text : String ,
97
101
98
102
// "Flags"
99
103
requires_redraw : Cell < bool > ,
@@ -114,6 +118,9 @@ impl App {
114
118
) -> Result < Self > {
115
119
log:: trace!( "open repo at: {:?}" , & repo) ;
116
120
121
+ let repo_path_text =
122
+ repo_work_dir ( & repo. borrow ( ) ) . unwrap_or_default ( ) ;
123
+
117
124
let queue = Queue :: new ( ) ;
118
125
let theme = Rc :: new ( theme) ;
119
126
let key_config = Rc :: new ( key_config) ;
@@ -311,6 +318,7 @@ impl App {
311
318
requires_redraw : Cell :: new ( false ) ,
312
319
file_to_open : None ,
313
320
repo,
321
+ repo_path_text,
314
322
popup_stack : PopupStack :: default ( ) ,
315
323
} ;
316
324
@@ -339,7 +347,7 @@ impl App {
339
347
340
348
self . cmdbar . borrow ( ) . draw ( f, chunks_main[ 2 ] ) ;
341
349
342
- self . draw_tabs ( f, chunks_main[ 0 ] ) ;
350
+ self . draw_top_bar ( f, chunks_main[ 0 ] ) ;
343
351
344
352
//TODO: component property + a macro `fullscreen_popup_open!`
345
353
// to make this scale better?
@@ -1104,23 +1112,47 @@ impl App {
1104
1112
}
1105
1113
1106
1114
//TODO: make this dynamic
1107
- fn draw_tabs < B : Backend > ( & self , f : & mut Frame < B > , r : Rect ) {
1115
+ fn draw_top_bar < B : Backend > ( & self , f : & mut Frame < B > , r : Rect ) {
1116
+ const DIVIDER_PAD_SPACES : usize = 2 ;
1117
+ const SIDE_PADS : usize = 2 ;
1118
+ const MARGIN_LEFT_AND_RIGHT : usize = 2 ;
1119
+
1108
1120
let r = r. inner ( & Margin {
1109
1121
vertical : 0 ,
1110
1122
horizontal : 1 ,
1111
1123
} ) ;
1112
1124
1113
- let tabs = [
1125
+ let tab_labels = [
1114
1126
Span :: raw ( strings:: tab_status ( & self . key_config ) ) ,
1115
1127
Span :: raw ( strings:: tab_log ( & self . key_config ) ) ,
1116
1128
Span :: raw ( strings:: tab_files ( & self . key_config ) ) ,
1117
1129
Span :: raw ( strings:: tab_stashing ( & self . key_config ) ) ,
1118
1130
Span :: raw ( strings:: tab_stashes ( & self . key_config ) ) ,
1119
- ]
1120
- . iter ( )
1121
- . cloned ( )
1122
- . map ( Spans :: from)
1123
- . collect ( ) ;
1131
+ ] ;
1132
+ let divider = strings:: tab_divider ( & self . key_config ) ;
1133
+
1134
+ // heuristic, since tui doesn't provide a way to know
1135
+ // how much space is needed to draw a `Tabs`
1136
+ let tabs_len: usize =
1137
+ tab_labels. iter ( ) . map ( Span :: width) . sum :: < usize > ( )
1138
+ + tab_labels. len ( ) . saturating_sub ( 1 )
1139
+ * ( divider. width ( ) + DIVIDER_PAD_SPACES )
1140
+ + SIDE_PADS + MARGIN_LEFT_AND_RIGHT ;
1141
+
1142
+ let left_right = Layout :: default ( )
1143
+ . direction ( Direction :: Horizontal )
1144
+ . constraints ( vec ! [
1145
+ Constraint :: Length (
1146
+ u16 :: try_from( tabs_len) . unwrap_or( r. width) ,
1147
+ ) ,
1148
+ Constraint :: Min ( 0 ) ,
1149
+ ] )
1150
+ . split ( r) ;
1151
+
1152
+ let table_area = r; // use entire area to allow drawing the horizontal separator line
1153
+ let text_area = left_right[ 1 ] ;
1154
+
1155
+ let tabs = tab_labels. into_iter ( ) . map ( Spans :: from) . collect ( ) ;
1124
1156
1125
1157
f. render_widget (
1126
1158
Tabs :: new ( tabs)
@@ -1131,9 +1163,21 @@ impl App {
1131
1163
)
1132
1164
. style ( self . theme . tab ( false ) )
1133
1165
. highlight_style ( self . theme . tab ( true ) )
1134
- . divider ( strings :: tab_divider ( & self . key_config ) )
1166
+ . divider ( divider )
1135
1167
. select ( self . tab ) ,
1136
- r,
1168
+ table_area,
1169
+ ) ;
1170
+
1171
+ f. render_widget (
1172
+ Paragraph :: new ( Spans :: from ( vec ! [ Span :: styled(
1173
+ ellipsis_trim_start(
1174
+ & self . repo_path_text,
1175
+ text_area. width as usize ,
1176
+ ) ,
1177
+ self . theme. title( true ) ,
1178
+ ) ] ) )
1179
+ . alignment ( Alignment :: Right ) ,
1180
+ text_area,
1137
1181
) ;
1138
1182
}
1139
1183
}
0 commit comments