- Add 'i ' prefix to EntryKind::Info and coordinate set_step_prompt deduplication to satisfy WCAG 1.4.1 across all 22 themes
- Drop unused _desk parameter from crosshair_background and clean up its call sites
- Document AutoCAD-standard context-based crosshair drafting surface architecture in crosshair_background
- Add doc comments documenting deliberate alpha omission in canvas_is_light and backlog scope in is_wide
- Add dropdown_popup_width helper in common.rs replacing magic formula heuristics
- Implement is_wide range table to count East Asian Wide/Fullwidth (CJK) glyphs double for localized strings
- Calibrate unit scale factor to 0.68 * font_size preserving existing width behavior at font size 11
- Apply shared calculation across viewport controls and ribbon dropdowns
- Update unit tests to verify width calculation on standard and CJK labels
- Raise accessible_accent default threshold from 2.0 to 3.0 (WCAG 1.4.11 UI state indicators)
- Raise EntryKind::Info command line history threshold from 3.0 to 4.5 (WCAG 1.4.3 normal text)
- Update themed_check_cell to verify >= 3.0:1 contrast across both weak popup panel and strong highlighted rows
- Replace fully-qualified accessible_accent_threshold calls inside closures with use imports
- Add comprehensive 9-suite theme accessibility contrast test suite covering all 22 themes across core surfaces
- Add canvas_is_light helper based on WCAG luminance (> 0.5)
- Ensure crosshair_background always returns sheet white in paper space
- Update resolve_selection_base_color to resolve user ACI -> light-canvas palette -> theme palette
- Add light_canvas_color with curated deep-green/deep-blue pairs for light surfaces
- Extract selection_fill_alpha with 1.35x contrast compensation on light surfaces
- Thread canvas_bg through draw_marquee and poly selection
- Note deliberate limitation for desk-spanning marquee edge case
- Add test coverage for paper space, ClassicDark, custom light bg, and fill alpha clamping
DIMAUNIT 4 is Surveyor's units, but format_angular_value matched only
0-3 and let 4 fall through the catch-all to decimal degrees. An angular
dimension in a drawing authored with surveyor units therefore read as
plain degrees, while AUNITS 4 in the same drawing writes a bearing for
the coordinate readout — the two disagreed on one angle.
Format the bearing from the dimension's own DMS path so it carries
DIMADEC, DIMAZIN and DIMDSEP, quantise before picking the quadrant so a
value just short of a cardinal does not quote a quarter turn, and offer
the option in the dimension-style dialog.
Centralize the 7 byte-identical `muted_style` helpers (alpha 0.68)
previously duplicated across src/ui/style/* into a single
`src/ui/style/common.rs::muted_style` (+ alias `muted_text_style`).
All 7 style windows and the style_manager wrapper now call the
common helper, ensuring a theme palette change updates one place.
`btn_s` is intentionally NOT deduped: plotstyle.rs:41 and
style_manager.rs:299 have divergent bodies (Disabled handling +
text alpha 0.45). Unifying would silently change plotstyle
disabled appearance : documented in common.rs and covered by test.
TDD: RED `common_tests` failed E0433 (missing common), GREEN
added common.rs and wired `pub mod common`, REFACTOR replaced
locals with `use crate::ui::style::common::muted_style`.
Tests:
- common_muted_style_matches_local_copy: asserts common output equals 0.68 alpha reference
- common_muted_text_style_alias_matches: alias identity
- btn_s_bodies_documented_as_divergent: documents intentional non-dedup
Pin Iced 0.15 so dialogs can measure content before distributing the resolved frame across child panels. Keep the web plugin notice compact and non-resizable.\n\nCloses #582
Replace the raw sentinel input with typed CAD lineweight options so special
values display correctly and unsupported values cannot be entered.
Refs #522
Make objects genuinely annotative — carrying real per-scale
representations that interoperate with other CAD apps — rather than just
a native flag. `create_annotation_context` synthesizes the extension-dict
chain (AcDbContextDataManager -> ACDB_ANNOTATIONSCALES -> per-scale leaf)
from the entity's placement; the editable Annotative toggle now covers
Text and block references as well as MText/MLeader; and a new
"Annotation Object Scale" dialog (OBJECTSCALE) adds/removes an object's
per-scale memberships. Requires the acadrust ObjectContextData encoder
(Cargo.lock bump).
Also fixes a render bug where objects carrying an *empty*
ACDB_ANNOTATIONSCALES (a single-representation marker with no per-scale
reps) were treated as annotative and (mis)scaled by the annotation factor
in scaled paper viewports, ballooning the text: an object is now
annotative-by-context only when its scale collection is non-empty, so
such objects render at their base geometry.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Double-click rename did nothing and ratio edits were lost when switching
scales — and on drawings saved by other programs nothing could be edited
at all.
- Fallback scales were virtual (no Scale objects), so edit/rename no-oped;
materialize the standard set into real staged objects when the manager
opens, reverted on close unless applied.
- On third-party DWGs the mutators walked the root named-objects dict ->
ACAD_SCALELIST, which can be unreachable, and matched dictionary keys
that are internal ids (*A1, A0) rather than scale names. Locate the
scale-list dict robustly and match scales by object name + handle.
- Rename rows inline via double-click; repair a dangling current-scale
header pointer on staged rollback.
- Stage text/mleader style-manager edits on switch so they persist like
the scale manager.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The scale manager now runs as a transaction, matching the style managers'
staging: New starts a blank editor draft (nothing is added to the drawing
until Apply), Delete removes immediately but staged, and closing the window
without Apply restores the snapshot taken on open — so a scale created or
deleted mid-session is discarded on cancel. Apply commits the staged list
changes as a single undo entry. This replaces the earlier behaviour where
New copied the selected scale and edits landed immediately.
A `changed` flag guards the commit so a no-op / failed Apply (blank or
invalid fields, or an edit that didn't apply) no longer dirties the drawing
or pushes a phantom undo entry. Set Current is deliberately outside the
transaction — it takes effect immediately like the scale pill (and syncs
CANNOSCALEVALUE), so it is never rolled back on close. Renaming the current
scale follows the pointer; editing one of the built-in fallback scales (shown
when the drawing has no scale list) materialises it as a real scale; the
snapshot restore touches only the ACAD_SCALELIST root entry.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Replace the scale popup's inline delete/add affordances with a single
"Manage scales..." row that opens a proper manager, matching the style
managers: it reuses the shared style-manager palette and chrome (toolbar +
list + editor frame), so it looks and behaves like the Text / Dim / MLeader
managers.
The manager lists the drawing's annotation scales (name + ratio, the current
one checked) and edits them through a Name / Paper units / Drawing units
editor: New adds a scale from the fields, Apply renames / re-ratios the
selected one, Delete removes it (never the current scale), and Set Current
makes the selected scale the model-space annotation scale. Backed by
Scene::add_scale / remove_scale / edit_scale on ACAD_SCALELIST.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The preview box rendered a hardcoded `text("AaBbCc 0123")` that ignored
every edited property. Replace it with a canvas that tessellates the
sample string through the same stroke path the text entities use
(`lff::tessellate_text_ex`), so font, width factor, oblique angle and the
backward/upside-down flags are reflected live as fields change. Effective
font follows the entity rule (TrueType name wins, else stroke font file);
the result is fit to the preview box with Y flipped.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
- Group the flat src/ui/ dir: move the 9 style editors into ui/style/
(dimstyle, mleaderstyle, mlstyle, plotstyle, textstyle, tablestyle,
point_style, style_list, style_manager) and the 6 popups into
ui/popup/ (cycle, isolate, scale, selection_filter, snap, units).
Call sites repointed to crate::ui::style::/crate::ui::popup::; no
compat re-exports. ui/ root drops from 36 to 21 files.
- Rename app/cmd_result.rs -> app/command_driver.rs: the file is the
StepInput->feed_command driver, not the CmdResult type (which lives
in command.rs). Name now matches contents.
Co-Authored-By: Claude Opus 4.8 <[email protected]>