forked from 1b-agent/opencadstudio-upstream
fix(view): zoom cursor per navigation tool, and ZOOM EXTENTS frames everything
Two viewport-navigation defects, both measured against commercial solutions.
The cursor stayed a hand during a zoom. `selection_overlay` took one boolean
for all three interactive navigation tools, so ZOOM Dynamic and ORBIT both
showed PAN's grab hand — which reads as "drag the sheet", the wrong promise
for either. Split it into a `NavCursor` enum: PAN keeps the open/closed hand,
ORBIT gets four-way arrows, and ZOOM Dynamic gets the magnifier carrying the
sign of the zoom actually under way — "+" dragging up, "-" dragging down,
latched with a 2 px dead zone so a hand held still cannot strobe the glyph.
ZOOM Dynamic also reused `box_anchor` to remember where a drag began, so a
selection marquee rubber-banded across the screen while the view zoomed; the
drawing is now suppressed, the state left alone for `reproject_box_anchor`.
ZOOM EXTENTS did not reach the whole drawing, for three separate reasons, now
answered by one shared `Scene::visible_block_bounds`:
- A quartile filter dropped any wire whose centroid sat outside the
inter-quartile consensus of the others. It was meant to stop one junk wire
from a bad parse poisoning the box, but it could not tell parser junk from
an outlying detail, a survey point, or a block placed away from the rest,
and silently refused to frame them. Gone; the absolute 1e16 sentinel gate
the paper path already used is the only filter, and the XLine / Ray display
segments that motivated the heuristic are handled explicitly.
- HATCH tessellates to no wires at all, and the model path never read the
fill models, so a drawing whose outermost geometry is a fill — or which is
nothing but fills — had nothing to frame. It now folds them in, reusing the
renderer's own warm cache on the hot path rather than re-exploding every
INSERT per ZOOM EXTENTS.
- Inside a floating viewport the fit came from `compute_model_space_extents`,
which walked only `key_vertices` — empty for every tessellated curve.
Circles, arcs, ellipses and splines contributed nothing. Fixing it also
corrects plot Extents, sheet-set framing, viewport auto-fit and SpaceMouse
model bounds, which all inherited that blind spot.
Bounds stay f64 into the camera: a UTM drawing lost whole metres to the old
f32 round-trip. Drawing extents also no longer read the camera — the result is
cached per geometry epoch, and a floating viewport's camera is derived FROM
the extents, so `camera_for_viewport` recursed into a stack overflow.
`model_space_extents_mixed_entities_accuracy` asserted the curve-blind result;
it now asserts the true bounds.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
bf7f37aaf4
commit
d596b5a6be
8 files changed
+514
-341
No files matched your search
+18
-1
@@ -45,6 +45,23 @@ fn crosshair_background(tab: &DocumentTab, is_paper: bool) -> [f32; 4] {
|
||||
tab.scene.paper_bg_color
|
||||
}
|
||||
|
||||
/// Which navigation tool the viewport cursor should advertise. The three flags
|
||||
/// are mutually exclusive — every command entry point clears all of them before
|
||||
/// arming one (`crate::app::commands`) — so the order here only settles a state
|
||||
/// that cannot occur.
|
||||
pub(in crate::app) fn nav_cursor(tab: &DocumentTab) -> crate::ui::overlay::NavCursor {
|
||||
use crate::ui::overlay::NavCursor;
|
||||
if tab.pan_mode {
|
||||
NavCursor::Pan
|
||||
} else if tab.orbit_mode {
|
||||
NavCursor::Orbit
|
||||
} else if tab.zoom_dynamic_mode {
|
||||
NavCursor::Zoom
|
||||
} else {
|
||||
NavCursor::None
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear gap (px) kept between the render-mode bar (top-left) and the ViewCube
|
||||
/// (top-right) before the cube is judged to collide and hides.
|
||||
const VIEWCUBE_GAP: f32 = 12.0;
|
||||
@@ -894,7 +911,7 @@ bg={bg_ms:.1}ms n={view_count}"
|
||||
dividers,
|
||||
pane_move_rect,
|
||||
pane_drop_rect,
|
||||
tab.pan_mode || tab.orbit_mode || tab.zoom_dynamic_mode,
|
||||
nav_cursor(tab),
|
||||
self.ribbon.open_dropdown.is_some(),
|
||||
hover_locked,
|
||||
crosshair_background(tab, is_paper),
|
||||
|
||||
Reference in new issue
Block a user