text: Add advanced horizontal text control codes

This commit is contained in:
Kamil Jarosz 2024-01-30 02:46:31 +01:00 committed by Nathan Adams
parent b39919951b
commit 0657d2daa2
3 changed files with 71 additions and 44 deletions

View File

@ -337,18 +337,31 @@ impl<'gc> ClipEvent<'gc> {
/// Control inputs to a text field /// Control inputs to a text field
#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize)]
pub enum TextControlCode { pub enum TextControlCode {
// TODO: Add control codes for Ctrl+Arrows and Home/End keys
MoveLeft, MoveLeft,
MoveLeftWord,
MoveLeftLine,
MoveLeftDocument,
MoveRight, MoveRight,
MoveRightWord,
MoveRightLine,
MoveRightDocument,
SelectLeft, SelectLeft,
SelectLeftWord,
SelectLeftLine,
SelectLeftDocument,
SelectRight, SelectRight,
SelectRightWord,
SelectRightLine,
SelectRightDocument,
SelectAll, SelectAll,
Copy, Copy,
Paste, Paste,
Cut, Cut,
Backspace, Backspace,
BackspaceWord,
Enter, Enter,
Delete, Delete,
DeleteWord,
} }
impl TextControlCode { impl TextControlCode {
@ -356,7 +369,13 @@ impl TextControlCode {
pub fn is_edit_input(self) -> bool { pub fn is_edit_input(self) -> bool {
matches!( matches!(
self, self,
Self::Paste | Self::Cut | Self::Backspace | Self::Enter | Self::Delete Self::Paste
| Self::Cut
| Self::Enter
| Self::Backspace
| Self::BackspaceWord
| Self::Delete
| Self::DeleteWord
) )
} }
} }

View File

@ -11,7 +11,6 @@ use winit::keyboard::{Key, KeyLocation, NamedKey};
/// Converts a winit event to a Ruffle `TextControlCode`. /// Converts a winit event to a Ruffle `TextControlCode`.
/// Returns `None` if there is no match. /// Returns `None` if there is no match.
/// TODO: Handle Ctrl+Arrows and Home/End keys
pub fn winit_to_ruffle_text_control( pub fn winit_to_ruffle_text_control(
event: &KeyEvent, event: &KeyEvent,
modifiers: &Modifiers, modifiers: &Modifiers,
@ -19,34 +18,40 @@ pub fn winit_to_ruffle_text_control(
let shift = modifiers.state().shift_key(); let shift = modifiers.state().shift_key();
let ctrl_cmd = modifiers.state().control_key() let ctrl_cmd = modifiers.state().control_key()
|| (modifiers.state().super_key() && cfg!(target_os = "macos")); || (modifiers.state().super_key() && cfg!(target_os = "macos"));
if ctrl_cmd { match event.logical_key.as_ref() {
match event.logical_key.as_ref() { Key::Character("a") if ctrl_cmd => Some(TextControlCode::SelectAll),
Key::Character("a") => Some(TextControlCode::SelectAll), Key::Character("c") if ctrl_cmd => Some(TextControlCode::Copy),
Key::Character("c") => Some(TextControlCode::Copy), Key::Character("v") if ctrl_cmd => Some(TextControlCode::Paste),
Key::Character("v") => Some(TextControlCode::Paste), Key::Character("x") if ctrl_cmd => Some(TextControlCode::Cut),
Key::Character("x") => Some(TextControlCode::Cut), Key::Named(NamedKey::Backspace) if ctrl_cmd => Some(TextControlCode::BackspaceWord),
_ => None, Key::Named(NamedKey::Backspace) => Some(TextControlCode::Backspace),
Key::Named(NamedKey::Delete) if ctrl_cmd => Some(TextControlCode::DeleteWord),
Key::Named(NamedKey::Delete) => Some(TextControlCode::Delete),
Key::Named(NamedKey::ArrowLeft) if ctrl_cmd && shift => {
Some(TextControlCode::SelectLeftWord)
} }
} else { Key::Named(NamedKey::ArrowLeft) if ctrl_cmd => Some(TextControlCode::MoveLeftWord),
match event.logical_key.as_ref() { Key::Named(NamedKey::ArrowLeft) if shift => Some(TextControlCode::SelectLeft),
Key::Named(NamedKey::Backspace) => Some(TextControlCode::Backspace), Key::Named(NamedKey::ArrowLeft) => Some(TextControlCode::MoveLeft),
Key::Named(NamedKey::Delete) => Some(TextControlCode::Delete), Key::Named(NamedKey::ArrowRight) if ctrl_cmd && shift => {
Key::Named(NamedKey::ArrowLeft) => { Some(TextControlCode::SelectRightWord)
if shift {
Some(TextControlCode::SelectLeft)
} else {
Some(TextControlCode::MoveLeft)
}
}
Key::Named(NamedKey::ArrowRight) => {
if shift {
Some(TextControlCode::SelectRight)
} else {
Some(TextControlCode::MoveRight)
}
}
_ => None,
} }
Key::Named(NamedKey::ArrowRight) if ctrl_cmd => Some(TextControlCode::MoveRightWord),
Key::Named(NamedKey::ArrowRight) if shift => Some(TextControlCode::SelectRight),
Key::Named(NamedKey::ArrowRight) => Some(TextControlCode::MoveRight),
Key::Named(NamedKey::Home) if ctrl_cmd && shift => {
Some(TextControlCode::SelectLeftDocument)
}
Key::Named(NamedKey::Home) if ctrl_cmd => Some(TextControlCode::MoveLeftDocument),
Key::Named(NamedKey::Home) if shift => Some(TextControlCode::SelectLeftLine),
Key::Named(NamedKey::Home) => Some(TextControlCode::MoveLeftLine),
Key::Named(NamedKey::End) if ctrl_cmd && shift => {
Some(TextControlCode::SelectRightDocument)
}
Key::Named(NamedKey::End) if ctrl_cmd => Some(TextControlCode::MoveRightDocument),
Key::Named(NamedKey::End) if shift => Some(TextControlCode::SelectRightLine),
Key::Named(NamedKey::End) => Some(TextControlCode::MoveRightLine),
_ => None,
} }
} }

View File

@ -1934,7 +1934,6 @@ fn web_key_to_codepoint(key: &str) -> Option<char> {
/// Convert a web `KeyboardEvent.key` value to a Ruffle `TextControlCode`, /// Convert a web `KeyboardEvent.key` value to a Ruffle `TextControlCode`,
/// given the states of the modifier keys. Return `None` if there is no match. /// given the states of the modifier keys. Return `None` if there is no match.
/// TODO: Handle Ctrl+Arrows and Home/End keys
pub fn web_to_ruffle_text_control( pub fn web_to_ruffle_text_control(
key: &str, key: &str,
ctrl_key: bool, ctrl_key: bool,
@ -1957,22 +1956,26 @@ pub fn web_to_ruffle_text_control(
} }
} else { } else {
match key { match key {
"Delete" if ctrl_key => Some(TextControlCode::DeleteWord),
"Delete" => Some(TextControlCode::Delete), "Delete" => Some(TextControlCode::Delete),
"Backspace" if ctrl_key => Some(TextControlCode::BackspaceWord),
"Backspace" => Some(TextControlCode::Backspace), "Backspace" => Some(TextControlCode::Backspace),
"ArrowLeft" => { "ArrowLeft" if ctrl_key && shift_key => Some(TextControlCode::SelectLeftWord),
if shift_key { "ArrowLeft" if ctrl_key => Some(TextControlCode::MoveLeftWord),
Some(TextControlCode::SelectLeft) "ArrowLeft" if shift_key => Some(TextControlCode::SelectLeft),
} else { "ArrowLeft" => Some(TextControlCode::MoveLeft),
Some(TextControlCode::MoveLeft) "ArrowRight" if ctrl_key && shift_key => Some(TextControlCode::SelectRightWord),
} "ArrowRight" if ctrl_key => Some(TextControlCode::MoveRightWord),
} "ArrowRight" if shift_key => Some(TextControlCode::SelectRight),
"ArrowRight" => { "ArrowRight" => Some(TextControlCode::MoveRight),
if shift_key { "Home" if ctrl_key && shift_key => Some(TextControlCode::SelectLeftDocument),
Some(TextControlCode::SelectRight) "Home" if ctrl_key => Some(TextControlCode::MoveLeftDocument),
} else { "Home" if shift_key => Some(TextControlCode::SelectLeftLine),
Some(TextControlCode::MoveRight) "Home" => Some(TextControlCode::MoveLeftLine),
} "End" if ctrl_key && shift_key => Some(TextControlCode::SelectRightDocument),
} "End" if ctrl_key => Some(TextControlCode::MoveRightDocument),
"End" if shift_key => Some(TextControlCode::SelectRightLine),
"End" => Some(TextControlCode::MoveRightLine),
_ => None, _ => None,
} }
} }