Skip to content

Commit

Permalink
Better GUI and increased resiliency of the program
Browse files Browse the repository at this point in the history
  • Loading branch information
Yeicor committed Jul 2, 2022
1 parent 24badc8 commit 7d2a541
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 16 deletions.
48 changes: 34 additions & 14 deletions src/app/cli.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use clap::Parser;
use eframe::egui;
use eframe::egui::Context;
use eframe::egui::{Context, TextEdit};
use eframe::egui::Widget;
use ehttp::Request;
use klask::app_state::AppState;

use crate::app::SDFViewerApp;
use crate::sdf::demo::SDFDemo;
use crate::sdf::SDFSurface;
use crate::sdf::wasm::load_sdf_wasm_send_sync;

#[derive(clap::Parser, Debug, Clone, PartialEq, Eq, Default)]
Expand Down Expand Up @@ -71,6 +72,10 @@ impl CliApp {
#[cfg(target_arch = "wasm32")]
{
tracing::error!("Failed to load SDF from URL: {:?}", err);
sender.send(unsafe {
// FIXME: Extremely unsafe code (forcing SDFDemo Send+Sync), but only used for this error path
std::mem::transmute(Box::new(SDFDemo::default()) as Box<dyn SDFSurface>)
});
}
#[cfg(not(target_arch = "wasm32"))]
{
Expand All @@ -88,6 +93,10 @@ impl CliApp {
}
Err(err2) => {
tracing::error!("Failed to load SDF from URL ({:?}) or file ({:?})", err, err2);
sender.send(unsafe {
// FIXME: Extremely unsafe code (forcing SDFDemo Send+Sync), but only used for this error path
std::mem::transmute(Box::new(SDFDemo::default()) as Box<dyn SDFSurface>)
});
}
}
}
Expand Down Expand Up @@ -133,16 +142,14 @@ impl SDFViewerAppSettings {
}

fn editing_to_instance(editing: &AppState) -> CliApp {
let args = editing.get_cmd_args(vec!["app".to_string()])
.or_else(|err| {
tracing::error!("Failed to parse CLI arguments (from settings GUI): {:?}", err);
Ok::<_, ()>(vec![])
}).unwrap();
<CliApp as clap::Parser>::try_parse_from(&args)
.or_else(|err| {
tracing::error!("Failed to parse CLI arguments (from settings GUI): {:?} --> {:?}", args, err);
Ok::<_, ()>(CliApp::default())
}).unwrap()
let args = editing.get_cmd_args(vec!["app".to_string()]).unwrap_or_else(|err| {
tracing::error!("Failed to parse CLI arguments (from settings GUI): {:?}", err);
vec![]
});
<CliApp as clap::Parser>::try_parse_from(&args).unwrap_or_else(|err| {
tracing::error!("Failed to parse CLI arguments (from settings GUI): {:?} --> {:?}", args, err);
CliApp::default()
})
}

pub fn show(app: &mut SDFViewerApp, ctx: &Context) {
Expand All @@ -161,7 +168,7 @@ impl SDFViewerAppSettings {
<&mut AppState>::ui(editing.as_mut().unwrap(), ui);

// # The cancel and apply buttons
ui.columns(2, |ui| {
let action = ui.columns(2, |ui| {
if ui[0].button("Cancel").clicked() {
return Some(SDFViewerAppSettings::Configured { settings: CliApp::clone(previous.as_ref().unwrap()) });
}
Expand All @@ -170,16 +177,29 @@ impl SDFViewerAppSettings {
return Some(SDFViewerAppSettings::Configured { settings: new_settings });
}
None
})
});

// The command line arguments that would generate this config (for copying)
let cmd_args = editing.as_mut().unwrap()
.get_cmd_args(vec![env!("CARGO_PKG_NAME").to_string()])
.unwrap_or_else(|err| vec![format!("Invalid configuration: {}", err)]);
ui.horizontal_wrapped(|ui| {
ui.label("CLI: ");
let mut cmd_args_str = cmd_args.join(" "); // TODO: Proper escaping
TextEdit::singleline(&mut cmd_args_str) // Not editable, but copyable
.desired_width(ui.available_width())
.ui(ui)
});

// TODO: The command line arguments that would generate this config (for copying)
action
}).and_then(|r| r.inner.flatten());
if prev_open && !open { // Closing the window is the same as cancelling
change_state = Some(SDFViewerAppSettings::Configured { settings: CliApp::clone(previous.as_ref().unwrap()) });
}

if let Some(new_state) = change_state {
if app.settings_values.previous() != &new_state.current() {
// TODO: Apply only the modified settings (know which settings were left unchanged / as default values)
new_state.current().apply(app)
// TODO: Auto-refresh the whole SDF.
}
Expand Down
5 changes: 3 additions & 2 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,12 @@ impl SDFViewerApp {
if settings_button.response.clicked() {
use clap::CommandFactory;
static LOC_SETTINGS: OnceCell<LocalizationSettings> = OnceCell::new();
let loc_settings = LOC_SETTINGS.get_or_init(LocalizationSettings::default);
self.settings_values = SDFViewerAppSettings::Configuring {
previous: values.clone(),
// TODO(klask): load initial values from the previous settings
editing: klask::app_state::AppState::new(
&CliApp::command(),
LOC_SETTINGS.get_or_init(|| LocalizationSettings::default())),
&CliApp::command(), loc_settings),
};
}
});
Expand Down
8 changes: 8 additions & 0 deletions src/run.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use eframe::AppCreator;
use klask::Settings;
use tracing::info;

use crate::app::SDFViewerApp;
Expand Down Expand Up @@ -38,6 +39,13 @@ pub async fn native_main() {
// Setup logging
tracing::subscriber::set_global_default(tracing_subscriber::FmtSubscriber::default())
.expect("Failed to set global default subscriber");
// If no arguments are provided, run a GUI interface for configuring the CLI arguments ;)
if std::env::args().nth(1).is_none() {
#[cfg(feature = "klask")]
klask::run_derived::<Cli, _>(Settings::default(), |_app| {
// Ignore me: this block will be skipped the second time (as arguments will be set)
});
}
// Run app
let native_options = eframe::NativeOptions::default();
if let Some(app_creator) = setup_app().await {
Expand Down

0 comments on commit 7d2a541

Please sign in to comment.