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