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 }