Text editing: improve double-click to select word
This commit is contained in:
parent
ab61f98a13
commit
861573c497
1 changed files with 49 additions and 8 deletions
|
@ -94,6 +94,13 @@ impl CCursorPair {
|
||||||
secondary: ccursor,
|
secondary: ccursor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn two(min: CCursor, max: CCursor) -> Self {
|
||||||
|
Self {
|
||||||
|
primary: max,
|
||||||
|
secondary: min,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A text region that the user can edit the contents of.
|
/// A text region that the user can edit the contents of.
|
||||||
|
@ -272,12 +279,10 @@ impl<'t> Widget for TextEdit<'t> {
|
||||||
if response.hovered && response.double_clicked {
|
if response.hovered && response.double_clicked {
|
||||||
// Select word:
|
// Select word:
|
||||||
let center = cursor_at_mouse;
|
let center = cursor_at_mouse;
|
||||||
let primary =
|
let ccursorp = select_word_at(text, center.ccursor);
|
||||||
galley.from_ccursor(ccursor_next_word(&galley.text, center.ccursor));
|
|
||||||
state.cursorp = Some(CursorPair {
|
state.cursorp = Some(CursorPair {
|
||||||
secondary: galley
|
primary: galley.from_ccursor(ccursorp.primary),
|
||||||
.from_ccursor(ccursor_previous_word(&galley.text, primary.ccursor)),
|
secondary: galley.from_ccursor(ccursorp.secondary),
|
||||||
primary,
|
|
||||||
});
|
});
|
||||||
} else if response.hovered && ui.input().mouse.pressed {
|
} else if response.hovered && ui.input().mouse.pressed {
|
||||||
ui.memory().request_kb_focus(id);
|
ui.memory().request_kb_focus(id);
|
||||||
|
@ -801,9 +806,44 @@ fn move_single_cursor(cursor: &mut Cursor, galley: &Galley, key: Key, modifiers:
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
fn select_word_at(text: &str, ccursor: CCursor) -> CCursorPair {
|
||||||
|
if ccursor.index == 0 {
|
||||||
|
CCursorPair::two(ccursor, ccursor_next_word(text, ccursor))
|
||||||
|
} else {
|
||||||
|
let it = text.chars();
|
||||||
|
let mut it = it.skip(ccursor.index - 1);
|
||||||
|
if let Some(char_before_cursor) = it.next() {
|
||||||
|
if let Some(char_after_cursor) = it.next() {
|
||||||
|
if is_word_char(char_before_cursor) && is_word_char(char_after_cursor) {
|
||||||
|
let min = ccursor_previous_word(text, ccursor + 1);
|
||||||
|
let max = ccursor_next_word(text, min);
|
||||||
|
CCursorPair::two(min, max)
|
||||||
|
} else if is_word_char(char_before_cursor) {
|
||||||
|
let min = ccursor_previous_word(text, ccursor);
|
||||||
|
let max = ccursor_next_word(text, min);
|
||||||
|
CCursorPair::two(min, max)
|
||||||
|
} else if is_word_char(char_after_cursor) {
|
||||||
|
let max = ccursor_next_word(text, ccursor);
|
||||||
|
CCursorPair::two(ccursor, max)
|
||||||
|
} else {
|
||||||
|
let min = ccursor_previous_word(text, ccursor);
|
||||||
|
let max = ccursor_next_word(text, ccursor);
|
||||||
|
CCursorPair::two(min, max)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let min = ccursor_previous_word(text, ccursor);
|
||||||
|
CCursorPair::two(min, ccursor)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let max = ccursor_next_word(text, ccursor);
|
||||||
|
CCursorPair::two(ccursor, max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn ccursor_next_word(text: &str, ccursor: CCursor) -> CCursor {
|
fn ccursor_next_word(text: &str, ccursor: CCursor) -> CCursor {
|
||||||
CCursor {
|
CCursor {
|
||||||
index: next_word_char_index(text.chars(), ccursor.index),
|
index: next_word_boundary_char_index(text.chars(), ccursor.index),
|
||||||
prefer_next_row: false,
|
prefer_next_row: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -811,12 +851,13 @@ fn ccursor_next_word(text: &str, ccursor: CCursor) -> CCursor {
|
||||||
fn ccursor_previous_word(text: &str, ccursor: CCursor) -> CCursor {
|
fn ccursor_previous_word(text: &str, ccursor: CCursor) -> CCursor {
|
||||||
let num_chars = text.chars().count();
|
let num_chars = text.chars().count();
|
||||||
CCursor {
|
CCursor {
|
||||||
index: num_chars - next_word_char_index(text.chars().rev(), num_chars - ccursor.index),
|
index: num_chars
|
||||||
|
- next_word_boundary_char_index(text.chars().rev(), num_chars - ccursor.index),
|
||||||
prefer_next_row: true,
|
prefer_next_row: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_word_char_index(it: impl Iterator<Item = char>, mut index: usize) -> usize {
|
fn next_word_boundary_char_index(it: impl Iterator<Item = char>, mut index: usize) -> usize {
|
||||||
let mut it = it.skip(index);
|
let mut it = it.skip(index);
|
||||||
if let Some(_first) = it.next() {
|
if let Some(_first) = it.next() {
|
||||||
index += 1;
|
index += 1;
|
||||||
|
|
Loading…
Reference in a new issue