fix(gui): disable text selection on UI labels, add edge-scroll during drag

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).
This commit is contained in:
2026-06-22 16:06:27 +08:00
parent 1da034c9b1
commit 84563ecfc8
7 changed files with 145 additions and 60 deletions

View File

@@ -8,7 +8,7 @@ use crate::panels::{config, console, font_settings, hex_view, plot_view, send_pa
use crate::perf::{DrainStats, GuiProfiler, GuiSnapshot};
use crate::shortcuts::{self, default_bindings};
use crate::ui_fonts::{self, FontCandidate, UiFontSettings};
use egui::{Color32, Layout, Panel, Pos2, Rect, UiBuilder};
use egui::{Color32, Label, Layout, Panel, Pos2, Rect, UiBuilder};
use pipeview_client::SessionManager;
use pipeview_client::config::SessionConfig;
use pipeview_client::session::SessionEvent;
@@ -537,7 +537,7 @@ impl XserialApp {
fn render_main_panel(&mut self, ui: &mut egui::Ui) {
egui::CentralPanel::default().show_inside(ui, |ui| {
if self.tabs.is_empty() {
ui.heading("No sessions.");
ui.add(Label::new(egui::RichText::new("No sessions.").heading()).selectable(false));
return;
}
@@ -557,10 +557,10 @@ impl XserialApp {
let (badge, status_text) = tab.status.badge();
ui.horizontal(|ui| {
ui.heading(format!("Session {}", tab.id));
ui.label(badge);
ui.add(Label::new(egui::RichText::new(format!("Session {}", tab.id)).heading()).selectable(false));
ui.add(Label::new(badge).selectable(false));
ui.separator();
ui.label(status_text);
ui.add(Label::new(status_text).selectable(false));
ui.separator();
if ui
.selectable_label(tab.view == View::Text, "Text")
@@ -584,7 +584,7 @@ impl XserialApp {
let mut display_changed = false;
ui.horizontal_wrapped(|ui| {
ui.label("Show:");
ui.add(Label::new("Show:").selectable(false));
display_changed |= ui
.checkbox(&mut display.show_timestamp, "Timestamp")
.changed();
@@ -598,7 +598,7 @@ impl XserialApp {
session_controls::render_search_bar(ui, tab);
if let ConnectionStatus::Error(message) = &tab.status {
ui.label(egui::RichText::new(message).color(Color32::RED));
ui.add(Label::new(egui::RichText::new(message).color(Color32::RED)).selectable(false));
}
let full = ui.available_rect_before_wrap();
@@ -629,11 +629,22 @@ impl XserialApp {
}
View::Plot => {
if tab.plot_view.detached {
ui.heading(format!(
"Plot window detached for Session {}",
tab.id
));
ui.label("The plot is currently shown in a floating window.");
ui.add(
Label::new(
egui::RichText::new(format!(
"Plot window detached for Session {}",
tab.id,
))
.heading(),
)
.selectable(false),
);
ui.add(
Label::new(
"The plot is currently shown in a floating window.",
)
.selectable(false),
);
if ui.button("Dock Plot Back").clicked() {
tab.plot_view.detached = false;
}
@@ -720,7 +731,7 @@ impl XserialApp {
fn render_top_bar(&mut self, ui: &mut egui::Ui) {
Panel::top("top_bar").show_inside(ui, |ui| {
ui.horizontal_wrapped(|ui| {
ui.heading("pipeview");
ui.add(Label::new(egui::RichText::new("pipeview").heading()).selectable(false));
ui.separator();
// ui.label(format!(
// "Fonts: {} + {} {:.1} pt",