The Snap and Grid tab showed static grid values with dead checkboxes, and every grid line stroked identically.
Grid X/Y spacing and Major-line-every are now editable inputs (validated 2-100 for majors, dirty-tracked, applied with an error message on bad input); Adaptive-grid and Display-beyond-Limits checkboxes are wired to live state. Every Nth line partitions into major_segments and strokes subtly brighter (1.5x alpha, 0.75px) for the reference hierarchy. GRIDMAJOR state persists to UserSettings. Covers partition, invalidation, and parse tests.
The viewport grid ignored the configured spacing and forced square grids: compute_grid_step hardcoded a 1.0 base, a single shared step drove both line families (including the tangent derivative used for gap measurement), and the display always clipped to LIMITS despite the beyond-Limits option.
Grid spacing now scales per-axis from GRIDUNIT via compute_grid_steps (adaptive 5x growth, fixed passthrough), GridParams carries step_x/step_y, snap tolerances follow the visible steps, and the LIMITS clip is skipped when beyond-Limits is set. Also fixes a per-axis overflow fallback that returned the X base for Y. Spacing state (X/Y, adaptive, beyond-Limits) is stored on the app and persisted to UserSettings at defaults; dialog wiring follows separately.
Comments and the Options help text describe the behaviour of commercial
solutions without naming any product. The command menu puts the command's
keywords directly under Enter / Cancel, with Recent Input and Snap
Overrides below them, so the choices that change from step to step are the
closest to the pointer.
Co-Authored-By: Claude Opus 5 <[email protected]>
The command menu now follows the commercial solutions' layout row for row: Enter, Cancel,
Recent Input ▸, the command's keywords, Snap Overrides ▸ (every object snap
with its glyph, Mid Between 2 Points, None, Osnap Settings…), then Pan and
Zoom. Pan / Zoom run transparently while a command is active ('PAN,
'ZOOM …): navigation modes leave the command untouched and an interactive
ZOOM Window parks it and resumes it afterwards. Rows carry an icon gutter
so labels align; the Enter row shows a default value ("<0.5000>") as its
hint instead of a second finish row.
ARC gets the commercial solutions' prompt flow with all keywords: start [Center], second
point [Center/End], end; after Center: end [Angle/chord Length]; after
End: center [Angle/Direction/Radius]; Enter continues tangent. The
previous default (Center/Start/End with method codes) stays as ARC_CSE.
Object snaps gain a one-shot "None" override. New strings in all locales.
Co-Authored-By: Claude Opus 5 <[email protected]>
Rows are 22 px (as the grip popup), the edit menu drops Select All and
Zoom Extents (both stay on the idle menu, matching the commercial solutions' edit menu),
and cursor-anchored panels now reserve the overlaid prompt lines
(CLIPROMPTLINES) as well as the input row, so a long menu is never hidden
behind the command area — it scrolls inside the visible canvas instead.
The automation port gains `pointer_right_press` / `pointer_right_release`
actions so scripts and MCP clients can exercise the context menu.
Co-Authored-By: Claude Opus 5 <[email protected]>
Every new UI string (menu rows, Options → Right-click Customization, the
PLINE sub-prompts and keyword labels, MOVE/COPY/OFFSET prompts) gets its
Fluent attribute in all 21 locales plus the source → attribute rows in
locale_catalog.rs; the SETVAR help line lists SHORTCUTMENU and
SHORTCUTMENUDURATION. Tests that compared prompt text now check command
state so they pass under any UI language.
Co-Authored-By: Claude Opus 5 <[email protected]>
A right-click while a grip is hot opens the grip menu: Enter places the
grip, Stretch / Move / Rotate / Scale / Mirror switch how the gripped
objects are edited (the latter four hand the selection to the matching
command with the grip as its base point), Base Point re-bases the gesture
at the next click, Copy leaves the originals in place and adds the moved
shapes as new entities while keeping the grip hot, Undo snaps the shapes
back to where the gesture started, Exit drops the edit.
The grip commit path moves out of the left-release handler into
`commit_active_grip_edit` so the menu, Enter and the placement click share
it; Enter with a hot grip now places it instead of repeating the last
command.
Co-Authored-By: Claude Opus 5 <[email protected]>
MOVE: Displacement, Enter at the second point uses the base as the vector.
COPY: Displacement, mOde (Single/Multiple), Undo of the last copy.
FILLET: Undo of the last fillet (the command refreshes its entity cache
through the new CadCommand::on_document_undone hook after the host undoes
the document step). CHAMFER: Multiple and Undo. OFFSET: Erase (the offset
replaces its source), Layer (Current/Source), Undo, Exit.
POLY3D, TRACE, MIRROR and MEASUREGEOM expose the keywords they already
accepted as options, so the context menu and option buttons list them.
The pinned prompt now keeps informational bracket groups such as
"[3 objects]" and only drops real option listings when the buttons take over.
Co-Authored-By: Claude Opus 5 <[email protected]>
PLINE now offers the commercial solutions' full option set: Arc/Close/Halfwidth/Length/
Undo/Width in line mode and Angle/CEnter/CLose/Direction/Halfwidth/Line/
Radius/Second pt/Undo/Width in arc mode, including the nested prompts
(Angle → CEnter/Radius, CEnter → Angle/Length, Radius → Angle → chord
direction). Widths land in the LwPolyline vertices (start/end per segment,
the end width carrying into the next segment) and PLINEWID persists per
session. Undo / Escape inside a sub-prompt only back out of it; every
sub-step previews its arc at the cursor.
Co-Authored-By: Claude Opus 5 <[email protected]>
The viewport context menu is now built from a pure model
(ui::popup::context_menu) rendered by the overlay: while a command runs it
offers Enter / Cancel / every keyword of the command's options() with the
keyword shown as a hint, a Recent Input submenu and M2P; when idle it offers
Repeat, Recent Input, Clipboard, Undo/Redo with history labels, the edit
block (Erase/Move/Copy/Scale/Rotate/Mirror/Draw Order), Isolate, Pan/Zoom,
selection tools, Properties and Options. The default row is anchored under
the pointer and the menu is keyboard-navigable (arrows, Enter, mnemonic
letters; any other key closes it and types into the command line).
Right-click behaviour is a user preference (Options → User Preferences,
SHORTCUTMENU / SHORTCUTMENUDURATION): shortcut menu (commercial solutions default),
time-sensitive, or the previous Enter-first cycle.
LINE gains options() (Close/Undo/eXit).
Co-Authored-By: Claude Opus 5 <[email protected]>
ExtrudeCommand never opted into dyn_commit_as_text(), so a typed
Enter fell through to generic point-resolution instead of
on_text_input, producing a near-zero height that silently failed
to commit. Mirror PresspullCommand's pattern, gated to the Height
step.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Production drawings show AutoCAD stacking two equal limits for a DIMLIM
style with zero offsets; the plain-value shortcut matched one drawing from
another authoring tool and broke twenty-five that AutoCAD wrote.
AutoCAD prints 0.4255 as 0.426; Rust's formatter rounds the binary value,
which sits a hair below the decimal tie, and printed 0.425. Decimal
dimension text, tolerances and limits now settle the tie the way the
drawings do.
Alternate units multiplied the raw measurement instead of the displayed
DIMLFAC-scaled value, so a paper-space dimension's bracketed value was off
by the viewport factor, and alternate limits were written high/low with a
slash where AutoCAD stacks them like the primary limits.
A limits style whose upper and lower offsets are both zero prints the plain
value in AutoCAD, not a stack of two equal numbers. A three-point angular
dimension whose extension point sits on its vertex has no measurable angle;
AutoCAD keeps showing the angle it stored, and the text now does too instead
of reading 0 degrees. Both cases came out of comparing saved picture blocks
with regenerated text across a set of production drawings.
Dimensions with DIMLIM on were regenerated as the nominal value plus a
separate stacked pair, and the pair was built from the unscaled
measurement. AutoCAD prints only the upper limit over the lower one, with
the offsets applied to the DIMLFAC-scaled, DIMRND-rounded value, and keeps
both halves at the same number of decimals under DIMTZIN. Drawings with a
limits-only style looked right on load, from their saved picture blocks,
and gained an extra number as soon as an associative refresh dropped the
picture.
Fit and fill estimates now count visible cells, so a stack is as wide as
its wider half at DIMTFAC, and the text-to-line offset uses the stacked
height.
Before and after captures of DIMLINEAR at the second-point and placement
stages and DIMANGULAR at arc placement, taken from the upstream base and
this branch with the same automation steps.
Show the styled dimension and its value while placing a dimension, using
the same builder the command commits with. Each creation command
(DIMLINEAR, DIMALIGNED, DIMANGULAR, DIMRADIUS, DIMDIAMETER, DIMARC,
DIMJOGGED, DIMORDINATE, DIMCONTINUE, DIMBASELINE, QDIM) reports the
dimensions it would commit at the current stage through
`CadCommand::dimension_preview`. The application applies the current
creation style, or the base dimension's style for DIMCONTINUEMODE=1,
and the same viewport measurement scale as commit, then tessellates the
transient entity through the normal dimension renderer.
While the second definition point is being acquired, a hovered model
snap supplies a provisional viewport scale; once both points are fixed,
hovering another viewport does not change the value. Angular dimensions
never receive length compensation. Degenerate geometry, an invalid
scale, or conflicting viewports fall back to the plain rubber-band
preview so no misleading value is shown.