mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-24 10:16:59 -06:00
Integration: "&" shows in native menu labels
This commit is contained in:
@@ -45,6 +45,11 @@ fn accel(sc: &str) -> Option<Accelerator> {
|
||||
Accelerator::from_str(&sc.replace("Cmd", "CMD").replace("Alt", "ALT").replace("Shift", "SHIFT").replace("Ctrl", "CTRL")).ok()
|
||||
}
|
||||
|
||||
/// A menu or item label in the interface language, as the native menu bar takes it.
|
||||
fn menu_title(app: &DesignApp, label: &str) -> String {
|
||||
menus::native_label(designcraft_ui_egui::i18n::tr(&app.ui.language, label))
|
||||
}
|
||||
|
||||
/// A command's default shortcut, as the in-window menus show it.
|
||||
fn shortcut(id: &str) -> Option<&'static str> {
|
||||
menus::ui_label(id).and_then(|(_, sc)| sc).or_else(|| designcraft_engine::find_command(id).and_then(|c| c.shortcut))
|
||||
@@ -71,7 +76,7 @@ impl NativeMenu {
|
||||
let _ = match *entry {
|
||||
AppMenuItem::Cmd { id, label, command } => {
|
||||
let sc = shortcut(command).and_then(accel);
|
||||
let item = MenuItem::with_id(id, designcraft_ui_egui::i18n::tr(&app.ui.language, label), true, sc);
|
||||
let item = MenuItem::with_id(id, menu_title(app, label), true, sc);
|
||||
let appended = app_menu.append(&item);
|
||||
items.insert(id.into(), (command.into(), Value::Null, Handle::Plain(item)));
|
||||
appended
|
||||
@@ -85,7 +90,7 @@ impl NativeMenu {
|
||||
}
|
||||
let _ = menu.append(&app_menu);
|
||||
for (title, entries) in menus::native_menu_tree() {
|
||||
let sub = Submenu::new(designcraft_ui_egui::i18n::tr(&app.ui.language, title), true);
|
||||
let sub = Submenu::new(menu_title(app, title), true);
|
||||
build(app, &sub, &entries, &mut items, &mut counter, title, &mut recent);
|
||||
let _ = menu.append(&sub);
|
||||
}
|
||||
@@ -121,7 +126,7 @@ impl NativeMenu {
|
||||
match it {
|
||||
Item::Cmd { label, id, params, .. } => {
|
||||
let mid = format!("dc-recent{position}");
|
||||
let item = MenuItem::with_id(mid.clone(), label, true, None);
|
||||
let item = MenuItem::with_id(mid.clone(), menus::native_label(&label), true, None);
|
||||
let _ = r.submenu.insert(&item, position);
|
||||
self.items.insert(mid.clone(), (id, params, Handle::Plain(item)));
|
||||
r.ids.push(mid);
|
||||
@@ -184,7 +189,7 @@ fn build(
|
||||
let _ = parent.append(&PredefinedMenuItem::separator());
|
||||
}
|
||||
Item::Sub(label, children) => {
|
||||
let sub = Submenu::new(designcraft_ui_egui::i18n::tr(&app.ui.language, label), true);
|
||||
let sub = Submenu::new(menu_title(app, label), true);
|
||||
let path = format!("{path}/{label}");
|
||||
build(app, &sub, children, items, counter, &path, recent);
|
||||
if path == menus::OPEN_RECENT {
|
||||
@@ -198,7 +203,7 @@ fn build(
|
||||
*counter += 1;
|
||||
let mid = format!("dc{counter}");
|
||||
let sc = if params.is_null() { shortcut.and_then(accel) } else { None };
|
||||
let label = designcraft_ui_egui::i18n::tr(&app.ui.language, label);
|
||||
let label = menu_title(app, label);
|
||||
let handle = if menus::checked(app, id, params).is_some() {
|
||||
let c = CheckMenuItem::with_id(mid.clone(), label, true, false, sc);
|
||||
let _ = parent.append(&c);
|
||||
|
||||
@@ -2308,6 +2308,12 @@ pub const MAC_APP_MENU: &[AppMenuItem] = &[
|
||||
AppMenuItem::Cmd { id: "dc-quit", label: "Quit DesignCraft", command: "app.quit" },
|
||||
];
|
||||
|
||||
/// A label as the macOS menu bar library takes it: it reads "&" as a mnemonic marker and drops
|
||||
/// it, and shows "&&" as one "&".
|
||||
pub fn native_label(label: &str) -> String {
|
||||
label.replace('&', "&&")
|
||||
}
|
||||
|
||||
/// The menu tree for the macOS menu bar: `menu_tree` without the commands `MAC_APP_MENU` holds,
|
||||
/// so each command (and its shortcut) appears once, and with the standard Window › Minimize (⌘M)
|
||||
/// at the top of the Window menu.
|
||||
@@ -5518,6 +5524,13 @@ mod tests {
|
||||
assert!(!open, "an open submenu closes when its row becomes fully clipped");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn native_labels_keep_their_ampersands() {
|
||||
assert_eq!(native_label("Numbering & Section Options…"), "Numbering && Section Options…");
|
||||
assert_eq!(native_label("A&&B"), "A&&&&B");
|
||||
assert_eq!(native_label("Pages"), "Pages");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_mac_window_menu_minimizes_with_cmd_m() {
|
||||
let window = native_menu_tree().into_iter().find(|(t, _)| *t == "Window").map(|(_, e)| e).unwrap_or_default();
|
||||
|
||||
Reference in New Issue
Block a user