@@ -4,28 +4,15 @@ use std::{
4
4
mem:: take,
5
5
} ;
6
6
7
- use egui:: { text:: LayoutJob , Id , Label , RichText , Sense , Widget } ;
7
+ use egui:: { text:: LayoutJob , Label , Sense , Widget } ;
8
8
use objdiff_core:: {
9
- diff:: { ObjDataDiff , ObjDataDiffKind , ObjDataRelocDiff , ObjDiff } ,
9
+ diff:: { ObjDataDiff , ObjDataDiffKind , ObjDataRelocDiff } ,
10
10
obj:: ObjInfo ,
11
11
} ;
12
- use time:: format_description;
13
12
14
- use crate :: {
15
- hotkeys,
16
- views:: {
17
- appearance:: Appearance ,
18
- column_layout:: { render_header, render_table} ,
19
- symbol_diff:: { DiffViewAction , DiffViewNavigation , DiffViewState } ,
20
- write_text,
21
- } ,
22
- } ;
23
-
24
- const BYTES_PER_ROW : usize = 16 ;
13
+ use crate :: views:: { appearance:: Appearance , write_text} ;
25
14
26
- fn find_section ( obj : & ObjInfo , section_name : & str ) -> Option < usize > {
27
- obj. sections . iter ( ) . position ( |section| section. name == section_name)
28
- }
15
+ pub ( crate ) const BYTES_PER_ROW : usize = 16 ;
29
16
30
17
fn data_row_hover_ui (
31
18
ui : & mut egui:: Ui ,
@@ -122,7 +109,7 @@ fn get_color_for_diff_kind(diff_kind: ObjDataDiffKind, appearance: &Appearance)
122
109
}
123
110
}
124
111
125
- fn data_row_ui (
112
+ pub ( crate ) fn data_row_ui (
126
113
ui : & mut egui:: Ui ,
127
114
obj : Option < & ObjInfo > ,
128
115
address : usize ,
@@ -210,7 +197,7 @@ fn data_row_ui(
210
197
}
211
198
}
212
199
213
- fn split_diffs (
200
+ pub ( crate ) fn split_diffs (
214
201
diffs : & [ ObjDataDiff ] ,
215
202
reloc_diffs : & [ ObjDataRelocDiff ] ,
216
203
) -> Vec < Vec < ( ObjDataDiff , Vec < ObjDataRelocDiff > ) > > {
@@ -271,169 +258,3 @@ fn split_diffs(
271
258
}
272
259
split_diffs
273
260
}
274
-
275
- #[ derive( Clone , Copy ) ]
276
- struct SectionDiffContext < ' a > {
277
- obj : & ' a ObjInfo ,
278
- diff : & ' a ObjDiff ,
279
- section_index : Option < usize > ,
280
- }
281
-
282
- impl < ' a > SectionDiffContext < ' a > {
283
- pub fn new ( obj : Option < & ' a ( ObjInfo , ObjDiff ) > , section_name : Option < & str > ) -> Option < Self > {
284
- obj. map ( |( obj, diff) | Self {
285
- obj,
286
- diff,
287
- section_index : section_name. and_then ( |section_name| find_section ( obj, section_name) ) ,
288
- } )
289
- }
290
-
291
- #[ inline]
292
- pub fn has_section ( & self ) -> bool { self . section_index . is_some ( ) }
293
- }
294
-
295
- fn data_table_ui (
296
- ui : & mut egui:: Ui ,
297
- available_width : f32 ,
298
- left_ctx : Option < SectionDiffContext < ' _ > > ,
299
- right_ctx : Option < SectionDiffContext < ' _ > > ,
300
- config : & Appearance ,
301
- ) -> Option < ( ) > {
302
- let left_obj = left_ctx. map ( |ctx| ctx. obj ) ;
303
- let right_obj = right_ctx. map ( |ctx| ctx. obj ) ;
304
- let left_section = left_ctx
305
- . and_then ( |ctx| ctx. section_index . map ( |i| ( & ctx. obj . sections [ i] , & ctx. diff . sections [ i] ) ) ) ;
306
- let right_section = right_ctx
307
- . and_then ( |ctx| ctx. section_index . map ( |i| ( & ctx. obj . sections [ i] , & ctx. diff . sections [ i] ) ) ) ;
308
- let total_bytes = left_section
309
- . or ( right_section) ?
310
- . 1
311
- . data_diff
312
- . iter ( )
313
- . fold ( 0usize , |accum, item| accum + item. len ) ;
314
- if total_bytes == 0 {
315
- return None ;
316
- }
317
- let total_rows = ( total_bytes - 1 ) / BYTES_PER_ROW + 1 ;
318
-
319
- let left_diffs =
320
- left_section. map ( |( _, section) | split_diffs ( & section. data_diff , & section. reloc_diff ) ) ;
321
- let right_diffs =
322
- right_section. map ( |( _, section) | split_diffs ( & section. data_diff , & section. reloc_diff ) ) ;
323
-
324
- hotkeys:: check_scroll_hotkeys ( ui, true ) ;
325
-
326
- render_table ( ui, available_width, 2 , config. code_font . size , total_rows, |row, column| {
327
- let i = row. index ( ) ;
328
- let address = i * BYTES_PER_ROW ;
329
- row. col ( |ui| {
330
- if column == 0 {
331
- if let Some ( left_diffs) = & left_diffs {
332
- data_row_ui ( ui, left_obj, address, & left_diffs[ i] , config) ;
333
- }
334
- } else if column == 1 {
335
- if let Some ( right_diffs) = & right_diffs {
336
- data_row_ui ( ui, right_obj, address, & right_diffs[ i] , config) ;
337
- }
338
- }
339
- } ) ;
340
- } ) ;
341
- Some ( ( ) )
342
- }
343
-
344
- #[ must_use]
345
- pub fn data_diff_ui (
346
- ui : & mut egui:: Ui ,
347
- state : & DiffViewState ,
348
- appearance : & Appearance ,
349
- ) -> Option < DiffViewAction > {
350
- let mut ret = None ;
351
- let Some ( result) = & state. build else {
352
- return ret;
353
- } ;
354
-
355
- let section_name =
356
- state. symbol_state . left_symbol . as_ref ( ) . and_then ( |s| s. section_name . as_deref ( ) ) . or_else (
357
- || state. symbol_state . right_symbol . as_ref ( ) . and_then ( |s| s. section_name . as_deref ( ) ) ,
358
- ) ;
359
- let left_ctx = SectionDiffContext :: new ( result. first_obj . as_ref ( ) , section_name) ;
360
- let right_ctx = SectionDiffContext :: new ( result. second_obj . as_ref ( ) , section_name) ;
361
-
362
- // If both sides are missing a symbol, switch to symbol diff view
363
- if !right_ctx. is_some_and ( |ctx| ctx. has_section ( ) )
364
- && !left_ctx. is_some_and ( |ctx| ctx. has_section ( ) )
365
- {
366
- return Some ( DiffViewAction :: Navigate ( DiffViewNavigation :: symbol_diff ( ) ) ) ;
367
- }
368
-
369
- // Header
370
- let available_width = ui. available_width ( ) ;
371
- render_header ( ui, available_width, 2 , |ui, column| {
372
- if column == 0 {
373
- // Left column
374
- if ui. button ( "⏴ Back" ) . clicked ( ) || hotkeys:: back_pressed ( ui. ctx ( ) ) {
375
- ret = Some ( DiffViewAction :: Navigate ( DiffViewNavigation :: symbol_diff ( ) ) ) ;
376
- }
377
-
378
- if let Some ( section) =
379
- left_ctx. and_then ( |ctx| ctx. section_index . map ( |i| & ctx. obj . sections [ i] ) )
380
- {
381
- ui. label (
382
- RichText :: new ( section. name . clone ( ) )
383
- . font ( appearance. code_font . clone ( ) )
384
- . color ( appearance. highlight_color ) ,
385
- ) ;
386
- } else {
387
- ui. label (
388
- RichText :: new ( "Missing" )
389
- . font ( appearance. code_font . clone ( ) )
390
- . color ( appearance. replace_color ) ,
391
- ) ;
392
- }
393
- } else if column == 1 {
394
- // Right column
395
- ui. horizontal ( |ui| {
396
- if ui. add_enabled ( !state. build_running , egui:: Button :: new ( "Build" ) ) . clicked ( ) {
397
- ret = Some ( DiffViewAction :: Build ) ;
398
- }
399
- ui. scope ( |ui| {
400
- ui. style_mut ( ) . override_text_style = Some ( egui:: TextStyle :: Monospace ) ;
401
- if state. build_running {
402
- ui. colored_label ( appearance. replace_color , "Building…" ) ;
403
- } else {
404
- ui. label ( "Last built:" ) ;
405
- let format = format_description:: parse ( "[hour]:[minute]:[second]" ) . unwrap ( ) ;
406
- ui. label (
407
- result. time . to_offset ( appearance. utc_offset ) . format ( & format) . unwrap ( ) ,
408
- ) ;
409
- }
410
- } ) ;
411
- } ) ;
412
-
413
- if let Some ( section) =
414
- right_ctx. and_then ( |ctx| ctx. section_index . map ( |i| & ctx. obj . sections [ i] ) )
415
- {
416
- ui. label (
417
- RichText :: new ( section. name . clone ( ) )
418
- . font ( appearance. code_font . clone ( ) )
419
- . color ( appearance. highlight_color ) ,
420
- ) ;
421
- } else {
422
- ui. label (
423
- RichText :: new ( "Missing" )
424
- . font ( appearance. code_font . clone ( ) )
425
- . color ( appearance. replace_color ) ,
426
- ) ;
427
- }
428
- }
429
- } ) ;
430
-
431
- // Table
432
- let id =
433
- Id :: new ( state. symbol_state . left_symbol . as_ref ( ) . and_then ( |s| s. section_name . as_deref ( ) ) )
434
- . with ( state. symbol_state . right_symbol . as_ref ( ) . and_then ( |s| s. section_name . as_deref ( ) ) ) ;
435
- ui. push_id ( id, |ui| {
436
- data_table_ui ( ui, available_width, left_ctx, right_ctx, appearance) ;
437
- } ) ;
438
- ret
439
- }
0 commit comments