mirror of https://github.com/encounter/objdiff.git
parent
79cd460333
commit
9710ccc38a
File diff suppressed because it is too large
Load Diff
|
@ -19,7 +19,8 @@ path = "src/main.rs"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["wgpu", "wsl"]
|
default = ["wgpu", "wsl"]
|
||||||
wgpu = ["eframe/wgpu"]
|
glow = ["eframe/glow"]
|
||||||
|
wgpu = ["eframe/wgpu", "dep:wgpu"]
|
||||||
wsl = []
|
wsl = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -29,7 +30,6 @@ cfg-if = "1.0.0"
|
||||||
const_format = "0.2.32"
|
const_format = "0.2.32"
|
||||||
cwdemangle = "1.0.0"
|
cwdemangle = "1.0.0"
|
||||||
dirs = "5.0.1"
|
dirs = "5.0.1"
|
||||||
eframe = { version = "0.27.2", features = ["persistence"] }
|
|
||||||
egui = "0.27.2"
|
egui = "0.27.2"
|
||||||
egui_extras = "0.27.2"
|
egui_extras = "0.27.2"
|
||||||
filetime = "0.2.23"
|
filetime = "0.2.23"
|
||||||
|
@ -50,6 +50,28 @@ strum = { version = "0.26.2", features = ["derive"] }
|
||||||
tempfile = "3.10.1"
|
tempfile = "3.10.1"
|
||||||
time = { version = "0.3.36", features = ["formatting", "local-offset"] }
|
time = { version = "0.3.36", features = ["formatting", "local-offset"] }
|
||||||
|
|
||||||
|
# Keep version in sync with egui
|
||||||
|
[dependencies.eframe]
|
||||||
|
version = "0.27.2"
|
||||||
|
features = [
|
||||||
|
"default_fonts",
|
||||||
|
"persistence",
|
||||||
|
"wayland",
|
||||||
|
"x11",
|
||||||
|
]
|
||||||
|
default-features = false
|
||||||
|
|
||||||
|
# Keep version in sync with eframe
|
||||||
|
[dependencies.wgpu]
|
||||||
|
version = "0.19.1"
|
||||||
|
features = [
|
||||||
|
"dx12",
|
||||||
|
"metal",
|
||||||
|
"webgpu",
|
||||||
|
]
|
||||||
|
optional = true
|
||||||
|
default-features = false
|
||||||
|
|
||||||
# For Linux static binaries, use rustls
|
# For Linux static binaries, use rustls
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
reqwest = { version = "0.12.4", default-features = false, features = ["blocking", "json", "multipart", "rustls-tls"] }
|
reqwest = { version = "0.12.4", default-features = false, features = ["blocking", "json", "multipart", "rustls-tls"] }
|
||||||
|
|
|
@ -37,6 +37,7 @@ use crate::{
|
||||||
demangle::{demangle_window, DemangleViewState},
|
demangle::{demangle_window, DemangleViewState},
|
||||||
frame_history::FrameHistory,
|
frame_history::FrameHistory,
|
||||||
function_diff::function_diff_ui,
|
function_diff::function_diff_ui,
|
||||||
|
graphics::{graphics_window, GraphicsConfig, GraphicsViewState},
|
||||||
jobs::jobs_ui,
|
jobs::jobs_ui,
|
||||||
symbol_diff::{symbol_diff_ui, DiffViewState, View},
|
symbol_diff::{symbol_diff_ui, DiffViewState, View},
|
||||||
},
|
},
|
||||||
|
@ -48,12 +49,14 @@ pub struct ViewState {
|
||||||
pub config_state: ConfigViewState,
|
pub config_state: ConfigViewState,
|
||||||
pub demangle_state: DemangleViewState,
|
pub demangle_state: DemangleViewState,
|
||||||
pub diff_state: DiffViewState,
|
pub diff_state: DiffViewState,
|
||||||
|
pub graphics_state: GraphicsViewState,
|
||||||
pub frame_history: FrameHistory,
|
pub frame_history: FrameHistory,
|
||||||
pub show_appearance_config: bool,
|
pub show_appearance_config: bool,
|
||||||
pub show_demangle: bool,
|
pub show_demangle: bool,
|
||||||
pub show_project_config: bool,
|
pub show_project_config: bool,
|
||||||
pub show_arch_config: bool,
|
pub show_arch_config: bool,
|
||||||
pub show_debug: bool,
|
pub show_debug: bool,
|
||||||
|
pub show_graphics: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The configuration for a single object file.
|
/// The configuration for a single object file.
|
||||||
|
@ -209,6 +212,7 @@ pub struct App {
|
||||||
config: AppConfigRef,
|
config: AppConfigRef,
|
||||||
modified: Arc<AtomicBool>,
|
modified: Arc<AtomicBool>,
|
||||||
watcher: Option<notify::RecommendedWatcher>,
|
watcher: Option<notify::RecommendedWatcher>,
|
||||||
|
app_path: Option<PathBuf>,
|
||||||
relaunch_path: Rc<Mutex<Option<PathBuf>>>,
|
relaunch_path: Rc<Mutex<Option<PathBuf>>>,
|
||||||
should_relaunch: bool,
|
should_relaunch: bool,
|
||||||
}
|
}
|
||||||
|
@ -222,6 +226,9 @@ impl App {
|
||||||
cc: &eframe::CreationContext<'_>,
|
cc: &eframe::CreationContext<'_>,
|
||||||
utc_offset: UtcOffset,
|
utc_offset: UtcOffset,
|
||||||
relaunch_path: Rc<Mutex<Option<PathBuf>>>,
|
relaunch_path: Rc<Mutex<Option<PathBuf>>>,
|
||||||
|
app_path: Option<PathBuf>,
|
||||||
|
graphics_config: GraphicsConfig,
|
||||||
|
graphics_config_path: Option<PathBuf>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// Load previous app state (if any).
|
// Load previous app state (if any).
|
||||||
// Note that you must enable the `persistence` feature for this to work.
|
// Note that you must enable the `persistence` feature for this to work.
|
||||||
|
@ -244,7 +251,32 @@ impl App {
|
||||||
}
|
}
|
||||||
app.appearance.init_fonts(&cc.egui_ctx);
|
app.appearance.init_fonts(&cc.egui_ctx);
|
||||||
app.appearance.utc_offset = utc_offset;
|
app.appearance.utc_offset = utc_offset;
|
||||||
|
app.app_path = app_path;
|
||||||
app.relaunch_path = relaunch_path;
|
app.relaunch_path = relaunch_path;
|
||||||
|
#[cfg(feature = "wgpu")]
|
||||||
|
if let Some(wgpu_render_state) = &cc.wgpu_render_state {
|
||||||
|
use eframe::egui_wgpu::wgpu::Backend;
|
||||||
|
let info = wgpu_render_state.adapter.get_info();
|
||||||
|
app.view_state.graphics_state.active_backend = match info.backend {
|
||||||
|
Backend::Empty => "Unknown",
|
||||||
|
Backend::Vulkan => "Vulkan",
|
||||||
|
Backend::Metal => "Metal",
|
||||||
|
Backend::Dx12 => "DirectX 12",
|
||||||
|
Backend::Gl => "OpenGL",
|
||||||
|
Backend::BrowserWebGpu => "WebGPU",
|
||||||
|
}
|
||||||
|
.to_string();
|
||||||
|
app.view_state.graphics_state.active_device.clone_from(&info.name);
|
||||||
|
}
|
||||||
|
#[cfg(feature = "glow")]
|
||||||
|
if let Some(gl) = &cc.gl {
|
||||||
|
use eframe::glow::HasContext;
|
||||||
|
app.view_state.graphics_state.active_backend = "OpenGL".to_string();
|
||||||
|
app.view_state.graphics_state.active_device =
|
||||||
|
unsafe { gl.get_parameter_string(0x1F01) }; // GL_RENDERER
|
||||||
|
}
|
||||||
|
app.view_state.graphics_state.graphics_config = graphics_config;
|
||||||
|
app.view_state.graphics_state.graphics_config_path = graphics_config_path;
|
||||||
app
|
app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,8 +299,8 @@ impl App {
|
||||||
JobResult::Update(state) => {
|
JobResult::Update(state) => {
|
||||||
if let Ok(mut guard) = self.relaunch_path.lock() {
|
if let Ok(mut guard) = self.relaunch_path.lock() {
|
||||||
*guard = Some(state.exe_path);
|
*guard = Some(state.exe_path);
|
||||||
|
self.should_relaunch = true;
|
||||||
}
|
}
|
||||||
self.should_relaunch = true;
|
|
||||||
}
|
}
|
||||||
_ => results.push(result),
|
_ => results.push(result),
|
||||||
}
|
}
|
||||||
|
@ -308,7 +340,7 @@ impl App {
|
||||||
fn post_update(&mut self, ctx: &egui::Context) {
|
fn post_update(&mut self, ctx: &egui::Context) {
|
||||||
self.appearance.post_update(ctx);
|
self.appearance.post_update(ctx);
|
||||||
|
|
||||||
let ViewState { jobs, diff_state, config_state, .. } = &mut self.view_state;
|
let ViewState { jobs, diff_state, config_state, graphics_state, .. } = &mut self.view_state;
|
||||||
config_state.post_update(ctx, jobs, &self.config);
|
config_state.post_update(ctx, jobs, &self.config);
|
||||||
diff_state.post_update(ctx, jobs, &self.config);
|
diff_state.post_update(ctx, jobs, &self.config);
|
||||||
|
|
||||||
|
@ -390,6 +422,15 @@ impl App {
|
||||||
jobs.push(start_build(ctx, diff_config));
|
jobs.push(start_build(ctx, diff_config));
|
||||||
config.queue_reload = false;
|
config.queue_reload = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if graphics_state.should_relaunch {
|
||||||
|
if let Some(app_path) = &self.app_path {
|
||||||
|
if let Ok(mut guard) = self.relaunch_path.lock() {
|
||||||
|
*guard = Some(app_path.clone());
|
||||||
|
self.should_relaunch = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,12 +451,14 @@ impl eframe::App for App {
|
||||||
config_state,
|
config_state,
|
||||||
demangle_state,
|
demangle_state,
|
||||||
diff_state,
|
diff_state,
|
||||||
|
graphics_state,
|
||||||
frame_history,
|
frame_history,
|
||||||
show_appearance_config,
|
show_appearance_config,
|
||||||
show_demangle,
|
show_demangle,
|
||||||
show_project_config,
|
show_project_config,
|
||||||
show_arch_config,
|
show_arch_config,
|
||||||
show_debug,
|
show_debug,
|
||||||
|
show_graphics,
|
||||||
} = view_state;
|
} = view_state;
|
||||||
|
|
||||||
frame_history.on_new_frame(ctx.input(|i| i.time), frame.info().cpu_usage);
|
frame_history.on_new_frame(ctx.input(|i| i.time), frame.info().cpu_usage);
|
||||||
|
@ -457,6 +500,10 @@ impl eframe::App for App {
|
||||||
*show_appearance_config = !*show_appearance_config;
|
*show_appearance_config = !*show_appearance_config;
|
||||||
ui.close_menu();
|
ui.close_menu();
|
||||||
}
|
}
|
||||||
|
if ui.button("Graphics…").clicked() {
|
||||||
|
*show_graphics = !*show_graphics;
|
||||||
|
ui.close_menu();
|
||||||
|
}
|
||||||
if ui.button("Quit").clicked() {
|
if ui.button("Quit").clicked() {
|
||||||
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
|
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
|
||||||
}
|
}
|
||||||
|
@ -543,6 +590,7 @@ impl eframe::App for App {
|
||||||
demangle_window(ctx, show_demangle, demangle_state, appearance);
|
demangle_window(ctx, show_demangle, demangle_state, appearance);
|
||||||
arch_config_window(ctx, config, show_arch_config, appearance);
|
arch_config_window(ctx, config, show_arch_config, appearance);
|
||||||
debug_window(ctx, show_debug, frame_history, appearance);
|
debug_window(ctx, show_debug, frame_history, appearance);
|
||||||
|
graphics_window(ctx, show_graphics, frame_history, graphics_state, appearance);
|
||||||
|
|
||||||
self.post_update(ctx);
|
self.post_update(ctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ use anyhow::{ensure, Result};
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
use time::UtcOffset;
|
use time::UtcOffset;
|
||||||
|
|
||||||
|
use crate::views::graphics::{load_graphics_config, GraphicsBackend, GraphicsConfig};
|
||||||
|
|
||||||
fn load_icon() -> Result<egui::IconData> {
|
fn load_icon() -> Result<egui::IconData> {
|
||||||
use bytes::Buf;
|
use bytes::Buf;
|
||||||
let decoder = png::Decoder::new(include_bytes!("../assets/icon_64.png").reader());
|
let decoder = png::Decoder::new(include_bytes!("../assets/icon_64.png").reader());
|
||||||
|
@ -31,6 +33,8 @@ fn load_icon() -> Result<egui::IconData> {
|
||||||
Ok(egui::IconData { rgba: buf, width: info.width, height: info.height })
|
Ok(egui::IconData { rgba: buf, width: info.width, height: info.height })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const APP_NAME: &str = "objdiff";
|
||||||
|
|
||||||
// When compiling natively:
|
// When compiling natively:
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -42,6 +46,7 @@ fn main() {
|
||||||
// https://github.com/time-rs/time/issues/293
|
// https://github.com/time-rs/time/issues/293
|
||||||
let utc_offset = UtcOffset::current_local_offset().unwrap_or(UtcOffset::UTC);
|
let utc_offset = UtcOffset::current_local_offset().unwrap_or(UtcOffset::UTC);
|
||||||
|
|
||||||
|
let app_path = std::env::current_exe().ok();
|
||||||
let exec_path: Rc<Mutex<Option<PathBuf>>> = Rc::new(Mutex::new(None));
|
let exec_path: Rc<Mutex<Option<PathBuf>>> = Rc::new(Mutex::new(None));
|
||||||
let exec_path_clone = exec_path.clone();
|
let exec_path_clone = exec_path.clone();
|
||||||
let mut native_options =
|
let mut native_options =
|
||||||
|
@ -54,14 +59,47 @@ fn main() {
|
||||||
log::warn!("Failed to load application icon: {}", e);
|
log::warn!("Failed to load application icon: {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let mut graphics_config = GraphicsConfig::default();
|
||||||
|
let mut graphics_config_path = None;
|
||||||
|
if let Some(storage_dir) = eframe::storage_dir(APP_NAME) {
|
||||||
|
let config_path = storage_dir.join("graphics.ron");
|
||||||
|
match load_graphics_config(&config_path) {
|
||||||
|
Ok(Some(config)) => {
|
||||||
|
graphics_config = config;
|
||||||
|
}
|
||||||
|
Ok(None) => {}
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("Failed to load native config: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
graphics_config_path = Some(config_path);
|
||||||
|
}
|
||||||
#[cfg(feature = "wgpu")]
|
#[cfg(feature = "wgpu")]
|
||||||
{
|
{
|
||||||
native_options.renderer = eframe::Renderer::Wgpu;
|
use eframe::egui_wgpu::wgpu::Backends;
|
||||||
|
if graphics_config.desired_backend.is_supported() {
|
||||||
|
native_options.wgpu_options.supported_backends = match graphics_config.desired_backend {
|
||||||
|
GraphicsBackend::Auto => native_options.wgpu_options.supported_backends,
|
||||||
|
GraphicsBackend::Dx12 => Backends::DX12,
|
||||||
|
GraphicsBackend::Metal => Backends::METAL,
|
||||||
|
GraphicsBackend::Vulkan => Backends::VULKAN,
|
||||||
|
GraphicsBackend::OpenGL => Backends::GL,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
eframe::run_native(
|
eframe::run_native(
|
||||||
"objdiff",
|
APP_NAME,
|
||||||
native_options,
|
native_options,
|
||||||
Box::new(move |cc| Box::new(app::App::new(cc, utc_offset, exec_path_clone))),
|
Box::new(move |cc| {
|
||||||
|
Box::new(app::App::new(
|
||||||
|
cc,
|
||||||
|
utc_offset,
|
||||||
|
exec_path_clone,
|
||||||
|
app_path,
|
||||||
|
graphics_config,
|
||||||
|
graphics_config_path,
|
||||||
|
))
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
.expect("Failed to run eframe application");
|
.expect("Failed to run eframe application");
|
||||||
|
|
||||||
|
@ -77,9 +115,7 @@ fn main() {
|
||||||
} else {
|
} else {
|
||||||
let result = std::process::Command::new(path)
|
let result = std::process::Command::new(path)
|
||||||
.args(std::env::args())
|
.args(std::env::args())
|
||||||
.spawn()
|
.spawn();
|
||||||
.unwrap()
|
|
||||||
.wait();
|
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
log::error!("Failed to relaunch: {:?}", e);
|
log::error!("Failed to relaunch: {:?}", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,9 @@ pub fn debug_window(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_ui(ui: &mut egui::Ui, frame_history: &mut FrameHistory, _appearance: &Appearance) {
|
fn debug_ui(ui: &mut egui::Ui, frame_history: &mut FrameHistory, _appearance: &Appearance) {
|
||||||
|
if ui.button("Clear memory").clicked() {
|
||||||
|
ui.memory_mut(|m| *m = Default::default());
|
||||||
|
}
|
||||||
ui.label(format!("Repainting the UI each frame. FPS: {:.1}", frame_history.fps()));
|
ui.label(format!("Repainting the UI each frame. FPS: {:.1}", frame_history.fps()));
|
||||||
frame_history.ui(ui);
|
frame_history.ui(ui);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,158 @@
|
||||||
|
use std::{
|
||||||
|
fs::File,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use egui::{text::LayoutJob, Context, FontId, RichText, TextFormat, TextStyle, Window};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use strum::{EnumIter, EnumMessage, IntoEnumIterator};
|
||||||
|
|
||||||
|
use crate::views::{appearance::Appearance, frame_history::FrameHistory};
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct GraphicsViewState {
|
||||||
|
pub active_backend: String,
|
||||||
|
pub active_device: String,
|
||||||
|
pub graphics_config: GraphicsConfig,
|
||||||
|
pub graphics_config_path: Option<PathBuf>,
|
||||||
|
pub should_relaunch: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Copy, Clone, Debug, Default, PartialEq, Eq, EnumIter, EnumMessage, Serialize, Deserialize,
|
||||||
|
)]
|
||||||
|
pub enum GraphicsBackend {
|
||||||
|
#[default]
|
||||||
|
#[strum(message = "Auto")]
|
||||||
|
Auto,
|
||||||
|
#[strum(message = "Vulkan")]
|
||||||
|
Vulkan,
|
||||||
|
#[strum(message = "Metal")]
|
||||||
|
Metal,
|
||||||
|
#[strum(message = "DirectX 12")]
|
||||||
|
Dx12,
|
||||||
|
#[strum(message = "OpenGL")]
|
||||||
|
OpenGL,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub struct GraphicsConfig {
|
||||||
|
#[serde(default)]
|
||||||
|
pub desired_backend: GraphicsBackend,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_graphics_config(path: &Path) -> Result<Option<GraphicsConfig>> {
|
||||||
|
if !path.exists() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
let file = File::open(path)?;
|
||||||
|
let config: GraphicsConfig = ron::de::from_reader(file)?;
|
||||||
|
Ok(Some(config))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save_graphics_config(path: &Path, config: &GraphicsConfig) -> Result<()> {
|
||||||
|
let file = File::create(path)?;
|
||||||
|
ron::ser::to_writer(file, config)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GraphicsBackend {
|
||||||
|
pub fn is_supported(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
GraphicsBackend::Auto => true,
|
||||||
|
GraphicsBackend::Vulkan => {
|
||||||
|
cfg!(all(feature = "wgpu", any(target_os = "windows", target_os = "linux")))
|
||||||
|
}
|
||||||
|
GraphicsBackend::Metal => cfg!(all(feature = "wgpu", target_os = "macos")),
|
||||||
|
GraphicsBackend::Dx12 => cfg!(all(feature = "wgpu", target_os = "windows")),
|
||||||
|
GraphicsBackend::OpenGL => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn graphics_window(
|
||||||
|
ctx: &Context,
|
||||||
|
show: &mut bool,
|
||||||
|
frame_history: &mut FrameHistory,
|
||||||
|
state: &mut GraphicsViewState,
|
||||||
|
appearance: &Appearance,
|
||||||
|
) {
|
||||||
|
Window::new("Graphics").open(show).show(ctx, |ui| {
|
||||||
|
ui.label("Graphics backend:");
|
||||||
|
ui.label(
|
||||||
|
RichText::new(&state.active_backend)
|
||||||
|
.color(appearance.emphasized_text_color)
|
||||||
|
.text_style(TextStyle::Monospace),
|
||||||
|
);
|
||||||
|
ui.label("Graphics device:");
|
||||||
|
ui.label(
|
||||||
|
RichText::new(&state.active_device)
|
||||||
|
.color(appearance.emphasized_text_color)
|
||||||
|
.text_style(TextStyle::Monospace),
|
||||||
|
);
|
||||||
|
ui.label(format!("FPS: {:.1}", frame_history.fps()));
|
||||||
|
|
||||||
|
ui.separator();
|
||||||
|
let mut job = LayoutJob::default();
|
||||||
|
job.append(
|
||||||
|
"WARNING: ",
|
||||||
|
0.0,
|
||||||
|
TextFormat::simple(appearance.ui_font.clone(), appearance.delete_color),
|
||||||
|
);
|
||||||
|
job.append(
|
||||||
|
"Changing the graphics backend may cause the application\nto no longer start or display correctly. Use with caution!",
|
||||||
|
0.0,
|
||||||
|
TextFormat::simple(appearance.ui_font.clone(), appearance.emphasized_text_color),
|
||||||
|
);
|
||||||
|
if let Some(config_path) = &state.graphics_config_path {
|
||||||
|
job.append(
|
||||||
|
"\n\nDelete the following file to reset:\n",
|
||||||
|
0.0,
|
||||||
|
TextFormat::simple(appearance.ui_font.clone(), appearance.emphasized_text_color),
|
||||||
|
);
|
||||||
|
job.append(
|
||||||
|
config_path.to_string_lossy().as_ref(),
|
||||||
|
0.0,
|
||||||
|
TextFormat::simple(
|
||||||
|
FontId {
|
||||||
|
family: appearance.code_font.family.clone(),
|
||||||
|
size: appearance.ui_font.size,
|
||||||
|
},
|
||||||
|
appearance.emphasized_text_color,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
job.append(
|
||||||
|
"\n\nChanging the graphics backend will restart the application.",
|
||||||
|
0.0,
|
||||||
|
TextFormat::simple(appearance.ui_font.clone(), appearance.replace_color),
|
||||||
|
);
|
||||||
|
ui.label(job);
|
||||||
|
|
||||||
|
ui.add_enabled_ui(state.graphics_config_path.is_some(), |ui| {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.label("Desired backend:");
|
||||||
|
for backend in GraphicsBackend::iter().filter(GraphicsBackend::is_supported) {
|
||||||
|
let selected = state.graphics_config.desired_backend == backend;
|
||||||
|
if ui.selectable_label(selected, backend.get_message().unwrap()).clicked() {
|
||||||
|
let prev_backend = state.graphics_config.desired_backend;
|
||||||
|
state.graphics_config.desired_backend = backend;
|
||||||
|
match save_graphics_config(
|
||||||
|
state.graphics_config_path.as_ref().unwrap(),
|
||||||
|
&state.graphics_config,
|
||||||
|
) {
|
||||||
|
Ok(()) => {
|
||||||
|
state.should_relaunch = true;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("Failed to save graphics config: {:?}", e);
|
||||||
|
state.graphics_config.desired_backend = prev_backend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ pub(crate) mod demangle;
|
||||||
pub(crate) mod file;
|
pub(crate) mod file;
|
||||||
pub(crate) mod frame_history;
|
pub(crate) mod frame_history;
|
||||||
pub(crate) mod function_diff;
|
pub(crate) mod function_diff;
|
||||||
|
pub(crate) mod graphics;
|
||||||
pub(crate) mod jobs;
|
pub(crate) mod jobs;
|
||||||
pub(crate) mod symbol_diff;
|
pub(crate) mod symbol_diff;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue