@@ -4,7 +4,7 @@ use crate::{
4
4
keys,
5
5
queue:: { InternalEvent , Queue } ,
6
6
strings,
7
- ui:: style:: Theme ,
7
+ ui:: { calc_scroll_top , style:: Theme } ,
8
8
} ;
9
9
use asyncgit:: { hash, DiffLine , DiffLineType , FileDiff } ;
10
10
use crossterm:: event:: Event ;
@@ -30,11 +30,12 @@ struct Current {
30
30
///
31
31
pub struct DiffComponent {
32
32
diff : FileDiff ,
33
- scroll : usize ,
34
- current_height : u16 ,
33
+ selection : usize ,
34
+ selected_hunk : Option < usize > ,
35
+ current_size : ( u16 , u16 ) ,
35
36
focused : bool ,
36
37
current : Current ,
37
- selected_hunk : Option < usize > ,
38
+ scroll_top : usize ,
38
39
queue : Option < Queue > ,
39
40
theme : Theme ,
40
41
}
@@ -48,8 +49,9 @@ impl DiffComponent {
48
49
current : Current :: default ( ) ,
49
50
selected_hunk : None ,
50
51
diff : FileDiff :: default ( ) ,
51
- scroll : 0 ,
52
- current_height : 0 ,
52
+ current_size : ( 0 , 0 ) ,
53
+ selection : 0 ,
54
+ scroll_top : 0 ,
53
55
theme : * theme,
54
56
}
55
57
}
@@ -65,10 +67,9 @@ impl DiffComponent {
65
67
pub fn clear ( & mut self ) -> Result < ( ) > {
66
68
self . current = Current :: default ( ) ;
67
69
self . diff = FileDiff :: default ( ) ;
68
- self . scroll = 0 ;
69
-
70
- self . selected_hunk =
71
- Self :: find_selected_hunk ( & self . diff , self . scroll ) ?;
70
+ self . scroll_top = 0 ;
71
+ self . selection = 0 ;
72
+ self . selected_hunk = None ;
72
73
73
74
Ok ( ( ) )
74
75
}
@@ -88,38 +89,42 @@ impl DiffComponent {
88
89
hash,
89
90
} ;
90
91
self . diff = diff;
91
- self . scroll = 0 ;
92
+ self . scroll_top = 0 ;
93
+ self . selection = 0 ;
92
94
93
95
self . selected_hunk =
94
- Self :: find_selected_hunk ( & self . diff , self . scroll ) ?;
96
+ Self :: find_selected_hunk ( & self . diff , self . selection ) ?;
95
97
}
96
98
97
99
Ok ( ( ) )
98
100
}
99
101
100
- fn scroll ( & mut self , scroll : ScrollType ) -> Result < ( ) > {
101
- let old = self . scroll ;
102
+ fn move_selection (
103
+ & mut self ,
104
+ move_type : ScrollType ,
105
+ ) -> Result < ( ) > {
106
+ let old = self . selection ;
102
107
103
- let scroll_max = self . diff . lines . saturating_sub ( 1 ) as usize ;
108
+ let max = self . diff . lines . saturating_sub ( 1 ) as usize ;
104
109
105
- self . scroll = match scroll {
106
- ScrollType :: Down => self . scroll . saturating_add ( 1 ) ,
107
- ScrollType :: Up => self . scroll . saturating_sub ( 1 ) ,
110
+ self . selection = match move_type {
111
+ ScrollType :: Down => old . saturating_add ( 1 ) ,
112
+ ScrollType :: Up => old . saturating_sub ( 1 ) ,
108
113
ScrollType :: Home => 0 ,
109
- ScrollType :: End => scroll_max ,
110
- ScrollType :: PageDown => self . scroll . saturating_add (
111
- self . current_height . saturating_sub ( 1 ) as usize ,
114
+ ScrollType :: End => max ,
115
+ ScrollType :: PageDown => self . selection . saturating_add (
116
+ self . current_size . 1 . saturating_sub ( 1 ) as usize ,
112
117
) ,
113
- ScrollType :: PageUp => self . scroll . saturating_sub (
114
- self . current_height . saturating_sub ( 1 ) as usize ,
118
+ ScrollType :: PageUp => self . selection . saturating_sub (
119
+ self . current_size . 1 . saturating_sub ( 1 ) as usize ,
115
120
) ,
116
121
} ;
117
122
118
- self . scroll = cmp:: min ( scroll_max , self . scroll ) ;
123
+ self . selection = cmp:: min ( max , self . selection ) ;
119
124
120
- if old != self . scroll {
125
+ if old != self . selection {
121
126
self . selected_hunk =
122
- Self :: find_selected_hunk ( & self . diff , self . scroll ) ?;
127
+ Self :: find_selected_hunk ( & self . diff , self . selection ) ?;
123
128
}
124
129
125
130
Ok ( ( ) )
@@ -149,9 +154,9 @@ impl DiffComponent {
149
154
}
150
155
151
156
fn get_text ( & self , width : u16 , height : u16 ) -> Result < Vec < Text > > {
152
- let selection = self . scroll ;
153
- let height_d2 = ( height / 2 ) as usize ;
154
- let min = self . scroll . saturating_sub ( height_d2 ) ;
157
+ let selection = self . selection ;
158
+
159
+ let min = self . scroll_top ;
155
160
let max = min + height as usize ;
156
161
157
162
let mut res = Vec :: new ( ) ;
@@ -290,19 +295,29 @@ impl DrawableComponent for DiffComponent {
290
295
f : & mut Frame < B > ,
291
296
r : Rect ,
292
297
) -> Result < ( ) > {
293
- self . current_height = r. height . saturating_sub ( 2 ) ;
298
+ self . current_size =
299
+ ( r. width . saturating_sub ( 2 ) , r. height . saturating_sub ( 2 ) ) ;
300
+
301
+ self . scroll_top = calc_scroll_top (
302
+ self . scroll_top ,
303
+ self . current_size . 1 as usize ,
304
+ self . selection ,
305
+ ) ;
306
+
294
307
let title =
295
308
format ! ( "{}{}" , strings:: TITLE_DIFF , self . current. path) ;
296
309
f. render_widget (
297
- Paragraph :: new ( self . get_text ( r. width , r. height ) ?. iter ( ) )
298
- . block (
299
- Block :: default ( )
300
- . title ( title. as_str ( ) )
301
- . borders ( Borders :: ALL )
302
- . border_style ( self . theme . block ( self . focused ) )
303
- . title_style ( self . theme . title ( self . focused ) ) ,
304
- )
305
- . alignment ( Alignment :: Left ) ,
310
+ Paragraph :: new (
311
+ self . get_text ( r. width , self . current_size . 1 ) ?. iter ( ) ,
312
+ )
313
+ . block (
314
+ Block :: default ( )
315
+ . title ( title. as_str ( ) )
316
+ . borders ( Borders :: ALL )
317
+ . border_style ( self . theme . block ( self . focused ) )
318
+ . title_style ( self . theme . title ( self . focused ) ) ,
319
+ )
320
+ . alignment ( Alignment :: Left ) ,
306
321
r,
307
322
) ;
308
323
@@ -352,27 +367,27 @@ impl Component for DiffComponent {
352
367
if let Event :: Key ( e) = ev {
353
368
return match e {
354
369
keys:: MOVE_DOWN => {
355
- self . scroll ( ScrollType :: Down ) ?;
370
+ self . move_selection ( ScrollType :: Down ) ?;
356
371
Ok ( true )
357
372
}
358
373
keys:: SHIFT_DOWN | keys:: END => {
359
- self . scroll ( ScrollType :: End ) ?;
374
+ self . move_selection ( ScrollType :: End ) ?;
360
375
Ok ( true )
361
376
}
362
377
keys:: HOME | keys:: SHIFT_UP => {
363
- self . scroll ( ScrollType :: Home ) ?;
378
+ self . move_selection ( ScrollType :: Home ) ?;
364
379
Ok ( true )
365
380
}
366
381
keys:: MOVE_UP => {
367
- self . scroll ( ScrollType :: Up ) ?;
382
+ self . move_selection ( ScrollType :: Up ) ?;
368
383
Ok ( true )
369
384
}
370
385
keys:: PAGE_UP => {
371
- self . scroll ( ScrollType :: PageUp ) ?;
386
+ self . move_selection ( ScrollType :: PageUp ) ?;
372
387
Ok ( true )
373
388
}
374
389
keys:: PAGE_DOWN => {
375
- self . scroll ( ScrollType :: PageDown ) ?;
390
+ self . move_selection ( ScrollType :: PageDown ) ?;
376
391
Ok ( true )
377
392
}
378
393
keys:: ENTER if !self . is_immutable ( ) => {
0 commit comments