From ddde08fb4c3c48888bc0170bec4d94cb24a9d41e Mon Sep 17 00:00:00 2001 From: jyviko <2501648+jyviko@users.noreply.github.com> Date: Wed, 14 Oct 2026 17:53:32 -0400 Subject: [PATCH] Results view: hover over contours is an outline, not a pink fill (#207) While result contours are shown, the hovered item's face fill is left out and only its outline, edges and nodes are drawn, so the hover never hides the colours under the pointer. Picker::hover is the hover's own overlay. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo --- crates/ui-egui/src/lib.rs | 5 +++-- crates/ui-egui/src/selection.rs | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index 6a35b5b..5c20f56 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -873,8 +873,9 @@ impl ModelApp { } let mut s = (*self.pick.selected_overlay.1).clone(); if let Some(hover) = self.pick.hover.clone() { - let h = self - .with_picker(|p| p.overlay(&selection::Selection::default(), Some(&hover), theme::rgb(t.pick_selected), theme::rgb(t.pick_hover))); + // Over result contours the hover is an outline, so it never hides the result (#207). + let fill = self.plot.1.is_none(); + let h = self.with_picker(|p| p.hover(&hover, theme::rgb(t.pick_hover), fill)); s.tris.extend(h.tris); s.lines.extend(h.lines); s.points.extend(h.points); diff --git a/crates/ui-egui/src/selection.rs b/crates/ui-egui/src/selection.rs index 1f26cd3..63d143a 100644 --- a/crates/ui-egui/src/selection.rs +++ b/crates/ui-egui/src/selection.rs @@ -544,6 +544,18 @@ impl Picker<'_> { s } + /// The hovered item drawn over the scene in `color`. With `fill` off (while result contours + /// are shown) its faces are left out and only their outline, edges and nodes are drawn, so + /// the hover never hides the colours under the pointer. + pub fn hover(&self, item: &Item, color: Rgb, fill: bool) -> Scene { + let mut s = Scene::default(); + self.mark(&Marks::of(self, std::iter::once(item)), color, &mut s); + if !fill { + s.tris.clear(); + } + s + } + fn mark(&self, m: &Marks, color: Rgb, s: &mut Scene) { if m.is_empty() { return; @@ -961,6 +973,13 @@ mod tests { // Hovering an element adds its skin triangles in the hover colour, drawn after. let o = p.overlay(&sel, Some(&Item::Element(1)), sel_c, hov_c); assert_eq!(o.tris.iter().filter(|t| t.color == hov_c).count(), 6); + // Over result contours the hover is its outline only: no face fills. + let filled = p.hover(&Item::Element(1), hov_c, true); + assert_eq!(filled.tris.len(), 6); + let outlined = p.hover(&Item::Element(1), hov_c, false); + assert!(outlined.tris.is_empty()); + assert_eq!(outlined.lines, filled.lines); + assert!(!outlined.lines.is_empty()); // Nodes, the edge and the vertex. sel.apply( [