@@ -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 ,
@@ -212,7 +199,7 @@ fn data_row_ui(
212199 }
213200}
214201
215- fn split_diffs (
202+ pub ( crate ) fn split_diffs (
216203 diffs : & [ ObjDataDiff ] ,
217204 reloc_diffs : & [ ObjDataRelocDiff ] ,
218205) -> Vec < Vec < ( ObjDataDiff , Vec < ObjDataRelocDiff > ) > > {
@@ -273,169 +260,3 @@ fn split_diffs(
273260 }
274261 split_diffs
275262}
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