Feat: lots of convenience stuff
This commit is contained in:
@@ -68,7 +68,9 @@ pub fn handle_key(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
|
||||
|
||||
if ctx.app.ui.show_title {
|
||||
ctx.dispatch(AppCommand::HideTitle);
|
||||
return InputResult::Continue;
|
||||
if matches!(key.code, KeyCode::Char('q') | KeyCode::Esc) {
|
||||
return InputResult::Continue;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.dispatch(AppCommand::ClearStatus);
|
||||
|
||||
@@ -60,15 +60,13 @@ pub fn convert_egui_events(ctx: &egui::Context) -> Vec<KeyEvent> {
|
||||
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);
|
||||
}
|
||||
convert_event(event, &mut events);
|
||||
}
|
||||
|
||||
events
|
||||
}
|
||||
|
||||
fn convert_event(event: &egui::Event) -> Option<KeyEvent> {
|
||||
fn convert_event(event: &egui::Event, events: &mut Vec<KeyEvent>) {
|
||||
match event {
|
||||
egui::Event::Key {
|
||||
key,
|
||||
@@ -77,33 +75,39 @@ fn convert_event(event: &egui::Event) -> Option<KeyEvent> {
|
||||
..
|
||||
} => {
|
||||
if !*pressed {
|
||||
return None;
|
||||
return;
|
||||
}
|
||||
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()));
|
||||
// For character keys, only handle Ctrl+key (without Alt) as shortcuts.
|
||||
// All other character input (bare, Shift, Alt/Option, AltGr=Ctrl+Alt)
|
||||
// defers to Event::Text which respects the active keyboard layout.
|
||||
if is_character_key(*key) {
|
||||
let ctrl_without_alt =
|
||||
mods.contains(KeyModifiers::CONTROL) && !mods.contains(KeyModifiers::ALT);
|
||||
if !ctrl_without_alt {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if let Some(code) = convert_key(*key) {
|
||||
events.push(KeyEvent::new(code, mods));
|
||||
}
|
||||
}
|
||||
egui::Event::Text(text) => {
|
||||
for c in text.chars() {
|
||||
if !c.is_control() {
|
||||
events.push(KeyEvent::new(KeyCode::Char(c), KeyModifiers::empty()));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
// egui intercepts Ctrl+C/V/X and converts them to these high-level events
|
||||
// instead of passing through raw Key events (see egui issue #4065).
|
||||
// Synthesize the equivalent KeyEvent so the application's input handler receives them.
|
||||
egui::Event::Copy => Some(KeyEvent::new(KeyCode::Char('c'), KeyModifiers::CONTROL)),
|
||||
egui::Event::Cut => Some(KeyEvent::new(KeyCode::Char('x'), KeyModifiers::CONTROL)),
|
||||
egui::Event::Paste(_) => Some(KeyEvent::new(KeyCode::Char('v'), KeyModifiers::CONTROL)),
|
||||
_ => None,
|
||||
egui::Event::Copy => events.push(KeyEvent::new(KeyCode::Char('c'), KeyModifiers::CONTROL)),
|
||||
egui::Event::Cut => events.push(KeyEvent::new(KeyCode::Char('x'), KeyModifiers::CONTROL)),
|
||||
egui::Event::Paste(_) => {
|
||||
events.push(KeyEvent::new(KeyCode::Char('v'), KeyModifiers::CONTROL));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +140,14 @@ fn convert_key(key: egui::Key) -> Option<KeyCode> {
|
||||
egui::Key::F10 => KeyCode::F(10),
|
||||
egui::Key::F11 => KeyCode::F(11),
|
||||
egui::Key::F12 => KeyCode::F(12),
|
||||
egui::Key::F13 => KeyCode::F(13),
|
||||
egui::Key::F14 => KeyCode::F(14),
|
||||
egui::Key::F15 => KeyCode::F(15),
|
||||
egui::Key::F16 => KeyCode::F(16),
|
||||
egui::Key::F17 => KeyCode::F(17),
|
||||
egui::Key::F18 => KeyCode::F(18),
|
||||
egui::Key::F19 => KeyCode::F(19),
|
||||
egui::Key::F20 => KeyCode::F(20),
|
||||
egui::Key::A => KeyCode::Char('a'),
|
||||
egui::Key::B => KeyCode::Char('b'),
|
||||
egui::Key::C => KeyCode::Char('c'),
|
||||
@@ -183,6 +195,13 @@ fn convert_key(key: egui::Key) -> Option<KeyCode> {
|
||||
egui::Key::Backslash => KeyCode::Char('\\'),
|
||||
egui::Key::Backtick => KeyCode::Char('`'),
|
||||
egui::Key::Quote => KeyCode::Char('\''),
|
||||
egui::Key::Colon => KeyCode::Char(':'),
|
||||
egui::Key::Pipe => KeyCode::Char('|'),
|
||||
egui::Key::Questionmark => KeyCode::Char('?'),
|
||||
egui::Key::Exclamationmark => KeyCode::Char('!'),
|
||||
egui::Key::OpenCurlyBracket => KeyCode::Char('{'),
|
||||
egui::Key::CloseCurlyBracket => KeyCode::Char('}'),
|
||||
egui::Key::Plus => KeyCode::Char('+'),
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
@@ -252,5 +271,12 @@ fn is_character_key(key: egui::Key) -> bool {
|
||||
| egui::Key::Backslash
|
||||
| egui::Key::Backtick
|
||||
| egui::Key::Quote
|
||||
| egui::Key::Colon
|
||||
| egui::Key::Pipe
|
||||
| egui::Key::Questionmark
|
||||
| egui::Key::Exclamationmark
|
||||
| egui::Key::OpenCurlyBracket
|
||||
| egui::Key::CloseCurlyBracket
|
||||
| egui::Key::Plus
|
||||
)
|
||||
}
|
||||
|
||||
@@ -465,7 +465,7 @@ fn render_footer(frame: &mut Frame, app: &App, area: Rect) {
|
||||
Page::Main => vec![
|
||||
("Space", "Play"),
|
||||
("Enter", "Edit"),
|
||||
("t", "Toggle"),
|
||||
("t", "On/Off"),
|
||||
("Tab", "Samples"),
|
||||
("?", "Keys"),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user