blob: 6fd881049b861479c18480a761677521d0355ed9 [file] [log] [blame]
use crate::views::render_view::RenderView;
use egui::{RichText, TextBuffer, Ui};
use egui_extras::{Column, TableBuilder};
use crate::app_state::AppState;
use crate::stream::CurrentFrame;
const AVM_SOURCE_ROOT: &str = "avm/";
pub struct SymbolInfoViewer;
impl RenderView for SymbolInfoViewer {
fn title(&self) -> String {
"Symbol Info".into()
}
fn render(&self, ui: &mut Ui, state: &mut AppState) -> anyhow::Result<()> {
let Some(frame) = state.stream.current_frame() else {
// No frame loaded yet.
return Ok(());
};
let Some(selected_object) = &mut state.settings.selected_object else {
// No coding unit is selected.
return Ok(());
};
let Ok(info) = selected_object.get_or_calculate_info(frame) else {
return Ok(());
};
ui.horizontal(|ui| {
ui.label("Filter:");
ui.text_edit_singleline(&mut state.settings.sharable.symbol_info_filter);
});
ui.end_row();
ui.checkbox(&mut state.settings.sharable.symbol_info_show_tags, "Show tags");
ui.separator();
TableBuilder::new(ui)
.column(Column::initial(200.0).resizable(true))
.column(Column::initial(100.0).resizable(true))
.column(Column::remainder())
.striped(true)
.header(20.0, |mut header| {
header.col(|ui| {
ui.label(RichText::new("Symbol Type").strong());
});
header.col(|ui| {
ui.label(RichText::new("Value").strong());
});
header.col(|ui| {
ui.label(RichText::new("Bits").strong());
});
})
.body(|body| {
let symbols = info.symbols.clone();
let symbols = if state.settings.sharable.symbol_info_filter.is_empty() {
symbols
} else {
symbols
.into_iter()
.filter(|row| {
row.func.contains(&state.settings.sharable.symbol_info_filter)
|| (state.settings.sharable.symbol_info_show_tags
&& row
.tags
.iter()
.any(|tag| tag.contains(&state.settings.sharable.symbol_info_filter)))
})
.collect()
};
body.rows(20.0, symbols.len(), |mut row| {
let symbol = &symbols[row.index()];
row.col(|col| {
let prefix_start = symbol.file.rfind(AVM_SOURCE_ROOT);
let name = if symbol.tags.is_empty() || !state.settings.sharable.symbol_info_show_tags {
symbol.func.to_string()
} else {
format!("{} ({})", symbol.func, symbol.tags.join("+"))
};
if let Some(prefix_start) = prefix_start {
let relative_path = symbol
.file
.char_range(prefix_start + AVM_SOURCE_ROOT.len()..symbol.file.len());
let url = format!(
"{}/{}#L{}",
state.settings.persistent.avm_source_url, relative_path, symbol.line
);
col.hyperlink_to(name, url);
} else {
col.label(name);
}
});
row.col(|col| {
col.label(format!("{}", symbol.value));
});
row.col(|col| {
col.label(format!("{}", symbol.bits));
});
});
});
Ok(())
}
}