use teksilo_core::event::{Key, Modifiers};
use teksilo_core::shortcut::KeyStroke;
#[cfg(not(target_os = "macos"))]
use teksilo_i18n::tr_widget;
pub fn format_keystroke(keystroke: KeyStroke) -> String {
let mut out = String::new();
write_modifiers(&mut out, keystroke.modifiers);
write_key(&mut out, keystroke.key);
out
}
#[cfg(target_os = "macos")]
fn write_modifiers(out: &mut String, modifiers: Modifiers) {
if modifiers.ctrl() {
out.push('\u{2303}');
}
if modifiers.alt() {
out.push('\u{2325}');
}
if modifiers.shift() {
out.push('\u{21E7}');
}
if modifiers.super_key() {
out.push('\u{2318}');
}
}
#[cfg(not(target_os = "macos"))]
fn write_modifiers(out: &mut String, modifiers: Modifiers) {
let sep = tr_widget!(keystroke_separator()).resolve_now();
if modifiers.ctrl() {
out.push_str(&tr_widget!(keystroke_modifier_ctrl()).resolve_now());
out.push_str(&sep);
}
if modifiers.shift() {
out.push_str(&tr_widget!(keystroke_modifier_shift()).resolve_now());
out.push_str(&sep);
}
if modifiers.alt() {
out.push_str(&tr_widget!(keystroke_modifier_alt()).resolve_now());
out.push_str(&sep);
}
if modifiers.super_key() {
out.push_str(&tr_widget!(keystroke_modifier_super()).resolve_now());
out.push_str(&sep);
}
}
#[cfg(target_os = "macos")]
fn write_key(out: &mut String, key: Key) {
match key {
Key::ArrowUp => out.push('\u{2191}'),
Key::ArrowDown => out.push('\u{2193}'),
Key::ArrowLeft => out.push('\u{2190}'),
Key::ArrowRight => out.push('\u{2192}'),
Key::Enter => out.push('\u{21A9}'),
Key::Backspace => out.push('\u{232B}'),
Key::Delete => out.push('\u{2326}'),
Key::Escape => out.push('\u{238B}'),
Key::Space => out.push_str("Space"),
Key::Tab => out.push('\u{21E5}'),
other => out.push_str(&other.to_string()),
}
}
#[cfg(not(target_os = "macos"))]
fn write_key(out: &mut String, key: Key) {
let label = match key {
Key::Space => Some(tr_widget!(keystroke_key_space()).resolve_now()),
Key::Enter => Some(tr_widget!(keystroke_key_enter()).resolve_now()),
Key::Escape => Some(tr_widget!(keystroke_key_escape()).resolve_now()),
Key::Tab => Some(tr_widget!(keystroke_key_tab()).resolve_now()),
Key::Backspace => Some(tr_widget!(keystroke_key_backspace()).resolve_now()),
Key::Delete => Some(tr_widget!(keystroke_key_delete()).resolve_now()),
Key::ArrowUp => Some(tr_widget!(keystroke_key_arrow_up()).resolve_now()),
Key::ArrowDown => Some(tr_widget!(keystroke_key_arrow_down()).resolve_now()),
Key::ArrowLeft => Some(tr_widget!(keystroke_key_arrow_left()).resolve_now()),
Key::ArrowRight => Some(tr_widget!(keystroke_key_arrow_right()).resolve_now()),
Key::Home => Some(tr_widget!(keystroke_key_home()).resolve_now()),
Key::End => Some(tr_widget!(keystroke_key_end()).resolve_now()),
Key::PageUp => Some(tr_widget!(keystroke_key_page_up()).resolve_now()),
Key::PageDown => Some(tr_widget!(keystroke_key_page_down()).resolve_now()),
_ => None,
};
match label {
Some(s) => out.push_str(&s),
None => out.push_str(&key.to_string()),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[cfg(not(target_os = "macos"))]
fn non_macos_uses_translated_modifiers() {
assert_eq!(format_keystroke(KeyStroke::ctrl(Key::S)), "Ctrl+S");
assert_eq!(
format_keystroke(KeyStroke::ctrl_shift(Key::Z)),
"Ctrl+Shift+Z"
);
assert_eq!(format_keystroke(KeyStroke::alt(Key::F4)), "Alt+F4");
}
#[test]
#[cfg(not(target_os = "macos"))]
fn non_macos_named_keys_route_through_bundle() {
assert_eq!(format_keystroke(KeyStroke::ctrl(Key::Enter)), "Ctrl+Enter");
assert_eq!(
format_keystroke(KeyStroke::new(Key::Escape, Modifiers::NONE)),
"Esc"
);
assert_eq!(
format_keystroke(KeyStroke::ctrl(Key::ArrowLeft)),
"Ctrl+Left"
);
assert_eq!(
format_keystroke(KeyStroke::new(Key::Tab, Modifiers::SHIFT)),
"Shift+Tab"
);
}
#[test]
#[cfg(target_os = "macos")]
fn macos_uses_symbols() {
assert_eq!(
format_keystroke(KeyStroke::new(Key::S, Modifiers::SUPER)),
"\u{2318}S"
);
assert_eq!(
format_keystroke(KeyStroke::new(Key::Z, Modifiers::SHIFT | Modifiers::SUPER)),
"\u{21E7}\u{2318}Z"
);
}
}