@@ -125,7 +125,10 @@ pub fn run(args: Args) -> Result<()> {
125
125
click_xy : None ,
126
126
left_highlight : HighlightKind :: None ,
127
127
right_highlight : HighlightKind :: None ,
128
- scroll : 0 ,
128
+ scroll_x : 0 ,
129
+ scroll_state_x : ScrollbarState :: default ( ) ,
130
+ scroll_y : 0 ,
131
+ scroll_state_y : ScrollbarState :: default ( ) ,
129
132
per_page : 0 ,
130
133
num_rows : 0 ,
131
134
symbol_name : args. symbol . clone ( ) ,
@@ -136,7 +139,6 @@ pub fn run(args: Args) -> Result<()> {
136
139
right_sym : None ,
137
140
reload_time : None ,
138
141
time_format,
139
- scroll_state : Default :: default ( ) ,
140
142
} ) ;
141
143
state. reload ( ) ?;
142
144
@@ -195,7 +197,10 @@ struct FunctionDiffUi {
195
197
click_xy : Option < ( u16 , u16 ) > ,
196
198
left_highlight : HighlightKind ,
197
199
right_highlight : HighlightKind ,
198
- scroll : usize ,
200
+ scroll_x : usize ,
201
+ scroll_state_x : ScrollbarState ,
202
+ scroll_y : usize ,
203
+ scroll_state_y : ScrollbarState ,
199
204
per_page : usize ,
200
205
num_rows : usize ,
201
206
symbol_name : String ,
@@ -206,7 +211,6 @@ struct FunctionDiffUi {
206
211
right_sym : Option < ObjSymbol > ,
207
212
reload_time : Option < time:: OffsetDateTime > ,
208
213
time_format : Vec < time:: format_description:: FormatItem < ' static > > ,
209
- scroll_state : ScrollbarState ,
210
214
}
211
215
212
216
enum FunctionDiffResult {
@@ -233,12 +237,13 @@ impl FunctionDiffUi {
233
237
] )
234
238
. split ( chunks[ 1 ] ) ;
235
239
236
- self . per_page = chunks[ 1 ] . height . saturating_sub ( 1 ) as usize ;
237
- let max_scroll = self . num_rows . saturating_sub ( self . per_page ) ;
238
- if self . scroll > max_scroll {
239
- self . scroll = max_scroll ;
240
+ self . per_page = chunks[ 1 ] . height . saturating_sub ( 2 ) as usize ;
241
+ let max_scroll_y = self . num_rows . saturating_sub ( self . per_page ) ;
242
+ if self . scroll_y > max_scroll_y {
243
+ self . scroll_y = max_scroll_y ;
240
244
}
241
- self . scroll_state = self . scroll_state . content_length ( max_scroll) . position ( self . scroll ) ;
245
+ self . scroll_state_y =
246
+ self . scroll_state_y . content_length ( max_scroll_y) . position ( self . scroll_y ) ;
242
247
243
248
let mut line_l = Line :: default ( ) ;
244
249
line_l
@@ -268,12 +273,19 @@ impl FunctionDiffUi {
268
273
|title : & ' static str | Block :: new ( ) . borders ( Borders :: TOP ) . gray ( ) . title ( title. bold ( ) ) ;
269
274
270
275
let mut left_highlight = None ;
276
+ let mut max_width = 0 ;
271
277
if let Some ( symbol) = & self . left_sym {
272
278
// Render left column
273
279
let mut text = Text :: default ( ) ;
274
- let rect = margin_top ( content_chunks[ 0 ] , 1 ) ;
280
+ let rect = content_chunks[ 0 ] . inner ( & Margin :: new ( 0 , 1 ) ) ;
275
281
let h = self . print_sym ( & mut text, symbol, rect, & self . left_highlight ) ;
276
- f. render_widget ( Paragraph :: new ( text) . block ( create_block ( "TARGET" ) ) , content_chunks[ 0 ] ) ;
282
+ max_width = max_width. max ( text. width ( ) ) ;
283
+ f. render_widget (
284
+ Paragraph :: new ( text)
285
+ . block ( create_block ( "TARGET" ) )
286
+ . scroll ( ( 0 , self . scroll_x as u16 ) ) ,
287
+ content_chunks[ 0 ] ,
288
+ ) ;
277
289
if let Some ( h) = h {
278
290
left_highlight = Some ( h) ;
279
291
}
@@ -283,25 +295,49 @@ impl FunctionDiffUi {
283
295
if let Some ( symbol) = & self . right_sym {
284
296
// Render margin
285
297
let mut text = Text :: default ( ) ;
286
- let rect = margin_top ( content_chunks[ 1 ] , 1 ) . inner ( & Margin :: new ( 1 , 0 ) ) ;
298
+ let rect = content_chunks[ 1 ] . inner ( & Margin :: new ( 1 , 1 ) ) ;
287
299
self . print_margin ( & mut text, symbol, rect) ;
288
300
f. render_widget ( text, rect) ;
289
301
290
302
// Render right column
291
303
let mut text = Text :: default ( ) ;
292
- let rect = margin_top ( content_chunks[ 2 ] , 1 ) ;
304
+ let rect = content_chunks[ 2 ] . inner ( & Margin :: new ( 0 , 1 ) ) ;
293
305
let h = self . print_sym ( & mut text, symbol, rect, & self . right_highlight ) ;
294
- f. render_widget ( Paragraph :: new ( text) . block ( create_block ( "CURRENT" ) ) , content_chunks[ 2 ] ) ;
306
+ max_width = max_width. max ( text. width ( ) ) ;
307
+ f. render_widget (
308
+ Paragraph :: new ( text)
309
+ . block ( create_block ( "CURRENT" ) )
310
+ . scroll ( ( 0 , self . scroll_x as u16 ) ) ,
311
+ content_chunks[ 2 ] ,
312
+ ) ;
295
313
if let Some ( h) = h {
296
314
right_highlight = Some ( h) ;
297
315
}
298
316
}
299
317
300
- // Render scrollbar
318
+ let max_scroll_x =
319
+ max_width. saturating_sub ( content_chunks[ 0 ] . width . min ( content_chunks[ 2 ] . width ) as usize ) ;
320
+ if self . scroll_x > max_scroll_x {
321
+ self . scroll_x = max_scroll_x;
322
+ }
323
+ self . scroll_state_x =
324
+ self . scroll_state_x . content_length ( max_scroll_x) . position ( self . scroll_x ) ;
325
+
326
+ // Render scrollbars
301
327
f. render_stateful_widget (
302
328
Scrollbar :: new ( ScrollbarOrientation :: VerticalRight ) . begin_symbol ( None ) . end_symbol ( None ) ,
303
- margin_top ( chunks[ 1 ] , 1 ) ,
304
- & mut self . scroll_state ,
329
+ chunks[ 1 ] . inner ( & Margin :: new ( 0 , 1 ) ) ,
330
+ & mut self . scroll_state_y ,
331
+ ) ;
332
+ f. render_stateful_widget (
333
+ Scrollbar :: new ( ScrollbarOrientation :: HorizontalBottom ) . thumb_symbol ( "■" ) ,
334
+ content_chunks[ 0 ] ,
335
+ & mut self . scroll_state_x ,
336
+ ) ;
337
+ f. render_stateful_widget (
338
+ Scrollbar :: new ( ScrollbarOrientation :: HorizontalBottom ) . thumb_symbol ( "■" ) ,
339
+ content_chunks[ 2 ] ,
340
+ & mut self . scroll_state_x ,
305
341
) ;
306
342
307
343
if let Some ( new_highlight) = left_highlight {
@@ -346,74 +382,92 @@ impl FunctionDiffUi {
346
382
KeyCode :: Esc | KeyCode :: Char ( 'q' ) => return FunctionDiffResult :: Break ,
347
383
// Page up
348
384
KeyCode :: PageUp => {
349
- self . scroll = self . scroll . saturating_sub ( self . per_page ) ;
385
+ self . scroll_y = self . scroll_y . saturating_sub ( self . per_page ) ;
350
386
self . redraw = true ;
351
387
}
352
388
// Page up (shift + space)
353
389
KeyCode :: Char ( ' ' ) if event. modifiers . contains ( KeyModifiers :: SHIFT ) => {
354
- self . scroll = self . scroll . saturating_sub ( self . per_page ) ;
390
+ self . scroll_y = self . scroll_y . saturating_sub ( self . per_page ) ;
355
391
self . redraw = true ;
356
392
}
357
393
// Page down
358
394
KeyCode :: Char ( ' ' ) | KeyCode :: PageDown => {
359
- self . scroll += self . per_page ;
395
+ self . scroll_y += self . per_page ;
360
396
self . redraw = true ;
361
397
}
362
398
// Page down (ctrl + f)
363
399
KeyCode :: Char ( 'f' ) if event. modifiers . contains ( KeyModifiers :: CONTROL ) => {
364
- self . scroll += self . per_page ;
400
+ self . scroll_y += self . per_page ;
365
401
self . redraw = true ;
366
402
}
367
403
// Page up (ctrl + b)
368
404
KeyCode :: Char ( 'b' ) if event. modifiers . contains ( KeyModifiers :: CONTROL ) => {
369
- self . scroll = self . scroll . saturating_sub ( self . per_page ) ;
405
+ self . scroll_y = self . scroll_y . saturating_sub ( self . per_page ) ;
370
406
self . redraw = true ;
371
407
}
372
408
// Half page down (ctrl + d)
373
409
KeyCode :: Char ( 'd' ) if event. modifiers . contains ( KeyModifiers :: CONTROL ) => {
374
- self . scroll += self . per_page / 2 ;
410
+ self . scroll_y += self . per_page / 2 ;
375
411
self . redraw = true ;
376
412
}
377
413
// Half page up (ctrl + u)
378
414
KeyCode :: Char ( 'u' ) if event. modifiers . contains ( KeyModifiers :: CONTROL ) => {
379
- self . scroll = self . scroll . saturating_sub ( self . per_page / 2 ) ;
415
+ self . scroll_y = self . scroll_y . saturating_sub ( self . per_page / 2 ) ;
380
416
self . redraw = true ;
381
417
}
382
418
// Scroll down
383
419
KeyCode :: Down | KeyCode :: Char ( 'j' ) => {
384
- self . scroll += 1 ;
420
+ self . scroll_y += 1 ;
385
421
self . redraw = true ;
386
422
}
387
423
// Scroll up
388
424
KeyCode :: Up | KeyCode :: Char ( 'k' ) => {
389
- self . scroll = self . scroll . saturating_sub ( 1 ) ;
425
+ self . scroll_y = self . scroll_y . saturating_sub ( 1 ) ;
390
426
self . redraw = true ;
391
427
}
392
428
// Scroll to start
393
429
KeyCode :: Char ( 'g' ) => {
394
- self . scroll = 0 ;
430
+ self . scroll_y = 0 ;
395
431
self . redraw = true ;
396
432
}
397
433
// Scroll to end
398
434
KeyCode :: Char ( 'G' ) => {
399
- self . scroll = self . num_rows ;
435
+ self . scroll_y = self . num_rows ;
400
436
self . redraw = true ;
401
437
}
402
438
// Reload
403
439
KeyCode :: Char ( 'r' ) => {
404
440
self . redraw = true ;
405
441
return FunctionDiffResult :: Reload ;
406
442
}
443
+ // Scroll right
444
+ KeyCode :: Right | KeyCode :: Char ( 'l' ) => {
445
+ self . scroll_x += 1 ;
446
+ self . redraw = true ;
447
+ }
448
+ // Scroll left
449
+ KeyCode :: Left | KeyCode :: Char ( 'h' ) => {
450
+ self . scroll_x = self . scroll_x . saturating_sub ( 1 ) ;
451
+ self . redraw = true ;
452
+ }
407
453
_ => { }
408
454
}
409
455
}
410
456
Event :: Mouse ( event) => match event. kind {
411
457
MouseEventKind :: ScrollDown => {
412
- self . scroll += 3 ;
458
+ self . scroll_y += 3 ;
413
459
self . redraw = true ;
414
460
}
415
461
MouseEventKind :: ScrollUp => {
416
- self . scroll = self . scroll . saturating_sub ( 3 ) ;
462
+ self . scroll_y = self . scroll_y . saturating_sub ( 3 ) ;
463
+ self . redraw = true ;
464
+ }
465
+ MouseEventKind :: ScrollRight => {
466
+ self . scroll_x += 3 ;
467
+ self . redraw = true ;
468
+ }
469
+ MouseEventKind :: ScrollLeft => {
470
+ self . scroll_x = self . scroll_x . saturating_sub ( 3 ) ;
417
471
self . redraw = true ;
418
472
}
419
473
MouseEventKind :: Down ( MouseButton :: Left ) => {
@@ -440,7 +494,7 @@ impl FunctionDiffUi {
440
494
let base_addr = symbol. address as u32 ;
441
495
let mut new_highlight = None ;
442
496
for ( y, ins_diff) in
443
- symbol. instructions . iter ( ) . skip ( self . scroll ) . take ( rect. height as usize ) . enumerate ( )
497
+ symbol. instructions . iter ( ) . skip ( self . scroll_y ) . take ( rect. height as usize ) . enumerate ( )
444
498
{
445
499
let mut sx = rect. x ;
446
500
let sy = rect. y + y as u16 ;
@@ -530,7 +584,7 @@ impl FunctionDiffUi {
530
584
}
531
585
532
586
fn print_margin ( & self , out : & mut Text , symbol : & ObjSymbol , rect : Rect ) {
533
- for ins_diff in symbol. instructions . iter ( ) . skip ( self . scroll ) . take ( rect. height as usize ) {
587
+ for ins_diff in symbol. instructions . iter ( ) . skip ( self . scroll_y ) . take ( rect. height as usize ) {
534
588
if ins_diff. kind != ObjInsDiffKind :: None {
535
589
out. lines . push ( Line :: raw ( match ins_diff. kind {
536
590
ObjInsDiffKind :: Delete => "<" ,
@@ -591,10 +645,3 @@ pub fn match_percent_color(match_percent: f32) -> Color {
591
645
Color :: LightRed
592
646
}
593
647
}
594
-
595
- #[ inline]
596
- fn margin_top ( mut rect : Rect , n : u16 ) -> Rect {
597
- rect. y = rect. y . saturating_add ( n) ;
598
- rect. height = rect. height . saturating_sub ( n) ;
599
- rect
600
- }
0 commit comments