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

+10
View File
@@ -727,6 +727,16 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
crate::app::expr_eval::eval_to_string(&raw)
};
self.command_line.input.clear();
// Remember the token for the context menu's Recent Input
// list (prose steps excluded: a table cell or text body
// is not a reusable value).
let is_prose = self.tabs[i]
.active_cmd
.as_ref()
.is_some_and(|c| c.input_kind().is_free_text());
if !is_prose {
self.command_line.record_recent_input(&text);
}
// Offer the typed text to the command's option handler
// first (keywords like PLINE's A/L/C, a radius, …). If it