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 <[email protected]>
This commit is contained in:
PanosandClaude Opus 5 committed 2026-09-17 12:05:14 +03:00
1 parent 65c0fe5494
commit e623c053ab
19 files changed
+2019 -199

No files matched your search

+8
View File
@@ -146,6 +146,12 @@ pub(super) struct DocumentTab {
pub(super) selected_grip_handles: Vec<Handle>,
/// Shift-selected grips, keyed by entity and object-local grip id.
pub(super) hot_grips: rustc_hash::FxHashSet<(Handle, usize)>,
/// Grip-mode "Copy" toggle (context menu): each grip placement leaves the
/// original in place and adds a modified copy, until Enter / Esc.
pub(super) grip_copy: bool,
/// Grip-mode "Base Point" (context menu): the next left-click re-bases
/// the active grip edit instead of committing it.
pub(super) grip_base_pending: bool,
pub(super) selected_handle: Option<Handle>,
/// Dynamic-block visibility grip for the current single selection.
pub(super) visibility_grip: Option<super::visibility::VisibilityGrip>,
@@ -601,6 +607,8 @@ impl DocumentTab {
selected_grips: vec![],
selected_grip_handles: vec![],
hot_grips: rustc_hash::FxHashSet::default(),
grip_copy: false,
grip_base_pending: false,
selected_handle: None,
visibility_grip: None,
wireframe: false,