Merge pull request #2865 from andymandias/expand-selection-by-word
Expandable Selection-by-Word via Mouse/Touch in `text_input`
This commit is contained in:
commit
1533d18640
1 changed files with 40 additions and 11 deletions
|
|
@ -780,11 +780,14 @@ where
|
||||||
} else {
|
} else {
|
||||||
state.cursor.move_to(position);
|
state.cursor.move_to(position);
|
||||||
}
|
}
|
||||||
state.is_dragging = true;
|
|
||||||
|
state.is_dragging = Some(Drag::Select);
|
||||||
}
|
}
|
||||||
click::Kind::Double => {
|
click::Kind::Double => {
|
||||||
if self.is_secure {
|
if self.is_secure {
|
||||||
state.cursor.select_all(&self.value);
|
state.cursor.select_all(&self.value);
|
||||||
|
|
||||||
|
state.is_dragging = None;
|
||||||
} else {
|
} else {
|
||||||
let position = find_cursor_position(
|
let position = find_cursor_position(
|
||||||
text_layout.bounds(),
|
text_layout.bounds(),
|
||||||
|
|
@ -798,13 +801,15 @@ where
|
||||||
self.value.previous_start_of_word(position),
|
self.value.previous_start_of_word(position),
|
||||||
self.value.next_end_of_word(position),
|
self.value.next_end_of_word(position),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
state.is_dragging = false;
|
state.is_dragging = Some(Drag::SelectWords {
|
||||||
|
anchor: position,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
click::Kind::Triple => {
|
click::Kind::Triple => {
|
||||||
state.cursor.select_all(&self.value);
|
state.cursor.select_all(&self.value);
|
||||||
state.is_dragging = false;
|
state.is_dragging = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -820,13 +825,13 @@ where
|
||||||
Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left))
|
Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left))
|
||||||
| Event::Touch(touch::Event::FingerLifted { .. })
|
| Event::Touch(touch::Event::FingerLifted { .. })
|
||||||
| Event::Touch(touch::Event::FingerLost { .. }) => {
|
| Event::Touch(touch::Event::FingerLost { .. }) => {
|
||||||
state::<Renderer>(tree).is_dragging = false;
|
state::<Renderer>(tree).is_dragging = None;
|
||||||
}
|
}
|
||||||
Event::Mouse(mouse::Event::CursorMoved { position })
|
Event::Mouse(mouse::Event::CursorMoved { position })
|
||||||
| Event::Touch(touch::Event::FingerMoved { position, .. }) => {
|
| Event::Touch(touch::Event::FingerMoved { position, .. }) => {
|
||||||
let state = state::<Renderer>(tree);
|
let state = state::<Renderer>(tree);
|
||||||
|
|
||||||
if state.is_dragging {
|
if let Some(is_dragging) = &state.is_dragging {
|
||||||
let text_layout = layout.children().next().unwrap();
|
let text_layout = layout.children().next().unwrap();
|
||||||
|
|
||||||
let target = {
|
let target = {
|
||||||
|
|
@ -857,9 +862,27 @@ where
|
||||||
|
|
||||||
let selection_before = state.cursor.selection(&value);
|
let selection_before = state.cursor.selection(&value);
|
||||||
|
|
||||||
state
|
match is_dragging {
|
||||||
.cursor
|
Drag::Select => {
|
||||||
.select_range(state.cursor.start(&value), position);
|
state.cursor.select_range(
|
||||||
|
state.cursor.start(&value),
|
||||||
|
position,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Drag::SelectWords { anchor } => {
|
||||||
|
if position < *anchor {
|
||||||
|
state.cursor.select_range(
|
||||||
|
self.value.previous_start_of_word(position),
|
||||||
|
self.value.next_end_of_word(*anchor),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
state.cursor.select_range(
|
||||||
|
self.value.previous_start_of_word(*anchor),
|
||||||
|
self.value.next_end_of_word(position),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(focus) = &mut state.is_focused {
|
if let Some(focus) = &mut state.is_focused {
|
||||||
focus.updated_at = Instant::now();
|
focus.updated_at = Instant::now();
|
||||||
|
|
@ -1201,7 +1224,7 @@ where
|
||||||
}
|
}
|
||||||
keyboard::Key::Named(key::Named::Escape) => {
|
keyboard::Key::Named(key::Named::Escape) => {
|
||||||
state.is_focused = None;
|
state.is_focused = None;
|
||||||
state.is_dragging = false;
|
state.is_dragging = None;
|
||||||
state.is_pasting = None;
|
state.is_pasting = None;
|
||||||
|
|
||||||
state.keyboard_modifiers =
|
state.keyboard_modifiers =
|
||||||
|
|
@ -1430,7 +1453,7 @@ pub struct State<P: text::Paragraph> {
|
||||||
placeholder: paragraph::Plain<P>,
|
placeholder: paragraph::Plain<P>,
|
||||||
icon: paragraph::Plain<P>,
|
icon: paragraph::Plain<P>,
|
||||||
is_focused: Option<Focus>,
|
is_focused: Option<Focus>,
|
||||||
is_dragging: bool,
|
is_dragging: Option<Drag>,
|
||||||
is_pasting: Option<Value>,
|
is_pasting: Option<Value>,
|
||||||
preedit: Option<input_method::Preedit>,
|
preedit: Option<input_method::Preedit>,
|
||||||
last_click: Option<mouse::Click>,
|
last_click: Option<mouse::Click>,
|
||||||
|
|
@ -1452,6 +1475,12 @@ struct Focus {
|
||||||
is_window_focused: bool,
|
is_window_focused: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
enum Drag {
|
||||||
|
Select,
|
||||||
|
SelectWords { anchor: usize },
|
||||||
|
}
|
||||||
|
|
||||||
impl<P: text::Paragraph> State<P> {
|
impl<P: text::Paragraph> State<P> {
|
||||||
/// Creates a new [`State`], representing an unfocused [`TextInput`].
|
/// Creates a new [`State`], representing an unfocused [`TextInput`].
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue