76 lines
2.5 KiB
Rust
76 lines
2.5 KiB
Rust
use winit::keyboard::{Key, ModifiersState, SmolStr};
|
|
|
|
#[derive(Clone, Copy)]
|
|
#[allow(dead_code)]
|
|
// LiveMode/EditorMode/ViewMode are dispatched but not yet bound to a shortcut
|
|
// — Linux has no menu bar to expose them via, so they wait for either a key
|
|
// binding decision or an iced-rendered menu inside the viewport.
|
|
pub enum MenuAction {
|
|
NewNote,
|
|
Open,
|
|
Save,
|
|
SaveAs,
|
|
Quit,
|
|
Bold,
|
|
Italic,
|
|
InsertTable,
|
|
Evaluate,
|
|
LiveMode,
|
|
EditorMode,
|
|
ViewMode,
|
|
ZoomIn,
|
|
ZoomOut,
|
|
ZoomReset,
|
|
Find,
|
|
Settings,
|
|
ExportCrate,
|
|
ToggleBrowser,
|
|
}
|
|
|
|
/// Matches an app-level shortcut. Returns Some(action) for combos that should
|
|
/// fire a MenuAction; None for combos that should fall through to the
|
|
/// viewport (cut/copy/paste/undo/redo/select-all are handled inside iced via
|
|
/// the Ctrl→LOGO modifier alias, plain typing, navigation, etc.).
|
|
pub fn match_shortcut(modifiers: ModifiersState, key: &Key) -> Option<MenuAction> {
|
|
// Alt+B mirrors macOS Ctrl+B for the document browser. Mac-Cmd maps to
|
|
// Ctrl on Linux/Windows, so Mac-Ctrl gets bumped to Alt to avoid collision.
|
|
if modifiers.alt_key() && !modifiers.control_key() && !modifiers.super_key() {
|
|
if let Key::Character(s) = key {
|
|
if ascii_lower(s) == 'b' {
|
|
return Some(MenuAction::ToggleBrowser);
|
|
}
|
|
}
|
|
}
|
|
|
|
if !modifiers.control_key() {
|
|
return None;
|
|
}
|
|
let shift = modifiers.shift_key();
|
|
|
|
match key {
|
|
Key::Character(s) => match (shift, ascii_lower(s)) {
|
|
(false, 'n') => Some(MenuAction::NewNote),
|
|
(false, 'o') => Some(MenuAction::Open),
|
|
(false, 's') => Some(MenuAction::Save),
|
|
(true, 's') => Some(MenuAction::SaveAs),
|
|
(false, 'q') => Some(MenuAction::Quit),
|
|
(false, 'b') => Some(MenuAction::Bold),
|
|
(false, 'i') => Some(MenuAction::Italic),
|
|
(false, 't') => Some(MenuAction::InsertTable),
|
|
(false, 'f') => Some(MenuAction::Find),
|
|
(false, 'e') => Some(MenuAction::Evaluate),
|
|
(true, 'e') => Some(MenuAction::ExportCrate),
|
|
(false, ',') => Some(MenuAction::Settings),
|
|
(false, '=') | (false, '+') => Some(MenuAction::ZoomIn),
|
|
(false, '-') => Some(MenuAction::ZoomOut),
|
|
(true, '0') => Some(MenuAction::ZoomReset),
|
|
_ => None,
|
|
},
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
fn ascii_lower(s: &SmolStr) -> char {
|
|
s.chars().next().map(|c| c.to_ascii_lowercase()).unwrap_or('\0')
|
|
}
|