Commit Graph
45 Commits
Author SHA1 Message Date
Hakan SevenandClaude Sonnet 4.6 f63858876d fix: align white paper fill with entity borders
- paper_entity_extents() computes the bounding box of actual DXF entities
  so the white fill always matches the drawn title-block / frame borders,
  regardless of whether Layout min/max_limits match entity positions
- Falls back to paper_limits() (→ A4 297×210) when layout has no entities
- Removed paper_boundary_wire: the white fill now acts as the visual paper
  edge so the near-white wire (invisible on white) was redundant
- LayoutCreate sets limits to A4 landscape immediately after add_layout()
  to override acadrust's imperial default (12×9)

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-23 14:21:03 +03:00
Hakan SevenandClaude Sonnet 4.6 f176f7c80a fix: correct ViewCubeSnap and MSPACE orbit to write viewport entity
- Add orbit_active_viewport(), snap_active_viewport_to_angles(),
  active_view_rotation_mat(), active_viewport_yaw_pitch() helpers so
  navigation gestures modify the DXF viewport entity's view_direction
  instead of the paper-space camera.
- Fix "already there → flip opposite" check: the previous code used
  rot * Vec4::W (always (0,0,0,1) for a rotation matrix); now reads
  (yaw, pitch) directly from camera_for_viewport() via the new helper.
- MSPACE right-drag orbit early-returns after writing the viewport
  entity, preventing the paper-space camera from also being modified.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-23 08:53:30 +03:00
Hakan SevenandClaude Sonnet 4.6 070ad1f9c5 feat: add Report/About/Changelog buttons to Support ribbon group
- REPORT opens GitHub new-issue page
- ABOUT opens a dialog window with version, OS and arch info + Copy Info button
- CHANGELOG opens GitHub releases page
- Fix Windows build: add windows-sys as target-specific dependency for PRINT command

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-22 22:22:33 +03:00
Hakan SevenandClaude Sonnet 4.6 bd68114bde feat: add style selector comboboxes to Annotate ribbon tab
New StyleComboGroup RibbonItem renders a dropdown combobox for selecting
text style, dimension style, multileader style, or table style. Ribbon
groups in the Annotate tab now match the reference layout: each group
has a large tool on the left and a style combobox with tool rows on the
right.

Each combobox shows the active style name, opens a scrollable item list
on click, and has an optional "Manage…" row that fires the style manager
command (STYLE / DIMSTYLE / MLEADERSTYLE / TABLESTYLE).

Style state is synced from the document on every layer refresh via
sync_ribbon_styles(). RibbonStyleChanged message propagates selections
back to the acadrust document header and the active_mleader_style field.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-09 03:38:23 +03:00
Hakan SevenandClaude Sonnet 4.6 08b9a21d31 feat: add missing Annotate tab commands and icons
New dimension commands: QDIM, DIMEDIT, DIMTEDIT, DIMBREAK, DIMSPACE,
DIMJOGLINE with full command workflows and SVG icons.

New multileader commands: MLEADERADD, MLEADERREMOVE, MLEADERALIGN,
MLEADERCOLLECT with entity injection pattern for in-place editing.

Updated annotate ribbon: all tools exposed across Text, Dimensions,
Leaders, Tables, Markup, and Annotation Scaling groups. Added STYLE,
FIND, DIMSTYLE shortcut buttons.

Added `inject_picked_entity` to the CadCommand trait for commands that
need a cloned copy of the picked entity to modify (DIMTEDIT, MLEADERADD,
MLEADERREMOVE). Sentinel-based dispatch in cmd_result.rs handles
DIMBREAK, DIMSPACE, DIMJOGLINE, MLEADERALIGN, and MLEADERCOLLECT.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-09 03:26:47 +03:00
Hakan SevenandClaude Sonnet 4.6 888095cc3e refactor: convert all overlay dialogs to separate OS windows
Every dialog panel that previously rendered as an in-viewport overlay is
now opened as its own OS window, matching the behaviour of the Layer
Properties Manager:

  • Page Setup           (520×460, non-resizable)
  • Text Style           (620×460)
  • Table Style          (620×420)
  • Multiline Style      (620×420)
  • Layout Manager       (640×320)
  • Plot Style Editor    (780×540)
  • Dimension Style Mgr  (720×560)
  • Keyboard Shortcuts   (720×520)

Changes:
  - mod.rs: replace *_open: bool fields with *_window: Option<window::Id>;
    add window IDs to OsWindowClosed tracker; add per-window title strings.
  - update.rs: Open handlers call window::open(); if already open, call
    window::gain_focus() instead of reopening. Close handlers call
    window::close(). OsWindowClosed clears all panel window IDs.
  - view.rs: each window_id is matched at the top of view() and returns
    the panel content directly. All overlay let-bindings and stack![]
    references removed.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-08 22:36:28 +03:00
Hakan SevenandClaude Sonnet 4.6 b24e0c5da9 feat: STEPOUT command — export 3D meshes to STEP AP203
Adds STEPOUT / STPOUT / EXPORTSTEP command that exports all tessellated
Solid3D / Region / Body meshes to an ISO 10303-21 (STEP AP203) file.

Each triangle is encoded as a minimal ADVANCED_FACE with a PLANE surface
and CLOSED_SHELL topology — sufficient for import into all major CAD systems.
A file-save dialog picks the output path; the command line reports success or
errors. Requires at least one tessellated solid in the drawing.

Closes ROADMAP 14.10.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-08 22:23:58 +03:00
Hakan SevenandClaude Sonnet 4.6 f515b556c7 feat: PRINT command — send layout to system printer via lp/lpr
The PRINT command renders the current layout to a temporary PDF (reusing
the existing PDF export pipeline) and dispatches it to the OS default
printer:
  - Linux/macOS: `lp` (CUPS) with `lpr` as fallback.
  - Windows: ShellExecute "print" verb (compiled-in, unused on Linux).

PLOT and EXPORT still open the save-file dialog as before.
Status messages are shown in the command line during the async job.

Closes ROADMAP 1.8.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-08 22:21:50 +03:00
Hakan SevenandClaude Sonnet 4.6 67b5f5e3d5 feat: Keyboard Shortcuts panel + SHORTCUTS command
Opens a reference panel listing all built-in keyboard shortcuts
(F3-F12, Ctrl+N/O/S/Z/C/X/V, etc.) and any user-defined overrides.

SHORTCUTS LIST         — open the panel
SHORTCUTS SET <k> <c>  — add/update a custom shortcut label
SHORTCUTS CLEAR <k>    — remove a custom entry

Custom shortcuts are stored in app state (runtime only) and shown
in the panel alongside the hardcoded bindings.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-08 18:34:10 +03:00
Hakan SevenandClaude Sonnet 4.6 e36fafe6df feat: COLORSCHEME command — runtime UI theme/color-scheme switching
Adds active_theme: Theme field to app state and wires the daemon's
.theme() callback to use it dynamically. COLORSCHEME <name> switches
among all 19 built-in iced themes (Dark, Light, Dracula, Nord, Tokyo
Night, Gruvbox, Kanagawa, Moonfly, Nightfly, etc.).

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-08 18:31:09 +03:00
Hakan SevenandClaude Sonnet 4.6 85f9b930a2 feat: Layout Manager GUI (LAYOUTMANAGER / LAYOUTPANEL command)
Panel overlay showing all layouts with their active status.
Supports: select, rename, new, delete, reorder (◀▶), set current.
Also adds Scene::swap_layout_order() for tab-order resequencing.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-08 18:28:30 +03:00
Hakan SevenandClaude Sonnet 4.6 b8d15e5155 feat: Plot Style Table Editor GUI (PLOTSTYLEPANEL / STYLESMANAGER)
Opens a panel overlay showing all 255 ACI entries with their current
overrides (color, lineweight, screening). Allows editing entries
interactively, creating a new identity table when none is loaded,
and saving the modified table back to a CTB/STB file.

Commands: PLOTSTYLEPANEL, PLOTSTYLEEDITOR, STYLESMANAGER

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-08 18:19:48 +03:00
Hakan SevenandClaude Sonnet 4.6 6fa3157e72 feat: OBJ mesh import (IMPORTOBJ / OBJIMPORT command)
Parses Wavefront OBJ files (v/vn/f, fan-triangulation, face normals
fallback) and inserts the result as a Solid3D placeholder + MeshModel
visible in the 3D viewport.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-08 12:59:27 +03:00
Hakan SevenandClaude Sonnet 4.6 25b91bc09e feat: STL export (STLOUT / EXPORTSTL command)
Exports all tessellated 3D mesh models in the current drawing to a
binary STL file via a save-file dialog. Normals are taken from the
MeshModel where available, otherwise computed from triangle vertices.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-08 00:46:05 +03:00
Hakan SevenandClaude Sonnet 4.6 3cdd86a674 feat: right-click context menu + CONSTRUCTIONLINE alias
Viewport right-click now shows a proper widget-based context menu:
- When a command is active: Cancel / Enter
- Otherwise: Repeat last commands, Delete/Move/Copy (if selected),
  Select All, Zoom Extents

CONSTRUCTIONLINE added as an alias for XLINE (XL).
Canvas-drawn placeholder removed; context menu closes on Escape,
click-outside, or when any action is taken.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-08 00:41:01 +03:00
Hakan SevenandClaude Sonnet 4.6 f73d38f0a2 feat: Object Snap Tracking (OTRACK / F11)
- snap/mod.rs: Snapper gains otrack_enabled, tracking_points, dwell state;
  update_otrack_dwell() acquires a snap point after DWELL_THRESHOLD=4
  consecutive moves near the same position; otrack_snap() returns an
  H/V alignment snap position; clear_tracking() resets state on command end
- overlay.rs: selection_overlay accepts ost_points + cursor_screen;
  draws light-blue dashed H/V lines from acquired points + small cross marker
- statusbar.rs: OTRACK pill (F11) added next to DYN
- view.rs: projects tracking_points to screen, passes to selection_overlay
- update.rs: calls update_otrack_dwell + otrack_snap in ViewportMove;
  overrides effective point with OST alignment when no normal snap is active
- ROADMAP.md: Object Snap Tracking marked ✅

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-08 00:26:54 +03:00
Hakan SevenandClaude Sonnet 4.6 51e6c4b359 feat: Dynamic Input overlay (DYNMODE / F12)
- overlay.rs: dynamic_input_overlay() canvas widget draws a semi-transparent
  coordinate tooltip near the cursor; shows X/Y in absolute mode or
  dist/angle relative to last_point when a command base point exists
- statusbar: DYN toggle pill with F12 tooltip (calls ToggleDynInput)
- app/mod.rs: dyn_input: bool field (default true), ToggleDynInput message
- view.rs: builds DYN label and pushes overlay into viewport_stack when
  dyn_input=true and a command is active
- document.rs: last_cursor_screen: iced::Point — updated on every ViewportMove
- ROADMAP.md: Dynamic Input overlay marked ✅

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-08 00:12:09 +03:00
Hakan SevenandClaude Sonnet 4.6 f80d694818 feat: DATAEXTRACTION — export entity data to CSV
- DATAEXTRACTION / EATTEXT / ATTEXT commands trigger an async save dialog
- Extracts all model-space entities with: Type, Handle, Layer, Color,
  Linetype, and a geometry summary per entity type (coords, radius, etc.)
- DataExtractionSave / DataExtractionSaveResult message pair drives
  the rfd save-file dialog asynchronously
- CSV fields are properly escaped (commas, quotes, newlines)
- ROADMAP.md: 12 DATAEXTRACTION marked ✅

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-08 00:07:58 +03:00
Hakan SevenandClaude Sonnet 4.6 b15be3af3d feat: WBLOCK — write block or selected entities to external file
- src/modules/insert/wblock.rs: extract_block_to_doc() copies a named
  block's entities into a fresh CadDocument; extract_entities_to_doc()
  does the same for a selection set; layer definitions are carried over
- WBLOCK <name> writes the named block; WBLOCK * writes selected entities
- WblockSave / WblockSaveResult messages drive the async save-dialog flow
- ROADMAP.md: 1.10 WBLOCK marked ✅

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-08 00:05:04 +03:00
Hakan SevenandClaude Sonnet 4.6 64837e9aed feat: XREF management — auto-resolve, XATTACH, XREF, XRELOAD
- src/io/xref.rs: resolve_xrefs() scans block_records for is_xref flags,
  resolves paths relative to the opened file's directory, loads the
  referenced DWG/DXF and merges model-space entities into the xref block
- src/modules/insert/xattach.rs: XATTACH command with file-picker flow
  (XAttachPick/XAttachPickResult messages), prepare_xref_block() creates
  BlockRecord + Block entities and immediately resolves content
- XREF command: lists all external references in the drawing
- XRELOAD command: re-resolves all xref paths and rebuilds scene caches
- Auto-resolve on FileOpened: reports Loaded/NotFound per xref block
- CadCommand trait: added optional xattach_path() method
- ROADMAP.md: 1.9 XREF management marked ✅

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-08 00:02:38 +03:00
Hakan SevenandClaude Sonnet 4.6 4c1c13cab6 feat: Grid snap adaptive spacing + Polar tracking improvements
Grid snap (F9):
  • snap spacing now tracks the visible grid zoom level — computed via
    compute_grid_step() (same adaptive pow-of-5 logic as draw_grid),
    updated on every ViewportMove so zooming in/out keeps snap aligned
    with the grid lines on screen

Polar tracking (F10):
  • configurable angle increment stored in polar_increment_deg (default 45°)
  • right-click the POLAR pill to cycle through 15 → 30 → 45 → 90°
  • pill label shows current angle ("POLAR 45°")
  • visual guide line: while drawing with polar on, a dashed cyan line is
    drawn from last_point along the snapped direction across the viewport
  • SetPolarAngle message + handler; all polar_constrain() calls use the
    stored increment instead of the hardcoded 45°

ROADMAP updated: Grid snap and Polar tracking marked ✅.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-07 19:30:25 +03:00
Hakan SevenandClaude Sonnet 4.6 a99115bda5 feat: Solid3D (3DSOLID) ACIS tessellation
Parse SAT geometry directly into GPU MeshModel without going through
the truck B-rep pipeline:
  • plane-surface faces  → fan-triangulate the coedge-loop polygon
  • cone-surface faces   → parametric grid (handles cylinders and cones)
  • sphere-surface faces → UV sphere grid (GRID_U × GRID_V)
  • torus-surface faces  → UV torus grid

Scene integration:
  • add_entity(): tessellates Solid3D on insert, stores in scene.meshes
  • erase_entities(): removes mesh from scene.meshes on delete
  • populate_meshes_from_document(): rebuilds all meshes on file load
    and undo/redo (called alongside populate_hatches/images)

ROADMAP updated: Solid3D tessellation marked ✅ in sections 2.12, 14.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-07 19:11:24 +03:00
Hakan SevenandClaude Sonnet 4.6 f6d716dfc5 feat: HATCHEDIT command to edit existing hatch pattern, scale, and angle
Add HATCHEDIT (HE alias) command. Works on pre-selected hatch or via
entity pick. Accepts text options: P <pattern>, S <scale>, A <angle>.
Enter applies changes; rebuilds hatch entity and GPU model via add_hatch.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-07 11:08:51 +03:00
Hakan SevenandClaude Sonnet 4.6 8078c4c9da feat: DDEDIT command and double-click text editing
Add DDEDIT (ED alias) command that edits Text/MText/Attribute entities
in-place via the command line. Double-clicking a text entity in model space
now auto-launches DDEDIT for that entity. Supports Text, MText,
AttributeDefinition, and AttributeEntity types.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-07 11:05:24 +03:00
Hakan SevenandClaude Sonnet 4.6 80ca095121 feat: command history navigation with up/down arrow keys
CommandLine now records every submitted command in a recall list (up to
50 entries).  Pressing ↑ in the command input walks back through the
list, ↓ moves forward, and returning to the newest position restores
the draft text the user had typed before navigating.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-07 00:04:12 +03:00
Hakan SevenandClaude Sonnet 4.6 efc259fdbe feat: per-viewport layer freeze columns in Layer Manager
Add VP freeze/thaw toggle columns to the layer panel when in a paper
space layout. Each viewport gets its own column (VP 1, VP 2, …) showing
a freeze icon per layer. Clicking toggles frozen_layers on the Viewport
entity and syncs back to the panel.

- scene: viewport_list() → [(handle, label, frozen_handles)]
- LayerPanel: VpCol + vp_frozen per layer, sync_with_viewports()
- Message::LayerToggleVpFreeze(layer_idx, vp_col_idx)
- Sync VP columns on layout switch, VPLAYER cmd, undo/redo, layer ops

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-06 23:41:39 +03:00
Hakan SevenandClaude Sonnet 4.6 4312b6c3a5 feat: raster image render pipeline (IMAGE command + GPU textured quad)
- Add IMAGE / IMAGEATTACH / IM command with async file-picker (rfd)
- src/scene/image_model.rs: ImageModel with RGBA pixel data + quad corners
- src/scene/pipeline/image_gpu.rs: ImageGpu with wgpu texture, sampler, opacity uniform
- src/scene/pipeline/mod.rs: image render pipeline (pass 2, between hatches and meshes)
- src/scene/render.rs: include images in Primitive, call upload_images in prepare
- src/scene/mod.rs: images HashMap, populate_images_from_document, cache on add_entity
- src/modules/home/draw/raster_image.rs: ImageCommand (two-click: origin + width, aspect-correct preview)
- src/io/mod.rs: pick_image_file() async helper (file dialog + dimension decode)
- app: ImagePick / ImagePickResult messages, populate on file open and undo/redo

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-06 23:19:08 +03:00
Hakan SevenandClaude Sonnet 4.6 3d1f355a5c feat: TextStyle font browser (STYLE DIALOG command)
- STYLE DIALOG / TEXTSTYLE DIALOG opens the Text Style Font Browser
- Three-panel dialog: style list | built-in CXF font list | properties
- Properties panel: font file text field, width factor, oblique angle
- Apply button commits edits; Set Current sets the active text style
- Built-in font picker (20 CXF fonts from assets/fonts/) auto-applies
  font to the selected style on click
- Preview pane shows "AaBbCc 0123" sample text

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-06 15:01:25 +03:00
Hakan SevenandClaude Sonnet 4.6 552ab7eb6a feat: TableStyle manager (TABLESTYLE command + dialog)
- TABLESTYLE/TS command: LIST, NEW subcommands for managing table styles
- Table Style Manager dialog: style list with details panel showing
  name, margins, suppression flags, and row styles (data/header/title)
  with text style, height, and alignment per row type
- New / Delete buttons in the dialog

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-06 14:57:11 +03:00
Hakan SevenandClaude Sonnet 4.6 34076b26bb feat: MLineStyle manager (MLSTYLE command + dialog)
- MLSTYLE command: LIST, NEW, SET, DEL subcommands
- Multiline Style Manager dialog: style list, element details (offset,
  color, linetype), Set Current / New / Delete buttons
- MLINE/ML command now reads document header.multiline_style to apply
  the current style to newly created MLine entities
- MlineCommand.with_style() constructor for style-aware multiline drawing

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-06 14:54:05 +03:00
Hakan SevenandClaude Sonnet 4.6 1db3ad6a33 Feat: implement CTB/STB plot style table with PDF export integration
- src/io/plot_style.rs: PlotStyleTable and PlotStyleEntry data structures;
  CTB reader (deflate/zlib decompressed text format) with ACI→RGB and
  ACI→lineweight lookup; CTB writer (zlib compressed); LW_TABLE constant
- src/io/pdf_export.rs: accept optional PlotStyleTable; apply ACI color
  and lineweight overrides during PDF rendering
- src/scene/wire_model.rs: add `aci: u8` field to carry ACI index
- src/scene/render.rs: render_style() now returns ACI alongside RGBA
- src/scene/mod.rs + tessellate.rs: propagate aci through wire building
- app: PlotStyleLoad/Loaded/Clear messages and handlers;
  PLOTSTYLE LOAD | CLEAR | STATUS command; active_plot_style state on H7CAD
- flate2 added as dependency

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-06 14:37:23 +03:00
Hakan SevenandClaude Sonnet 4.6 911e36ba04 Feat: add Dimension Style Manager dialog (DIMSTYLE/DDIM)
- Add DimStyleDialogOpen/Close/Apply/Select/Tab/New/SetCurrent/Delete
  messages and DsEdit/DsToggle with DsField enum for fine-grained edits
- Store active dialog state (selected style, current tab, edit buffers)
  directly on H7CAD for all 28 most-used DimStyle properties
- dimstyle_overlay: 5-tab modal panel (Lines, Arrows, Text,
  Scale/Units, Tolerances) with style list, Apply and Close buttons
- DIMSTYLE / DDIM with no sub-command now opens the dialog;
  DIMSTYLE LIST / NEW / SET sub-commands remain available

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-06 14:25:13 +03:00
Hakan SevenandClaude Sonnet 4.6 20629d587a Feat: implement WCS↔UCS coordinate transform pipeline
- Add `active_ucs: Option<Ucs>` per-tab state to DocumentTab
- Add `ucs_to_wcs`, `wcs_to_ucs`, `ucs_z_axis`, `ucs_rotated_z` helpers
- Add `Camera::pick_on_plane` for ray–plane intersection against any plane
- Mouse picks project onto the active UCS XY plane instead of world XY
- Typed coordinates are converted from UCS space to WCS before dispatch
- UCS command now really activates/deactivates a UCS:
  - `UCS W` resets to WCS (clears active_ucs)
  - `UCS <name>` activates a named UCS
  - `UCS SAVE <name>` saves the current active UCS
  - `UCS ORIGIN x,y,z` shifts origin (in current UCS space)
  - `UCS X/Y/Z <angle>` rotates the UCS around its own axes

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-06 14:16:06 +03:00
Hakan SevenandClaude Sonnet 4.6 0aef1fc12f Feat: ROADMAP Phase 1-5 batch — trim/extend, plot scale, viewport UX, mline caps, table alignment
- TRIM/EXTEND: Ray and XLine entities supported as cutting boundaries and trim targets;
  trim results in Ray→Line/Ray, XLine→Ray/Ray or Line; hover preview added
- Plot scale override: Fit/1:1/1:2/1:5/1:10/1:20/1:50/1:100/2:1 buttons added to Page Setup
  panel; PageSetupCommit applies scale to PlotSettings
- Viewport UX: locked viewport gets orange border; selected viewport gets white border
- Named view → viewport assignment: Choice dropdown in properties panel copies
  view_target/direction/height to the viewport entity
- MLine caps: perpendicular start/end cap lines added for open (non-closed) MLines
- Wipeout polygon grips: boundary vertices become editable grips when clipping_enabled+Polygonal;
  world→pixel back-projection on drag
- Table cell alignment: CellStyle.alignment (1-9) drives left/center/right + top/middle/bottom
  text positioning; cxf::measure_text() helper added
- New commands/features: DIMCONTINUE (DCO), DIMBASELINE (DBA), TOLERANCE (TOL), TABLE,
  ATTDEF, ATTEDIT, ATTDISP, BREAKATPOINT (BAP), PLOTWINDOW (PW), MLINE (ML);
  DIMSTYLE/DIMCURRENT/CLAYER/LTSCALE/CELTSCALE/SCALETEXT/XDATA/UCSICON/REGEN/DRAWORDER extended
- PLINE arc mode: A/L/CLOSE text input, bulge computation, arc preview
- Warning cleanup: removed unused imports and unreachable patterns

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-03 15:31:05 +03:00
Hakan SevenandClaude Sonnet 4.6 36bda2ac2b Feat: viewport UCS name picker from document UCS table
- properties.rs: inject 'UCS Name' Choice property for viewports when
  document.ucss is non-empty; resolves current handle to display name
- update.rs: intercept PropGeomChoiceChanged for 'vp_ucs_name'; clones
  UCS origin/x_axis/y_axis into viewport and sets ucs_handle — no
  trait signature change required

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-01 00:30:45 +03:00
Hakan SevenandClaude Sonnet 4.6 1aa44ac987 Fix: remove unused imports and suppress dead_code warnings
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-01 00:15:58 +03:00
Hakan SevenandClaude Sonnet 4.6 617d7ba56a Feat: Phase 2 — expanded PageSetup panel and PlotSettings integration
PageSetup panel:
- Paper size presets (A4/A3/A2/A1/A0 portrait+landscape, Letter)
- Plot area selector: Layout vs Extents
- Center-on-page toggle
- Plot offset X/Y fields
- Rotation picker: 0° / 90° / 180° / 270°

PlotSettings (acadrust object):
- PageSetupCommit finds or creates a PlotSettings object in the document
- Writes paper size, plot type, centering, offset, rotation to it
- DXF round-trip: PlotSettings persisted to file

PDF export:
- Reads PlotSettings for the active layout
- Applies centering (auto-computes offset from wire extents)
- Applies offset X/Y from PlotSettings
- Applies rotation via PDF CTM transformation matrix
- Swaps paper dimensions for 90°/270° rotation

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-04-01 00:12:07 +03:00
Hakan SevenandClaude Sonnet 4.6 748d90af7e Fix: disable snap during entity-pick and selection-gathering modes
Snap is now suppressed (both cursor indicator and coordinate snapping)
when a command is in entity-pick mode (needs_entity_pick) or
selection-gathering mode (is_selection_gathering), and restored
automatically when the mode ends.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-31 23:05:24 +03:00
Hakan SevenandClaude Sonnet 4.6 9cee12d1c7 Feat: PSPACE/MSPACE interaction isolation + paper-space drawing
Selection, snapping and editing are now mode-aware:

PSPACE (paper layout, no active viewport)
- Only paper-space entities (viewport borders, title blocks, etc.) are
  hit-testable and selectable. Viewport content wires are invisible to
  the interaction layer.
- Drawing commands add entities to the paper-space layout block so
  annotations/title blocks land on the sheet, not in model space.

MSPACE (active viewport entered)
- Only model-space entities visible through the active viewport are
  hit-testable. Other viewports' content and paper entities are ignored.
- Drawing commands add entities to model space (correct DXF block).
- Snap results from projected viewport-content wires are converted from
  paper-space back to model-space via paper_to_model so that placed
  coordinates and command previews are consistent.

Entering/exiting MSPACE clears the current selection so no stale
cross-space selection is carried over.

Implementation:
- Scene::hit_test_wires() returns mode-filtered wires for all
  hit-tests, snaps, and selections (entity_wires() still returns
  everything for rendering and PDF export).
- viewport_content_wires() gains an Option<Handle> filter to render
  only the active viewport's content for MSPACE hit-testing.
- Scene::add_entity() routes to the paper-layout block or model-space
  block depending on current_layout / active_viewport.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-31 13:07:25 +03:00
Hakan SevenandClaude Sonnet 4.6 0beb589f2c Fix: viewport MSPACE activation and navigation
Four bugs prevented viewports from working like AutoCAD model-space windows:

1. Dead-code double-click block: `!is_down2` was always false because
   `is_down2 = sel.left_down` is captured while the button is still held
   (before the selection block clears it). Changed to `is_down` so the
   double-click handler actually fires.

2. Inverted pan direction: pan_active_viewport used `-=` on the delta
   returned by screen_delta_to_world, which is the same delta that cam.pan
   *adds* to its target — causing reversed drag. Changed to `+=`.

3. Zoom not cursor-centered: zoom_active_viewport now accepts an optional
   paper-space cursor position and adjusts view_target so the model point
   under the cursor stays fixed (same as cam.zoom_about_point).

4. ESC did not exit MSPACE: CommandEscape now calls ExitViewport when
   active_viewport is set and no command is running.

Also added MS/MSPACE and PSPACE command aliases, and MspaceCommand /
PspaceCommand messages so MS auto-enters the first viewport.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-31 12:52:07 +03:00
Hakan SevenandClaude Sonnet 4.6 845770938c Fix: paper limits, Cohen-Sutherland clipping, frozen layers UI, PDF improvements
Paper limits:
- Change A4 fallback from 12×9 to 297×210 mm in paper_limits()

Context menu:
- Translate layout context menu labels to English (Rename / Delete)

Viewport clipping:
- Replace AABB-only culling with proper Cohen-Sutherland line clipping
  in viewport_content_wires(); each projected segment is now clipped at
  the exact viewport boundary instead of being included or discarded whole
- Add cs_clip() and clip_polyline_to_rect() free functions in scene/mod.rs

Frozen layers per-viewport UI:
- Inject a "Frozen Layers" EditText property in the Properties panel for
  viewport entities (layer names resolved from handles at display time)
- Handle "frozen_layers" in PropGeomCommit: parse comma-separated names,
  resolve to layer handles, update vp.frozen_layers in-place

PDF export improvements:
- Add offset_x/offset_y params to export_pdf() for model-space normalization:
  coordinates are shifted so the drawing origin maps to the page origin
- Model space export computes extents via model_space_extents() (now public)
  and adds a 5 % margin; falls back to A4 landscape for empty drawings
- Skip __paper_boundary__ wire in PDF (white background covers it)
- Map yellow (active viewport border) → black and cyan (vp border) → dark
  blue for print-friendly output

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-31 08:18:29 +03:00
Hakan SevenandClaude Sonnet 4.6 e1d296da10 Phase 7: Plot settings and PDF export
- Add printpdf 0.9.1 dependency for native PDF generation.
- New src/io/pdf_export.rs: converts paper-space WireModels to a PDF
  page (per-wire stroke color, line weight in Pt, NaN-split segments).
  White/near-white colors are inverted to black for print output.
- Add PlotExport / PlotExportPath messages: opens a save-file dialog
  and writes a .pdf next to the drawing file.
- Add PageSetupOpen/Close/WidthEdit/HeightEdit/Commit messages: a
  centered modal panel lets the user enter paper width and height (mm);
  on commit the Layout object's min/max_limits are updated in-place.
- Register PRINT / PLOT / EXPORT and PAGESETUP (PS) commands in
  dispatch_command; fix MVIEW error message to English.
- Layout ribbon gains a "Plot" group with Page Setup and Export PDF
  ribbon buttons.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-31 08:05:17 +03:00
Hakan SevenandClaude Sonnet 4.6 523ba74c10 Phase 3: Active viewport MSPACE/PSPACE workflow
- Add active_viewport: Option<Handle> field to Scene
- Add EnterViewport(Handle) and ExitViewport messages
- Double-click on a user viewport (id > 1) enters MSPACE;
  double-click on empty area while in MSPACE exits to PSPACE
- MSPACE middle-drag pans the viewport's model-space view (view_target)
- MSPACE scroll zooms the viewport's view_height / custom_scale
- Drawing commands inside MSPACE receive model-space coordinates
  via paper_to_model() coordinate transform
- Active viewport rendered with yellow dashed border (vs. cyan solid)
- Camera screen_delta_to_world helper for MSPACE pan conversion
- LayoutSwitch clears active_viewport

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-31 07:24:16 +03:00
Hakan SevenandClaude Sonnet 4.6 9b14719ec5 Aşama 1: Layout yönetim UI — yeniden adlandırma, silme, context menüsü
- Layout sekme sağ-tıklamasında context menüsü (Yeniden Adlandır / Sil)
- Inline rename: sekme metin-giriş alanına dönüşür, Enter ile commit, ✕ ile iptal
- LayoutDelete: layout ve sahip olduğu tüm entity'leri kaldırır
- LayoutRename: Layout nesnesinin adını yerinde günceller
- LayoutCreate çakışma koruması: mevcut isimler arasında benzersiz ad bulur
- Escape tuşu açık rename/context menüsünü kapatır

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-31 07:13:36 +03:00
Hakan SevenandClaude Sonnet 4.6 ed9cbc2092 Refactor src/main.rs into modular src/app/ structure
Split the 4500-line main.rs into focused submodules under src/app/:
- mod.rs: H7CAD struct, Message enum, boot/new/run
- document.rs: DocumentTab, HistorySnapshot, HistoryState
- helpers.rs: pure helper functions
- history.rs: undo/redo logic
- properties.rs: properties panel logic
- layers.rs: layer sync
- commands.rs: dispatch_command
- cmd_result.rs: apply_cmd_result
- view.rs: view, subscription, tab bar
- update.rs: update message handler

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-03-22 22:44:32 +03:00