mirror of https://github.com/encounter/objdiff.git
Add dark/light theme toggle (light theme WIP)
This commit is contained in:
parent
c7a326b160
commit
b02e32f2b7
|
@ -2412,7 +2412,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "objdiff"
|
||||
version = "0.3.3"
|
||||
version = "0.3.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"byteorder",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "objdiff"
|
||||
version = "0.3.3"
|
||||
version = "0.3.4"
|
||||
edition = "2021"
|
||||
rust-version = "1.65"
|
||||
authors = ["Luke Street <luke@street.dev>"]
|
||||
|
|
65
src/app.rs
65
src/app.rs
|
@ -68,6 +68,21 @@ pub struct ViewConfig {
|
|||
pub code_font: FontId,
|
||||
pub diff_colors: Vec<Color32>,
|
||||
pub reverse_fn_order: bool,
|
||||
pub theme: eframe::Theme,
|
||||
#[serde(skip)]
|
||||
pub text_color: Color32, // GRAY
|
||||
#[serde(skip)]
|
||||
pub emphasized_text_color: Color32, // LIGHT_GRAY
|
||||
#[serde(skip)]
|
||||
pub deemphasized_text_color: Color32, // DARK_GRAY
|
||||
#[serde(skip)]
|
||||
pub highlight_color: Color32, // WHITE
|
||||
#[serde(skip)]
|
||||
pub replace_color: Color32, // LIGHT_BLUE
|
||||
#[serde(skip)]
|
||||
pub insert_color: Color32, // GREEN
|
||||
#[serde(skip)]
|
||||
pub delete_color: Color32, // RED
|
||||
}
|
||||
|
||||
impl Default for ViewConfig {
|
||||
|
@ -77,6 +92,14 @@ impl Default for ViewConfig {
|
|||
code_font: FontId { size: 14.0, family: FontFamily::Monospace },
|
||||
diff_colors: DEFAULT_COLOR_ROTATION.to_vec(),
|
||||
reverse_fn_order: false,
|
||||
theme: eframe::Theme::Dark,
|
||||
text_color: Color32::GRAY,
|
||||
emphasized_text_color: Color32::LIGHT_GRAY,
|
||||
deemphasized_text_color: Color32::DARK_GRAY,
|
||||
highlight_color: Color32::WHITE,
|
||||
replace_color: Color32::LIGHT_BLUE,
|
||||
insert_color: Color32::GREEN,
|
||||
delete_color: Color32::from_rgb(200, 40, 41),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -249,7 +272,7 @@ impl eframe::App for App {
|
|||
let Self { config, view_state, .. } = self;
|
||||
|
||||
{
|
||||
let config = &view_state.view_config;
|
||||
let config = &mut view_state.view_config;
|
||||
let mut style = (*ctx.style()).clone();
|
||||
style.text_styles.insert(TextStyle::Body, FontId {
|
||||
size: (config.ui_font.size * 0.75).floor(),
|
||||
|
@ -262,6 +285,28 @@ impl eframe::App for App {
|
|||
family: config.ui_font.family.clone(),
|
||||
});
|
||||
style.text_styles.insert(TextStyle::Monospace, config.code_font.clone());
|
||||
match config.theme {
|
||||
eframe::Theme::Dark => {
|
||||
style.visuals = egui::Visuals::dark();
|
||||
config.text_color = Color32::GRAY;
|
||||
config.emphasized_text_color = Color32::LIGHT_GRAY;
|
||||
config.deemphasized_text_color = Color32::DARK_GRAY;
|
||||
config.highlight_color = Color32::WHITE;
|
||||
config.replace_color = Color32::LIGHT_BLUE;
|
||||
config.insert_color = Color32::GREEN;
|
||||
config.delete_color = Color32::from_rgb(200, 40, 41);
|
||||
}
|
||||
eframe::Theme::Light => {
|
||||
style.visuals = egui::Visuals::light();
|
||||
config.text_color = Color32::GRAY;
|
||||
config.emphasized_text_color = Color32::DARK_GRAY;
|
||||
config.deemphasized_text_color = Color32::LIGHT_GRAY;
|
||||
config.highlight_color = Color32::BLACK;
|
||||
config.replace_color = Color32::DARK_BLUE;
|
||||
config.insert_color = Color32::DARK_GREEN;
|
||||
config.delete_color = Color32::from_rgb(200, 40, 41);
|
||||
}
|
||||
}
|
||||
ctx.set_style(style);
|
||||
}
|
||||
|
||||
|
@ -323,6 +368,20 @@ impl eframe::App for App {
|
|||
}
|
||||
|
||||
egui::Window::new("Config").open(&mut view_state.show_config).show(ctx, |ui| {
|
||||
egui::ComboBox::from_label("Theme")
|
||||
.selected_text(format!("{:?}", view_state.view_config.theme))
|
||||
.show_ui(ui, |ui| {
|
||||
ui.selectable_value(
|
||||
&mut view_state.view_config.theme,
|
||||
eframe::Theme::Dark,
|
||||
"Dark",
|
||||
);
|
||||
ui.selectable_value(
|
||||
&mut view_state.view_config.theme,
|
||||
eframe::Theme::Light,
|
||||
"Light",
|
||||
);
|
||||
});
|
||||
ui.label("UI font:");
|
||||
egui::introspection::font_id_ui(ui, &mut view_state.view_config.ui_font);
|
||||
ui.separator();
|
||||
|
@ -359,7 +418,7 @@ impl eframe::App for App {
|
|||
{
|
||||
ui.scope(|ui| {
|
||||
ui.style_mut().override_text_style = Some(TextStyle::Monospace);
|
||||
ui.colored_label(Color32::LIGHT_BLUE, &demangled);
|
||||
ui.colored_label(view_state.view_config.replace_color, &demangled);
|
||||
});
|
||||
if ui.button("Copy").clicked() {
|
||||
ui.output_mut(|output| output.copied_text = demangled);
|
||||
|
@ -367,7 +426,7 @@ impl eframe::App for App {
|
|||
} else {
|
||||
ui.scope(|ui| {
|
||||
ui.style_mut().override_text_style = Some(TextStyle::Monospace);
|
||||
ui.colored_label(Color32::LIGHT_RED, "[invalid]");
|
||||
ui.colored_label(view_state.view_config.replace_color, "[invalid]");
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -406,7 +406,9 @@ pub fn diff_objs(left: &mut ObjInfo, right: &mut ObjInfo, _diff_config: &DiffCon
|
|||
}
|
||||
}
|
||||
} else {
|
||||
let Some(right_section) = right.sections.iter_mut().find(|s| s.name == left_section.name) else {
|
||||
let Some(right_section) =
|
||||
right.sections.iter_mut().find(|s| s.name == left_section.name)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
if left_section.kind == ObjSectionKind::Data {
|
||||
|
|
|
@ -37,7 +37,8 @@ fn main() {
|
|||
|
||||
let exec_path: Rc<Mutex<Option<PathBuf>>> = Rc::new(Mutex::new(None));
|
||||
let exec_path_clone = exec_path.clone();
|
||||
let mut native_options = eframe::NativeOptions::default();
|
||||
let mut native_options =
|
||||
eframe::NativeOptions { follow_system_theme: false, ..Default::default() };
|
||||
match load_icon() {
|
||||
Ok(data) => {
|
||||
native_options.icon_data = Some(data);
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::sync::{Arc, RwLock};
|
|||
#[cfg(windows)]
|
||||
use anyhow::{Context, Result};
|
||||
use const_format::formatcp;
|
||||
use egui::{output::OpenUrl, Color32};
|
||||
use egui::output::OpenUrl;
|
||||
use self_update::cargo_crate_version;
|
||||
|
||||
use crate::{
|
||||
|
@ -79,7 +79,7 @@ pub fn config_ui(ui: &mut egui::Ui, config: &Arc<RwLock<AppConfig>>, view_state:
|
|||
if let Some(state) = &view_state.check_update {
|
||||
ui.label(format!("Latest version: {}", state.latest_release.version));
|
||||
if state.update_available {
|
||||
ui.colored_label(Color32::LIGHT_GREEN, "Update available");
|
||||
ui.colored_label(view_state.view_config.insert_color, "Update available");
|
||||
ui.horizontal(|ui| {
|
||||
if state.found_binary
|
||||
&& ui
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::{cmp::min, default::Default, mem::take};
|
||||
|
||||
use egui::{text::LayoutJob, Align, Color32, Label, Layout, Sense, Vec2};
|
||||
use egui::{text::LayoutJob, Align, Label, Layout, Sense, Vec2};
|
||||
use egui_extras::{Column, TableBuilder};
|
||||
use time::format_description;
|
||||
|
||||
|
@ -8,7 +8,7 @@ use crate::{
|
|||
app::{SymbolReference, View, ViewConfig, ViewState},
|
||||
jobs::Job,
|
||||
obj::{ObjDataDiff, ObjDataDiffKind, ObjInfo, ObjSection},
|
||||
views::{write_text, COLOR_RED},
|
||||
views::write_text,
|
||||
};
|
||||
|
||||
const BYTES_PER_ROW: usize = 16;
|
||||
|
@ -24,17 +24,17 @@ fn data_row_ui(ui: &mut egui::Ui, address: usize, diffs: &[ObjDataDiff], config:
|
|||
let mut job = LayoutJob::default();
|
||||
write_text(
|
||||
format!("{address:08X}: ").as_str(),
|
||||
Color32::GRAY,
|
||||
config.text_color,
|
||||
&mut job,
|
||||
config.code_font.clone(),
|
||||
);
|
||||
let mut cur_addr = 0usize;
|
||||
for diff in diffs {
|
||||
let base_color = match diff.kind {
|
||||
ObjDataDiffKind::None => Color32::GRAY,
|
||||
ObjDataDiffKind::Replace => Color32::LIGHT_BLUE,
|
||||
ObjDataDiffKind::Delete => COLOR_RED,
|
||||
ObjDataDiffKind::Insert => Color32::GREEN,
|
||||
ObjDataDiffKind::None => config.text_color,
|
||||
ObjDataDiffKind::Replace => config.replace_color,
|
||||
ObjDataDiffKind::Delete => config.delete_color,
|
||||
ObjDataDiffKind::Insert => config.insert_color,
|
||||
};
|
||||
if diff.data.is_empty() {
|
||||
let mut str = " ".repeat(diff.len);
|
||||
|
@ -58,15 +58,15 @@ fn data_row_ui(ui: &mut egui::Ui, address: usize, diffs: &[ObjDataDiff], config:
|
|||
let mut str = " ".to_string();
|
||||
str.push_str(" ".repeat(n).as_str());
|
||||
str.push_str(" ".repeat(n / 8).as_str());
|
||||
write_text(str.as_str(), Color32::GRAY, &mut job, config.code_font.clone());
|
||||
write_text(str.as_str(), config.text_color, &mut job, config.code_font.clone());
|
||||
}
|
||||
write_text(" ", Color32::GRAY, &mut job, config.code_font.clone());
|
||||
write_text(" ", config.text_color, &mut job, config.code_font.clone());
|
||||
for diff in diffs {
|
||||
let base_color = match diff.kind {
|
||||
ObjDataDiffKind::None => Color32::GRAY,
|
||||
ObjDataDiffKind::Replace => Color32::LIGHT_BLUE,
|
||||
ObjDataDiffKind::Delete => COLOR_RED,
|
||||
ObjDataDiffKind::Insert => Color32::GREEN,
|
||||
ObjDataDiffKind::None => config.text_color,
|
||||
ObjDataDiffKind::Replace => config.replace_color,
|
||||
ObjDataDiffKind::Delete => config.delete_color,
|
||||
ObjDataDiffKind::Insert => config.insert_color,
|
||||
};
|
||||
if diff.data.is_empty() {
|
||||
write_text(
|
||||
|
@ -163,7 +163,8 @@ fn data_table_ui(
|
|||
|
||||
pub fn data_diff_ui(ui: &mut egui::Ui, view_state: &mut ViewState) -> bool {
|
||||
let mut rebuild = false;
|
||||
let (Some(result), Some(selected_symbol)) = (&view_state.build, &view_state.selected_symbol) else {
|
||||
let (Some(result), Some(selected_symbol)) = (&view_state.build, &view_state.selected_symbol)
|
||||
else {
|
||||
return rebuild;
|
||||
};
|
||||
|
||||
|
@ -188,7 +189,10 @@ pub fn data_diff_ui(ui: &mut egui::Ui, view_state: &mut ViewState) -> bool {
|
|||
ui.scope(|ui| {
|
||||
ui.style_mut().override_text_style = Some(egui::TextStyle::Monospace);
|
||||
ui.style_mut().wrap = Some(false);
|
||||
ui.colored_label(Color32::WHITE, &selected_symbol.symbol_name);
|
||||
ui.colored_label(
|
||||
view_state.view_config.highlight_color,
|
||||
&selected_symbol.symbol_name,
|
||||
);
|
||||
ui.label("Diff target:");
|
||||
});
|
||||
},
|
||||
|
|
|
@ -14,12 +14,18 @@ use crate::{
|
|||
ObjInfo, ObjIns, ObjInsArg, ObjInsArgDiff, ObjInsDiff, ObjInsDiffKind, ObjReloc,
|
||||
ObjRelocKind, ObjSymbol,
|
||||
},
|
||||
views::{symbol_diff::match_color_for_symbol, write_text, COLOR_RED},
|
||||
views::{symbol_diff::match_color_for_symbol, write_text},
|
||||
};
|
||||
|
||||
fn write_reloc_name(reloc: &ObjReloc, color: Color32, job: &mut LayoutJob, font_id: FontId) {
|
||||
fn write_reloc_name(
|
||||
reloc: &ObjReloc,
|
||||
color: Color32,
|
||||
job: &mut LayoutJob,
|
||||
font_id: FontId,
|
||||
config: &ViewConfig,
|
||||
) {
|
||||
let name = reloc.target.demangled_name.as_ref().unwrap_or(&reloc.target.name);
|
||||
write_text(name, Color32::LIGHT_GRAY, job, font_id.clone());
|
||||
write_text(name, config.emphasized_text_color, job, font_id.clone());
|
||||
match reloc.target.addend.cmp(&0i64) {
|
||||
Ordering::Greater => {
|
||||
write_text(&format!("+{:#X}", reloc.target.addend), color, job, font_id)
|
||||
|
@ -31,51 +37,57 @@ fn write_reloc_name(reloc: &ObjReloc, color: Color32, job: &mut LayoutJob, font_
|
|||
}
|
||||
}
|
||||
|
||||
fn write_reloc(reloc: &ObjReloc, color: Color32, job: &mut LayoutJob, font_id: FontId) {
|
||||
fn write_reloc(
|
||||
reloc: &ObjReloc,
|
||||
color: Color32,
|
||||
job: &mut LayoutJob,
|
||||
font_id: FontId,
|
||||
config: &ViewConfig,
|
||||
) {
|
||||
match reloc.kind {
|
||||
ObjRelocKind::PpcAddr16Lo => {
|
||||
write_reloc_name(reloc, color, job, font_id.clone());
|
||||
write_reloc_name(reloc, color, job, font_id.clone(), config);
|
||||
write_text("@l", color, job, font_id);
|
||||
}
|
||||
ObjRelocKind::PpcAddr16Hi => {
|
||||
write_reloc_name(reloc, color, job, font_id.clone());
|
||||
write_reloc_name(reloc, color, job, font_id.clone(), config);
|
||||
write_text("@h", color, job, font_id);
|
||||
}
|
||||
ObjRelocKind::PpcAddr16Ha => {
|
||||
write_reloc_name(reloc, color, job, font_id.clone());
|
||||
write_reloc_name(reloc, color, job, font_id.clone(), config);
|
||||
write_text("@ha", color, job, font_id);
|
||||
}
|
||||
ObjRelocKind::PpcEmbSda21 => {
|
||||
write_reloc_name(reloc, color, job, font_id.clone());
|
||||
write_reloc_name(reloc, color, job, font_id.clone(), config);
|
||||
write_text("@sda21", color, job, font_id);
|
||||
}
|
||||
ObjRelocKind::MipsHi16 => {
|
||||
write_text("%hi(", color, job, font_id.clone());
|
||||
write_reloc_name(reloc, color, job, font_id.clone());
|
||||
write_reloc_name(reloc, color, job, font_id.clone(), config);
|
||||
write_text(")", color, job, font_id);
|
||||
}
|
||||
ObjRelocKind::MipsLo16 => {
|
||||
write_text("%lo(", color, job, font_id.clone());
|
||||
write_reloc_name(reloc, color, job, font_id.clone());
|
||||
write_reloc_name(reloc, color, job, font_id.clone(), config);
|
||||
write_text(")", color, job, font_id);
|
||||
}
|
||||
ObjRelocKind::MipsGot16 => {
|
||||
write_text("%got(", color, job, font_id.clone());
|
||||
write_reloc_name(reloc, color, job, font_id.clone());
|
||||
write_reloc_name(reloc, color, job, font_id.clone(), config);
|
||||
write_text(")", color, job, font_id);
|
||||
}
|
||||
ObjRelocKind::MipsCall16 => {
|
||||
write_text("%call16(", color, job, font_id.clone());
|
||||
write_reloc_name(reloc, color, job, font_id.clone());
|
||||
write_reloc_name(reloc, color, job, font_id.clone(), config);
|
||||
write_text(")", color, job, font_id);
|
||||
}
|
||||
ObjRelocKind::MipsGpRel16 => {
|
||||
write_text("%gp_rel(", color, job, font_id.clone());
|
||||
write_reloc_name(reloc, color, job, font_id.clone());
|
||||
write_reloc_name(reloc, color, job, font_id.clone(), config);
|
||||
write_text(")", color, job, font_id);
|
||||
}
|
||||
ObjRelocKind::PpcRel24 | ObjRelocKind::PpcRel14 | ObjRelocKind::Mips26 => {
|
||||
write_reloc_name(reloc, color, job, font_id);
|
||||
write_reloc_name(reloc, color, job, font_id, config);
|
||||
}
|
||||
ObjRelocKind::Absolute | ObjRelocKind::MipsGpRel32 => {
|
||||
write_text("[INVALID]", color, job, font_id);
|
||||
|
@ -93,16 +105,16 @@ fn write_ins(
|
|||
) {
|
||||
let base_color = match diff_kind {
|
||||
ObjInsDiffKind::None | ObjInsDiffKind::OpMismatch | ObjInsDiffKind::ArgMismatch => {
|
||||
Color32::GRAY
|
||||
config.text_color
|
||||
}
|
||||
ObjInsDiffKind::Replace => Color32::LIGHT_BLUE,
|
||||
ObjInsDiffKind::Delete => COLOR_RED,
|
||||
ObjInsDiffKind::Insert => Color32::GREEN,
|
||||
ObjInsDiffKind::Replace => config.replace_color,
|
||||
ObjInsDiffKind::Delete => config.delete_color,
|
||||
ObjInsDiffKind::Insert => config.insert_color,
|
||||
};
|
||||
write_text(
|
||||
&format!("{:<11}", ins.mnemonic),
|
||||
match diff_kind {
|
||||
ObjInsDiffKind::OpMismatch => Color32::LIGHT_BLUE,
|
||||
ObjInsDiffKind::OpMismatch => config.replace_color,
|
||||
_ => base_color,
|
||||
},
|
||||
job,
|
||||
|
@ -137,10 +149,22 @@ fn write_ins(
|
|||
}
|
||||
},
|
||||
ObjInsArg::Reloc => {
|
||||
write_reloc(ins.reloc.as_ref().unwrap(), base_color, job, config.code_font.clone());
|
||||
write_reloc(
|
||||
ins.reloc.as_ref().unwrap(),
|
||||
base_color,
|
||||
job,
|
||||
config.code_font.clone(),
|
||||
config,
|
||||
);
|
||||
}
|
||||
ObjInsArg::RelocWithBase => {
|
||||
write_reloc(ins.reloc.as_ref().unwrap(), base_color, job, config.code_font.clone());
|
||||
write_reloc(
|
||||
ins.reloc.as_ref().unwrap(),
|
||||
base_color,
|
||||
job,
|
||||
config.code_font.clone(),
|
||||
config,
|
||||
);
|
||||
write_text("(", base_color, job, config.code_font.clone());
|
||||
writing_offset = true;
|
||||
continue;
|
||||
|
@ -176,7 +200,7 @@ fn write_ins(
|
|||
}
|
||||
}
|
||||
|
||||
fn ins_hover_ui(ui: &mut egui::Ui, ins: &ObjIns) {
|
||||
fn ins_hover_ui(ui: &mut egui::Ui, ins: &ObjIns, config: &ViewConfig) {
|
||||
ui.scope(|ui| {
|
||||
ui.style_mut().override_text_style = Some(egui::TextStyle::Monospace);
|
||||
ui.style_mut().wrap = Some(false);
|
||||
|
@ -202,13 +226,16 @@ fn ins_hover_ui(ui: &mut egui::Ui, ins: &ObjIns) {
|
|||
|
||||
if let Some(reloc) = &ins.reloc {
|
||||
ui.label(format!("Relocation type: {:?}", reloc.kind));
|
||||
ui.colored_label(Color32::WHITE, format!("Name: {}", reloc.target.name));
|
||||
ui.colored_label(config.highlight_color, format!("Name: {}", reloc.target.name));
|
||||
if let Some(section) = &reloc.target_section {
|
||||
ui.colored_label(Color32::WHITE, format!("Section: {section}"));
|
||||
ui.colored_label(Color32::WHITE, format!("Address: {:x}", reloc.target.address));
|
||||
ui.colored_label(Color32::WHITE, format!("Size: {:x}", reloc.target.size));
|
||||
ui.colored_label(config.highlight_color, format!("Section: {section}"));
|
||||
ui.colored_label(
|
||||
config.highlight_color,
|
||||
format!("Address: {:x}", reloc.target.address),
|
||||
);
|
||||
ui.colored_label(config.highlight_color, format!("Size: {:x}", reloc.target.size));
|
||||
} else {
|
||||
ui.colored_label(Color32::WHITE, "Extern".to_string());
|
||||
ui.colored_label(config.highlight_color, "Extern".to_string());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -291,16 +318,16 @@ fn asm_row_ui(ui: &mut egui::Ui, ins_diff: &ObjInsDiff, symbol: &ObjSymbol, conf
|
|||
|
||||
let base_color = match ins_diff.kind {
|
||||
ObjInsDiffKind::None | ObjInsDiffKind::OpMismatch | ObjInsDiffKind::ArgMismatch => {
|
||||
Color32::GRAY
|
||||
config.text_color
|
||||
}
|
||||
ObjInsDiffKind::Replace => Color32::LIGHT_BLUE,
|
||||
ObjInsDiffKind::Delete => COLOR_RED,
|
||||
ObjInsDiffKind::Insert => Color32::GREEN,
|
||||
ObjInsDiffKind::Replace => config.replace_color,
|
||||
ObjInsDiffKind::Delete => config.delete_color,
|
||||
ObjInsDiffKind::Insert => config.insert_color,
|
||||
};
|
||||
let mut pad = 6;
|
||||
if let Some(line) = ins.line {
|
||||
let line_str = format!("{line} ");
|
||||
write_text(&line_str, Color32::DARK_GRAY, &mut job, config.code_font.clone());
|
||||
write_text(&line_str, config.deemphasized_text_color, &mut job, config.code_font.clone());
|
||||
pad = 12 - line_str.len();
|
||||
}
|
||||
write_text(
|
||||
|
@ -329,7 +356,7 @@ fn asm_row_ui(ui: &mut egui::Ui, ins_diff: &ObjInsDiff, symbol: &ObjSymbol, conf
|
|||
);
|
||||
}
|
||||
ui.add(Label::new(job).sense(Sense::click()))
|
||||
.on_hover_ui_at_pointer(|ui| ins_hover_ui(ui, ins))
|
||||
.on_hover_ui_at_pointer(|ui| ins_hover_ui(ui, ins, config))
|
||||
.context_menu(|ui| ins_context_menu(ui, ins));
|
||||
}
|
||||
|
||||
|
@ -362,7 +389,8 @@ fn asm_table_ui(
|
|||
|
||||
pub fn function_diff_ui(ui: &mut egui::Ui, view_state: &mut ViewState) -> bool {
|
||||
let mut rebuild = false;
|
||||
let (Some(result), Some(selected_symbol)) = (&view_state.build, &view_state.selected_symbol) else {
|
||||
let (Some(result), Some(selected_symbol)) = (&view_state.build, &view_state.selected_symbol)
|
||||
else {
|
||||
return rebuild;
|
||||
};
|
||||
|
||||
|
@ -389,7 +417,7 @@ pub fn function_diff_ui(ui: &mut egui::Ui, view_state: &mut ViewState) -> bool {
|
|||
let mut job = LayoutJob::simple(
|
||||
name.to_string(),
|
||||
view_state.view_config.code_font.clone(),
|
||||
Color32::WHITE,
|
||||
view_state.view_config.highlight_color,
|
||||
column_width,
|
||||
);
|
||||
job.wrap.break_anywhere = true;
|
||||
|
@ -443,7 +471,7 @@ pub fn function_diff_ui(ui: &mut egui::Ui, view_state: &mut ViewState) -> bool {
|
|||
.and_then(|symbol| symbol.match_percent)
|
||||
{
|
||||
ui.colored_label(
|
||||
match_color_for_symbol(match_percent),
|
||||
match_color_for_symbol(match_percent, &view_state.view_config),
|
||||
&format!("{match_percent:.0}%"),
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use egui::{Color32, ProgressBar, Widget};
|
||||
use egui::{ProgressBar, Widget};
|
||||
|
||||
use crate::app::ViewState;
|
||||
|
||||
|
@ -33,7 +33,7 @@ pub fn jobs_ui(ui: &mut egui::Ui, view_state: &mut ViewState) {
|
|||
if let Some(err) = &status.error {
|
||||
let err_string = err.to_string();
|
||||
ui.colored_label(
|
||||
Color32::from_rgb(255, 0, 0),
|
||||
view_state.view_config.delete_color,
|
||||
if err_string.len() > STATUS_LENGTH - 10 {
|
||||
format!("Error: {}...", &err_string[0..STATUS_LENGTH - 10])
|
||||
} else {
|
||||
|
|
|
@ -6,8 +6,6 @@ pub(crate) mod function_diff;
|
|||
pub(crate) mod jobs;
|
||||
pub(crate) mod symbol_diff;
|
||||
|
||||
const COLOR_RED: Color32 = Color32::from_rgb(200, 40, 41);
|
||||
|
||||
fn write_text(str: &str, color: Color32, job: &mut LayoutJob, font_id: FontId) {
|
||||
job.append(str, 0.0, TextFormat::simple(font_id, color));
|
||||
}
|
||||
|
|
|
@ -11,13 +11,13 @@ use crate::{
|
|||
views::write_text,
|
||||
};
|
||||
|
||||
pub fn match_color_for_symbol(match_percent: f32) -> Color32 {
|
||||
pub fn match_color_for_symbol(match_percent: f32, config: &ViewConfig) -> Color32 {
|
||||
if match_percent == 100.0 {
|
||||
Color32::GREEN
|
||||
config.insert_color
|
||||
} else if match_percent >= 50.0 {
|
||||
Color32::LIGHT_BLUE
|
||||
config.replace_color
|
||||
} else {
|
||||
Color32::RED
|
||||
config.delete_color
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,17 +39,17 @@ fn symbol_context_menu_ui(ui: &mut Ui, symbol: &ObjSymbol) {
|
|||
});
|
||||
}
|
||||
|
||||
fn symbol_hover_ui(ui: &mut Ui, symbol: &ObjSymbol) {
|
||||
fn symbol_hover_ui(ui: &mut Ui, symbol: &ObjSymbol, config: &ViewConfig) {
|
||||
ui.scope(|ui| {
|
||||
ui.style_mut().override_text_style = Some(egui::TextStyle::Monospace);
|
||||
ui.style_mut().wrap = Some(false);
|
||||
|
||||
ui.colored_label(Color32::WHITE, format!("Name: {}", symbol.name));
|
||||
ui.colored_label(Color32::WHITE, format!("Address: {:x}", symbol.address));
|
||||
ui.colored_label(config.highlight_color, format!("Name: {}", symbol.name));
|
||||
ui.colored_label(config.highlight_color, format!("Address: {:x}", symbol.address));
|
||||
if symbol.size_known {
|
||||
ui.colored_label(Color32::WHITE, format!("Size: {:x}", symbol.size));
|
||||
ui.colored_label(config.highlight_color, format!("Size: {:x}", symbol.size));
|
||||
} else {
|
||||
ui.colored_label(Color32::WHITE, format!("Size: {:x} (assumed)", symbol.size));
|
||||
ui.colored_label(config.highlight_color, format!("Size: {:x} (assumed)", symbol.size));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -70,33 +70,38 @@ fn symbol_ui(
|
|||
if let Some(sym) = highlighted_symbol {
|
||||
selected = sym == &symbol.name;
|
||||
}
|
||||
write_text("[", Color32::GRAY, &mut job, config.code_font.clone());
|
||||
write_text("[", config.text_color, &mut job, config.code_font.clone());
|
||||
if symbol.flags.0.contains(ObjSymbolFlags::Common) {
|
||||
write_text("c", Color32::from_rgb(0, 255, 255), &mut job, config.code_font.clone());
|
||||
} else if symbol.flags.0.contains(ObjSymbolFlags::Global) {
|
||||
write_text("g", Color32::GREEN, &mut job, config.code_font.clone());
|
||||
} else if symbol.flags.0.contains(ObjSymbolFlags::Local) {
|
||||
write_text("l", Color32::GRAY, &mut job, config.code_font.clone());
|
||||
}
|
||||
if symbol.flags.0.contains(ObjSymbolFlags::Weak) {
|
||||
write_text("w", Color32::GRAY, &mut job, config.code_font.clone());
|
||||
}
|
||||
write_text("] ", Color32::GRAY, &mut job, config.code_font.clone());
|
||||
if let Some(match_percent) = symbol.match_percent {
|
||||
write_text("(", Color32::GRAY, &mut job, config.code_font.clone());
|
||||
write_text(
|
||||
&format!("{match_percent:.0}%"),
|
||||
match_color_for_symbol(match_percent),
|
||||
"c",
|
||||
config.replace_color, /* Color32::from_rgb(0, 255, 255) */
|
||||
&mut job,
|
||||
config.code_font.clone(),
|
||||
);
|
||||
write_text(") ", Color32::GRAY, &mut job, config.code_font.clone());
|
||||
} else if symbol.flags.0.contains(ObjSymbolFlags::Global) {
|
||||
write_text("g", config.insert_color, &mut job, config.code_font.clone());
|
||||
} else if symbol.flags.0.contains(ObjSymbolFlags::Local) {
|
||||
write_text("l", config.text_color, &mut job, config.code_font.clone());
|
||||
}
|
||||
write_text(name, Color32::WHITE, &mut job, config.code_font.clone());
|
||||
if symbol.flags.0.contains(ObjSymbolFlags::Weak) {
|
||||
write_text("w", config.text_color, &mut job, config.code_font.clone());
|
||||
}
|
||||
write_text("] ", config.text_color, &mut job, config.code_font.clone());
|
||||
if let Some(match_percent) = symbol.match_percent {
|
||||
write_text("(", config.text_color, &mut job, config.code_font.clone());
|
||||
write_text(
|
||||
&format!("{match_percent:.0}%"),
|
||||
match_color_for_symbol(match_percent, config),
|
||||
&mut job,
|
||||
config.code_font.clone(),
|
||||
);
|
||||
write_text(") ", config.text_color, &mut job, config.code_font.clone());
|
||||
}
|
||||
write_text(name, config.highlight_color, &mut job, config.code_font.clone());
|
||||
let response = SelectableLabel::new(selected, job)
|
||||
.ui(ui)
|
||||
.context_menu(|ui| symbol_context_menu_ui(ui, symbol))
|
||||
.on_hover_ui_at_pointer(|ui| symbol_hover_ui(ui, symbol));
|
||||
.on_hover_ui_at_pointer(|ui| symbol_hover_ui(ui, symbol, config));
|
||||
if response.clicked() {
|
||||
if let Some(section) = section {
|
||||
if section.kind == ObjSectionKind::Code {
|
||||
|
@ -200,13 +205,13 @@ fn symbol_list_ui(
|
|||
});
|
||||
}
|
||||
|
||||
fn build_log_ui(ui: &mut Ui, status: &BuildStatus) {
|
||||
fn build_log_ui(ui: &mut Ui, status: &BuildStatus, config: &ViewConfig) {
|
||||
ScrollArea::both().auto_shrink([false, false]).show(ui, |ui| {
|
||||
ui.scope(|ui| {
|
||||
ui.style_mut().override_text_style = Some(egui::TextStyle::Monospace);
|
||||
ui.style_mut().wrap = Some(false);
|
||||
|
||||
ui.colored_label(Color32::from_rgb(255, 0, 0), &status.log);
|
||||
ui.colored_label(config.replace_color, &status.log);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -296,7 +301,7 @@ pub fn symbol_diff_ui(ui: &mut Ui, view_state: &mut ViewState) {
|
|||
);
|
||||
}
|
||||
} else {
|
||||
build_log_ui(ui, &result.first_status);
|
||||
build_log_ui(ui, &result.first_status, &view_state.view_config);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -315,7 +320,7 @@ pub fn symbol_diff_ui(ui: &mut Ui, view_state: &mut ViewState) {
|
|||
);
|
||||
}
|
||||
} else {
|
||||
build_log_ui(ui, &result.second_status);
|
||||
build_log_ui(ui, &result.second_status, &view_state.view_config);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue