forked from 1b-agent/opencadstudio-upstream
feat(viewport): hide ViewCube then render bar as the viewport narrows
When the viewport got too narrow the top-left render-mode bar and the top-right ViewCube overlapped. Hide them adaptively, measuring the render bar's real width rather than guessing: - Wrap the render bar in DensitySwap, which measures its natural width every frame and swaps it for an empty spacer once it no longer fits the tile. Add report_width0 so it publishes that measured width to render_bar_w. - Compute viewcube_visible from that measured width: the cube shows only while bar_w + gap + cube region fits. This one flag drives the ViewCube nav/UCS widgets, the hover hit-test, and — threaded through build_viewports / build_viewport_for_pane / viewport_data_for — the GPU cube itself, which previously ignored the pane flag (show_viewcube was inst.active only), so the cube stayed while its surrounding widgets vanished. Result: the ViewCube gives way first, then the render bar once it too has no room — no overlap, sized to the bar's real width (which varies with the render-mode label, split buttons and tile count). Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
07eb9dcb9a
commit
7cba5c8679
5 files changed
+128
-27
No files matched your search
@@ -670,6 +670,11 @@ pub struct DensitySwap<'a> {
|
||||
variants: Vec<Element<'a, Message>>,
|
||||
chosen: Cell<usize>,
|
||||
height_out: Option<Arc<AtomicU32>>,
|
||||
/// Receives the FIRST (widest) variant's natural width in bits of an `f32`,
|
||||
/// measured every layout regardless of which variant is shown — so a caller
|
||||
/// can place a neighbouring widget relative to the full-size content even
|
||||
/// while a narrower variant is on screen.
|
||||
width0_out: Option<Arc<AtomicU32>>,
|
||||
}
|
||||
|
||||
impl<'a> DensitySwap<'a> {
|
||||
@@ -678,6 +683,7 @@ impl<'a> DensitySwap<'a> {
|
||||
variants,
|
||||
chosen: Cell::new(0),
|
||||
height_out: None,
|
||||
width0_out: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -687,6 +693,12 @@ impl<'a> DensitySwap<'a> {
|
||||
self.height_out = Some(out);
|
||||
self
|
||||
}
|
||||
|
||||
/// Report the first variant's natural (unconstrained) width — see `width0_out`.
|
||||
pub fn report_width0(mut self, out: Arc<AtomicU32>) -> Self {
|
||||
self.width0_out = Some(out);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Widget<Message, Theme, Renderer> for DensitySwap<'a> {
|
||||
@@ -718,6 +730,11 @@ impl<'a> Widget<Message, Theme, Renderer> for DensitySwap<'a> {
|
||||
let mut pick = self.variants.len().saturating_sub(1);
|
||||
for (i, v) in self.variants.iter_mut().enumerate() {
|
||||
let n = v.as_widget_mut().layout(&mut tree.children[i], renderer, &natural);
|
||||
if i == 0 {
|
||||
if let Some(out) = &self.width0_out {
|
||||
out.store(n.size().width.to_bits(), Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
if n.size().width <= max_w {
|
||||
pick = i;
|
||||
break;
|
||||
|
||||
Reference in new issue
Block a user