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
#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize)]
pub enum TextControlCode {
// TODO: Add control codes for Ctrl+Arrows and Home/End keys
MoveLeft,
MoveLeftWord,
MoveLeftLine,
MoveLeftDocument,
MoveRight,
MoveRightWord,
MoveRightLine,
MoveRightDocument,
SelectLeft,
SelectLeftWord,
SelectLeftLine,
SelectLeftDocument,
SelectRight,
SelectRightWord,
SelectRightLine,
SelectRightDocument,
SelectAll,
Copy,
Paste,
Cut,
Backspace,
BackspaceWord,
Enter,
Delete,
DeleteWord,
}
impl TextControlCode {
@ -356,7 +369,13 @@ impl TextControlCode {
pub fn is_edit_input(self) -> bool {
matches!(
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`.
/// Returns `None` if there is no match.
/// TODO: Handle Ctrl+Arrows and Home/End keys
pub fn winit_to_ruffle_text_control(
event: &KeyEvent,
modifiers: &Modifiers,
@ -19,34 +18,40 @@ pub fn winit_to_ruffle_text_control(
let shift = modifiers.state().shift_key();
let ctrl_cmd = modifiers.state().control_key()
|| (modifiers.state().super_key() && cfg!(target_os = "macos"));
if ctrl_cmd {
match event.logical_key.as_ref() {
Key::Character("a") => Some(TextControlCode::SelectAll),
Key::Character("c") => Some(TextControlCode::Copy),
Key::Character("v") => Some(TextControlCode::Paste),
Key::Character("x") => Some(TextControlCode::Cut),
_ => None,
match event.logical_key.as_ref() {
Key::Character("a") if ctrl_cmd => Some(TextControlCode::SelectAll),
Key::Character("c") if ctrl_cmd => Some(TextControlCode::Copy),
Key::Character("v") if ctrl_cmd => Some(TextControlCode::Paste),
Key::Character("x") if ctrl_cmd => Some(TextControlCode::Cut),
Key::Named(NamedKey::Backspace) if ctrl_cmd => Some(TextControlCode::BackspaceWord),
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 {
match event.logical_key.as_ref() {
Key::Named(NamedKey::Backspace) => Some(TextControlCode::Backspace),
Key::Named(NamedKey::Delete) => Some(TextControlCode::Delete),
Key::Named(NamedKey::ArrowLeft) => {
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::ArrowLeft) if ctrl_cmd => Some(TextControlCode::MoveLeftWord),
Key::Named(NamedKey::ArrowLeft) if shift => Some(TextControlCode::SelectLeft),
Key::Named(NamedKey::ArrowLeft) => Some(TextControlCode::MoveLeft),
Key::Named(NamedKey::ArrowRight) if ctrl_cmd && shift => {
Some(TextControlCode::SelectRightWord)
}
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`,
/// 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(
key: &str,
ctrl_key: bool,
@ -1957,22 +1956,26 @@ pub fn web_to_ruffle_text_control(
}
} else {
match key {
"Delete" if ctrl_key => Some(TextControlCode::DeleteWord),
"Delete" => Some(TextControlCode::Delete),
"Backspace" if ctrl_key => Some(TextControlCode::BackspaceWord),
"Backspace" => Some(TextControlCode::Backspace),
"ArrowLeft" => {
if shift_key {
Some(TextControlCode::SelectLeft)
} else {
Some(TextControlCode::MoveLeft)
}
}
"ArrowRight" => {
if shift_key {
Some(TextControlCode::SelectRight)
} else {
Some(TextControlCode::MoveRight)
}
}
"ArrowLeft" if ctrl_key && shift_key => Some(TextControlCode::SelectLeftWord),
"ArrowLeft" if ctrl_key => Some(TextControlCode::MoveLeftWord),
"ArrowLeft" if shift_key => Some(TextControlCode::SelectLeft),
"ArrowLeft" => 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" => Some(TextControlCode::MoveRight),
"Home" if ctrl_key && shift_key => Some(TextControlCode::SelectLeftDocument),
"Home" if ctrl_key => Some(TextControlCode::MoveLeftDocument),
"Home" if shift_key => Some(TextControlCode::SelectLeftLine),
"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,
}
}