@@ -4,28 +4,15 @@ use std::{
44 mem:: take,
55} ;
66
7- use egui:: { text:: LayoutJob , Id , Label , RichText , Sense , Widget } ;
7+ use egui:: { text:: LayoutJob , Label , Sense , Widget } ;
88use objdiff_core:: {
9- diff:: { ObjDataDiff , ObjDataDiffKind , ObjDataRelocDiff , ObjDiff } ,
9+ diff:: { ObjDataDiff , ObjDataDiffKind , ObjDataRelocDiff } ,
1010 obj:: ObjInfo ,
1111} ;
12- use time:: format_description;
1312
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} ;
2514
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 ;
2916
3017fn data_row_hover_ui (
3118 ui : & mut egui:: Ui ,
@@ -122,7 +109,7 @@ fn get_color_for_diff_kind(diff_kind: ObjDataDiffKind, appearance: &Appearance)
122109 }
123110}
124111
125- fn data_row_ui (
112+ pub ( crate ) fn data_row_ui (
126113 ui : & mut egui:: Ui ,
127114 obj : Option < & ObjInfo > ,
128115 address : usize ,
@@ -210,7 +197,7 @@ fn data_row_ui(
210197 }
211198}
212199
213- fn split_diffs (
200+ pub ( crate ) fn split_diffs (
214201 diffs : & [ ObjDataDiff ] ,
215202 reloc_diffs : & [ ObjDataRelocDiff ] ,
216203) -> Vec < Vec < ( ObjDataDiff , Vec < ObjDataRelocDiff > ) > > {
@@ -271,169 +258,3 @@ fn split_diffs(
271258 }
272259 split_diffs
273260}
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