The dialog laid its pages out as a row of buttons across the top, which is
what AutoCAD does and what fits while there are four of them. The pages this
series adds take it to nine, and the names are translated into 21 languages —
a row of nine German or Russian page names does not fit at any dialog width
worth having.
The rail is now a vertical list down the left, the dialog is 880×620 rather
than 540×560, and the content pane scrolls on its own.
Which page was open is now remembered. With four pages, reopening on General
was a shrug; with nine it means hunting for the one you were last in.
The ribbon's Options tool has existed all along — `ToolDef`, icon and all —
but was marked `#[allow(dead_code)]` and never added to a group, so the
dialog could only be reached by typing OPTIONS or from the start page. It
now sits in Manage ▸ Application, beside About.
No settings change in this commit; it is only the shell the rest needs.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
manage/mod.rs never declared `mod mview`, so this file was never
compiled. It also carried a stale f32 `on_point` signature predating
the DVec3 command trait. The live MVIEW command is layout/mview.rs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The ABOUT command and its version-reporting window already exist, but
the ToolDef sat dead-code in the draw module with no ribbon entry, so
the only way in was typing ABOUT. Move it to the manage module and give
it an Application group on the Manage tab, as a discoverable fallback
for version diagnostics.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Rearchitect SDF text from a document-wide collector to per-entity
production during tessellation, so each entity owns its glyph quads and
composite/nested text is covered for free (no re-explosion, no per-frame
document walk).
- WireModel gains `text_verts`: glyph quads ride on the wire, so they are
cached by the tess memo, cloned on hit, and transformed by the block
expand loop exactly like `points`.
- Text arm (tessellate.rs) builds the quads when SDF is on and suppresses
the strokes; render gathers text_verts from the viewport wire set
(`gather_text_verts`, cached on wire content id) — the old collector is
removed. Covers model, dimension, table, block-internal and paper-sheet
text uniformly.
- MLEADER text (lays out via layout_mtext, not the Text arm) gets its own
SDF branch driven by the per-run GlyphRun.
- Pick box comes from the rendered glyph quads (true text extent), not
entity_aabb which mis-places the box for MTEXT; composite paths no longer
clobber the empty text wire's tight AABB (dim pick box hugs the text).
- Selection / hover highlight via a text-highlight overlay (upload_text_
highlight, keyed on selection_generation) mirroring the selected-wire
xray overlay; base glyphs stay neutral so a deselect leaves no stale tint.
- Debug: env OCS_TEXT_BOX draws each run's glyph-bounds rectangle.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Change CadModule::ribbon_groups() from -> Vec<RibbonGroup> to -> &[RibbonGroup],
backed by a per-module OnceLock cache. The ribbon group tree is static data
(&'static str, Copy enums) that was being fully reconstructed — Vecs, String
clones, enum discriminants — on every call, including all three per-frame
call sites (view(), dropdown_overlay(), style_combo_overlay()).
- 7 built-in modules + 2 plugin templates cache via function-local OnceLock.
Safe because each is a unit struct with exactly one instance per process
(plugins run in isolated child processes; see PluginProcess::spawn()).
- SharedCadModule avoids the static pattern entirely, storing groups in an
instance field (owned.rs).
- IPC runner converts &RibbonGroup -> OwnedRibbonGroup directly via new
From<&T> impls, avoiding an intermediate clone.
- render_small/render_large and the two make_tool_row closures now borrow
(&RibbonItem, &[ToolDef]) instead of taking ownership, so the view loop
doesn't need to clone items to satisfy the old by-value signatures.
- Various match-ergonomics deref fixes (*id, *default, *icon, etc.) from
the &RibbonItem pattern change.
UI chrome (dropdown carets, undo/redo, checkmarks, close/menu/osnap,
layer/file-menu icons) and ribbon tool icons were drawn as Unicode
glyphs. Desktop fills missing glyphs via system-font fallback, but the
web build bundles only Fira Sans with no fallback, so they rendered as
empty tofu boxes (issue #116).
Add a shared src/ui/icons.rs (SVG-backed, tintable) plus bundled assets,
and switch every glyph site and IconKind::Glyph tool def to SVG.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move the 30 flat modules under src/scene/ into six folders by role:
convert (entity→geometry), text (fonts/shaping), model (render models),
pick (hit-test/selection/grips/xclip), view (camera/transform/render),
cache (block + property caches). pipeline/ is unchanged.
Full path migration — all `scene::X` references become
`scene::<group>::X`, no compatibility re-exports. render.rs items that
were `pub(super)` (parent was scene) become `pub(in crate::scene)` to
keep their original scene-wide visibility.
No behavior change; build and tests are green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two behaviour changes that bring the command line in line with
established CAD workflow:
1. **Always-on keyboard capture.** The input was blurred whenever no
command was running, so typed letters went nowhere until the user
clicked into the field. Replace the blur with a re-focus on every
command lifecycle transition (cmd_result.rs) and on viewport / tab
/ ribbon clicks (update.rs), focus the input at startup, and add
a global key subscription that catches any unhandled character key
or backspace and routes it into the buffer via two new messages
(CommandAppendChar / CommandBackspace) — so the command line keeps
accumulating keystrokes even if focus parks somewhere not
focusable. Removes the unused blur_cmd_input helper.
2. **Space submits.** Typing a space at the end of the input now
submits the buffer the same way Enter does. Only exception: an
active command that's currently collecting free-form prose
(TEXT / MTEXT / DDEDIT body, ATTDEF prompt / default value,
INSERT attribute value, ATTEDIT cell). Those advertise the new
`CadCommand::wants_text_with_spaces()` flag so the Space character
reaches the buffer as a literal.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Each item below was gated by #[allow(dead_code)] and has zero callers
across src/ — none of them are part of any public API consumed by
external crates (this is a binary, not a library):
* modules/insert/underlay_frames.rs + edit_aliases.rs — toolbar stubs
whose `tool()` registrars were never wired into the ribbon; the
parent mod.rs inlines its own include_bytes! for the SVGs, so the
files were orphan dead weight.
* ui/snap_popup.rs:snap_marker_color — never called.
* ui/ribbon/mod.rs:last_dropdown_cmd — never called.
* ui/scale_popup.rs:anno_scale_for_label — never called.
* ui/layers.rs:color_name_to_aci — inverse of aci_color_display
with zero call sites.
* linetypes.rs:name_list — never called.
* scene/pipeline/wire_gpu.rs:new_ghost — never called.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The preview rectangle used c1.y (constant) for all four corners and
pt.z for Z instead of c1.z. Corners 3 and 4 now correctly use pt.y
(varying Y) and the constant c1.z, producing a proper XY-plane rectangle.
Fixed in both layout/mview.rs and manage/mview.rs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>