From 7c661c94beec89bc467b75a1d3193fb40aefd9d3 Mon Sep 17 00:00:00 2001 From: Remmirad Date: Sat, 12 Apr 2025 12:25:39 +0200 Subject: [PATCH 1/2] Introduce `select_range` to `operation::text_input` --- core/src/widget/operation/text_input.rs | 37 +++++++++++++++++++++++++ widget/src/text_input.rs | 9 ++++++ 2 files changed, 46 insertions(+) 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/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( From e3e94de473109335ae290d308841de988b3694de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 25 Nov 2025 10:40:12 +0100 Subject: [PATCH 2/2] Expose `select_range` in `runtime::widget::operation` --- runtime/src/widget/operation.rs | 9 +++++++++ 1 file changed, 9 insertions(+) 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, + ))) +}