forked from 1b-agent/opencadstudio-upstream
fix: hide sheet viewport border and improve crossing selection
Two layout-related fixes: 1. Sheet viewport (id=1) was rendered as a grey rectangle border in paper-space layouts. It is the paper boundary, not a user viewport, and should not appear. Now filtered via is_content_viewport() before tessellation. The redundant id==1 color branch is removed. 2. Box crossing-selection (right-to-left drag) only detected wires whose vertex points fell inside the selection box. Large entities like viewport frames could be visually crossed without any corner inside the box and would not be selected. Added segment-box edge intersection tests so any wire segment that crosses the selection rectangle boundary is included. Fixes part of #10 Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
1 parent
c0ee0d6edc
commit
ebef467720
2 files changed
+24
-4
No files matched your search
+18
-1
@@ -57,7 +57,9 @@ pub fn click_hit<'a>(
|
||||
/// - **Window mode** (`crossing = false`, left→right drag):
|
||||
/// ALL projected points must lie inside the box.
|
||||
/// - **Crossing mode** (`crossing = true`, right→left drag):
|
||||
/// ANY projected point inside the box is sufficient.
|
||||
/// ANY projected point inside the box, OR any wire segment crosses the box
|
||||
/// boundary (so large entities like viewport frames are caught even when
|
||||
/// no corner falls inside the selection rectangle).
|
||||
pub fn box_hit<'a>(
|
||||
corner_a: Point,
|
||||
corner_b: Point,
|
||||
@@ -78,6 +80,12 @@ pub fn box_hit<'a>(
|
||||
|
||||
let inside = |sp: Point| sp.x >= min_x && sp.x <= max_x && sp.y >= min_y && sp.y <= max_y;
|
||||
|
||||
// Box corners for segment-intersection tests (crossing mode only).
|
||||
let box_tl = Point { x: min_x, y: min_y };
|
||||
let box_tr = Point { x: max_x, y: min_y };
|
||||
let box_bl = Point { x: min_x, y: max_y };
|
||||
let box_br = Point { x: max_x, y: max_y };
|
||||
|
||||
wires
|
||||
.iter()
|
||||
.filter_map(|wire| {
|
||||
@@ -92,7 +100,16 @@ pub fn box_hit<'a>(
|
||||
.collect();
|
||||
|
||||
let hit = if crossing {
|
||||
// A wire is hit when any vertex is inside the box OR any of its
|
||||
// segments crosses one of the four box edges.
|
||||
screen.iter().any(|&sp| inside(sp))
|
||||
|| screen.windows(2).any(|seg| {
|
||||
let (a, b) = (seg[0], seg[1]);
|
||||
segments_intersect(a, b, box_tl, box_tr)
|
||||
|| segments_intersect(a, b, box_tr, box_br)
|
||||
|| segments_intersect(a, b, box_br, box_bl)
|
||||
|| segments_intersect(a, b, box_bl, box_tl)
|
||||
})
|
||||
} else {
|
||||
screen.iter().all(|&sp| inside(sp))
|
||||
};
|
||||
|
||||
+6
-3
@@ -3084,12 +3084,15 @@ fn tessellate_entity(
|
||||
let sel = selected.contains(&h);
|
||||
|
||||
if let EntityType::Viewport(vp) = e {
|
||||
// The sheet viewport (overall/id=1) is never shown — it represents the
|
||||
// paper boundary, not a user-defined content window.
|
||||
if !Scene::is_content_viewport(vp) {
|
||||
return vec![];
|
||||
}
|
||||
let is_active = active_viewport == Some(h);
|
||||
let is_locked = vp.status.locked;
|
||||
let color = if sel && vp.id != 1 {
|
||||
let color = if sel {
|
||||
[1.0, 1.0, 1.0, 1.0]
|
||||
} else if vp.id == 1 {
|
||||
[0.40, 0.40, 0.40, 1.0]
|
||||
} else if is_active {
|
||||
[1.0, 0.90, 0.20, 1.0]
|
||||
} else if is_locked {
|
||||
|
||||
Reference in new issue
Block a user