keyboard-codes 0.3.0

Cross-platform keyboard key code mapping and conversion
Documentation
//! GUI 应用快捷键系统示例
//! 运行: cargo run --example gui_shortcuts

// use keyboard_codes::*;
// use std::collections::HashMap;

use keyboard_codes::{
    current_platform, parse_shortcut_with_aliases, Key, KeyCodeMapper, Modifier, Platform, Shortcut,
};
use std::collections::HashMap;

#[derive(Debug, Clone, Copy, PartialEq)]
enum AppCommand {
    NewFile,
    OpenFile,
    Save,
    SaveAs,
    CloseTab,
    Undo,
    Redo,
    Cut,
    Copy,
    Paste,
    SelectAll,
    Find,
    Replace,
    Quit,
    Preferences,
}

struct ShortcutManager {
    platform: Platform,
    shortcuts: HashMap<Shortcut, AppCommand>,
}

impl ShortcutManager {
    fn new(platform: Platform) -> Self {
        let mut shortcuts = HashMap::new();

        // 文件操作 - 使用安全的添加方法
        Self::add_shortcut(&mut shortcuts, "ctrl+n", AppCommand::NewFile);
        Self::add_shortcut(&mut shortcuts, "ctrl+o", AppCommand::OpenFile);
        Self::add_shortcut(&mut shortcuts, "ctrl+s", AppCommand::Save);
        Self::add_shortcut(&mut shortcuts, "ctrl+shift+s", AppCommand::SaveAs);
        Self::add_shortcut(&mut shortcuts, "ctrl+w", AppCommand::CloseTab);

        // 编辑操作
        Self::add_shortcut(&mut shortcuts, "ctrl+z", AppCommand::Undo);
        Self::add_shortcut(&mut shortcuts, "ctrl+y", AppCommand::Redo);
        Self::add_shortcut(&mut shortcuts, "ctrl+x", AppCommand::Cut);
        Self::add_shortcut(&mut shortcuts, "ctrl+c", AppCommand::Copy);
        Self::add_shortcut(&mut shortcuts, "ctrl+v", AppCommand::Paste);
        Self::add_shortcut(&mut shortcuts, "ctrl+a", AppCommand::SelectAll);
        Self::add_shortcut(&mut shortcuts, "ctrl+f", AppCommand::Find);
        Self::add_shortcut(&mut shortcuts, "ctrl+h", AppCommand::Replace);

        // 跨平台退出命令 - 修复逗号问题
        if platform == Platform::MacOS {
            Self::add_shortcut(&mut shortcuts, "cmd+q", AppCommand::Quit);
            // 移除有问题的逗号快捷键,改用其他键
            Self::add_shortcut(&mut shortcuts, "cmd+p", AppCommand::Preferences);
        } else {
            Self::add_shortcut(&mut shortcuts, "alt+f4", AppCommand::Quit);
            Self::add_shortcut(&mut shortcuts, "ctrl+p", AppCommand::Preferences);
        }

        Self {
            platform,
            shortcuts,
        }
    }

    // 安全的快捷键添加方法
    fn add_shortcut(
        shortcuts: &mut HashMap<Shortcut, AppCommand>,
        input: &str,
        command: AppCommand,
    ) {
        match parse_shortcut_with_aliases(input) {
            Ok(shortcut) => {
                shortcuts.insert(shortcut, command);
            }
            Err(e) => {
                eprintln!("警告: 无法解析快捷键 '{}': {}", input, e);
            }
        }
    }

    fn get_command(&self, modifier_vks: &[usize], key_vk: usize) -> Option<AppCommand> {
        // 转换修饰键
        let modifiers: Vec<Modifier> = modifier_vks
            .iter()
            .filter_map(|&code| Modifier::from_code(code, self.platform))
            .collect();

        // 转换主键
        if let Some(key) = Key::from_code(key_vk, self.platform) {
            let shortcut = Shortcut::new(modifiers, key);
            return self.shortcuts.get(&shortcut).copied();
        }

        None
    }

    fn print_shortcut_reference(&self) {
        println!("快捷键参考表:");
        println!("{:-<40}", "");

        let mut commands: Vec<(&Shortcut, &AppCommand)> = self.shortcuts.iter().collect();
        commands.sort_by_key(|(_, cmd)| format!("{:?}", cmd));

        for (shortcut, command) in commands {
            println!("  {:20} -> {:?}", shortcut, command);
        }
    }
}

fn main() {
    println!("=== GUI 应用快捷键系统示例 ===\n");

    let platform = current_platform();
    let shortcut_manager = ShortcutManager::new(platform);

    shortcut_manager.print_shortcut_reference();

    // 模拟快捷键输入
    println!("\n模拟快捷键处理:");
    let test_combinations = [
        (vec![0x11], 0x53),       // Ctrl + S (Save)
        (vec![0x11], 0x43),       // Ctrl + C (Copy)
        (vec![0x11, 0x10], 0x53), // Ctrl + Shift + S (Save As)
    ];

    for (modifiers, key) in test_combinations {
        if let Some(command) = shortcut_manager.get_command(&modifiers, key) {
            println!("  {:02X?} + {:02X} -> {:?}", modifiers, key, command);
        } else {
            println!("  {:02X?} + {:02X} -> 无匹配命令", modifiers, key);
        }
    }
}