Commit Graph
81 Commits
Author SHA1 Message Date
ramox81 cd82deff3c Expose Break at Point in the Modify extension 2026-09-11 09:35:04 +03:00
Hakan Seven f4eeba75df style(icons): refresh editing tool artwork 2026-09-10 22:20:34 +03:00
Hakan Seven 464ebc3140 Merge pull request #1151 from ramox81 2026-09-10 17:15:58 +03:00
Hakan Seven 0c46d2d828 Merge pull request #1150 from ramox81 2026-09-10 17:15:57 +03:00
Hakan Seven 1ad8eccbe6 Merge pull request #1149 from ramox81 2026-09-10 17:15:55 +03:00
Hakan Seven 9e9664c843 Merge pull request #1147 from ramox81 2026-09-10 17:15:50 +03:00
Hakan Seven ae4f739757 Merge pull request #1146 from ramox81 2026-09-10 17:15:49 +03:00
Hakan Seven abfd7943f3 Merge pull request #1145 from ramox81 2026-09-10 17:15:47 +03:00
Hakan Seven dc3602e774 Merge pull request #1144 from ramox81 2026-09-10 17:15:45 +03:00
Hakan Seven dbd3bf15a9 Merge pull request #1143 from ramox81 2026-09-10 17:15:44 +03:00
Hakan Seven 8b17ddaa22 Merge pull request #1142 from ramox81 2026-09-10 17:15:42 +03:00
ramox81 8604950912 feat: expose Donut in the Draw expansion 2026-09-10 15:57:26 +03:00
ramox81 cf34df4061 feat: expose Helix in the Draw expansion 2026-09-10 15:57:25 +03:00
ramox81 274706ee99 feat: expose Boundary in the Draw expansion 2026-09-10 15:57:24 +03:00
ramox81 c50610e37b feat: expose Region in the Draw expansion 2026-09-10 15:57:22 +03:00
ramox81 1abfb30659 feat: expose Measure in the Draw expansion 2026-09-10 15:57:22 +03:00
ramox81 894058fa60 feat: expose Divide in the Draw expansion 2026-09-10 15:57:21 +03:00
ramox81 0f81166c3a feat: expose Multiple Points in the Draw expansion 2026-09-10 15:57:20 +03:00
ramox81 cc503f1847 feat: expose Ray in the Draw expansion 2026-09-10 15:57:19 +03:00
ramox81 dc83a3e5fa feat: expose Construction Line in the Draw expansion 2026-09-10 15:57:18 +03:00
ramox81 306d998ebf feat: expose Spline CV in the Draw expansion 2026-09-10 15:57:17 +03:00
Hakan Seven 200ed541f5 Update intersection icon artwork 2026-09-05 17:28:30 +03:00
Hakan Seven 826a437dfc Clarify subtract and intersect modelling icons 2026-09-05 17:14:08 +03:00
Hakan Seven 055f1cdb1a Redesign modelling ribbon icons 2026-09-05 14:46:06 +03:00
gianlucafiore 863dd555c1 feat(ribbon): add measurement dropdown 2026-09-03 19:23:37 -03:00
Hakan Seven 0237652963 style(icons): unify theme-aware palette 2026-08-29 12:20:24 +03:00
Hakan Seven 2be8e00066 style(icons): apply reviewed icon set 2026-08-29 02:23:21 +03:00
Hakan Seven 81e7add1dd fix(tolerance): complete workflow integration
Sync current main and companion codec changes before preserving unsupported frame rows, rendering in the entity plane, and sharing final layout metrics with placement preview.
2026-08-27 00:14:08 +03:00
Hakan Seven 06cd0ec6a9 feat(model): add exact solid modelling tools 2026-08-23 22:53:31 +03:00
Karim Jerbi 236b7756f8 feat(draworder): HATCHTOBACK command and interactive DRAWORDER workflows
Implement the AutoCAD compatible HATCHTOBACK (HB) command and enhance the interactive DRAWORDER command pipeline with comprehensive verb selection and viewport entity picking.

Key implementations and architectural details:

1. HATCHTOBACK command execution
   * Isolates entities belonging to the active layout block record or global space.
   * Filters out entities residing on locked layers using an efficient hash set lookup.
   * Records targeted delta undo operations on SortEntitiesTable objects (~100 bytes) rather than snapshotting full document structures.
   * Performs granular draw depth cache invalidation via Scene::invalidate_draw_depth, preserving existing geometry tessellations and spatial indices.
   * Emits localized user notifications when no qualifying hatch entities are found.

2. Interactive DrawOrderCommand state machine
   * Supports preselected entities as well as interactive on demand selection gathering.
   * Implements subverb selection supporting single character shortcuts (A for Above, U for Under, F for Front, B for Back) and case insensitive keyword parsing.
   * Enables interactive reference object picking directly in the viewport via needs_entity_pick and on_entity_pick callbacks.
   * Supports hexadecimal handle specification directly from the command line interface.

3. Ecosystem and system integration
   * Bumps DEFAULT_ALIASES_VERSION from 2 to 3 to register the HB alias while preserving existing user overrides.
   * Integrates HATCHTOBACK and HB into dynamic autocomplete registries.
   * Adds localized message strings across all 20 Fluent translation catalogs.
   * Corrects hatch boundary serialization flags to ensure outermost boundary rings consistently carry the external attribute.
2026-08-23 18:56:01 +01:00
Hakan Seven 5630f48b4e feat: improve start page links 2026-08-15 23:33:18 +03:00
Karim Jerbi d2e18ead38 feat(aliases): R/RA/RE/REA for REDRAW/REGEN; register verbs 2026-08-10 23:26:26 +01:00
Hakan Seven adb8ced8b5 feat(view): complete ZOOM options
Add command-line navigation modes and persistent wheel controls.\n\nRefs #412
2026-08-08 20:37:53 +03:00
Hakan Seven 5bd5c884e0 fix(aliases): map CP to COPY 2026-08-08 19:20:34 +03:00
Hakan SevenandClaude Opus 5 7c8271c716 fix(icon): draw every icon from the logo file
Two places still showed the old mark after the logo was redrawn.

The window icon was built by drawing the letterforms stroke by stroke in
code, background colour and all, which made it the one icon in the
application not coming from assets/logo.svg. It now rasterises that file,
fitted to the square without distorting whatever aspect the logo has. It
returns nothing when the logo cannot be rendered, so the window falls back
to the platform default instead of to something invented here -- which is
how it ended up stale in the first place.

The icon installed into the icon theme was only ever written from inside
the desktop-entry write, behind that write's own "nothing changed" early
return. The entry's text does not change when the logo does, so once it
had been written the icon was never refreshed again. The two change for
different reasons; the icon is now checked first and on its own terms. It
already compares bytes, so an unchanged logo still costs only a read.

Worth knowing on Wayland: the compositor ignores the window icon entirely
and takes the dock icon from the desktop entry, so there the installed
theme file is the only one that matters -- and it refreshes when the file
associations are next set up, not at launch.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-07 17:37:59 +03:00
Hakan SevenandClaude Opus 5 b5a1146966 feat(view): one list of visual styles behind every way of choosing one
The ribbon offered four styles and dispatched each one's id as a command.
Two of those ids were not visual-style commands: "Shaded" carried SOLID,
which draws a 2D filled polygon, so choosing it started a draw command;
"Hidden" carried HIDDEN, which matched nothing at all, so it did nothing.
The intent had been for the button to fire its tool's event, but the
dropdown never reads one -- it dispatches the id.

Behind that sat two generations of the same feature. The render-mode
picker offered the seven styles a viewport can actually be drawn in;
everything else -- the ribbon, VSCURRENT, SHADEMODE, VISUALSTYLES and a
handful of bare verbs -- went through a binary wireframe-or-shaded flag
that could only approximate them, reporting "Hidden (shown shaded)" and
"X-Ray (shown as wireframe)" when asked for something it had no way to
draw. Four descriptions of one choice, each drifting on its own.

There is one list now. Each style names itself once -- mode, label, icon,
and the command that applies it -- and the ribbon, the picker, the
VISUALSTYLES verb and the interactive prompt all read from it, down to
the line that lists the choices, so what is offered cannot disagree with
what works. Keywords are the render modes' own names, since there is one
set of styles left to name.

The binary path is gone rather than kept alongside: its message, its
module event, the tool definitions that produced it, the ribbon's
special-cased highlight arms, the bare style verbs and the older keyword
spellings. X-Ray goes with it -- no render mode draws one, and it was
already coming out as a plain wireframe. Three files that had been left
holding a single icon constant each fold into the list.

Note: ModuleEvent::SetWireframe leaves the plugin API with it.

Closes #621

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-07 14:15:59 +03:00
Karim Jerbi 8f009d0058 feat(insert): add docked block palette
Add a searchable block palette with previews, file import, collision-safe nested definitions, and dependency/table-record import. Keep palette thumbnails current across drawing switches and block-definition edits.
2026-08-06 11:02:52 +03:00
Hakan Seven d1f9055901 feat(ui): refine ribbon and view navigation 2026-08-04 18:21:52 +03:00
Hakan Seven fb0f409bfd feat(input): expand shortcut support 2026-08-04 14:20:02 +03:00
Hakan Seven 4be8d9735c feat(ui): add dockable properties panel
Preserve panel width across left/right docking and persist resize, position, and auto-collapse preferences.

Refs #348
Refs #650
2026-08-04 13:46:02 +03:00
Hakan Seven 325cd2474c feat(plot): complete plot configuration
- unify Model and Paper Space plot area behavior
- add CTB discovery, read/write, and bundled defaults
- apply scale, render mode, and output options consistently
2026-07-31 13:41:34 +03:00
Hakan Seven dba8ec3d63 fix(web): outline sponsor logo text
Render the wordmark and tagline as vector paths so web SVG rasterization does not depend on unavailable system fonts.\n\nRefs #573
2026-07-30 20:21:18 +03:00
Hakan Seven 02d15f5d23 feat(ribbon): add layer isolation tools
Closes #589
2026-07-30 18:07:06 +03:00
Hakan Seven fd8b206515 feat(start): add OpenAEC sponsor 2026-07-29 21:38:19 +03:00
Hakan Seven 28d8246c68 feat(ui): add discussions and semantic theming
Generate web discussion snapshots in CI; native builds use the public
feed and an offline cache.
2026-07-28 11:49:45 +03:00
Hakan SevenandClaude Fable 5 b6720230c9 feat(start): live tutorial-video rail from the YouTube playlist
Replace the two baked-in intro video cards (and their bundled JPEG
thumbnails) with a Tutorials rail listing the official playlist. The
list is fetched at boot on a dedicated thread — ordered video ids from
the playlist page, titles via the key-less oEmbed endpoint — and each
thumbnail is downloaded once and cached under the config directory, so
nothing ships in the binary and later launches show the list instantly
(offline included). The rail overlays the welcome column's empty left
side so the centre action buttons keep their position, shows
"Loading videos…" until the first fetch lands, and the side-by-side
layout hands over to the tabbed one (with a Videos tab) before the
centred content could slide under the rail.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-21 10:06:55 +03:00
Hakan SevenandClaude Opus 4.8 977701b47e feat(ui): MTEXT editor in shared modal + resizable dialogs
Route the MTEXT editor through the shared in-canvas modal frame with an
Apply-at-top toolbar (style-manager style): Apply commits and keeps the
editor open (creates on first apply, updates in place after), the ✕
cancels. Give every modal a bottom-right corner resize grip driven by a
shared grow-only `modal_resize` delta that resets with `modal_offset` on
open/close, so each dialog opens at its natural size and can be dragged
larger — style managers included.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-19 15:47:09 +03:00
Hakan SevenandClaude Opus 4.8 c10e8dae44 fix(tolerance): draw the feature control frame properly
A tolerance drew one row of ASCII soup — "RUN | ANGtol(M) | ..." — about
a tenth of its proper size. Six defects, each independent.

Rows were split on the two-character string "^J". A DWG stores a raw
newline, and the text-DXF reader rewrites the on-disk ^J to one before we
see it, so that split never fired on either mainstream path and every row
collapsed into the first. It now normalises all four spellings the break
arrives in — including the \P our own DXF writer emits, which made
open-DWG → save-DXF → reopen asymmetric.

Symbols were replaced with ASCII labels from a table that was itself
wrong: it read r as circular runout, n as angularity, p as position. The
font's own encoding says concentricity, diameter, projected tolerance
zone, and the benchmark's pre-exploded reference agrees. That table was
an inversion of acadrust's, which is self-contradictory — it binds n to
two different meanings. Do not re-derive from it.

The frame is a proportion of the character height: a compartment spans
-h..+h about its row's centreline, so it is 2h tall and the margin falls
out of that. It was built as height + 2*DIMGAP instead, which is a
different entity's geometry — DIMGAP sizes the dimension line's break and
the rectangle around a basic dimension, where it genuinely applies twice
per axis. Even fed a self-consistent style that can only ever produce
1.5h, so it was wrong in kind rather than mis-fed.

Height came from the entity's own field, which a DWG never sets — the
reader carries only the style's handle, leaving a small non-zero default
that a "> 0" test happily used. It now resolves the style by handle first
and name second: a DWG records the handle and defaults the name, a DXF
the reverse, so matching on the name alone would have picked the wrong
style for every DWG-read tolerance. An entity may also override single
style variables on itself, and this one halves its character height that
way; ignoring that drew the frame several times too large.

Rows stacked upward, every row inherited the widest row's columns, and
one full-width border boxed them all — none of which showed while the
parse only ever produced a single row. The insertion point sits on the
first row's centreline; anchoring the frame's bottom-left there offset it
by its own height, and by an amount that changed with the row count.

Cell text ran together because the glyph run asked for no letter spacing
while the width measurement assumed the font's own, so the characters
crowded inside correctly-sized boxes. Compartments are also measured by
what they draw now: the pen advance stops one letter-space past the last
glyph, and counting that made every one of them too wide.

Symbols come from a bundled stroke font, restored from this repository's
own history: it shipped QCAD's gdt.cxf until the text engine moved from
CXF to LFF, which removed every .cxf and left nothing in their place —
the ASCII labels date from exactly there. Converted to LFF, keyed by the
letter its \Fgdt;X escape carries, and registered under that name like
any other font, so a switch to it resolves through the ordinary lookup:
an MTEXT carrying the escape, or a text style named gdt.shx, reaches it
too, with no code of their own. The geometry is public domain by explicit
waiver; provenance is in the file's header.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-15 22:22:07 +03:00
Hakan SevenandClaude Opus 4.8 ba3b3202e8 feat(thumbnails): embed DWG previews and wire cross-platform file thumbnails
Round-trip a raster preview through the DWG's embedded preview slot and
surface it to the OS file managers, so drawings show their contents in
Explorer / Finder / Nautilus instead of a generic document icon.

OCS:
* io::thumbnail — rasterize the scene to a BMP DIB on save (embedded via
  acadrust's new Preview type) and read it back on open for the Start
  page recent list; `--dwg-thumbnail IN OUT SIZE` CLI extracts a badged
  PNG for external thumbnailers.
* io::file_association::install_thumbnailer — self-install the OS
  integration on startup: Linux writes a .thumbnailer + hicolor mimetype
  icons; Windows registers the IThumbnailProvider DLL under HKCU.

Shared core:
* crates/dwg-thumbnailer — lean (image-only) preview extractor + the
  `badge_dwg` full-width "DWG" band, used by every platform so the
  ribbon is single-sourced. Ships an rlib+staticlib.
* crates/dwg-thumbnailer-win — IThumbnailProvider COM in-proc server
  (cfg(windows), CI-built as a workspace member).
* macos/ — QuickLook thumbnail extension (Swift + C-ABI bridge to the
  core staticlib), assembled into a .appex.

Icons & packaging (single SVG source -> per-platform assets in CI):
* assets/mimetypes/image-vnd.{dwg,dxf}.svg — themed file icons.
* packaging: WiX ships dwg/dxf.ico + the thumbnail DLL and points the
  ProgIds at them; Info.plist gets CFBundleTypeIconFile + the QuickLook
  extension in Contents/PlugIns.
* release.yml — generate .ico (Windows) and .icns (macOS) from the SVGs,
  build the QuickLook .appex, and bundle everything.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-11 01:27:17 +03:00
Hakan SevenandClaude Opus 4.8 91ba9f7699 feat(alias): centralize command aliases in user-editable ocad.pgp (#286/#288)
Command aliases (L→LINE, CC→COPYCLIP) were scattered across dispatch match
arms and CommandRegistration name arrays. Move them all into a single
user-editable file:

- assets/ocad.pgp: shipped default alias table (ALIAS,*COMMAND format),
  embedded and copied to config/ocad.pgp on first launch; only that user
  copy is read after. AA→AREA default closes #286.
- resolve_alias() rewrites the leading command token at the top of
  dispatch_command_inner, so aliases resolve for every path (families,
  plugins, Repeat menu). Args after the first space are untouched.
- Autocomplete hides alias keys and, when the whole input is an alias,
  surfaces its target command as the top (highlighted) suggestion so the
  highlight matches what Enter runs (AA→AREA, L→LINE).
- ALIASEDIT opens a new editor modal (add/edit/delete rows) with an Apply
  button; Apply persists to ocad.pgp, closing discards unapplied edits.
- Strip alias tokens from all 8 dispatch match-arm files and 71 module
  CommandRegistration arrays, keeping canonical/synonym/distinct-command
  names. ocad.pgp is now the sole source: deleting or remapping an alias
  there takes effect. CUI stays on the keyboard-shortcut panel.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-10 12:39:22 +03:00