Distinguish polyline midpoint grips from vertices (#1950) (#1958)

* ui: distinguish polyline midpoint grips

* docs: the midpoint-grip row belongs in the revision history (CodeRabbit)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Antoine Boxho
2026-10-24 01:51:36 -04:00
committed by GitHub
co-authored by Claude Opus 5.5 Brandon Thomas
parent 63dec85749
commit 64c35cadff
2 changed files with 19 additions and 7 deletions
+16 -5
View File
@@ -1937,10 +1937,12 @@ pub fn show(app: &mut CadApp, ui: &mut egui::Ui) {
let gs = app.session.settings.gripsize as f32;
for h in sel.iter().take(200) {
if let Some(e) = st.doc.entity(*h) {
for (gi, g) in e.kind.grips().into_iter().enumerate() {
let grips = e.kind.grips();
let count = grips.len();
for (gi, g) in grips.into_iter().enumerate() {
let sp = xf.to_screen(g);
if rect.contains(sp) {
let r = Rect::from_center_size(sp, vec2(gs * 2.0, gs * 2.0));
let r = grip_rect(&e.kind, count, gi, sp, gs);
let hot = app.canvas.hot_grips.contains(&(*h, gi));
let warm = !hot && hover_pos.is_some_and(|hp| r.expand(2.0).contains(hp));
painter.rect_filled(
@@ -2668,11 +2670,18 @@ fn grip_menu(app: &mut CadApp, resp: &egui::Response) {
}
}
/// Polyline segment midpoint grips are rectangular; vertex grips remain square.
fn grip_rect(kind: &cadcraft_doc::EntityKind, count: usize, index: usize, center: Pos2, size: f32) -> Rect {
// The grip list interleaves vertices and available segment midpoints, then any remaining vertices.
let midpoint = matches!(kind, cadcraft_doc::EntityKind::LwPolyline(p) if index % 2 == 1 && index / 2 < count.saturating_sub(p.vertices.len()));
Rect::from_center_size(center, vec2(size * 2.0, if midpoint { size } else { size * 2.0 }))
}
/// The grip of a selected object under the cursor, if any: (object, grip index).
fn grip_at(app: &CadApp, xf: &Xf, hover: Option<Pos2>) -> Option<(Handle, usize)> {
let hp = hover?;
let st = app.session.state().ok()?;
let gs = app.session.settings.gripsize as f32 + 3.0;
let gs = app.session.settings.gripsize as f32;
let sel = app.session.selection();
if !app.session.shows_grips(sel.len()) {
return None;
@@ -2682,9 +2691,11 @@ fn grip_at(app: &CadApp, xf: &Xf, hover: Option<Pos2>) -> Option<(Handle, usize)
if st.doc.layer(&e.common.layer).is_some_and(|l| l.locked) {
continue;
}
for (i, g) in e.kind.grips().into_iter().enumerate() {
let grips = e.kind.grips();
let count = grips.len();
for (i, g) in grips.into_iter().enumerate() {
let sp = xf.to_screen(g);
if (sp.x - hp.x).abs() <= gs && (sp.y - hp.y).abs() <= gs {
if grip_rect(&e.kind, count, i, sp, gs).expand(3.0).contains(hp) {
return Some((*h, i));
}
}
+3 -2
View File
@@ -1,6 +1,6 @@
# UI parity
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-13 · **Change:** minor (stable dash anchors on filled-object highlights) · **Target:** Autodesk AutoCAD 2027 for Mac (26.0)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-22 · **Change:** minor (distinct polyline midpoint grips) · **Target:** Autodesk AutoCAD 2027 for Mac (26.0)
How CADCraft's interaction compares with AutoCAD's: point entry, object snaps, tracking, dynamic
input, grips, selection, the command line, chrome and navigation. A drafter's speed in AutoCAD
@@ -119,7 +119,7 @@ down-arrow options menu (DYNPROMPT), and DYNDIM.
| Multifunctional grip hover menus (Add Vertex, Remove Vertex, Convert to Arc, Lengthen …) | yes | **no** |
| Grip dimensional input (length/angle fields) | yes | no |
| Dynamic block grips | yes | no (no dynamic blocks) |
| Grip appearance (GRIPSIZE, colours, hover) | yes | GRIPSIZE, GRIPS and GRIPOBJLIMIT honoured (Options ▸ Selection); no grip colours |
| Grip appearance (GRIPSIZE, colours, hover) | yes | GRIPSIZE, GRIPS and GRIPOBJLIMIT honoured (Options ▸ Selection); polyline segment midpoints use rectangles, vertices use squares; no grip colours |
## Selection (≈ 40%)
@@ -203,6 +203,7 @@ down-arrow options menu (DYNPROMPT), and DYNDIM.
| Date | Change | Summary |
|---|---|---|
| 2026-10-22 | minor | Polyline segment midpoint grips use rectangles, distinct from square vertex grips, with matching hover and pick bounds (#1950) |
| 2026-10-13 | minor | Filled-region highlight boundaries are traversed in deterministic coordinate order, fixing dash-phase jumps on CPU hover/selection redraws and GPU highlight rebuilds; CPU dash-position, pixel and GPU mesh regressions |
| 2026-10-14 | minor | Selection cycling (#1143): the list and badge of SELECTIONCYCLING, Shift+Space through overlapping objects (#1145) |
| 2026-10-14 | minor | Hatch Edit dialog adds boundaries from picked points or closed objects and removes selected loops |