diff --git a/core/src/widget/operation/text_input.rs b/core/src/widget/operation/text_input.rs index de2ac1a0..6fbafb79 100644 --- a/core/src/widget/operation/text_input.rs +++ b/core/src/widget/operation/text_input.rs @@ -21,6 +21,8 @@ pub trait TextInput { /// Selects all the content of the text input. fn select_all(&mut self); + /// Selects the given content range of the text input. + fn select_range(&mut self, start: usize, end: usize); } /// Produces an [`Operation`] that moves the cursor of the widget with the given [`Id`] to the @@ -142,3 +144,38 @@ pub fn select_all(target: Id) -> impl Operation { MoveCursor { target } } + +/// Produces an [`Operation`] that selects the given content range of the widget with the given [`Id`]. +pub fn select_range( + target: Id, + start: usize, + end: usize, +) -> impl Operation { + struct SelectRange { + target: Id, + start: usize, + end: usize, + } + + impl Operation for SelectRange { + fn text_input( + &mut self, + id: Option<&Id>, + _bounds: Rectangle, + state: &mut dyn TextInput, + ) { + match id { + Some(id) if id == &self.target => { + state.select_range(self.start, self.end); + } + _ => {} + } + } + + fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation)) { + operate(self); + } + } + + SelectRange { target, start, end } +} diff --git a/runtime/src/widget/operation.rs b/runtime/src/widget/operation.rs index ab03bbe0..8a1af55a 100644 --- a/runtime/src/widget/operation.rs +++ b/runtime/src/widget/operation.rs @@ -86,3 +86,12 @@ pub fn move_cursor_to(id: impl Into, position: usize) -> Task { pub fn select_all(id: impl Into) -> Task { task::effect(Action::widget(operation::text_input::select_all(id.into()))) } + +/// Selects the given content range of the widget with the given [`Id`]. +pub fn select_range(id: impl Into, start: usize, end: usize) -> Task { + task::effect(Action::widget(operation::text_input::select_range( + id.into(), + start, + end, + ))) +} diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 2d6ac701..469f6c63 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -1534,6 +1534,11 @@ impl State

{ pub fn select_all(&mut self) { self.cursor.select_range(0, usize::MAX); } + + /// Selects the given range of the content of the [`TextInput`]. + pub fn select_range(&mut self, start: usize, end: usize) { + self.cursor.select_range(start, end); + } } impl operation::Focusable for State

{ @@ -1574,6 +1579,10 @@ impl operation::TextInput for State

{ fn select_all(&mut self) { State::select_all(self); } + + fn select_range(&mut self, start: usize, end: usize) { + State::select_range(self, start, end); + } } fn offset(