forked from 1b-agent/opencadstudio-upstream
ui: neutral wording in code and help text; keywords first in the command menu
Comments and the Options help text describe the behaviour of commercial solutions without naming any product. The command menu puts the command's keywords directly under Enter / Cancel, with Recent Input and Snap Overrides below them, so the choices that change from step to step are the closest to the pointer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
02cd98e790
commit
0fbb5bcb4f
35 files changed
+83
-81
No files matched your search
@@ -63,7 +63,7 @@ impl OpenCADStudio {
|
||||
// routing, so every path below (Start-tab gate, plugins, all dispatch
|
||||
// families, the Repeat menu) sees the canonical command. Arguments after
|
||||
// the first space are left untouched. A non-alias passes through as-is.
|
||||
// AutoCAD's transparent prefix: `'PAN` / `'ZOOM` run in the middle
|
||||
// The transparent prefix of commercial solutions: `'PAN` / `'ZOOM` run in the middle
|
||||
// of another command and hand control back to it afterwards.
|
||||
let (cmd, quoted) = match cmd.trim().strip_prefix('\'') {
|
||||
Some(rest) => (rest.trim(), true),
|
||||
|
||||
@@ -1492,9 +1492,9 @@ impl OpenCADStudio {
|
||||
Ok((format!("ZOOMFACTOR = {}", self.zoom_factor), false))
|
||||
}
|
||||
},
|
||||
// AutoCAD bit code: 0 = no shortcut menus (right-click
|
||||
// Bit code of commercial solutions: 0 = no shortcut menus (right-click
|
||||
// is Enter), 16 = time-sensitive; everything else is the
|
||||
// regular shortcut menu. Reported as AutoCAD's defaults
|
||||
// regular shortcut menu. Reported as the defaults of commercial solutions
|
||||
// (11 = default+edit+command menus, +16 when
|
||||
// time-sensitive).
|
||||
"SHORTCUTMENU" => {
|
||||
|
||||
+3
-3
@@ -132,16 +132,16 @@ impl CursorType {
|
||||
}
|
||||
}
|
||||
|
||||
/// What a right-click in the drawing area does (AutoCAD SHORTCUTMENU /
|
||||
/// What a right-click in the drawing area does (SHORTCUTMENU in commercial solutions /
|
||||
/// "Right-click Customization").
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum RightClickMode {
|
||||
/// AutoCAD default: a right-click always opens the shortcut menu (Enter /
|
||||
/// The default of commercial solutions: a right-click always opens the shortcut menu (Enter /
|
||||
/// Cancel / the command's options while a command runs; Repeat / edit
|
||||
/// tools when idle).
|
||||
#[default]
|
||||
ShortcutMenu,
|
||||
/// AutoCAD "time-sensitive right-click": a quick click is Enter (or
|
||||
/// The "time-sensitive right-click" of commercial solutions: a quick click is Enter (or
|
||||
/// repeats the last command when idle); holding the button longer than
|
||||
/// `right_click_hold_ms` opens the shortcut menu.
|
||||
TimeSensitive,
|
||||
|
||||
@@ -234,7 +234,7 @@ impl OpenCADStudio {
|
||||
/// when the message was consumed; `None` lets it fall through to the
|
||||
/// normal handlers (after closing the menu when the key is not a menu key,
|
||||
/// so typing a command name or a coordinate just works — the menu gets
|
||||
/// out of the way exactly as it does in AutoCAD).
|
||||
/// out of the way exactly as it does in commercial solutions).
|
||||
pub(in crate::app) fn intercept_context_menu_key(&mut self, msg: &Message) -> Option<Task<Message>> {
|
||||
match msg {
|
||||
Message::ArrowKeyPressed { direction, .. }
|
||||
@@ -308,7 +308,7 @@ impl OpenCADStudio {
|
||||
None
|
||||
}
|
||||
|
||||
/// Grip-mode shortcut menu (AutoCAD's grip menu): the grip stays hot
|
||||
/// Grip-mode shortcut menu (the grip menu of commercial solutions): the grip stays hot
|
||||
/// for Stretch / Base Point / Copy / Undo; Move / Rotate / Scale / Mirror
|
||||
/// hand the selection to the matching command with the grip as its base
|
||||
/// point; Exit drops the edit.
|
||||
|
||||
@@ -304,7 +304,7 @@ impl OpenCADStudio {
|
||||
}
|
||||
// The open right-click context menu owns the keyboard the same way:
|
||||
// arrows / Enter / mnemonic letters drive it, any other key closes it
|
||||
// and falls through to the command line (AutoCAD behaviour).
|
||||
// and falls through to the command line (the behaviour of commercial solutions).
|
||||
if self.context_menu_open() {
|
||||
if let Some(task) = self.intercept_context_menu_key(&msg) {
|
||||
return task;
|
||||
@@ -3582,7 +3582,7 @@ impl OpenCADStudio {
|
||||
return self.update(Message::CommandFinalize);
|
||||
}
|
||||
// A right-click. What it does is the user's choice (Options →
|
||||
// User Preferences, AutoCAD's SHORTCUTMENU):
|
||||
// User Preferences, SHORTCUTMENU in commercial solutions):
|
||||
// • Shortcut menu — always open the context menu, whose
|
||||
// default row (Enter / Repeat) sits under the pointer.
|
||||
// • Time-sensitive — a quick click is Enter while a command
|
||||
@@ -3607,7 +3607,7 @@ impl OpenCADStudio {
|
||||
sel.right_click_entered = true;
|
||||
drop(sel);
|
||||
// CommandFinalize is Enter during a command and "repeat
|
||||
// the last command" when idle — exactly AutoCAD's quick
|
||||
// the last command" when idle — exactly the quick
|
||||
// right-click.
|
||||
return self.update(Message::CommandFinalize);
|
||||
}
|
||||
|
||||
@@ -6237,7 +6237,7 @@ properties={:.1}ms picked={}",
|
||||
|
||||
/// Grip-menu Copy: leave the originals where they were and add the
|
||||
/// edited shapes as new entities, then re-arm the same grip at its
|
||||
/// origin so the next placement makes another copy (AutoCAD grip Copy).
|
||||
/// origin so the next placement makes another copy (grip Copy, as in commercial solutions).
|
||||
fn commit_active_grip_edit_as_copy(&mut self, grip: GripEdit) -> Task<Message> {
|
||||
let i = self.active_tab;
|
||||
let handles = std::mem::take(&mut self.grip_preview_handles);
|
||||
|
||||
@@ -1150,7 +1150,7 @@ fn context_menu_gutter(icon: Option<MenuIcon>) -> Element<'static, Message> {
|
||||
/// Render the right-click context menu (rows from
|
||||
/// `ui::popup::context_menu::build_context_menu`). The panel is placed so the
|
||||
/// default row sits under the pointer: right-click then left-click in place
|
||||
/// completes the step without moving the mouse (AutoCAD anchors its shortcut
|
||||
/// completes the step without moving the mouse (commercial solutions anchor their shortcut
|
||||
/// menu the same way). `highlighted` is the keyboard highlight, if any.
|
||||
pub(super) fn viewport_context_menu_overlay(
|
||||
pos: iced::Point,
|
||||
|
||||
@@ -5131,7 +5131,7 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
|
||||
"Right-click Customization" => Some(("options", "right-click-customization")),
|
||||
"Right-click in drawing area" => Some(("options", "right-click-in-drawing-area")),
|
||||
"Hold duration" => Some(("options", "hold-duration")),
|
||||
"Shortcut menu: right-click always opens the menu (AutoCAD default). Time-sensitive: a quick click is Enter, holding longer opens the menu (SHORTCUTMENUDURATION)." => Some(("options", "right-click-mode-help")),
|
||||
"Shortcut menu: right-click always opens the menu. Time-sensitive: a quick click is Enter, holding longer opens the menu (SHORTCUTMENUDURATION)." => Some(("options", "right-click-mode-help")),
|
||||
"Shortcut menu" => Some(("options", "right-click-mode-shortcut-menu")),
|
||||
"Time-sensitive (quick click = Enter)" => Some(("options", "right-click-mode-time-sensitive")),
|
||||
"Enter first, second click = menu" => Some(("options", "right-click-mode-enter-first")),
|
||||
|
||||
@@ -411,9 +411,9 @@ impl CadCommand for ArcCSECommand {
|
||||
}
|
||||
}
|
||||
|
||||
// ── ARC: AutoCAD prompt flow ──────────────────────────────────────────────
|
||||
// ── ARC: compatible prompt flow ───────────────────────────────────────────
|
||||
//
|
||||
// The plain ARC command follows AutoCAD's prompts, so every keyword a user
|
||||
// The plain ARC command follows the prompts of commercial solutions, so every keyword a user
|
||||
// knows is there at the same step:
|
||||
// Specify start point of arc or [Center]
|
||||
// Specify second point of arc or [Center/End]
|
||||
@@ -620,7 +620,7 @@ impl CadCommand for ArcCommand {
|
||||
CmdResult::NeedPoint
|
||||
}
|
||||
ArcStep::EndSC { s, c } => self.commit(self.sc_end(s, c, pt)),
|
||||
// At a typed prompt a pick reads as AutoCAD does: the cursor's
|
||||
// At a typed prompt a pick reads as commercial solutions do: the cursor's
|
||||
// direction from the centre (angle) or its distance (length,
|
||||
// radius), the cursor itself for a direction / sagitta.
|
||||
ArcStep::AngleSC { s, c } => {
|
||||
@@ -726,7 +726,7 @@ impl CadCommand for ArcCommand {
|
||||
fn on_enter(&mut self) -> CmdResult {
|
||||
match self.step {
|
||||
// Enter at the start prompt: continue tangent from the last
|
||||
// line or arc, as AutoCAD does.
|
||||
// line or arc, as commercial solutions do.
|
||||
ArcStep::Start => CmdResult::Dispatch("ARC_CONT".into()),
|
||||
_ => CmdResult::Cancel,
|
||||
}
|
||||
@@ -1997,7 +1997,7 @@ mod acad_flow_tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prompts_follow_autocad_keywords() {
|
||||
fn prompts_follow_compatible_keywords() {
|
||||
let mut cmd = ArcCommand::new();
|
||||
assert_eq!(keywords(&cmd), ["C"]);
|
||||
cmd.on_point(p(0.0, 0.0));
|
||||
|
||||
@@ -73,7 +73,7 @@ impl CadCommand for LineCommand {
|
||||
|
||||
fn options(&self) -> Vec<crate::command::CmdOption> {
|
||||
use crate::command::CmdOption;
|
||||
// Mirrors AutoCAD's LINE prompt: Undo once a point is placed, Close
|
||||
// Covers the LINE prompt of commercial solutions: Undo once a point is placed, Close
|
||||
// once a closing segment is possible, eXit always.
|
||||
match self.points.len() {
|
||||
0 => Vec::new(),
|
||||
@@ -201,7 +201,7 @@ impl CadCommand for LineCommand {
|
||||
}
|
||||
}
|
||||
// eXit: end the command keeping every segment drawn so far
|
||||
// (AutoCAD LINE's third keyword).
|
||||
// (the third LINE keyword of commercial solutions).
|
||||
"X" | "EXIT" => Some(CmdResult::Cancel),
|
||||
"U" | "UNDO" => {
|
||||
if self.points.len() >= 2 {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Polyline tool — ribbon definition + interactive command.
|
||||
//
|
||||
// Command: PLINE (PL)
|
||||
// Each click adds a vertex. Keywords follow AutoCAD:
|
||||
// Each click adds a vertex. Keywords match commercial solutions:
|
||||
// Line mode: Arc / Close / Halfwidth / Length / Undo / Width
|
||||
// Arc mode: Angle / CEnter / CLose / Direction / Halfwidth / Line /
|
||||
// Radius / Second pt / Undo / Width
|
||||
@@ -42,7 +42,7 @@ enum SegMode {
|
||||
Arc,
|
||||
}
|
||||
|
||||
/// A keyword sub-step inside PLINE (AutoCAD's option prompts). `None` is the
|
||||
/// A keyword sub-step inside PLINE (the option prompts of commercial solutions). `None` is the
|
||||
/// regular "specify next point" step for the current segment mode. Every
|
||||
/// sub-step returns to `None` once it has produced a vertex, or when Undo /
|
||||
/// Enter / Escape backs out of it.
|
||||
@@ -114,7 +114,7 @@ pub struct PlineCommand {
|
||||
/// `(start, end)` width for segment i → i+1, parallel to `bulges`.
|
||||
widths: Vec<(f64, f64)>,
|
||||
/// Width pair applied to the next segment. After a segment lands its end
|
||||
/// width becomes the next start width, as in AutoCAD.
|
||||
/// width becomes the next start width, as in commercial solutions.
|
||||
cur_width: (f64, f64),
|
||||
mode: SegMode,
|
||||
sub: Sub,
|
||||
@@ -696,7 +696,7 @@ pub(crate) fn arc_sample_points(a: Vec3, bulge: f64, b: Vec3, n: usize) -> Vec<[
|
||||
|
||||
impl PlineCommand {
|
||||
/// Close the polyline: in Arc mode the closing segment is an arc tangent
|
||||
/// to the last segment (AutoCAD's CLose), in Line mode a straight one.
|
||||
/// to the last segment (CLose in commercial solutions), in Line mode a straight one.
|
||||
fn close(&mut self) -> CmdResult {
|
||||
if self.vertices.len() < 2 {
|
||||
return CmdResult::NeedPoint;
|
||||
@@ -779,7 +779,7 @@ impl CadCommand for PlineCommand {
|
||||
let can_close = self.vertices.len() >= 3
|
||||
|| (self.vertices.len() == 2 && matches!(self.mode, SegMode::Arc));
|
||||
match self.sub {
|
||||
// AutoCAD's keyword sets, in AutoCAD's order.
|
||||
// The keyword sets of commercial solutions, in their order.
|
||||
Sub::None => match self.mode {
|
||||
SegMode::Line => {
|
||||
let mut opts = vec![CmdOption::new("Arc", "A")];
|
||||
@@ -849,7 +849,7 @@ impl CadCommand for PlineCommand {
|
||||
match self.sub {
|
||||
Sub::None => {}
|
||||
// A picked point at a typed-value prompt reads as the distance
|
||||
// (or angle) from the last vertex, as AutoCAD allows.
|
||||
// (or angle) from the last vertex, as commercial solutions allow.
|
||||
sub if sub.is_scalar() => {
|
||||
let value = if sub.is_angle() {
|
||||
(p - a).y.atan2((p - a).x).to_degrees()
|
||||
@@ -1068,7 +1068,7 @@ impl CadCommand for PlineCommand {
|
||||
self.sub = Sub::ArcCenter;
|
||||
Some(CmdResult::NeedPoint)
|
||||
}
|
||||
// AutoCAD wants CL in arc mode; a bare C is accepted as well.
|
||||
// Commercial solutions want CL in arc mode; a bare C is accepted as well.
|
||||
(SegMode::Arc, "CL" | "C" | "CLOSE") => Some(self.close()),
|
||||
(SegMode::Arc, "D" | "DIRECTION") => {
|
||||
self.sub = Sub::ArcDirection;
|
||||
@@ -1272,7 +1272,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn options_per_mode_match_autocad_keywords() {
|
||||
fn options_per_mode_match_compatible_keywords() {
|
||||
let mut cmd = pl(&[(0.0, 0.0), (10.0, 0.0)]);
|
||||
assert_eq!(keywords(&cmd), ["A", "H", "L", "U", "W", ""]);
|
||||
cmd.on_point(DVec3::new(10.0, 5.0, 0.0));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// Requires at least one entity selected before starting.
|
||||
// Step 1: pick base point, or D = type the displacement vector directly
|
||||
// Step 2: pick destination → translates all selected entities by (dest - base);
|
||||
// Enter uses the base point as the displacement (AutoCAD).
|
||||
// Enter uses the base point as the displacement (commercial solutions).
|
||||
|
||||
use acadrust::Handle;
|
||||
use glam::DVec3;
|
||||
@@ -119,7 +119,7 @@ impl CadCommand for MoveCommand {
|
||||
|
||||
fn on_enter(&mut self) -> CmdResult {
|
||||
match self.step {
|
||||
// AutoCAD: Enter at the second point uses the base point as the
|
||||
// Commercial solutions: Enter at the second point uses the base point as the
|
||||
// displacement from the origin.
|
||||
Step::Target(base) => CmdResult::TransformSelected(
|
||||
self.handles.clone(),
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//! walks the same rows to resolve Up/Down/Enter/mnemonic picks, so what the
|
||||
//! user sees and what a keypress selects can never diverge.
|
||||
//!
|
||||
//! The layout mirrors AutoCAD's shortcut menus, which the user base already
|
||||
//! The layout covers the shortcut menus of commercial solutions, which the user base already
|
||||
//! knows: while a command runs the menu offers Enter / Cancel / the command's
|
||||
//! own keyword options (with the keyword shown as a hint, so the menu also
|
||||
//! teaches the typed shortcut); when idle it offers Repeat / Recent Input /
|
||||
@@ -44,7 +44,7 @@ pub enum SubmenuId {
|
||||
SnapOverrides,
|
||||
}
|
||||
|
||||
/// Glyph drawn in a row's icon gutter (AutoCAD shows one for object snaps
|
||||
/// Glyph drawn in a row's icon gutter (commercial solutions show one for object snaps
|
||||
/// and the navigation rows).
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum MenuIcon {
|
||||
@@ -54,7 +54,7 @@ pub enum MenuIcon {
|
||||
Zoom,
|
||||
}
|
||||
|
||||
/// What a grip-menu row does (AutoCAD grip-mode shortcut menu).
|
||||
/// What a grip-menu row does (the grip-mode shortcut menu of commercial solutions).
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum GripMenuCmd {
|
||||
Stretch,
|
||||
@@ -425,8 +425,10 @@ fn command_rows(
|
||||
open_submenu: Option<SubmenuId>,
|
||||
) -> Vec<MenuRow> {
|
||||
let mut rows = Vec::new();
|
||||
// AutoCAD order: Enter, Cancel, Recent Input, the command's keywords,
|
||||
// Snap Overrides, then the transparent navigation commands.
|
||||
// Ordered by how often a drafter reaches for each row: Enter / Cancel
|
||||
// under the pointer, the command's own keywords right below them (the
|
||||
// choices that change from step to step), then the recall and snap
|
||||
// helpers, and the transparent navigation commands last.
|
||||
//
|
||||
// A command may name its own finish action (PLINE "Done", OFFSET's
|
||||
// "<0.5000>" default). That row *is* Enter: it is not listed twice, and
|
||||
@@ -442,14 +444,6 @@ fn command_rows(
|
||||
rows.push(MenuRow::Item(
|
||||
MenuItem::new(t!("Cancel").into_owned(), MenuAction::Cancel).hint("Esc"),
|
||||
));
|
||||
rows.push(recent_input_submenu(
|
||||
recent_inputs
|
||||
.iter()
|
||||
.take(RECENT_LIMIT)
|
||||
.map(|tok| MenuItem::new(tok.clone(), MenuAction::FeedInput(tok.clone())))
|
||||
.collect(),
|
||||
open_submenu,
|
||||
));
|
||||
|
||||
let keyword_opts: Vec<&CmdOption> = options.iter().filter(|o| !o.keyword.is_empty()).collect();
|
||||
if !keyword_opts.is_empty() {
|
||||
@@ -463,8 +457,16 @@ fn command_rows(
|
||||
}
|
||||
}
|
||||
|
||||
rows.push(MenuRow::Separator);
|
||||
rows.push(recent_input_submenu(
|
||||
recent_inputs
|
||||
.iter()
|
||||
.take(RECENT_LIMIT)
|
||||
.map(|tok| MenuItem::new(tok.clone(), MenuAction::FeedInput(tok.clone())))
|
||||
.collect(),
|
||||
open_submenu,
|
||||
));
|
||||
if has_point_step {
|
||||
rows.push(MenuRow::Separator);
|
||||
rows.push(MenuRow::Submenu {
|
||||
id: SubmenuId::SnapOverrides,
|
||||
label: t!("Snap Overrides").into_owned(),
|
||||
@@ -478,7 +480,7 @@ fn command_rows(
|
||||
rows
|
||||
}
|
||||
|
||||
/// Recent Input ▸ — always listed (AutoCAD keeps the entry even when there
|
||||
/// Recent Input ▸ — always listed (commercial solutions keep the entry even when there
|
||||
/// is nothing to recall yet; it is simply disabled then).
|
||||
fn recent_input_submenu(items: Vec<MenuItem>, open_submenu: Option<SubmenuId>) -> MenuRow {
|
||||
MenuRow::Submenu {
|
||||
@@ -489,7 +491,7 @@ fn recent_input_submenu(items: Vec<MenuItem>, open_submenu: Option<SubmenuId>) -
|
||||
}
|
||||
}
|
||||
|
||||
/// Snap Overrides ▸: one-shot object snaps for the next pick, in AutoCAD's
|
||||
/// Snap Overrides ▸: one-shot object snaps for the next pick, in the
|
||||
/// grouping (M2P, then the edge snaps, the curve snaps, the relation snaps,
|
||||
/// None) plus the settings dialog.
|
||||
fn snap_override_items() -> Vec<MenuItem> {
|
||||
@@ -520,7 +522,7 @@ fn snap_override_items() -> Vec<MenuItem> {
|
||||
}
|
||||
|
||||
/// Pan / Zoom rows. While a command runs they execute transparently (the
|
||||
/// `'` prefix, as in AutoCAD) so the command resumes afterwards.
|
||||
/// `'` prefix, as in commercial solutions) so the command resumes afterwards.
|
||||
fn navigation_rows(transparent: bool) -> Vec<MenuRow> {
|
||||
let prefix = if transparent { "'" } else { "" };
|
||||
vec![
|
||||
@@ -607,7 +609,7 @@ fn idle_rows(
|
||||
));
|
||||
rows.push(MenuRow::Separator);
|
||||
|
||||
// ── Selection edit block (AutoCAD "Edit" shortcut menu) ────────────
|
||||
// ── Selection edit block (the "Edit" shortcut menu of commercial solutions) ──
|
||||
if has_selection {
|
||||
rows.push(MenuRow::Item(MenuItem::new(
|
||||
t!("Erase").into_owned(),
|
||||
@@ -663,7 +665,7 @@ fn idle_rows(
|
||||
// ── Navigation ─────────────────────────────────────────────────────
|
||||
rows.extend(navigation_rows(false));
|
||||
// The edit menu is long already; Zoom Extents stays on the idle menu
|
||||
// (and on the middle button's double-click), as in AutoCAD.
|
||||
// (and on the middle button's double-click), as in commercial solutions.
|
||||
if !has_selection {
|
||||
rows.push(MenuRow::Item(cmd(t!("Zoom Extents").into_owned(), "ZOOM EXTENTS")));
|
||||
}
|
||||
@@ -775,25 +777,25 @@ mod tests {
|
||||
#[test]
|
||||
fn command_menu_lists_options_with_hints() {
|
||||
let menu = build_context_menu(&line_ctx(), None);
|
||||
// AutoCAD order: Enter, Cancel, Recent Input, keywords, Snap
|
||||
// Overrides, Pan / Zoom.
|
||||
// Enter / Cancel, the keywords, then the recall / snap helpers and
|
||||
// the navigation rows.
|
||||
assert_eq!(
|
||||
labels(&menu),
|
||||
vec![
|
||||
tl("Enter"),
|
||||
tl("Cancel"),
|
||||
format!("{} >", tl("Recent Input")),
|
||||
"---".into(),
|
||||
tl("Close"),
|
||||
tl("Undo"),
|
||||
"---".into(),
|
||||
format!("{} >", tl("Recent Input")),
|
||||
format!("{} >", tl("Snap Overrides")),
|
||||
"---".into(),
|
||||
tl("Pan"),
|
||||
tl("Zoom"),
|
||||
]
|
||||
);
|
||||
let close = item_at(&menu, 4);
|
||||
let close = item_at(&menu, 3);
|
||||
assert_eq!(close.hint.as_deref(), Some("C"));
|
||||
assert_eq!(close.mnemonic, Some('C'));
|
||||
assert_eq!(close.action, MenuAction::Option("C".into()));
|
||||
@@ -821,8 +823,8 @@ mod tests {
|
||||
[
|
||||
MenuAction::Enter,
|
||||
MenuAction::Cancel,
|
||||
MenuAction::Option("A".into()),
|
||||
MenuAction::ToggleSubmenu(SubmenuId::RecentInput),
|
||||
MenuAction::Option("A".into())
|
||||
]
|
||||
);
|
||||
// A default value shows on the Enter row as its hint (OFFSET <dist>).
|
||||
@@ -1014,10 +1016,10 @@ mod tests {
|
||||
recent_inputs: Vec::new(),
|
||||
};
|
||||
let menu = build_context_menu(&ctx, None);
|
||||
// rows: Enter(0) Cancel(1) Recent Input(2) Angle(3) CEnter(4) CLose(5) …
|
||||
assert_eq!(menu.find_mnemonic('c', None), Some(4));
|
||||
assert_eq!(menu.find_mnemonic('C', Some(4)), Some(5));
|
||||
assert_eq!(menu.find_mnemonic('C', Some(5)), Some(4));
|
||||
// rows: Enter(0) Cancel(1) Angle(2) CEnter(3) CLose(4) …
|
||||
assert_eq!(menu.find_mnemonic('c', None), Some(3));
|
||||
assert_eq!(menu.find_mnemonic('C', Some(3)), Some(4));
|
||||
assert_eq!(menu.find_mnemonic('C', Some(4)), Some(3));
|
||||
assert_eq!(menu.find_mnemonic('Z', None), None);
|
||||
}
|
||||
|
||||
|
||||
@@ -1269,7 +1269,7 @@ pub fn view_window<'a>(
|
||||
.align_y(iced::Center),
|
||||
Space::new().height(6),
|
||||
text(crate::t!(
|
||||
"Shortcut menu: right-click always opens the menu (AutoCAD default). Time-sensitive: a quick click is Enter, holding longer opens the menu (SHORTCUTMENUDURATION)."
|
||||
"Shortcut menu: right-click always opens the menu. Time-sensitive: a quick click is Enter, holding longer opens the menu (SHORTCUTMENUDURATION)."
|
||||
))
|
||||
.size(11)
|
||||
.width(sizing.width),
|
||||
|
||||
Reference in new issue
Block a user