Commit Graph
11 Commits
Author SHA1 Message Date
PanosandClaude Opus 5 e623c053ab feat(ui): compatible right-click context menu driven by command options
The viewport context menu is now built from a pure model
(ui::popup::context_menu) rendered by the overlay: while a command runs it
offers Enter / Cancel / every keyword of the command's options() with the
keyword shown as a hint, a Recent Input submenu and M2P; when idle it offers
Repeat, Recent Input, Clipboard, Undo/Redo with history labels, the edit
block (Erase/Move/Copy/Scale/Rotate/Mirror/Draw Order), Isolate, Pan/Zoom,
selection tools, Properties and Options. The default row is anchored under
the pointer and the menu is keyboard-navigable (arrows, Enter, mnemonic
letters; any other key closes it and types into the command line).

Right-click behaviour is a user preference (Options → User Preferences,
SHORTCUTMENU / SHORTCUTMENUDURATION): shortcut menu (commercial solutions default),
time-sensitive, or the previous Enter-first cycle.

LINE gains options() (Close/Undo/eXit).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 12:05:14 +03:00
Karim Jerbi 58c9fcb748 perf(bench): introduce standardized 25-metric CAD and UI benchmark suite
- Add comprehensive performance benchmark harness in benches/performance_benchmarks.rs
  configured with harness = false in Cargo.toml (runs via cargo bench in --release,
  isolated from cargo test).
- Benchmark coverage across 25 distinct CAD & UI operations:
  * Entity Ingestion, GPU Wire Partitioning, Analytical & Wide/Tapered Arc Tessellation
  * 100x Zoom Navigation, Spatial InteractionIndex, Multi-mode Hit-Testing, OSnap Tracking
  * 2D Parametric Dogleg Constraint Solving, DXF Import/Export Throughput
  * UI Ribbon View Construction, Viewport Grid Projection, Grid Cache Evaluation
  * Themed SVG Icon Lookup Caching, Cold Extents AABB Calculation
  * Batch Entity Transformation, Draworder Depth Map Full/Patch, Delta-Undo Recording
- Expose internal calculation hooks with #[doc(hidden)] pub to prevent API leakage.
- Remove 644 lines of legacy, scattered ad-hoc #[test] #[ignore] benchmarks across src/.
- Add developer and regression documentation in benches/README.md.
2026-09-12 13:46:01 +01:00
Karim Jerbi 46190ccba1 refactor(selection): migrate Scene.selection to Arc<RefCell> to avoid per-frame deep clone
Scene.selection was Rc<RefCell<SelectionState>> (31 fields, ~1.6KB
with poly_points) cloned deep per view_main per pane via
(*sel_ref).clone() at view/mod.rs:760. Replace with
Arc<RefCell<SelectionState>> (Arc::new(RefCell::new(...)) at
scene/mod.rs:1436,1868), SelectionCanvas holds Arc<RefCell> and
selection_overlay takes Arc<RefCell> (overlay.rs:365,415),
view_main does Arc::clone(&tab.scene.selection) (atomic bump)
instead of deep clone. sel_ref stays borrowed for field reads
(vp_size etc.).

Bench (release, n=5000): SelectionState::clone 39-68ns (64pts) /
11-22ns (0pts) vs Arc::clone 7ns — 5-9x on the hot path.

Tests:
- selection_is_arc_not_refcell: asserts type_name contains Arc
- bench_selection_state_clone / bench_selection_arc_clone / bench_selection_state_clone_empty (ignored, release)
2026-09-02 22:14:32 +01:00
ramox81 708c30831c Capture pointer input during grip edits 2026-09-02 15:21:57 +03:00
Hakan SevenandClaude Opus 5 5c5c7606a1 feat(select): offer the selection modes at "Select objects"
Only Previous and Last were on offer, so Window, Crossing, Fence, the two
polygons and All could not be reached at all -- and with no keyboard to
type them into, the buttons were the only way in.

Window and Crossing fix the sense of the next box. Dragging derives that
from the direction the corner travels and would overwrite it the moment
the corner moved, so the derivation stands down while a keyword holds it.
Add and Remove decide what a pick does for the rest of the round: Remove
subtracts the way Shift already does, rather than through PICKADD, which
decides whether a pick *replaces* the set and so would have wiped
everything gathered so far. Both are dropped when the next command
starts, since neither outlives the selection that asked for them.

Fence and the polygons are picked point by point, which TRIM and EXTEND
already ask for. That gesture -- the points, the rubber-banded dashed
preview, whether the path closes -- moves into one place both bind to,
and the two preview builders duplicated in trim.rs go with it.

A fence is not the polygon test with crossing set: that closes the point
list and counts whatever lies inside, so a line drawn past a row of
objects would take everything behind it too. It gets a hit test that only
counts a real intersection, and skips the area-based geometry entirely.

The lasso gathered its hits from wires, hatches, block hatches, meshes and
block meshes inline; the new modes need the same list, and a second copy
would drift. Both now come through `Scene::path_hit_handles`.

Closes #596

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 13:32:11 +03:00
Hakan SevenandClaude Opus 4.8 e015fbe328 fix(stretch): free crossing-window corners from Ortho, draw filled marquee (#291)
STRETCH picks its crossing window as two corner points. After the first
corner set last_point, Ortho/Polar constrained the opposite corner to an axis
through it, collapsing the window to a line and making selection impossible.

Add CadCommand::window_corner_pick(); STRETCH returns true for its two window
steps, and the viewport skips the ortho/polar (and OTRACK) lock for that point
in both the preview and commit paths — the corners are now free.

Also render the window like a normal box selection instead of a bare green
outline: add SelectionState::preview_box (a hit-test-free marquee), draw it
with the shared draw_marquee helper (green crossing fill + stroke), and drive
it from the command's new window_first_corner(). Cleared on command end.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 13:32:32 +03:00
Hakan SevenandClaude Opus 4.8 98aa051a74 feat(nav): turntable orbit, selection/cursor pivot, Shift+MMB rotate (#229)
Rework 3D view navigation:

- Turntable / lock-horizon orbit: horizontal drag yaws about world +Z,
  vertical drag pitches about the horizontal camera-right axis, so the
  view never banks. Pitch is pole-clamped but the straight-down default
  view can still be tilted out of.
- Orbit centre: the selection's centre when something is selected,
  otherwise the point under the cursor — no longer only the file centre.
  The camera revolves rigidly about the pivot, so it stays put on screen
  and the view doesn't jump.
- Mouse scheme: Zoom = wheel, Pan = MMB, Rotate = Shift+MMB. Right-drag
  no longer orbits (right-click stays context menu / Enter). Floating
  viewports orbit with Shift+MMB too.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 21:58:04 +03:00
Hakan SevenandClaude Opus 4.8 c303900bd2 fix(select): pin box-selection anchor to the world during zoom/pan (#234)
The window/crossing selection anchor was stored only in screen pixels, so
zooming or panning mid-drag left it frozen while the drawing moved under
it — the rectangle then covered the wrong world area and selected too much
or too little.

Store the anchor's world point and re-project it to the screen anchor
whenever the model-space view zooms (on_viewport_scroll) or pans
(on_viewport_move), so the rectangle tracks the drawing. The moving corner
already follows the cursor. (MSPACE floating-viewport box-select would
need the viewport camera and is left as-is.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 21:10:04 +03:00
Hakan SevenandClaude Opus 4.8 b691854e7a feat(viewport): RMB 1st=Enter, 2nd=menu (no setting)
Replaces the opt-in `rmb_enter` setting (and `RMBENTER` command) with
always-on behavior. While a command is active, the first viewport
right-click acts as Enter (commit / close) and a second consecutive
right-click opens the context menu instead. Idle right-click still opens
the menu; right-drag still orbits.

The cycle is tracked per tab (`right_click_entered`) and restarts on any
other interaction — a left-click pick, a new command, an orbit, or
leaving the viewport — so the next right-click is Enter again.

Refines #185.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 16:32:40 +03:00
Hakan SevenandClaude Opus 4.8 098585bb2d feat(viewport): RMB=Enter option + timed right-click
Adds a configurable right-mouse-button behavior without disturbing orbit
or the context menu.

- New persisted setting `rmb_enter` (command `RMBENTER [ON|OFF]`, default
  off): when on, a right-click while a command is active acts as Enter
  (commit/close); when idle it still opens the context menu. Right-drag
  always orbits, so nothing is lost.
- Right-click vs orbit is now time-based: orbit engages only after the
  button is held >=150ms and the pointer moves, so a quick right-click is
  no longer swallowed by slight pointer jitter (was an 8px distance gate).
- The right-click Repeat menu now lists commands from every source
  (command line, ribbon, context menu, shortcuts) via a unified
  recents list recorded at the dispatch choke point, instead of only
  typed commands.

Closes #185

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 16:16:08 +03:00
Hakan SevenandClaude Opus 4.8 9b8ee94c0c refactor: rename mislabeled scene files to match contents
Two names collided with the pick subsystem and misdescribed their files:

- scene/hittest.rs -> scene/camera_ops.rs. Its contents are camera/view
  operations (zoom, fit-all, named-view restore, camera<->document sync,
  per-tile grid/snap), not hit-testing — the real screen-space hit-test
  lives in scene/pick/hit_test.rs.
- scene/pick/selection.rs -> scene/pick/selection_state.rs. It holds only
  the SelectionState struct; the name clashed with scene/selection.rs
  (the Scene selection operations).

Callers are unaffected (the crate::scene::SelectionState re-export path is
unchanged). No behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 23:45:16 +03:00