use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; pub fn convert_egui_events(ctx: &egui::Context) -> Vec { let mut events = Vec::new(); for event in &ctx.input(|i| i.events.clone()) { if let Some(key_event) = convert_event(event) { events.push(key_event); } } events } fn convert_event(event: &egui::Event) -> Option { match event { egui::Event::Key { key, pressed, modifiers, .. } => { if !*pressed { return None; } let mods = convert_modifiers(*modifiers); // For character keys without ctrl/alt, let Event::Text handle it if is_character_key(*key) && !mods.intersects(KeyModifiers::CONTROL | KeyModifiers::ALT) { return None; } let code = convert_key(*key)?; Some(KeyEvent::new(code, mods)) } egui::Event::Text(text) => { if text.len() == 1 { let c = text.chars().next()?; if !c.is_control() { return Some(KeyEvent::new(KeyCode::Char(c), KeyModifiers::empty())); } } None } _ => None, } } fn convert_key(key: egui::Key) -> Option { Some(match key { egui::Key::ArrowDown => KeyCode::Down, egui::Key::ArrowLeft => KeyCode::Left, egui::Key::ArrowRight => KeyCode::Right, egui::Key::ArrowUp => KeyCode::Up, egui::Key::Escape => KeyCode::Esc, egui::Key::Tab => KeyCode::Tab, egui::Key::Backspace => KeyCode::Backspace, egui::Key::Enter => KeyCode::Enter, egui::Key::Space => KeyCode::Char(' '), egui::Key::Insert => KeyCode::Insert, egui::Key::Delete => KeyCode::Delete, egui::Key::Home => KeyCode::Home, egui::Key::End => KeyCode::End, egui::Key::PageUp => KeyCode::PageUp, egui::Key::PageDown => KeyCode::PageDown, egui::Key::F1 => KeyCode::F(1), egui::Key::F2 => KeyCode::F(2), egui::Key::F3 => KeyCode::F(3), egui::Key::F4 => KeyCode::F(4), egui::Key::F5 => KeyCode::F(5), egui::Key::F6 => KeyCode::F(6), egui::Key::F7 => KeyCode::F(7), egui::Key::F8 => KeyCode::F(8), egui::Key::F9 => KeyCode::F(9), egui::Key::F10 => KeyCode::F(10), egui::Key::F11 => KeyCode::F(11), egui::Key::F12 => KeyCode::F(12), egui::Key::A => KeyCode::Char('a'), egui::Key::B => KeyCode::Char('b'), egui::Key::C => KeyCode::Char('c'), egui::Key::D => KeyCode::Char('d'), egui::Key::E => KeyCode::Char('e'), egui::Key::F => KeyCode::Char('f'), egui::Key::G => KeyCode::Char('g'), egui::Key::H => KeyCode::Char('h'), egui::Key::I => KeyCode::Char('i'), egui::Key::J => KeyCode::Char('j'), egui::Key::K => KeyCode::Char('k'), egui::Key::L => KeyCode::Char('l'), egui::Key::M => KeyCode::Char('m'), egui::Key::N => KeyCode::Char('n'), egui::Key::O => KeyCode::Char('o'), egui::Key::P => KeyCode::Char('p'), egui::Key::Q => KeyCode::Char('q'), egui::Key::R => KeyCode::Char('r'), egui::Key::S => KeyCode::Char('s'), egui::Key::T => KeyCode::Char('t'), egui::Key::U => KeyCode::Char('u'), egui::Key::V => KeyCode::Char('v'), egui::Key::W => KeyCode::Char('w'), egui::Key::X => KeyCode::Char('x'), egui::Key::Y => KeyCode::Char('y'), egui::Key::Z => KeyCode::Char('z'), egui::Key::Num0 => KeyCode::Char('0'), egui::Key::Num1 => KeyCode::Char('1'), egui::Key::Num2 => KeyCode::Char('2'), egui::Key::Num3 => KeyCode::Char('3'), egui::Key::Num4 => KeyCode::Char('4'), egui::Key::Num5 => KeyCode::Char('5'), egui::Key::Num6 => KeyCode::Char('6'), egui::Key::Num7 => KeyCode::Char('7'), egui::Key::Num8 => KeyCode::Char('8'), egui::Key::Num9 => KeyCode::Char('9'), egui::Key::Minus => KeyCode::Char('-'), egui::Key::Equals => KeyCode::Char('='), egui::Key::OpenBracket => KeyCode::Char('['), egui::Key::CloseBracket => KeyCode::Char(']'), egui::Key::Semicolon => KeyCode::Char(';'), egui::Key::Comma => KeyCode::Char(','), egui::Key::Period => KeyCode::Char('.'), egui::Key::Slash => KeyCode::Char('/'), egui::Key::Backslash => KeyCode::Char('\\'), egui::Key::Backtick => KeyCode::Char('`'), egui::Key::Quote => KeyCode::Char('\''), _ => return None, }) } fn convert_modifiers(mods: egui::Modifiers) -> KeyModifiers { let mut result = KeyModifiers::empty(); if mods.shift { result |= KeyModifiers::SHIFT; } if mods.ctrl || mods.command { result |= KeyModifiers::CONTROL; } if mods.alt { result |= KeyModifiers::ALT; } result } fn is_character_key(key: egui::Key) -> bool { matches!( key, egui::Key::A | egui::Key::B | egui::Key::C | egui::Key::D | egui::Key::E | egui::Key::F | egui::Key::G | egui::Key::H | egui::Key::I | egui::Key::J | egui::Key::K | egui::Key::L | egui::Key::M | egui::Key::N | egui::Key::O | egui::Key::P | egui::Key::Q | egui::Key::R | egui::Key::S | egui::Key::T | egui::Key::U | egui::Key::V | egui::Key::W | egui::Key::X | egui::Key::Y | egui::Key::Z | egui::Key::Num0 | egui::Key::Num1 | egui::Key::Num2 | egui::Key::Num3 | egui::Key::Num4 | egui::Key::Num5 | egui::Key::Num6 | egui::Key::Num7 | egui::Key::Num8 | egui::Key::Num9 | egui::Key::Space | egui::Key::Minus | egui::Key::Equals | egui::Key::OpenBracket | egui::Key::CloseBracket | egui::Key::Semicolon | egui::Key::Comma | egui::Key::Period | egui::Key::Slash | egui::Key::Backslash | egui::Key::Backtick | egui::Key::Quote ) }