diff --git a/crates/ui-egui/src/menus.rs b/crates/ui-egui/src/menus.rs index ad1a322..7c2e4b6 100644 --- a/crates/ui-egui/src/menus.rs +++ b/crates/ui-egui/src/menus.rs @@ -244,7 +244,7 @@ fn menu_node(app: &mut SoundApp, ui: &mut egui::Ui, n: &MenuNode, extra: &[(&str let (enabled, checked) = item_state(app, &n.path, id.as_deref()); let label = if checked { format!("✔ {}", n.label) } else { n.label.clone() }; let shortcut = id.as_deref().and_then(soundcraft_engine::find_command).and_then(|c| c.shortcut).unwrap_or(""); - let btn = egui::Button::new(label).shortcut_text(shortcut); + let btn = egui::Button::new(label).shortcut_text(crate::shortcuts::shortcut_label(shortcut, ui.ctx().os().is_mac())); if ui.add_enabled(enabled, btn).clicked() && let Some(id) = id { diff --git a/crates/ui-egui/src/palette.rs b/crates/ui-egui/src/palette.rs index 6291aea..916087b 100644 --- a/crates/ui-egui/src/palette.rs +++ b/crates/ui-egui/src/palette.rs @@ -95,7 +95,8 @@ pub fn show(app: &mut SoundApp, ctx: &egui::Context) { let l = ui.selectable_label(sel, &e.label); ui.label(egui::RichText::new(&e.path).small().color(t.text_dim)); ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { - ui.label(egui::RichText::new(&e.shortcut).font(mono(10.0)).color(t.text_dim)); + let sc = crate::shortcuts::shortcut_label(&e.shortcut, ctx.os().is_mac()); + ui.label(egui::RichText::new(sc).font(mono(10.0)).color(t.text_dim)); }); l }); diff --git a/crates/ui-egui/src/shortcuts.rs b/crates/ui-egui/src/shortcuts.rs index 15141c8..856a45d 100644 --- a/crates/ui-egui/src/shortcuts.rs +++ b/crates/ui-egui/src/shortcuts.rs @@ -239,6 +239,41 @@ fn tab_clip(app: &mut SoundApp, back: bool) { } } +/// Shortcut text for display. The registry stores macOS-style strings ("Cmd+N"); off macOS the Cmd +/// modifier is the Ctrl key. Mac-only Control chords ("Cmd+Ctrl+S") have no key there, so they show nothing. +pub fn shortcut_label(s: &str, mac: bool) -> String { + if mac || !s.split('+').any(|p| p == "Cmd") { + return s.to_string(); + } + if s.split('+').any(|p| p == "Ctrl") { + return String::new(); + } + s.split('+').map(|p| if p == "Cmd" { "Ctrl" } else { p }).collect::>().join("+") +} + +#[cfg(test)] +mod label_tests { + use super::shortcut_label; + + #[test] + fn cmd_becomes_ctrl_off_mac() { + assert_eq!(shortcut_label("Cmd+N", false), "Ctrl+N"); + assert_eq!(shortcut_label("Cmd+Shift+W", false), "Ctrl+Shift+W"); + assert_eq!(shortcut_label("Cmd+Alt+B", false), "Ctrl+Alt+B"); + assert_eq!(shortcut_label("Cmd+,", false), "Ctrl+,"); + assert_eq!(shortcut_label("Shift+R", false), "Shift+R"); + assert_eq!(shortcut_label("Cmd+Ctrl+S", false), ""); + assert_eq!(shortcut_label("", false), ""); + } + + #[test] + fn unchanged_on_mac() { + for s in ["Cmd+N", "Cmd+Shift+W", "Cmd+Alt+B", "Shift+R", "Cmd+Ctrl+S"] { + assert_eq!(shortcut_label(s, true), s); + } + } +} + #[cfg(test)] mod tests { use super::{mods_match, parse, search_chord}; diff --git a/crates/ui-egui/src/windows.rs b/crates/ui-egui/src/windows.rs index 332a46f..1a98e79 100644 --- a/crates/ui-egui/src/windows.rs +++ b/crates/ui-egui/src/windows.rs @@ -429,11 +429,12 @@ pub fn io_setup(app: &mut SoundApp, ctx: &egui::Context) { /// Setup › Keyboard Shortcuts. pub fn shortcuts_window(app: &mut SoundApp, ctx: &egui::Context) { let mut open = app.ui.show_shortcuts; + let mac = ctx.os().is_mac(); win(ctx, &mut open, "Keyboard Shortcuts", vec2(520.0, 480.0), |ui| { egui::ScrollArea::vertical().show(ui, |ui| { egui::Grid::new("sc").num_columns(3).striped(true).show(ui, |ui| { for c in soundcraft_engine::command_specs().iter().filter(|c| c.shortcut.is_some()) { - ui.label(egui::RichText::new(c.shortcut.unwrap_or("")).font(mono(11.0))); + ui.label(egui::RichText::new(crate::shortcuts::shortcut_label(c.shortcut.unwrap_or(""), mac)).font(mono(11.0))); ui.label(c.label); ui.label(egui::RichText::new(c.menu.join(" › ")).small()); ui.end_row();