refactor(gui): split app.rs into models and panel modules
Extract types (models.rs), font settings, session controls, and send panel into separate modules. Reduces app.rs from 1488 to 848 lines. Zero behavior change. - models.rs: ConnectionStatus, View, SendMode, LineEnding, DisplayOptions, SearchState, SessionTab - panels/font_settings.rs: font selector and settings window - panels/session_controls.rs: session connect/disconnect UI - panels/send_panel.rs: send input and payload building
This commit is contained in:
147
crates/pipeview-gui/src/panels/session_controls.rs
Normal file
147
crates/pipeview-gui/src/panels/session_controls.rs
Normal file
@@ -0,0 +1,147 @@
|
||||
use crate::models::{ConnectionStatus, SessionTab, View};
|
||||
use egui::TextEdit;
|
||||
use pipeview_client::SessionManager;
|
||||
use pipeview_core::transport::TransportConfig;
|
||||
|
||||
pub fn render_search_bar(ui: &mut egui::Ui, tab: &mut SessionTab) {
|
||||
if !tab.search.active {
|
||||
return;
|
||||
}
|
||||
ui.horizontal(|ui| {
|
||||
let response = ui.add(
|
||||
TextEdit::singleline(&mut tab.search.query)
|
||||
.hint_text("Search...")
|
||||
.desired_width(200.0),
|
||||
);
|
||||
if tab.search.just_opened {
|
||||
response.request_focus();
|
||||
tab.search.just_opened = false;
|
||||
}
|
||||
if response.changed() {
|
||||
let matches = match tab.view {
|
||||
View::Text => tab.console.search(&tab.search.query, tab.search.case_sensitive),
|
||||
View::Hex => tab.hex.search(&tab.search.query, tab.search.case_sensitive),
|
||||
View::Plot => Vec::new(),
|
||||
};
|
||||
tab.search.matches = matches;
|
||||
tab.search.current_match = 0;
|
||||
}
|
||||
if response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) {
|
||||
tab.search.next();
|
||||
}
|
||||
|
||||
ui.label(format!(
|
||||
"{}/{}",
|
||||
tab.search.current_display(),
|
||||
tab.search.match_count()
|
||||
));
|
||||
|
||||
if ui.button("▲").clicked() {
|
||||
tab.search.prev();
|
||||
}
|
||||
if ui.button("▼").clicked() {
|
||||
tab.search.next();
|
||||
}
|
||||
|
||||
if ui.checkbox(&mut tab.search.case_sensitive, "Aa").changed() {
|
||||
let matches = match tab.view {
|
||||
View::Text => tab.console.search(&tab.search.query, tab.search.case_sensitive),
|
||||
View::Hex => tab.hex.search(&tab.search.query, tab.search.case_sensitive),
|
||||
View::Plot => Vec::new(),
|
||||
};
|
||||
tab.search.matches = matches;
|
||||
tab.search.current_match = 0;
|
||||
}
|
||||
|
||||
if ui.button("✕").clicked() {
|
||||
tab.search.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn render_session_controls(
|
||||
ui: &mut egui::Ui,
|
||||
manager: &SessionManager,
|
||||
tab: &mut SessionTab,
|
||||
) -> bool {
|
||||
let mut auto_reconnect_changed = false;
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
let connected = matches!(
|
||||
tab.status,
|
||||
ConnectionStatus::Connected | ConnectionStatus::Connecting
|
||||
);
|
||||
let connect_label = if connected { "Disconnect" } else { "Connect" };
|
||||
if ui.button(connect_label).clicked() {
|
||||
if let Some(handle) = manager.get(tab.id) {
|
||||
if connected {
|
||||
tab.status = ConnectionStatus::Disconnected;
|
||||
tokio::spawn(async move {
|
||||
let _ = handle.disconnect().await;
|
||||
});
|
||||
} else {
|
||||
tab.status = ConnectionStatus::Connecting;
|
||||
tokio::spawn(async move {
|
||||
let _ = handle.connect().await;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
tab.status = ConnectionStatus::Error(String::from("session not found"));
|
||||
}
|
||||
}
|
||||
|
||||
// if ui.button("Reconnect").clicked() {
|
||||
// if let Some(handle) = manager.get(tab.id) {
|
||||
// tab.status = ConnectionStatus::Connecting;
|
||||
// tokio::spawn(async move {
|
||||
// let _ = handle.reconnect().await;
|
||||
// });
|
||||
// } else {
|
||||
// tab.status = ConnectionStatus::Error(String::from("session not found"));
|
||||
// }
|
||||
// }
|
||||
|
||||
if ui.button("Clear").clicked() {
|
||||
tab.console.clear();
|
||||
tab.hex.clear();
|
||||
tab.plot.clear();
|
||||
tab.send_status = Some(String::from("Cleared"));
|
||||
}
|
||||
|
||||
let response = ui.checkbox(&mut tab.auto_reconnect, "Auto reconnect");
|
||||
if response.changed() {
|
||||
tab.session_config.auto_reconnect = tab.auto_reconnect;
|
||||
auto_reconnect_changed = true;
|
||||
if let Some(handle) = manager.get(tab.id) {
|
||||
let enabled = tab.auto_reconnect;
|
||||
tokio::spawn(async move {
|
||||
let _ = handle.set_auto_reconnect(enabled).await;
|
||||
});
|
||||
} else {
|
||||
tab.status = ConnectionStatus::Error(String::from("session not found"));
|
||||
}
|
||||
}
|
||||
if matches!(tab.status, ConnectionStatus::Connected)
|
||||
&& matches!(tab.session_config.transport, TransportConfig::Serial { .. })
|
||||
{
|
||||
let dtr_changed = ui.checkbox(&mut tab.dtr, "DTR").changed();
|
||||
let rts_changed = ui.checkbox(&mut tab.rts, "RTS").changed();
|
||||
if dtr_changed || rts_changed {
|
||||
if let Some(handle) = manager.get(tab.id) {
|
||||
let dtr = tab.dtr;
|
||||
let rts = tab.rts;
|
||||
tokio::spawn(async move {
|
||||
if dtr_changed {
|
||||
let _ = handle.set_dtr(dtr).await;
|
||||
}
|
||||
if rts_changed {
|
||||
let _ = handle.set_rts(rts).await;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
tab.status = ConnectionStatus::Error(String::from("session not found"));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
auto_reconnect_changed
|
||||
}
|
||||
Reference in New Issue
Block a user