mirror of
https://github.com/hubaldv/bioz-host-rs.git
synced 2026-07-23 16:47:43 +00:00
895
Cargo.lock
generated
895
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
14
Cargo.toml
14
Cargo.toml
@@ -5,14 +5,14 @@ edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
defmt = { version = "1.0.1" }
|
||||
eframe = { version = "0.33.3"}
|
||||
egui_plot = "0.34.0"
|
||||
egui_dock = "0.18.0"
|
||||
egui_extras = "0.33.3"
|
||||
eframe = { version = "0.34.1"}
|
||||
egui_plot = "0.35.0"
|
||||
egui_dock = "0.19.1"
|
||||
egui_extras = "0.34.1"
|
||||
log = "0.4.29"
|
||||
simple_logger = "5.0.0"
|
||||
simple_logger = "5.2.0"
|
||||
atomic_float = "1.1.0"
|
||||
chrono = { version = "0.4.43" }
|
||||
chrono = { version = "0.4.44" }
|
||||
rfd = { version = "0.17.2" }
|
||||
|
||||
[dependencies.bioz-icd-rs]
|
||||
@@ -32,7 +32,7 @@ version = "0.2.5"
|
||||
features = ["derive", "heapless_v0_8"]
|
||||
|
||||
[dependencies.tokio]
|
||||
version = "1.49.0"
|
||||
version = "1.52.1"
|
||||
features = [
|
||||
"rt-multi-thread",
|
||||
"macros",
|
||||
|
||||
167
src/app.rs
167
src/app.rs
@@ -716,9 +716,9 @@ impl App {
|
||||
}
|
||||
|
||||
impl eframe::App for App {
|
||||
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||
fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
|
||||
// Egui add a top bar
|
||||
egui::TopBottomPanel::top("top_bar").show(ctx, |ui| {
|
||||
egui::Panel::top("top_bar").show_inside(ui, |ui| {
|
||||
egui::MenuBar::new().ui(ui, |ui| {
|
||||
let is_connected = self.hardware_state_rx.borrow().hardware_connected != HardwareConnected::None;
|
||||
|
||||
@@ -782,52 +782,6 @@ impl eframe::App for App {
|
||||
}
|
||||
});
|
||||
|
||||
if self.log_marker_modal {
|
||||
if Modal::new(Id::new("modal_marker"))
|
||||
.show(ctx, |ui| {
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.heading("Add marker");
|
||||
|
||||
ui.add_space(16.0);
|
||||
|
||||
// Input field for marker
|
||||
let text_edit_response = TextEdit::singleline(&mut self.log_marker)
|
||||
.desired_width(100.0)
|
||||
.id(Id::new("marker_field"))
|
||||
.hint_text("Marker name")
|
||||
.ui(ui);
|
||||
|
||||
ui.add_space(16.0);
|
||||
|
||||
// Centered Add button
|
||||
let add_clicked = Button::new("Add")
|
||||
.corner_radius(5.0)
|
||||
.min_size(egui::vec2(80.0, 30.0))
|
||||
.ui(ui)
|
||||
.clicked();
|
||||
|
||||
// Check for Enter key in the TextEdit
|
||||
let enter_pressed = text_edit_response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter));
|
||||
|
||||
if add_clicked || enter_pressed {
|
||||
self.logging_control_tx.try_send(LoggingSignal::AddMarker(self.log_marker.clone())).unwrap_or_else(|e| {
|
||||
error!("Failed to send logging marker signal: {:?}", e);
|
||||
});
|
||||
self.log_marker = String::new();
|
||||
ui.close();
|
||||
}
|
||||
|
||||
// Request focus on the text edit when the modal opens
|
||||
text_edit_response.request_focus();
|
||||
});
|
||||
})
|
||||
.should_close()
|
||||
{
|
||||
self.log_marker_modal = false;
|
||||
self.log_marker = String::new();
|
||||
}
|
||||
}
|
||||
|
||||
ui.separator();
|
||||
|
||||
ui.add_enabled_ui(gui_logging_state == LoggingState::Idle, |ui| {
|
||||
@@ -866,30 +820,77 @@ impl eframe::App for App {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Show connection status in the bottom panel, green if connected
|
||||
if self.app_state_rx.borrow().tcp_connected {
|
||||
let frame = egui::Frame::default().fill(Color32::DARK_GREEN);
|
||||
|
||||
egui::TopBottomPanel::bottom("bottom_panel")
|
||||
.frame(frame)
|
||||
.show(ctx, |ui| {
|
||||
ui.with_layout(
|
||||
egui::Layout::centered_and_justified(egui::Direction::LeftToRight),
|
||||
|ui| {
|
||||
ui.label(
|
||||
RichText::new("TCP interface active")
|
||||
.color(Color32::WHITE),
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
// Show connection status in the bottom panel, green if connected
|
||||
if self.app_state_rx.borrow().tcp_connected {
|
||||
let frame = egui::Frame::default().fill(Color32::DARK_GREEN);
|
||||
|
||||
egui::Panel::bottom("bottom_panel")
|
||||
.frame(frame)
|
||||
.show_inside(ui, |ui| {
|
||||
ui.with_layout(
|
||||
egui::Layout::centered_and_justified(egui::Direction::LeftToRight),
|
||||
|ui| {
|
||||
ui.label(
|
||||
RichText::new("TCP interface active")
|
||||
.color(Color32::WHITE),
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Show log marker input field (or marker modal) if log_marker_modal is true
|
||||
if self.log_marker_modal {
|
||||
if Modal::new(Id::new("modal_marker"))
|
||||
.show(ui, |ui| {
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.heading("Add marker");
|
||||
|
||||
ui.add_space(16.0);
|
||||
|
||||
// Input field for marker
|
||||
let text_edit_response = TextEdit::singleline(&mut self.log_marker)
|
||||
.desired_width(100.0)
|
||||
.id(Id::new("marker_field"))
|
||||
.hint_text("Marker name")
|
||||
.ui(ui);
|
||||
|
||||
ui.add_space(16.0);
|
||||
|
||||
// Centered Add button
|
||||
let add_clicked = Button::new("Add")
|
||||
.corner_radius(5.0)
|
||||
.min_size(egui::vec2(80.0, 30.0))
|
||||
.ui(ui)
|
||||
.clicked();
|
||||
|
||||
// Check for Enter key in the TextEdit
|
||||
let enter_pressed = text_edit_response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter));
|
||||
|
||||
if add_clicked || enter_pressed {
|
||||
self.logging_control_tx.try_send(LoggingSignal::AddMarker(self.log_marker.clone())).unwrap_or_else(|e| {
|
||||
error!("Failed to send logging marker signal: {:?}", e);
|
||||
});
|
||||
self.log_marker = String::new();
|
||||
ui.close();
|
||||
}
|
||||
|
||||
// Request focus on the text edit when the modal opens
|
||||
text_edit_response.request_focus();
|
||||
});
|
||||
})
|
||||
.should_close()
|
||||
{
|
||||
self.log_marker_modal = false;
|
||||
self.log_marker = String::new();
|
||||
}
|
||||
}
|
||||
|
||||
egui::CentralPanel::default().show_inside(ui, |ui| {
|
||||
DockArea::new(&mut self.tree)
|
||||
.style(Style::from_egui(ctx.style().as_ref()))
|
||||
.style(Style::from_egui(ui.style().as_ref()))
|
||||
.show_leaf_close_all_buttons(false)
|
||||
.show_leaf_collapse_buttons(false)
|
||||
.show_close_buttons(false)
|
||||
@@ -900,49 +901,49 @@ impl eframe::App for App {
|
||||
if let Some((_, name)) = self.tree.find_active_focused() {
|
||||
if self.app_state_rx.borrow().tab_active.to_string() != *name {
|
||||
let active_tab = self.app_state_rx.borrow().tab_active.to_string();
|
||||
self.tree.set_active_tab(self.tree.find_tab(&active_tab).unwrap());
|
||||
self.tree.set_active_tab(self.tree.find_tab(&active_tab).unwrap()).unwrap();
|
||||
}
|
||||
} else {
|
||||
let active_tab = self.app_state_rx.borrow().tab_active.to_string();
|
||||
self.tree.set_active_tab(self.tree.find_tab(&active_tab).unwrap());
|
||||
self.tree.set_active_tab(self.tree.find_tab(&active_tab).unwrap()).unwrap();
|
||||
}
|
||||
|
||||
// CMD- or control-W to close window
|
||||
if ctx.input(|i| i.modifiers.cmd_ctrl_matches(Modifiers::COMMAND))
|
||||
&& ctx.input(|i| i.key_pressed(Key::W))
|
||||
if ui.input(|i| i.modifiers.cmd_ctrl_matches(Modifiers::COMMAND))
|
||||
&& ui.input(|i| i.key_pressed(Key::W))
|
||||
{
|
||||
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
|
||||
ui.send_viewport_cmd(egui::ViewportCommand::Close);
|
||||
}
|
||||
|
||||
// Check if the file name field is focused
|
||||
// If it is, we don't want to trigger shortcuts
|
||||
let file_name_field_is_focused = ctx.memory(|memory| memory.has_focus(Id::new("file_name_field")));
|
||||
let marker_field_is_focused = ctx.memory(|memory| memory.has_focus(Id::new("marker_field")));
|
||||
let file_name_field_is_focused = ui.memory(|memory| memory.has_focus(Id::new("file_name_field")));
|
||||
let marker_field_is_focused = ui.memory(|memory| memory.has_focus(Id::new("marker_field")));
|
||||
if !file_name_field_is_focused && !marker_field_is_focused {
|
||||
|
||||
// Space to start/stop measurement
|
||||
if ctx.input(|i| i.key_pressed(Key::Space))
|
||||
if ui.input(|i| i.key_pressed(Key::Space))
|
||||
{
|
||||
self.toggle_start_stop();
|
||||
}
|
||||
|
||||
// Send stop command when the window is closed
|
||||
if ctx.input(|i| i.viewport().close_requested()) {
|
||||
if ui.input(|i| i.viewport().close_requested()) {
|
||||
self.toggle_start_stop();
|
||||
}
|
||||
|
||||
// Reset view
|
||||
if ctx.input(|i| i.key_pressed(Key::R)) {
|
||||
if ui.input(|i| i.key_pressed(Key::R)) {
|
||||
self.reset_view();
|
||||
}
|
||||
|
||||
// Toggle marker modal
|
||||
if ctx.input(|i| i.key_pressed(egui::Key::A)) && *self.logging_state_rx.borrow() == LoggingState::Logging {
|
||||
if ui.input(|i| i.key_pressed(egui::Key::A)) && *self.logging_state_rx.borrow() == LoggingState::Logging {
|
||||
self.log_marker_modal = !self.log_marker_modal;
|
||||
}
|
||||
|
||||
// Enable/disable GUI logging
|
||||
if ctx.input(|i| i.key_pressed(egui::Key::L)) {
|
||||
if ui.input(|i| i.key_pressed(egui::Key::L)) {
|
||||
let gui_logging_enabled = *self.logging_state_rx.borrow();
|
||||
match gui_logging_enabled {
|
||||
LoggingState::Starting => {
|
||||
@@ -963,7 +964,7 @@ impl eframe::App for App {
|
||||
}
|
||||
|
||||
// Toggle setttings view
|
||||
if ctx.input(|i| i.key_pressed(egui::Key::S)) {
|
||||
if ui.input(|i| i.key_pressed(egui::Key::S)) {
|
||||
self.tab_viewer.show_settings = !self.tab_viewer.show_settings;
|
||||
if self.tab_viewer.show_settings {
|
||||
self.tab_viewer.show_settings_toggle = Some(true);
|
||||
@@ -973,7 +974,7 @@ impl eframe::App for App {
|
||||
}
|
||||
}
|
||||
|
||||
ctx.request_repaint();
|
||||
ui.request_repaint();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
10
src/plot.rs
10
src/plot.rs
@@ -31,16 +31,16 @@ impl TimeSeriesPlot {
|
||||
self.values.push_back(PlotPoint::new(last_x + 1.0, val));
|
||||
}
|
||||
|
||||
pub fn plot_values(&self) -> PlotPoints {
|
||||
pub fn plot_values(&self) -> PlotPoints<'_> {
|
||||
PlotPoints::Owned(Vec::from_iter(self.values.iter().copied()))
|
||||
}
|
||||
|
||||
pub fn plot_values_negative(&self) -> PlotPoints {
|
||||
pub fn plot_values_negative(&self) -> PlotPoints<'_> {
|
||||
let mut values = Vec::from_iter(self.values.iter().copied());
|
||||
for point in &mut values {
|
||||
point.y = -point.y;
|
||||
}
|
||||
PlotPoints::Owned(Vec::from_iter(values))
|
||||
PlotPoints::Owned(values)
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
@@ -74,11 +74,11 @@ impl BodePlot {
|
||||
self.phases = freqs.into_iter().zip(phases.into_iter()).map(|(f, p)| PlotPoint::new((f as f32).log10(), p)).collect(); // Convert to f32 first due to rouding errors
|
||||
}
|
||||
|
||||
pub fn plot_magnitudes(&self) -> PlotPoints {
|
||||
pub fn plot_magnitudes(&self) -> PlotPoints<'_> {
|
||||
PlotPoints::Owned(self.magnitudes.clone())
|
||||
}
|
||||
|
||||
pub fn plot_phases(&self) -> PlotPoints {
|
||||
pub fn plot_phases(&self) -> PlotPoints<'_> {
|
||||
PlotPoints::Owned(self.phases.clone())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user