Skip to content

Commit 70ab82f

Browse files
committed
gui: Highlight registers in columns separately
This matches the behavior of decomp.me and the CLI. Resolves #71
1 parent c589668 commit 70ab82f

File tree

1 file changed

+79
-12
lines changed

1 file changed

+79
-12
lines changed

objdiff-gui/src/views/function_diff.rs

Lines changed: 79 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::default::Default;
22

3-
use egui::{text::LayoutJob, Align, Label, Layout, Response, Sense, Vec2, Widget};
3+
use egui::{epaint::color, text::LayoutJob, Align, Label, Layout, Response, Sense, Vec2, Widget};
44
use egui_extras::{Column, TableBuilder, TableRow};
55
use objdiff_core::{
66
arch::ObjArch,
@@ -17,9 +17,54 @@ use crate::views::{
1717
symbol_diff::{match_color_for_symbol, DiffViewState, SymbolRefByName, View},
1818
};
1919

20+
#[derive(Copy, Clone, Eq, PartialEq)]
21+
enum ColumnId {
22+
Left,
23+
Right,
24+
}
25+
2026
#[derive(Default)]
2127
pub struct FunctionViewState {
22-
pub highlight: HighlightKind,
28+
pub left_highlight: HighlightKind,
29+
pub right_highlight: HighlightKind,
30+
}
31+
32+
impl FunctionViewState {
33+
pub fn highlight(&self, column: ColumnId) -> &HighlightKind {
34+
match column {
35+
ColumnId::Left => &self.left_highlight,
36+
ColumnId::Right => &self.right_highlight,
37+
}
38+
}
39+
40+
pub fn set_highlight(&mut self, column: ColumnId, highlight: HighlightKind) {
41+
match column {
42+
ColumnId::Left => {
43+
if highlight == self.left_highlight {
44+
if highlight == self.right_highlight {
45+
self.left_highlight = HighlightKind::None;
46+
self.right_highlight = HighlightKind::None;
47+
} else {
48+
self.right_highlight = self.left_highlight.clone();
49+
}
50+
} else {
51+
self.left_highlight = highlight;
52+
}
53+
}
54+
ColumnId::Right => {
55+
if highlight == self.right_highlight {
56+
if highlight == self.left_highlight {
57+
self.left_highlight = HighlightKind::None;
58+
self.right_highlight = HighlightKind::None;
59+
} else {
60+
self.left_highlight = self.right_highlight.clone();
61+
}
62+
} else {
63+
self.right_highlight = highlight;
64+
}
65+
}
66+
}
67+
}
2368
}
2469

2570
fn ins_hover_ui(
@@ -179,6 +224,7 @@ fn diff_text_ui(
179224
ins_diff: &ObjInsDiff,
180225
appearance: &Appearance,
181226
ins_view_state: &mut FunctionViewState,
227+
column: ColumnId,
182228
space_width: f32,
183229
response_cb: impl Fn(Response) -> Response,
184230
) {
@@ -243,7 +289,7 @@ fn diff_text_ui(
243289
}
244290

245291
let len = label_text.len();
246-
let highlight = ins_view_state.highlight == text;
292+
let highlight = *ins_view_state.highlight(column) == text;
247293
let mut response = Label::new(LayoutJob::single_section(
248294
label_text,
249295
appearance.code_text_format(base_color, highlight),
@@ -252,11 +298,7 @@ fn diff_text_ui(
252298
.ui(ui);
253299
response = response_cb(response);
254300
if response.clicked() {
255-
if highlight {
256-
ins_view_state.highlight = HighlightKind::None;
257-
} else {
258-
ins_view_state.highlight = text.into();
259-
}
301+
ins_view_state.set_highlight(column, text.into());
260302
}
261303
if len < pad_to {
262304
ui.add_space((pad_to - len) as f32 * space_width);
@@ -269,6 +311,7 @@ fn asm_row_ui(
269311
symbol: &ObjSymbol,
270312
appearance: &Appearance,
271313
ins_view_state: &mut FunctionViewState,
314+
column: ColumnId,
272315
response_cb: impl Fn(Response) -> Response,
273316
) {
274317
ui.spacing_mut().item_spacing.x = 0.0;
@@ -278,7 +321,16 @@ fn asm_row_ui(
278321
}
279322
let space_width = ui.fonts(|f| f.glyph_width(&appearance.code_font, ' '));
280323
display_diff(ins_diff, symbol.address, |text| {
281-
diff_text_ui(ui, text, ins_diff, appearance, ins_view_state, space_width, &response_cb);
324+
diff_text_ui(
325+
ui,
326+
text,
327+
ins_diff,
328+
appearance,
329+
ins_view_state,
330+
column,
331+
space_width,
332+
&response_cb,
333+
);
282334
Ok::<_, ()>(())
283335
})
284336
.unwrap();
@@ -290,6 +342,7 @@ fn asm_col_ui(
290342
symbol_ref: SymbolRef,
291343
appearance: &Appearance,
292344
ins_view_state: &mut FunctionViewState,
345+
column: ColumnId,
293346
) {
294347
let (section, symbol) = obj.0.section_symbol(symbol_ref);
295348
let section = section.unwrap();
@@ -305,7 +358,7 @@ fn asm_col_ui(
305358
}
306359
};
307360
let (_, response) = row.col(|ui| {
308-
asm_row_ui(ui, ins_diff, symbol, appearance, ins_view_state, response_cb);
361+
asm_row_ui(ui, ins_diff, symbol, appearance, ins_view_state, column, response_cb);
309362
});
310363
response_cb(response);
311364
}
@@ -344,12 +397,26 @@ fn asm_table_ui(
344397
table.body(|body| {
345398
body.rows(appearance.code_font.size, instructions_len, |mut row| {
346399
if let (Some(left_obj), Some(left_symbol_ref)) = (left_obj, left_symbol) {
347-
asm_col_ui(&mut row, left_obj, left_symbol_ref, appearance, ins_view_state);
400+
asm_col_ui(
401+
&mut row,
402+
left_obj,
403+
left_symbol_ref,
404+
appearance,
405+
ins_view_state,
406+
ColumnId::Left,
407+
);
348408
} else {
349409
empty_col_ui(&mut row);
350410
}
351411
if let (Some(right_obj), Some(right_symbol_ref)) = (right_obj, right_symbol) {
352-
asm_col_ui(&mut row, right_obj, right_symbol_ref, appearance, ins_view_state);
412+
asm_col_ui(
413+
&mut row,
414+
right_obj,
415+
right_symbol_ref,
416+
appearance,
417+
ins_view_state,
418+
ColumnId::Right,
419+
);
353420
} else {
354421
empty_col_ui(&mut row);
355422
}

0 commit comments

Comments
 (0)