Windows GUI

This commit is contained in:
2026-05-19 11:35:26 +02:00
parent b620a8a2b4
commit 93ed0f33d7
4 changed files with 387 additions and 2 deletions
+15
View File
@@ -0,0 +1,15 @@
[package]
name = "svldgui"
version = "0.1.0"
edition = "2024"
[[bin]]
name = "svldgui"
test = false
bench = false
[dependencies]
libsvld = { path = "../libsvld" }
native-windows-gui = { version = "1.0.13", features = ["file-dialog"] }
native-windows-derive = "1.0.5"
can-dbc = "9.1.0"
+131
View File
@@ -0,0 +1,131 @@
#![windows_subsystem = "windows"]
extern crate native_windows_gui as nwg;
extern crate native_windows_derive as nwd;
use std::{cell::RefCell, ffi::OsStr, fs, path::PathBuf};
use can_dbc::Dbc;
use nwd::NwgUi;
use nwg::NativeUi;
#[derive(Default, NwgUi)]
pub struct BasicApp {
#[nwg_control(size: (800, 200), title: "Sane Vector Log Decoder", flags: "WINDOW|VISIBLE")]
#[nwg_events( OnWindowClose: [BasicApp::say_goodbye] )]
window: nwg::Window,
#[nwg_layout(parent: window, spacing: 1)]
grid: nwg::GridLayout,
#[nwg_resource(title: "Select DBC", action: nwg::FileDialogAction::Open, filters: "DBC(*.dbc)|Any(*.*)")]
dbc_dialog: nwg::FileDialog,
#[nwg_resource(title: "Select ASC(s)", action: nwg::FileDialogAction::Open, multiselect: true, filters: "ASC(*.asc)|Any(*.*)")]
asc_dialog: nwg::FileDialog,
#[nwg_resource(title: "Select output directory", action: nwg::FileDialogAction::OpenDirectory)]
out_dialog: nwg::FileDialog,
#[nwg_control(readonly: true)]
#[nwg_layout_item(layout: grid, col: 1, row: 0, col_span: 2)]
dbc_file_name: nwg::TextInput,
#[nwg_control(readonly: true)]
#[nwg_layout_item(layout: grid, col: 1, row: 1, col_span: 2)]
asc_file_names: nwg::TextInput,
#[nwg_control(readonly: true)]
#[nwg_layout_item(layout: grid, col: 1, row: 2, col_span: 2)]
out_directory: nwg::TextInput,
#[nwg_control(text: "Select DBC")]
#[nwg_layout_item(layout: grid, col: 0, row: 0)]
#[nwg_events( OnButtonClick: [BasicApp::pick_dbc] )]
dbc_button: nwg::Button,
#[nwg_control(text: "Select ASC(s)")]
#[nwg_layout_item(layout: grid, col: 0, row: 1)]
#[nwg_events( OnButtonClick: [BasicApp::pick_asc] )]
asc_button: nwg::Button,
#[nwg_control(text: "Select output dir")]
#[nwg_layout_item(layout: grid, col: 0, row: 2)]
#[nwg_events( OnButtonClick: [BasicApp::pick_out] )]
outdir_button: nwg::Button,
#[nwg_control(text: "Zrób fikołka")]
#[nwg_layout_item(layout: grid, col: 0, row: 3, col_span: 3)]
#[nwg_events( OnButtonClick: [BasicApp::action] )]
action_button: nwg::Button,
dbc_path: RefCell<Option<PathBuf>>,
asc_paths: RefCell<Option<Vec<PathBuf>>>,
out_path: RefCell<Option<PathBuf>>,
}
impl BasicApp {
fn action(&self) {
let dbc_path = self.dbc_path.borrow();
let asc_paths = self.asc_paths.borrow();
let out_path = self.out_path.borrow();
if let Some(dbc_path) = dbc_path.as_ref() &&
let Some(asc_paths) = asc_paths.as_ref() &&
let Some(out_path) = out_path.as_ref() {
let dbc_data = fs::read_to_string(dbc_path).unwrap();
let dbc = Dbc::try_from(dbc_data.as_str()).unwrap();
for asc_path in asc_paths {
libsvld::decode(&dbc, asc_path, out_path.as_path());
}
nwg::modal_info_message(&self.window,
"Okej",
"Finished!");
} else {
nwg::modal_error_message(&self.window,
"ERROR",
"Select all the paths first, you idiot");
}
}
fn pick_dbc(&self) {
if self.dbc_dialog.run(Some(&self.window)) &&
let Ok(file) = self.dbc_dialog.get_selected_item() {
*self.dbc_path.borrow_mut() = Some(file.clone().try_into().unwrap());
self.dbc_file_name.set_text(&file.into_string().unwrap());
}
}
fn pick_asc(&self) {
println!("here");
if self.asc_dialog.run(Some(&self.window)) &&
let Ok(files) = self.asc_dialog.get_selected_items() {
*self.asc_paths.borrow_mut() = Some(files
.clone()
.iter()
.map(|x| x.try_into().unwrap())
.collect());
self.asc_file_names.set_text(&files.join(OsStr::new("; ")).into_string().unwrap());
}
}
fn pick_out(&self) {
if self.out_dialog.run(Some(&self.window)) &&
let Ok(path) = self.out_dialog.get_selected_item() {
*self.out_path.borrow_mut() = Some(path.clone().try_into().unwrap());
self.out_directory.set_text(&path.into_string().unwrap());
}
}
fn say_goodbye(&self) {
nwg::stop_thread_dispatch();
}
}
fn main() {
nwg::init().expect("Failed to init Native Windows GUI");
nwg::Font::set_global_family("Segoe UI").expect("Failed to set default font");
let _app = BasicApp::build_ui(Default::default()).expect("Failed to build UI");
nwg::dispatch_thread_events();
}