Multi-functional grip popup expansion
- Custom hover menus for every remaining entity: Polyline / Polyline2D / Polyline3D, Spline, MLine, Hatch, Leader, MultiLeader, Text, MText. New
GripMenuActionvocabulary covers Add / Remove Vertex, Refine Vertices, Tangent Direction, Origin Point / Hatch Angle / Hatch Scale, Move with Text, Stack / Unstack, Move with Leader / Move Independent. - Spline CV grips support Add / Remove Vertex (chord-midpoint insertion, weights kept in sync, knots cleared so to_truck rebuilds a uniform knot vector) plus Refine Vertices (inserts a CV between every adjacent pair).
- Hatch centroid grips expose Origin Point / Hatch Angle / Hatch Scale; Angle (degrees → radians) and Scale (positive scalar) prompt for a value on the command line.
- Leader path-vertex grips add / remove intermediate vertices; arrow head and centroid stay Stretch-only. MultiLeader text-location grips offer Move-with-Leader / Move-Independent (menu vocabulary live, structural multi-leader edits stubbed).
- Text / MText insertion grips add Move with Text and Rotate (Rotate prompts for degrees and rewrites the entity rotation). MText width grip stays Stretch-only.
Spline,LeaderandMultiLeaderare converted from theimpl_entity_basics!macro to manual trait impls sogrip_menucan be overridden per entity.
Quick Select / Select Similar (#28)
- New right-click context-menu entry Select Similar (or
SELECTSIMILAR/SELSIM) walks the active layout and, for every (entity type, layer) pair already in the selection, adds every matching entity. The seed selection stays selected; matches already selected are not double-counted. - New right-click Quick Select… (or
QSELECT/QS) opens a centred floating panel with the classic single-filter shape: Object type → Property → Operator → Value, plus an Append-to-current-selection checkbox.- The Property dropdown is type-aware: always lists the common four (Layer, Color, Linetype, Lineweight); selecting a specific Object type appends that type's
geometry_propertiesrows (Start X, Length, Radius, Pattern Angle, …) sampled from the first entity of that type in the active layout. Changing the Object type drops the Property when the new type no longer offers it. - Operators:
= Equals,!= Not equal,> Greater than,< Less than,* Any value. Eq / Neq are case-insensitive string compares; Gt / Lt parse both sides as f64 and reject anything non-numeric; Any skips the value test. The Value field is disabled while no Property is picked or the operator is Any. - Scope is the entire active layout, so a paper-layout filter never reaches into model-space entities (and vice versa). Common-property values are canonicalised (
ByLayer/ByBlock/<aci>/r,g,bfor colour;0.30mmfor lineweight) so the typed value matches what the panel will show.
- The Property dropdown is type-aware: always lists the common four (Layer, Color, Linetype, Lineweight); selecting a specific Object type appends that type's
Right-click context menu rebuild
- The context menu used to be anchored in window-relative coordinates while the cursor position it followed was canvas-relative — the menu drifted away from the cursor by the size of the surrounding ribbon and side panels. Moved inside
viewport_stackso the anchor resolves in the same coordinate space the cursor was captured in. - New shared
position_canvas_overlay(anchor, panel)helper wraps a panel in fixed-width spacers andiced::widget::opaque(panel)so events on the menu itself don't fall through to the viewport mouse area. The multi-functional grip popup is rewritten to use the same helper. - Outside-click dismiss mirrors the grip popup:
ViewportLeftPresschecksselection.context_menu.take()at the top and returns early when it was set, so a press that reaches the viewport mouse area (i.e. outside the opaque panel) closes the menu without running the rest of the left-click handler. - Right-drag threshold for orbit was 3 px squared — small enough that normal hand jitter promoted a click-and-release to an orbit drag and the menu never opened. Bumped to 8 px squared.
Message::ViewportExitno longer clearscontext_menu. With the menu now living above the viewport mouse area, the opaque panel capturing the cursor fired the underlying area's exit handler — which closed the menu the instant it opened.
Layer command refresh (#42)
- Eight layer-state commands (
LAYOFF,LAYFRZ,LAYLCK,LAYULK,LAYON,LAYTHW,LAYISO,LAYUNISO) mutateddocument.layersdirectly and calledrefresh_layer_panel()— but never bumped the scene's geometry epoch. The 3D viewport caches its uploaded geometry by that epoch, so visibility / freeze changes only took effect once something else triggered a re-render (pressing Esc was the workaround because the Esc handler callsdeselect_all(), which bumps geometry). - Each command branch now calls
scene.bump_geometry()after the layer mutation loop so the viewport repaints immediately.
File associations + Windows installer (#36)
- The boot task now consumes
std::env::args_os().nth(1)as a path and dispatchesMessage::OpenRecent, so a file passed on the command line opens after startup. Flag-style args are ignored, and a bogus path lands as a clean command-line error. - Linux: the AppImage's desktop entry adds
image/vnd.dwgalongside the existingimage/vnd.dxfMIME type and grows a%fplaceholder inExec=so the launcher forwards the picked file path. macOSInfo.plistalready declared the DWG / DXF UTIs, so combined with the argv-handling change a Finder double-click now opens the file. - Windows ships a new MSI installer alongside the bare exe: per-machine install to
Program Files\Open CAD Studio, Start Menu shortcut,MajorUpgradeso newer MSIs replace older ones, and a single ProgID that owns both.dwgand.dxfand launches the exe with the file asargv[1]. The icon is converted from the SVG logo to a multi-resolution ICO at build time. The release page now exposes both…-windows-x86_64-portable.exeand…-windows-x86_64-installer.msi.
DX12 / FXC shader crash on Windows (#31)
- Both hatch fragment shaders ended
fs_mainwith a barediscard;after the pattern-match for-loop fell through without matching. naga (the Linux/Vulkan path) accepts that; DX12's FXC compiler (default on Windows) rejects it withX3507: 'fs_main': Not all control paths return a valueand took the entire pipeline create-down on every drawing open. Append an unreachablereturn vec4<f32>(0.0);after each terminaldiscard;so every control path syntactically ends in a return.
Update-check delay
- GitHub Actions takes ~15 min to build and attach the platform binaries after a tag is pushed, but the latest-release API returns the tag the moment it is published — users were getting a popup pointing at a release page whose asset list was still empty. The check now parses
published_atand suppresses the notification while the release is younger than 30 minutes.
Full Changelog: v0.4.4...v0.4.5