UI labels (status, headings, control text) no longer selectable. Console/hex content remains selectable for copy. ScrollArea now nudges when drag-selecting near the bottom edge (~240px/s).
151 lines
5.3 KiB
Rust
151 lines
5.3 KiB
Rust
use crate::models::{ConnectionStatus, SessionTab, View};
|
|
use egui::{Label, 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.add(
|
|
Label::new(format!(
|
|
"{}/{}",
|
|
tab.search.current_display(),
|
|
tab.search.match_count()
|
|
))
|
|
.selectable(false),
|
|
);
|
|
|
|
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
|
|
}
|