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 {
|
||||
state.cursor.move_to(position);
|
||||
}
|
||||
state.is_dragging = true;
|
||||
|
||||
state.is_dragging = Some(Drag::Select);
|
||||
}
|
||||
click::Kind::Double => {
|
||||
if self.is_secure {
|
||||
state.cursor.select_all(&self.value);
|
||||
|
||||
state.is_dragging = None;
|
||||
} else {
|
||||
let position = find_cursor_position(
|
||||
text_layout.bounds(),
|
||||
|
|
@ -798,13 +801,15 @@ where
|
|||
self.value.previous_start_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 => {
|
||||
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::Touch(touch::Event::FingerLifted { .. })
|
||||
| Event::Touch(touch::Event::FingerLost { .. }) => {
|
||||
state::<Renderer>(tree).is_dragging = false;
|
||||
state::<Renderer>(tree).is_dragging = None;
|
||||
}
|
||||
Event::Mouse(mouse::Event::CursorMoved { position })
|
||||
| Event::Touch(touch::Event::FingerMoved { position, .. }) => {
|
||||
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 target = {
|
||||
|
|
@ -857,9 +862,27 @@ where
|
|||
|
||||
let selection_before = state.cursor.selection(&value);
|
||||
|
||||
state
|
||||
.cursor
|
||||
.select_range(state.cursor.start(&value), position);
|
||||
match is_dragging {
|
||||
Drag::Select => {
|
||||
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 {
|
||||
focus.updated_at = Instant::now();
|
||||
|
|
@ -1201,7 +1224,7 @@ where
|
|||
}
|
||||
keyboard::Key::Named(key::Named::Escape) => {
|
||||
state.is_focused = None;
|
||||
state.is_dragging = false;
|
||||
state.is_dragging = None;
|
||||
state.is_pasting = None;
|
||||
|
||||
state.keyboard_modifiers =
|
||||
|
|
@ -1430,7 +1453,7 @@ pub struct State<P: text::Paragraph> {
|
|||
placeholder: paragraph::Plain<P>,
|
||||
icon: paragraph::Plain<P>,
|
||||
is_focused: Option<Focus>,
|
||||
is_dragging: bool,
|
||||
is_dragging: Option<Drag>,
|
||||
is_pasting: Option<Value>,
|
||||
preedit: Option<input_method::Preedit>,
|
||||
last_click: Option<mouse::Click>,
|
||||
|
|
@ -1452,6 +1475,12 @@ struct Focus {
|
|||
is_window_focused: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum Drag {
|
||||
Select,
|
||||
SelectWords { anchor: usize },
|
||||
}
|
||||
|
||||
impl<P: text::Paragraph> State<P> {
|
||||
/// Creates a new [`State`], representing an unfocused [`TextInput`].
|
||||
pub fn new() -> Self {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue