feat(statusbar): highlight cycling-list object on row hover

Add a scene hover_highlight handle that renders an entity with the
selection colour without joining the real selection. The cycling list
box sets it on row enter / clears on exit, so hovering a row glows the
matching object in the drawing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-06-05 00:00:52 +03:00
commit a9228b9021
4 changed files with 45 additions and 6 deletions

View file

@ -553,6 +553,9 @@ pub struct Scene {
/// `tessellate_block`'s visibility test skips these, so they neither
/// render nor hit-test until isolation ends.
pub hidden: HashSet<Handle>,
/// Entity drawn with the selection-highlight colour without being part
/// of the real selection — used to preview a row in the cycling list box.
pub hover_highlight: Option<Handle>,
/// Whether entity transparency is honoured on screen. When false the
/// wire shader forces every line opaque (a uniform toggle, no retessellate).
pub transparency_display: bool,
@ -704,6 +707,7 @@ impl Scene {
document: CadDocument::new(),
selected: HashSet::new(),
hidden: HashSet::new(),
hover_highlight: None,
transparency_display: true,
selection_filter: HashSet::new(),
preview_wires: vec![],
@ -1334,6 +1338,15 @@ impl Scene {
!self.hidden.is_empty()
}
/// Set (or clear) the previewed entity that renders with the selection
/// highlight without joining the real selection. Re-tessellates on change.
pub fn set_hover_highlight(&mut self, handle: Option<Handle>) {
if self.hover_highlight != handle {
self.hover_highlight = handle;
self.bump_geometry();
}
}
/// Hide every drawable entity except the current selection (Isolate).
pub fn isolate_selected(&mut self) {
if self.selected.is_empty() {
@ -2005,7 +2018,19 @@ impl Scene {
// Tessellate in parallel across all available CPU cores.
use rayon::prelude::*;
let doc = &self.document;
let sel = &self.selected;
// Fold the hover-preview entity into the highlight set so it renders
// selected without being part of the real selection.
let hl_set;
let sel: &HashSet<Handle> = if let Some(h) = self.hover_highlight {
hl_set = {
let mut s = self.selected.clone();
s.insert(h);
s
};
&hl_set
} else {
&self.selected
};
let avp = self.active_viewport;
// A paper-space content viewport renders MODEL block entities while
// the user is sitting in a paper layout — that path expects