Skip to content

Commit 5af40e0

Browse files
committed
Auto-scroll the keyboard-selected symbols into view if offscreen
1 parent dfa145e commit 5af40e0

File tree

2 files changed

+32
-16
lines changed

2 files changed

+32
-16
lines changed

objdiff-gui/src/views/function_diff.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ fn asm_table_ui(
409409
right_ctx: Option<FunctionDiffContext<'_>>,
410410
appearance: &Appearance,
411411
ins_view_state: &FunctionViewState,
412-
symbol_state: &SymbolViewState,
412+
symbol_state: &mut SymbolViewState,
413413
) -> Option<DiffViewAction> {
414414
let mut ret = None;
415415
let left_len = left_ctx.and_then(|ctx| {
@@ -516,8 +516,9 @@ fn asm_table_ui(
516516
SymbolRefByName::new(right_symbol, right_section),
517517
));
518518
}
519-
DiffViewAction::SetSymbolHighlight(_, _) => {
520-
// Ignore
519+
DiffViewAction::SetSymbolHighlight(left, right, scroll) => {
520+
symbol_state.highlighted_symbol = (left, right);
521+
symbol_state.scroll_highlighted_symbol_into_view = scroll;
521522
}
522523
_ => {
523524
ret = Some(action);
@@ -576,8 +577,9 @@ fn asm_table_ui(
576577
right_symbol_ref,
577578
));
578579
}
579-
DiffViewAction::SetSymbolHighlight(_, _) => {
580-
// Ignore
580+
DiffViewAction::SetSymbolHighlight(left, right, scroll) => {
581+
symbol_state.highlighted_symbol = (left, right);
582+
symbol_state.scroll_highlighted_symbol_into_view = scroll;
581583
}
582584
_ => {
583585
ret = Some(action);
@@ -620,7 +622,7 @@ impl<'a> FunctionDiffContext<'a> {
620622
#[must_use]
621623
pub fn function_diff_ui(
622624
ui: &mut egui::Ui,
623-
state: &DiffViewState,
625+
state: &mut DiffViewState,
624626
appearance: &Appearance,
625627
) -> Option<DiffViewAction> {
626628
let mut ret = None;
@@ -823,7 +825,7 @@ pub fn function_diff_ui(
823825
right_ctx,
824826
appearance,
825827
&state.function_state,
826-
&state.symbol_state,
828+
&mut state.symbol_state,
827829
)
828830
})
829831
.inner

objdiff-gui/src/views/symbol_diff.rs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use std::{collections::BTreeMap, mem::take, ops::Bound};
22

33
use egui::{
4-
text::LayoutJob, CollapsingHeader, Color32, Id, OpenUrl, ScrollArea, SelectableLabel, TextEdit,
5-
Ui, Widget,
4+
style::ScrollAnimation, text::LayoutJob, CollapsingHeader, Color32, Id, OpenUrl, ScrollArea,
5+
SelectableLabel, TextEdit, Ui, Widget,
66
};
77
use objdiff_core::{
88
arch::ObjArch,
@@ -57,8 +57,8 @@ pub enum DiffViewAction {
5757
Build,
5858
/// Navigate to a new diff view
5959
Navigate(DiffViewNavigation),
60-
/// Set the highlighted symbols in the symbols view
61-
SetSymbolHighlight(Option<SymbolRef>, Option<SymbolRef>),
60+
/// Set the highlighted symbols in the symbols view, optionally scrolling them into view.
61+
SetSymbolHighlight(Option<SymbolRef>, Option<SymbolRef>, bool),
6262
/// Set the symbols view search filter
6363
SetSearch(String),
6464
/// Submit the current function to decomp.me
@@ -136,6 +136,7 @@ pub struct DiffViewState {
136136
#[derive(Default)]
137137
pub struct SymbolViewState {
138138
pub highlighted_symbol: (Option<SymbolRef>, Option<SymbolRef>),
139+
pub scroll_highlighted_symbol_into_view: bool,
139140
pub left_symbol: Option<SymbolRefByName>,
140141
pub right_symbol: Option<SymbolRefByName>,
141142
pub reverse_fn_order: bool,
@@ -247,8 +248,9 @@ impl DiffViewState {
247248
self.post_build_nav = Some(nav);
248249
}
249250
}
250-
DiffViewAction::SetSymbolHighlight(left, right) => {
251+
DiffViewAction::SetSymbolHighlight(left, right, scroll) => {
251252
self.symbol_state.highlighted_symbol = (left, right);
253+
self.symbol_state.scroll_highlighted_symbol_into_view = scroll;
252254
}
253255
DiffViewAction::SetSearch(search) => {
254256
self.search_regex = if search.is_empty() {
@@ -471,7 +473,7 @@ fn symbol_ui(
471473
symbol: &ObjSymbol,
472474
symbol_diff: &ObjSymbolDiff,
473475
section: Option<&ObjSection>,
474-
state: &SymbolViewState,
476+
state: &mut SymbolViewState,
475477
appearance: &Appearance,
476478
column: usize,
477479
) -> Option<DiffViewAction> {
@@ -534,6 +536,14 @@ fn symbol_ui(
534536
ret = Some(DiffViewAction::Navigate(result));
535537
}
536538
});
539+
if selected && state.scroll_highlighted_symbol_into_view {
540+
// Scroll the view to encompass the selected symbol in case the user selected an offscreen
541+
// symbol by using a keyboard shortcut.
542+
ui.scroll_to_rect_animation(response.rect, None, ScrollAnimation::none());
543+
// Then reset this flag so that we don't repeatedly scroll the view back when the user is
544+
// trying to manually scroll away.
545+
state.scroll_highlighted_symbol_into_view = false;
546+
}
537547
if response.clicked() || (selected && hotkeys::enter_pressed(ui.ctx())) {
538548
if let Some(section) = section {
539549
match section.kind {
@@ -565,11 +575,13 @@ fn symbol_ui(
565575
DiffViewAction::SetSymbolHighlight(
566576
Some(symbol_diff.symbol_ref),
567577
symbol_diff.target_symbol,
578+
false,
568579
)
569580
} else {
570581
DiffViewAction::SetSymbolHighlight(
571582
symbol_diff.target_symbol,
572583
Some(symbol_diff.symbol_ref),
584+
false,
573585
)
574586
});
575587
}
@@ -603,7 +615,7 @@ pub fn symbol_list_ui(
603615
ui: &mut Ui,
604616
ctx: SymbolDiffContext<'_>,
605617
other_ctx: Option<SymbolDiffContext<'_>>,
606-
state: &SymbolViewState,
618+
state: &mut SymbolViewState,
607619
filter: SymbolFilter<'_>,
608620
appearance: &Appearance,
609621
column: usize,
@@ -685,11 +697,13 @@ pub fn symbol_list_ui(
685697
DiffViewAction::SetSymbolHighlight(
686698
Some(*new_sym_ref),
687699
new_symbol_diff.target_symbol,
700+
true,
688701
)
689702
} else {
690703
DiffViewAction::SetSymbolHighlight(
691704
new_symbol_diff.target_symbol,
692705
Some(*new_sym_ref),
706+
true,
693707
)
694708
});
695709
}
@@ -941,7 +955,7 @@ pub fn symbol_diff_ui(
941955
.second_obj
942956
.as_ref()
943957
.map(|(obj, diff)| SymbolDiffContext { obj, diff }),
944-
&state.symbol_state,
958+
&mut state.symbol_state,
945959
filter,
946960
appearance,
947961
column,
@@ -965,7 +979,7 @@ pub fn symbol_diff_ui(
965979
.first_obj
966980
.as_ref()
967981
.map(|(obj, diff)| SymbolDiffContext { obj, diff }),
968-
&state.symbol_state,
982+
&mut state.symbol_state,
969983
filter,
970984
appearance,
971985
column,

0 commit comments

Comments
 (0)