- PSETUPIN / -PSETUPIN: with no arguments a file picker offers the chosen
drawing's named page setups in the Plot dialog; `PSETUPIN <file>` opens
the same chooser on that file; `PSETUPIN <file> *` or
`PSETUPIN <file> name,name` import straight away. Same-named setups are
replaced, the import is one undo step, and the report counts both.
- The Plot dialog's page-setup list gains "Import…": the chooser shows the
source drawing's setups with a tick each, All, Import and Cancel, and
selects the first imported setup afterwards. The source is read off the
UI thread with the same reader the editor uses for its own setups
(`scene::document_page_setups`), and handles that only meant something
in the source drawing (plot view, visual style) are dropped on import.
- Options → General → Plotting: "Show the page setup for new layouts"
opens the Plot / Page Setup dialog whenever a layout is created
(persisted with the plot preferences).
Tests: the document reader, the command (all / named / unknown / missing
file / undo) against a drawing saved by the app, the chooser flow, and the
new-layout option. Nine new strings in all 21 locales.
Co-Authored-By: Claude Opus 5 <[email protected]>
Plot dialog:
- "Units" (millimetres / inches) is the page setup's own unit: the offsets
and the custom scale are shown in it, the stored ratio converts with it
so the plotted result and the paper space's unit stay the same
- "Custom: [paper] mm = [drawing] units" spells the picked scale in that
unit and accepts a typed ratio, which selects the list's name for it or
becomes a ratio entry of its own
- "Hide paperspace objects" is the page setup's plot-hidden flag; it is no
longer derived from the "Hidden Line" shade mode
- "Save changes to layout" (paper layouts, on by default) writes the dialog
into the layout when a plot is sent; previews never touch it
- offsets are labelled in the page-setup unit and kept in millimetres in
the file
System variables (typeable, through SETVAR, listed by SETVAR ?):
- PLOTOFFSET, PAPERUPDATE, PLOTROTMODE, PLOTTRANSPARENCYOVERRIDE and
BACKGROUNDPLOT live with the persisted plot preferences: the plot origin
counts from the printable corner unless PLOTOFFSET says the paper edge;
a printer that does not list the sheet either warns or switches to its
default sheet; transparency can be forced on or off; BACKGROUNDPLOT bit 1
is the dialog's background switch and bit 2 drives batch plots
- CTAB and TILEMODE read and switch the current layout
Tests cover every new control and variable; six new strings in all 21
locales; the Plot dialog grows to 940×690 for the two extra rows.
Co-Authored-By: Claude Opus 5 <[email protected]>
Older GPUs without usable DirectX 12 Feature Level 12_0 or working
Vulkan support (e.g. legacy Intel iGPUs and other old parts), and old
GLES drivers whose shader compiler rejects iced's own shaders, crash
at startup or on the first drawing viewport: StagingBelt aborts in
Buffer::get_mapped_range (panic=abort, silent exit) on the DX12 path,
and shader compilation fails inside iced's gradient pipeline on the
GLES path. Selecting a working backend via WGPU_BACKEND before iced
boots avoids both classes.
- Probe each candidate backend (Windows: dx12,vulkan,gl; Linux:
vulkan,gl) in an isolated --gpu-probe child: device request,
staging-style mapped upload, render pipeline creation (its fragment
shader reads a private vec4 array, catching old-Mesa compile
failures), offscreen render and readback. First fully-passing
backend wins; explicit --backend / WGPU_BACKEND / --safe-mode
always win, and Windows keeps preferring DX12/Vulkan (#55).
- Software adapters (WARP/llvmpipe/SwiftShader) are the last resort
before a best-effort GL attempt: slow but alive.
- The crash sentinel names the attempted backend so only implicated
backends are skipped next launch.
- Winning probes report adapter limits; GPUs without shader storage
buffers get the packed compatibility renderer automatically, with
a startup command-line notice so the switch is never silent.
A drawing saved by a commercial CAD application (tests/fixtures/plot,
provided by Panos: one 10 m line, three layouts) corrects several
assumptions of the previous commit:
- rotation is relative to the medium's own orientation: an unchanged sheet
keeps the driver's exact medium (its PDF driver lists landscape media of
its own, written with rotation 0; a system printer's portrait A3 plotted
landscape carries 90); only a newly picked sheet is written as the
catalogue's portrait medium
- the stored scale factor (DXF 147) is the ratio × 25.4 on millimetre page
setups and the plain ratio on inch ones; the "use standard scale" bit
stays clear for standard and custom scales and is set for fit-to-paper;
a standard code is kept across a paper-unit conversion ("1:1" on an
inch page setup over a millimetre paper space is 1 in = 25.4 units)
- layout plots take the same scale path as every other area, so a foreign
layout's paper-space unit survives
- "plot with plot styles" / "display plot styles" round-trip as the
dialog's checkboxes, independent of a style table being named
- layout limits place the sheet at minus its displayed margins, the way the
source application does (the printable corner is the paper-space origin);
the margin ↔ rotation mapping shared by the printable-area guide now
turns the medium's top margin into the layout's left one at 90°
The fixture round-trips through the dialog with every stored field
unchanged; picking a new sheet on it writes the canonical form.
Co-Authored-By: Claude Opus 5 <[email protected]>
One writer (plot_settings_from_dialog) now serves both the layout's embedded
settings and named page setups, so the two can no longer drift apart:
- media are stored as the portrait sheet with the orientation in the
rotation code (0/90/180/270; upside-down adds a half turn) instead of
swapped width/height with rotation limited to 0/180
- standard scales are written by their code (1:1 … 100:1) with matching
numerator/denominator; other scales as a readable custom ratio in the
layout's own paper unit, converting from the drawing's scale-family unit
(a metre drawing plotting "1:100" stores 10 mm = 1 unit, an inch layout
stores 1 in = 2540 units); reading converts back and keeps a ratio the
scale list has no name for instead of snapping to 1:1
- the layout's paper unit and every flag the dialog does not edit survive a
round trip untouched; layout limits follow the paper-space unit
- new drawings, new layouts, CLEAR and the automation "new" op share one
default page setup (canonical A4 name, rotation 90, none_device, 1:1
layout plot) through Scene::reset_to_new_drawing
Scene gains scale_family_unit_mm, scale_ratio and a scale-name ratio parser
(ratios and architectural names). Round-trip tests cover orientation,
standard/custom/fit scales, unit conversion, named-setup parity, preserved
flags and the default layout.
Co-Authored-By: Claude Opus 5 <[email protected]>
The toolbar Help button was a disabled tip that could never be clicked. It now opens a modal window explaining the manager on the web build: read-only reference list, disabled Attach/Refresh/Change Path (no filesystem access or native file pickers, so no add/reload/repath and no previews), nested read-only rows, and saved-drawing requirement for relative paths.
Includes a Report-an-issue button opening the GitHub issues page and a Close button; wired as ModalKind::XrefHelp through the shared modal frame so dismissal works on native and web.
- The per-character width estimate is 0.66 text heights, measured by
rendering the text of 106 saved dimension pictures with the bundled
fonts; the old 0.60 left every fit and hook estimate ten percent narrow.
With it, the "text plus DIMGAP must clear the arrowheads" rule reproduces
AutoCAD's arrow placement for 1047 of 1078 pictured linear dimensions
whose text sits between the extension lines.
- DIMTMOVE 1 stores where the leader's hook starts, not where it ends: on 39
such radial dimensions the stored point sits DIMASZ plus DIMGAP before the
text. The hook now runs from the stored point one arrow toward the text.
- The diameter prefix is U+2205, matching the %%c expansion and the pictures.
- A diameter whose text the user dragged keeps the DIMTAD lift from #1323;
the four AutoCAD-authored diameters with DIMTAD above in the sample all
store the lifted point directly, so this applies only to dragged text.
Saved dimension pictures across 1311 diameter dimensions carry U+2205 (806) or a
literal %%c (168); U+2300 never appears. The bundled romans and simplex fonts
have U+2205 and lack Latin O-stroke, so one character now serves the %%c
expansion and, in the dimension formatter, the diameter prefix.
The fit and break estimates used two halves at STACK_HALF_SCALE; the stack
is laid out from the lower half's baseline to the upper half's cap, which is
STACK_RAISE + STACK_HALF_SCALE of the run height. The taller estimate flips
arrows outside for a few more stacked texts that AutoCAD drew that way.
A negative DIMLFAC scales a paper-space dimension only when it measures
model space through a viewport. AutoCAD records the factor it used as
ACAD_DIMASSOC_CALC_DIMLFAC; a zero there marks a dimension of paper-space
geometry, which reads its sheet distance unscaled. Regenerating such a
dimension multiplied it by the factor anyway, turning 4.457 into 18.110.
Text placed past an extension line along the dimension's own axis pulls the
dimension line out to its near edge rather than stopping at the two-arrow
stub. A radial leader already within 15 degrees of horizontal runs straight to
the text instead of turning a hook, and a diameter with outside text draws its
single leader for every DIMTMOVE except 2, which keeps only the arrowhead.
Subset parity: 870 of 1076 pictured dimensions now regenerate as drawn.
Comparing the saved picture block of every dimension in a set of production
drawings with the geometry regenerated after a refresh showed half of them
differing. The differences trace to a few layout rules:
- The stored text middle point (group 11) is where the text was drawn, for
automatic and hand-placed text alike; a regenerated dimension keeps it and
only a cleared point is placed from the style.
- Arrows move outside when the text, where it is drawn, would run into an
arrowhead. The text is measured along the dimension line, so horizontal
text on a vertical dimension counts its height, a limits stack its two
lines and `\P` continuation lines their number.
- Text pushed outside starts past the two-arrow stub and a gap; arrow
length is DIMASZ, not the text height.
- Horizontal text outside a non-horizontal dimension gets a leg to its
height and a hook one arrow long that it sits against, both when drawn
and when auto-placed.
- A radius with outside text draws no line to the centre unless DIMTOFL,
a leader to a hook the text sits against, and an arrowhead whose body
points toward the text. A diameter with outside text and no DIMTOFL is a
single leader with one arrowhead, no line across the circle.
- DIMTMOVE 1 stores the hook end; the leader is drawn to it exactly.
- Width estimates measure the widest `\P` line and skip MText format codes.
On a 30-drawing subset with 1076 pictured dimensions the regenerated
drawing now matches the picture for 838 of them, up from 584.
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]>