something
This commit is contained in:
Generated
+57
@@ -30,6 +30,8 @@ version = "0.24.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5351dcebb14b579ccab05f288596b2ae097005be7ee50a7c3d4ca9d0d5a66f6a"
|
checksum = "5351dcebb14b579ccab05f288596b2ae097005be7ee50a7c3d4ca9d0d5a66f6a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"enumn",
|
||||||
|
"serde",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -225,6 +227,7 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
"getrandom 0.3.4",
|
"getrandom 0.3.4",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"serde",
|
||||||
"version_check",
|
"version_check",
|
||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
@@ -1449,6 +1452,7 @@ checksum = "55f6cc0cb3b84a21232c468db972ebcddd34decbf1ff02cdebffd807c13bbd81"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"emath",
|
"emath",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1466,6 +1470,7 @@ dependencies = [
|
|||||||
"egui_glow",
|
"egui_glow",
|
||||||
"glutin",
|
"glutin",
|
||||||
"glutin-winit",
|
"glutin-winit",
|
||||||
|
"home",
|
||||||
"image",
|
"image",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
@@ -1477,6 +1482,8 @@ dependencies = [
|
|||||||
"pollster",
|
"pollster",
|
||||||
"profiling",
|
"profiling",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
|
"ron",
|
||||||
|
"serde",
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"wasm-bindgen-futures",
|
"wasm-bindgen-futures",
|
||||||
@@ -1501,6 +1508,8 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"nohash-hasher",
|
"nohash-hasher",
|
||||||
"profiling",
|
"profiling",
|
||||||
|
"ron",
|
||||||
|
"serde",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
]
|
]
|
||||||
@@ -1541,6 +1550,7 @@ dependencies = [
|
|||||||
"objc2-ui-kit 0.3.2",
|
"objc2-ui-kit 0.3.2",
|
||||||
"profiling",
|
"profiling",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
|
"serde",
|
||||||
"smithay-clipboard",
|
"smithay-clipboard",
|
||||||
"web-time",
|
"web-time",
|
||||||
"webbrowser",
|
"webbrowser",
|
||||||
@@ -1597,6 +1607,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "a74fbbf7501c430b89df62d102b6bfa02162faaf3e155512c677c9d20f5708d1"
|
checksum = "a74fbbf7501c430b89df62d102b6bfa02162faaf3e155512c677c9d20f5708d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1635,6 +1646,17 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enumn"
|
||||||
|
version = "0.1.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "epaint"
|
name = "epaint"
|
||||||
version = "0.34.2"
|
version = "0.34.2"
|
||||||
@@ -1652,6 +1674,7 @@ dependencies = [
|
|||||||
"parking_lot",
|
"parking_lot",
|
||||||
"profiling",
|
"profiling",
|
||||||
"self_cell",
|
"self_cell",
|
||||||
|
"serde",
|
||||||
"skrifa",
|
"skrifa",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"vello_cpu",
|
"vello_cpu",
|
||||||
@@ -1868,6 +1891,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "5b38ad915f6dadd993ced50848a8291a543bd41ca62bc10740d5e64e2ab4cfd7"
|
checksum = "5b38ad915f6dadd993ced50848a8291a543bd41ca62bc10740d5e64e2ab4cfd7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2360,6 +2384,15 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
|
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "home"
|
||||||
|
version = "0.5.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "htmlparser"
|
name = "htmlparser"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@@ -4819,6 +4852,20 @@ dependencies = [
|
|||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ron"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.11.1",
|
||||||
|
"once_cell",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"typeid",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rowan"
|
name = "rowan"
|
||||||
version = "0.16.1"
|
version = "0.16.1"
|
||||||
@@ -5216,6 +5263,9 @@ name = "smallvec"
|
|||||||
version = "1.15.1"
|
version = "1.15.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smithay-client-toolkit"
|
name = "smithay-client-toolkit"
|
||||||
@@ -5461,6 +5511,7 @@ dependencies = [
|
|||||||
"egui_plot",
|
"egui_plot",
|
||||||
"fuzzy-matcher",
|
"fuzzy-matcher",
|
||||||
"libsvld",
|
"libsvld",
|
||||||
|
"rfd",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -5839,6 +5890,12 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typeid"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.20.0"
|
version = "1.20.0"
|
||||||
|
|||||||
@@ -12,8 +12,12 @@ bench = false
|
|||||||
libsvld = { path = "../libsvld" }
|
libsvld = { path = "../libsvld" }
|
||||||
can-dbc = "9.1"
|
can-dbc = "9.1"
|
||||||
|
|
||||||
eframe = "0.34"
|
eframe = {
|
||||||
|
version = "0.34",
|
||||||
|
features = ["persistence"]
|
||||||
|
}
|
||||||
egui = "0.34"
|
egui = "0.34"
|
||||||
egui_plot = "0.35"
|
egui_plot = "0.35"
|
||||||
egui_ltreeview = "0.7"
|
egui_ltreeview = "0.7"
|
||||||
fuzzy-matcher = "0.3"
|
fuzzy-matcher = "0.3"
|
||||||
|
rfd = "0.17"
|
||||||
|
|||||||
+262
-26
@@ -3,7 +3,13 @@ mod plot_list;
|
|||||||
mod signal;
|
mod signal;
|
||||||
mod tree;
|
mod tree;
|
||||||
|
|
||||||
use std::{fs, path::Path};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
fs,
|
||||||
|
path::PathBuf,
|
||||||
|
sync::{mpsc::{channel, Receiver}, Arc},
|
||||||
|
thread,
|
||||||
|
};
|
||||||
|
|
||||||
use can_dbc::Dbc;
|
use can_dbc::Dbc;
|
||||||
use eframe::egui;
|
use eframe::egui;
|
||||||
@@ -20,50 +26,171 @@ use crate::tree::{build_tree, decode_signal_node_id, show_dbc_tree, MsgNode};
|
|||||||
fn main() {
|
fn main() {
|
||||||
let native_options = eframe::NativeOptions::default();
|
let native_options = eframe::NativeOptions::default();
|
||||||
eframe::run_native(
|
eframe::run_native(
|
||||||
"My egui App",
|
"svldplotter",
|
||||||
native_options,
|
native_options,
|
||||||
Box::new(|cc| Ok(Box::new(MyEguiApp::new(cc)))),
|
Box::new(|cc| {
|
||||||
|
let mut app = MyEguiApp::default();
|
||||||
|
// Optional CLI quick-load: `svldplotter [DBC [ASC]]`. Both args
|
||||||
|
// are optional and intended for dev iteration.
|
||||||
|
let args: Vec<String> = std::env::args().collect();
|
||||||
|
if let Some(dbc) = args.get(1) {
|
||||||
|
app.load_dbc(PathBuf::from(dbc));
|
||||||
|
}
|
||||||
|
if let Some(asc) = args.get(2) {
|
||||||
|
app.asc_paths.push(PathBuf::from(asc));
|
||||||
|
app.set_active_asc(app.asc_paths.len() - 1, Some(&cc.egui_ctx));
|
||||||
|
}
|
||||||
|
Ok(Box::new(app))
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, PartialEq, Eq)]
|
||||||
|
enum LeftTab {
|
||||||
|
#[default]
|
||||||
|
Signals,
|
||||||
|
Files,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DecodeJob {
|
||||||
|
asc_index: usize,
|
||||||
|
asc_path: PathBuf,
|
||||||
|
receiver: Receiver<Arc<DecodeResult>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
struct MyEguiApp {
|
struct MyEguiApp {
|
||||||
data: DecodeResult,
|
dbc: Option<Arc<Dbc>>,
|
||||||
|
dbc_path: Option<PathBuf>,
|
||||||
|
asc_paths: Vec<PathBuf>,
|
||||||
|
active_asc: Option<usize>,
|
||||||
|
data: Option<Arc<DecodeResult>>,
|
||||||
|
decode_cache: HashMap<PathBuf, Arc<DecodeResult>>,
|
||||||
|
pending: Option<DecodeJob>,
|
||||||
tree: Vec<MsgNode>,
|
tree: Vec<MsgNode>,
|
||||||
filter: String,
|
filter: String,
|
||||||
plots: Vec<PlotGroup>,
|
plots: Vec<PlotGroup>,
|
||||||
next_plot_id: u64,
|
next_plot_id: u64,
|
||||||
cursor_x: Option<f64>,
|
cursor_x: Option<f64>,
|
||||||
|
left_tab: LeftTab,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MyEguiApp {
|
impl MyEguiApp {
|
||||||
fn new(_cc: &eframe::CreationContext<'_>) -> Self {
|
fn load_dbc(&mut self, path: PathBuf) {
|
||||||
let args: Vec<_> = std::env::args().collect();
|
let Ok(text) = fs::read_to_string(&path) else {
|
||||||
|
return;
|
||||||
let dbc_text =
|
};
|
||||||
fs::read_to_string(Path::new(&args[1])).expect("Unable to read input file");
|
let Ok(dbc) = Dbc::try_from(text.as_str()) else {
|
||||||
let dbc = Dbc::try_from(dbc_text.as_str()).expect("Failed to parse dbc file");
|
return;
|
||||||
|
};
|
||||||
let asc_path = Path::new(&args[2]);
|
self.dbc = Some(Arc::new(dbc));
|
||||||
let data = libsvld::decode(&dbc, asc_path);
|
self.dbc_path = Some(path);
|
||||||
let tree = build_tree(&dbc, &data);
|
// DBC change invalidates the decode cache.
|
||||||
|
self.decode_cache.clear();
|
||||||
Self {
|
self.pending = None;
|
||||||
data,
|
self.data = None;
|
||||||
tree,
|
self.tree.clear();
|
||||||
filter: String::new(),
|
if let Some(idx) = self.active_asc {
|
||||||
plots: Vec::new(),
|
self.start_or_use_cached(idx, None);
|
||||||
next_plot_id: 1,
|
|
||||||
cursor_x: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_asc(&mut self, path: PathBuf) {
|
||||||
|
self.asc_paths.push(path);
|
||||||
|
if self.active_asc.is_none() {
|
||||||
|
self.set_active_asc(self.asc_paths.len() - 1, None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Switch to a given ASC. Use the cached DecodeResult if present;
|
||||||
|
/// otherwise spawn a background decode and show progress via the
|
||||||
|
/// `pending` job.
|
||||||
|
fn set_active_asc(&mut self, idx: usize, ctx: Option<&egui::Context>) {
|
||||||
|
if idx >= self.asc_paths.len() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.active_asc = Some(idx);
|
||||||
|
self.start_or_use_cached(idx, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_or_use_cached(&mut self, idx: usize, ctx: Option<&egui::Context>) {
|
||||||
|
let Some(dbc) = self.dbc.clone() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let path = self.asc_paths[idx].clone();
|
||||||
|
if self.decode_cache.contains_key(&path) {
|
||||||
|
self.activate_decoded(idx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let (tx, rx) = channel();
|
||||||
|
let dbc_for_thread = dbc;
|
||||||
|
let path_for_thread = path.clone();
|
||||||
|
let ctx_for_thread = ctx.cloned();
|
||||||
|
thread::spawn(move || {
|
||||||
|
let result = libsvld::decode(&dbc_for_thread, &path_for_thread);
|
||||||
|
let _ = tx.send(Arc::new(result));
|
||||||
|
if let Some(ctx) = ctx_for_thread {
|
||||||
|
ctx.request_repaint();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
self.pending = Some(DecodeJob {
|
||||||
|
asc_index: idx,
|
||||||
|
asc_path: path,
|
||||||
|
receiver: rx,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pull a finished decode out of `pending` and install it.
|
||||||
|
fn poll_pending(&mut self) {
|
||||||
|
let Some(job) = self.pending.as_ref() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Ok(result) = job.receiver.try_recv() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let asc_index = job.asc_index;
|
||||||
|
let asc_path = job.asc_path.clone();
|
||||||
|
self.pending = None;
|
||||||
|
self.decode_cache.insert(asc_path, result);
|
||||||
|
if self.active_asc == Some(asc_index) {
|
||||||
|
self.activate_decoded(asc_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Point `self.data`/`self.tree` at the cached result for `idx` and
|
||||||
|
/// re-resolve every plotted signal against the new data.
|
||||||
|
fn activate_decoded(&mut self, idx: usize) {
|
||||||
|
let Some(dbc) = self.dbc.as_ref() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let path = &self.asc_paths[idx];
|
||||||
|
let Some(data) = self.decode_cache.get(path).cloned() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
self.tree = build_tree(dbc, &data);
|
||||||
|
// Re-resolve plotted signals so existing plots survive an ASC switch.
|
||||||
|
for plot in &mut self.plots {
|
||||||
|
for sig in &mut plot.signals {
|
||||||
|
if let Some((msg_id, sig_idx)) = decode_signal_node_id(sig.id) {
|
||||||
|
if let Some(new_sig) = compute_signal(&data, msg_id, sig_idx, sig.id) {
|
||||||
|
*sig = new_sig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.data = Some(data);
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_dbc_toggles(&mut self, toggles: Vec<u64>) {
|
fn handle_dbc_toggles(&mut self, toggles: Vec<u64>) {
|
||||||
|
let Some(data) = self.data.clone() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
for id in toggles {
|
for id in toggles {
|
||||||
if contains_signal(&self.plots, id) {
|
if contains_signal(&self.plots, id) {
|
||||||
remove_signal(&mut self.plots, id);
|
remove_signal(&mut self.plots, id);
|
||||||
} else if let Some((msg_id, sig_idx)) = decode_signal_node_id(id) {
|
} else if let Some((msg_id, sig_idx)) = decode_signal_node_id(id) {
|
||||||
if let Some(sig) = compute_signal(&self.data, msg_id, sig_idx, id) {
|
if let Some(sig) = compute_signal(&data, msg_id, sig_idx, id) {
|
||||||
add_signal_auto(&mut self.plots, &mut self.next_plot_id, sig);
|
add_signal_auto(&mut self.plots, &mut self.next_plot_id, sig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,8 +209,64 @@ impl MyEguiApp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum FilesAction {
|
||||||
|
LoadDbc(PathBuf),
|
||||||
|
AddAsc(PathBuf),
|
||||||
|
SetActive(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_files_tab(
|
||||||
|
ui: &mut egui::Ui,
|
||||||
|
dbc_path: Option<&PathBuf>,
|
||||||
|
asc_paths: &[PathBuf],
|
||||||
|
active: Option<usize>,
|
||||||
|
) -> Vec<FilesAction> {
|
||||||
|
let mut actions = Vec::new();
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
if ui.button("Load DBC").clicked() {
|
||||||
|
if let Some(p) = rfd::FileDialog::new()
|
||||||
|
.add_filter("DBC files", &["dbc"])
|
||||||
|
.pick_file()
|
||||||
|
{
|
||||||
|
actions.push(FilesAction::LoadDbc(p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let label = dbc_path
|
||||||
|
.map(|p| p.file_name().map(|s| s.to_string_lossy().into_owned()).unwrap_or_default())
|
||||||
|
.unwrap_or_else(|| "(none)".to_string());
|
||||||
|
ui.label(label);
|
||||||
|
});
|
||||||
|
ui.separator();
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
if ui.button("Add ASC").clicked() {
|
||||||
|
if let Some(p) = rfd::FileDialog::new()
|
||||||
|
.add_filter("ASC files", &["asc"])
|
||||||
|
.pick_file()
|
||||||
|
{
|
||||||
|
actions.push(FilesAction::AddAsc(p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui.label(format!("{} file(s)", asc_paths.len()));
|
||||||
|
});
|
||||||
|
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||||
|
for (i, path) in asc_paths.iter().enumerate() {
|
||||||
|
let name = path
|
||||||
|
.file_name()
|
||||||
|
.map(|s| s.to_string_lossy().into_owned())
|
||||||
|
.unwrap_or_else(|| path.display().to_string());
|
||||||
|
if ui.selectable_label(active == Some(i), name).clicked() {
|
||||||
|
actions.push(FilesAction::SetActive(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
actions
|
||||||
|
}
|
||||||
|
|
||||||
impl eframe::App for MyEguiApp {
|
impl eframe::App for MyEguiApp {
|
||||||
fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
|
fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
|
||||||
|
self.poll_pending();
|
||||||
|
|
||||||
|
let ctx = ui.ctx().clone();
|
||||||
egui::Panel::left(egui::Id::new("LeftPanel"))
|
egui::Panel::left(egui::Id::new("LeftPanel"))
|
||||||
.resizable(true)
|
.resizable(true)
|
||||||
.show_inside(ui, |ui| {
|
.show_inside(ui, |ui| {
|
||||||
@@ -92,13 +275,66 @@ impl eframe::App for MyEguiApp {
|
|||||||
.default_size(220.0)
|
.default_size(220.0)
|
||||||
.show_inside(ui, |ui| show_plot_list(ui, &self.plots))
|
.show_inside(ui, |ui| show_plot_list(ui, &self.plots))
|
||||||
.inner;
|
.inner;
|
||||||
let toggles = egui::CentralPanel::default()
|
let (toggles, files_actions) = egui::CentralPanel::default()
|
||||||
.show_inside(ui, |ui| show_dbc_tree(ui, &mut self.filter, &self.tree))
|
.show_inside(ui, |ui| {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.selectable_value(
|
||||||
|
&mut self.left_tab,
|
||||||
|
LeftTab::Signals,
|
||||||
|
"Signals",
|
||||||
|
);
|
||||||
|
ui.selectable_value(
|
||||||
|
&mut self.left_tab,
|
||||||
|
LeftTab::Files,
|
||||||
|
"Files",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
ui.separator();
|
||||||
|
match self.left_tab {
|
||||||
|
LeftTab::Signals => (
|
||||||
|
show_dbc_tree(ui, &mut self.filter, &self.tree),
|
||||||
|
Vec::new(),
|
||||||
|
),
|
||||||
|
LeftTab::Files => (
|
||||||
|
Vec::new(),
|
||||||
|
show_files_tab(
|
||||||
|
ui,
|
||||||
|
self.dbc_path.as_ref(),
|
||||||
|
&self.asc_paths,
|
||||||
|
self.active_asc,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
})
|
||||||
.inner;
|
.inner;
|
||||||
self.handle_dbc_toggles(toggles);
|
self.handle_dbc_toggles(toggles);
|
||||||
self.handle_plot_actions(plot_actions);
|
self.handle_plot_actions(plot_actions);
|
||||||
|
for action in files_actions {
|
||||||
|
match action {
|
||||||
|
FilesAction::LoadDbc(p) => self.load_dbc(p),
|
||||||
|
FilesAction::AddAsc(p) => self.add_asc(p),
|
||||||
|
FilesAction::SetActive(i) => self.set_active_asc(i, Some(&ctx)),
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
show_plot_panel(ui, &self.plots, &mut self.cursor_x);
|
show_plot_panel(ui, &self.plots, &mut self.cursor_x);
|
||||||
|
|
||||||
|
if let Some(job) = self.pending.as_ref() {
|
||||||
|
let name = job
|
||||||
|
.asc_path
|
||||||
|
.file_name()
|
||||||
|
.map(|s| s.to_string_lossy().into_owned())
|
||||||
|
.unwrap_or_else(|| job.asc_path.display().to_string());
|
||||||
|
egui::Modal::new(egui::Id::new("DecodingModal")).show(&ctx, |ui| {
|
||||||
|
ui.set_min_width(280.0);
|
||||||
|
ui.vertical_centered(|ui| {
|
||||||
|
ui.heading("Decoding...");
|
||||||
|
ui.add_space(6.0);
|
||||||
|
ui.label(name);
|
||||||
|
ui.add_space(6.0);
|
||||||
|
ui.spinner();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user